From 2865f496cfb683a01ce0c22e652e65e21c061b89 Mon Sep 17 00:00:00 2001 From: "5684185+vsariola@users.noreply.github.com" <5684185+vsariola@users.noreply.github.com> Date: Sun, 18 Jan 2026 16:59:54 +0200 Subject: [PATCH] drafting --- tracker/gioui/song_panel.go | 108 +++++++++++++++++++++++++++++++--- tracker/gioui/specanalyzer.go | 2 +- tracker/gioui/theme.go | 1 + tracker/gioui/theme.yml | 1 + 4 files changed, 103 insertions(+), 9 deletions(-) diff --git a/tracker/gioui/song_panel.go b/tracker/gioui/song_panel.go index 82f91d6..a32603e 100644 --- a/tracker/gioui/song_panel.go +++ b/tracker/gioui/song_panel.go @@ -8,7 +8,10 @@ import ( "strconv" "strings" + "gioui.org/f32" "gioui.org/gesture" + "gioui.org/io/event" + "gioui.org/io/pointer" "gioui.org/layout" "gioui.org/op/clip" "gioui.org/op/paint" @@ -41,9 +44,11 @@ type SongPanel struct { List *layout.List ScrollBar *ScrollBar - Scope *OscilloscopeState + Scope *OscilloscopeState + ScopeScaleBar *ScaleBar - SpectrumState *SpectrumState + SpectrumState *SpectrumState + SpectrumScaleBar *ScaleBar MenuBar *MenuBar PlayBar *PlayBar @@ -74,7 +79,9 @@ func NewSongPanel(tr *Tracker) *SongPanel { List: &layout.List{Axis: layout.Vertical}, ScrollBar: &ScrollBar{Axis: layout.Vertical}, - SpectrumState: NewSpectrumState(), + SpectrumState: NewSpectrumState(), + SpectrumScaleBar: &ScaleBar{Axis: layout.Vertical, BarSize: 10, Size: 300}, + ScopeScaleBar: &ScaleBar{Axis: layout.Vertical, BarSize: 10, Size: 300}, } return ret } @@ -263,12 +270,16 @@ func (t *SongPanel) layoutSongOptions(gtx C) D { }, ) case 4: - gtx.Constraints.Max.Y = gtx.Dp(300) scope := Scope(tr.Theme, tr.Model.SignalAnalyzer(), t.Scope) - return t.ScopeExpander.Layout(gtx, tr.Theme, "Oscilloscope", func(gtx C) D { return D{} }, scope.Layout) + scopeScaleBar := func(gtx C) D { + return t.ScopeScaleBar.Layout(gtx, scope.Layout) + } + return t.ScopeExpander.Layout(gtx, tr.Theme, "Oscilloscope", func(gtx C) D { return D{} }, scopeScaleBar) case 5: - gtx.Constraints.Max.Y = gtx.Dp(300) - return t.SpectrumExpander.Layout(gtx, tr.Theme, "Spectrum", func(gtx C) D { return D{} }, t.SpectrumState.Layout) + spectrumScaleBar := func(gtx C) D { + return t.SpectrumScaleBar.Layout(gtx, t.SpectrumState.Layout) + } + return t.SpectrumExpander.Layout(gtx, tr.Theme, "Spectrum", func(gtx C) D { return D{} }, spectrumScaleBar) case 6: return Label(tr.Theme, &tr.Theme.SongPanel.Version, version.VersionOrHash).Layout(gtx) default: @@ -277,7 +288,7 @@ func (t *SongPanel) layoutSongOptions(gtx C) D { } gtx.Constraints.Min = gtx.Constraints.Max dims := t.List.Layout(gtx, 7, listItem) - t.ScrollBar.Layout(gtx, &tr.Theme.ScrollBar, 7, &t.List.Position) + t.ScrollBar.Layout(gtx, &tr.Theme.SongPanel.ScrollBar, 7, &t.List.Position) tr.SpecAnEnabled().SetValue(t.SpectrumExpander.Expanded) return dims } @@ -303,6 +314,87 @@ func layoutSongOptionRow(gtx C, th *Theme, label string, widget layout.Widget) D ) } +type ScaleBar struct { + Size, BarSize unit.Dp + Axis layout.Axis + + drag bool + dragID pointer.ID + dragStart f32.Point +} + +func (s *ScaleBar) Layout(gtx C, w layout.Widget) D { + s.Update(gtx) + pxBar := gtx.Dp(s.BarSize) + pxTot := gtx.Dp(s.Size) + pxBar + var rect image.Rectangle + var size image.Point + if s.Axis == layout.Horizontal { + pxTot = min(max(gtx.Constraints.Min.X, pxTot), gtx.Constraints.Max.X) + px := pxTot - pxBar + rect = image.Rect(px, 0, pxTot, gtx.Constraints.Max.Y) + size = image.Pt(pxTot, gtx.Constraints.Max.Y) + gtx.Constraints.Max.X = px + gtx.Constraints.Min.X = min(gtx.Constraints.Min.X, px) + } else { + pxTot = min(max(gtx.Constraints.Min.Y, pxTot), gtx.Constraints.Max.Y) + px := pxTot - pxBar + rect = image.Rect(0, px, gtx.Constraints.Max.X, pxTot) + size = image.Pt(gtx.Constraints.Max.X, pxTot) + gtx.Constraints.Max.Y = px + gtx.Constraints.Min.Y = min(gtx.Constraints.Min.Y, px) + } + area := clip.Rect(rect).Push(gtx.Ops) + event.Op(gtx.Ops, s) + if s.Axis == layout.Horizontal { + pointer.CursorColResize.Add(gtx.Ops) + } else { + pointer.CursorRowResize.Add(gtx.Ops) + } + area.Pop() + w(gtx) + return D{Size: size} +} + +func (s *ScaleBar) Update(gtx C) { + for { + ev, ok := gtx.Event(pointer.Filter{ + Target: s, + Kinds: pointer.Press | pointer.Drag | pointer.Release, + }) + if !ok { + break + } + e, ok := ev.(pointer.Event) + if !ok { + continue + } + + switch e.Kind { + case pointer.Press: + if s.drag { + break + } + s.dragID = e.PointerID + s.dragStart = e.Position + s.drag = true + case pointer.Drag: + if s.dragID != e.PointerID { + break + } + if s.Axis == layout.Horizontal { + s.Size += gtx.Metric.PxToDp(int(e.Position.X - s.dragStart.X)) + } else { + s.Size += gtx.Metric.PxToDp(int(e.Position.Y - s.dragStart.Y)) + } + s.Size = max(s.Size, unit.Dp(50)) + s.dragStart = e.Position + case pointer.Release, pointer.Cancel: + s.drag = false + } + } +} + type Expander struct { Expanded bool click gesture.Click diff --git a/tracker/gioui/specanalyzer.go b/tracker/gioui/specanalyzer.go index 56ffe55..9de8a95 100644 --- a/tracker/gioui/specanalyzer.go +++ b/tracker/gioui/specanalyzer.go @@ -26,7 +26,7 @@ const ( func NewSpectrumState() *SpectrumState { return &SpectrumState{ - plot: NewPlot(plotRange{-4, 0}, plotRange{SpectrumDbMax, SpectrumDbMin}, SpectrumDbMin), + plot: NewPlot(plotRange{-3.7, 0}, plotRange{SpectrumDbMax, SpectrumDbMin}, SpectrumDbMin), resolutionNumber: NewNumericUpDownState(), speed: NewNumericUpDownState(), chnModeBtn: new(Clickable), diff --git a/tracker/gioui/theme.go b/tracker/gioui/theme.go index 8ea4a41..141c448 100644 --- a/tracker/gioui/theme.go +++ b/tracker/gioui/theme.go @@ -41,6 +41,7 @@ type Theme struct { Version LabelStyle ErrorColor color.NRGBA Bg color.NRGBA + ScrollBar ScrollBarStyle } Alert AlertStyles NoteEditor struct { diff --git a/tracker/gioui/theme.yml b/tracker/gioui/theme.yml index d5d5850..cd08210 100644 --- a/tracker/gioui/theme.yml +++ b/tracker/gioui/theme.yml @@ -113,6 +113,7 @@ songpanel: version: textsize: 12 color: *mediumemphasis + scrollbar: { width: 6, color: *scrollbarcolor } alert: error: bg: *errorcolor