From 42c95ab8eefd4c556e388171dd740e7ade9a0e3b Mon Sep 17 00:00:00 2001 From: "5684185+vsariola@users.noreply.github.com" <5684185+vsariola@users.noreply.github.com> Date: Sun, 27 Apr 2025 09:07:46 +0300 Subject: [PATCH] feat(tracker/gioui): rework the labels of numeric updowns --- tracker/gioui/instrument_editor.go | 19 ++++---- tracker/gioui/note_editor.go | 6 ++- tracker/gioui/numericupdown.go | 4 +- tracker/gioui/oscilloscope.go | 19 ++++++-- tracker/gioui/songpanel.go | 71 +++++++++--------------------- 5 files changed, 49 insertions(+), 70 deletions(-) diff --git a/tracker/gioui/instrument_editor.go b/tracker/gioui/instrument_editor.go index ec5faad..1d30721 100644 --- a/tracker/gioui/instrument_editor.go +++ b/tracker/gioui/instrument_editor.go @@ -138,20 +138,15 @@ func (ie *InstrumentEditor) Layout(gtx C, t *Tracker) D { newBtnStyle := ActionIcon(gtx, t.Theme, ie.newInstrumentBtn, icons.ContentAdd, ie.addInstrumentHint) ret := layout.Flex{Axis: layout.Vertical}.Layout(gtx, layout.Rigid(func(gtx C) D { - return layout.Flex{}.Layout( + return layout.Flex{Axis: layout.Horizontal, Alignment: layout.Middle}.Layout( gtx, layout.Flexed(1, func(gtx C) D { return ie.layoutInstrumentList(gtx, t) }), - layout.Rigid(func(gtx C) D { - inset := layout.UniformInset(unit.Dp(6)) - return inset.Layout(gtx, func(gtx C) D { - return layout.Flex{Axis: layout.Horizontal}.Layout(gtx, - layout.Rigid(Label("OCT:", white, t.Theme.Shaper)), - layout.Rigid(octave), - ) - }) - }), + layout.Rigid(layout.Spacer{Width: 10}.Layout), + layout.Rigid(LabelStyle{Text: "Octave", Color: disabledTextColor, Alignment: layout.W, FontSize: t.Theme.TextSize * 14.0 / 16.0, Shaper: t.Theme.Shaper}.Layout), + layout.Rigid(layout.Spacer{Width: 4}.Layout), + layout.Rigid(octave), layout.Rigid(func(gtx C) D { return layout.E.Layout(gtx, linkBtnStyle.Layout) }), @@ -218,7 +213,9 @@ func (ie *InstrumentEditor) layoutInstrumentHeader(gtx C, t *Tracker) D { header := func(gtx C) D { return layout.Flex{Axis: layout.Horizontal, Alignment: layout.Middle}.Layout(gtx, - layout.Rigid(Label("Voices: ", white, t.Theme.Shaper)), + layout.Rigid(layout.Spacer{Width: 6}.Layout), + layout.Rigid(LabelStyle{Text: "Voices", Color: disabledTextColor, Alignment: layout.W, FontSize: t.Theme.TextSize * 14.0 / 16.0, Shaper: t.Theme.Shaper}.Layout), + layout.Rigid(layout.Spacer{Width: 4}.Layout), layout.Rigid(func(gtx layout.Context) layout.Dimensions { numStyle := NumericUpDown(t.Theme, t.InstrumentVoices, "Number of voices for this instrument") dims := numStyle.Layout(gtx) diff --git a/tracker/gioui/note_editor.go b/tracker/gioui/note_editor.go index 0006878..4dcffa2 100644 --- a/tracker/gioui/note_editor.go +++ b/tracker/gioui/note_editor.go @@ -160,7 +160,7 @@ func (te *NoteEditor) layoutButtons(gtx C, t *Tracker) D { newTrackBtnStyle := ActionIcon(gtx, t.Theme, te.NewTrackBtn, icons.ContentAdd, te.addTrackHint) in := layout.UniformInset(unit.Dp(1)) voiceUpDown := func(gtx C) D { - numStyle := NumericUpDown(t.Theme, te.TrackVoices, "Number of voices for this track") + numStyle := NumericUpDown(t.Theme, te.TrackVoices, "Track voices") return in.Layout(gtx, numStyle.Layout) } effectBtnStyle := ToggleButton(gtx, t.Theme, te.EffectBtn, "Hex") @@ -175,7 +175,9 @@ func (te *NoteEditor) layoutButtons(gtx C, t *Tracker) D { layout.Rigid(noteOffBtnStyle.Layout), layout.Rigid(effectBtnStyle.Layout), layout.Rigid(uniqueBtnStyle.Layout), - layout.Rigid(Label(" Voices:", white, t.Theme.Shaper)), + layout.Rigid(layout.Spacer{Width: 10}.Layout), + layout.Rigid(LabelStyle{Text: "Voices", Color: disabledTextColor, Alignment: layout.W, FontSize: t.Theme.TextSize * 14.0 / 16.0, Shaper: t.Theme.Shaper}.Layout), + layout.Rigid(layout.Spacer{Width: 4}.Layout), layout.Rigid(voiceUpDown), layout.Rigid(splitTrackBtnStyle.Layout), layout.Flexed(1, func(gtx C) D { return layout.Dimensions{Size: gtx.Constraints.Min} }), diff --git a/tracker/gioui/numericupdown.go b/tracker/gioui/numericupdown.go index 2fa9540..bfa231d 100644 --- a/tracker/gioui/numericupdown.go +++ b/tracker/gioui/numericupdown.go @@ -110,14 +110,14 @@ func (s *NumericUpDownStyle) Update(gtx layout.Context) { } } -func (s *NumericUpDownStyle) Layout(gtx C) D { +func (s NumericUpDownStyle) Layout(gtx C) D { if s.Tooltip.Text.Text != "" { return s.NumberInput.tipArea.Layout(gtx, s.Tooltip, s.actualLayout) } return s.actualLayout(gtx) } -func (s NumericUpDownStyle) actualLayout(gtx C) D { +func (s *NumericUpDownStyle) actualLayout(gtx C) D { s.Update(gtx) gtx.Constraints = layout.Exact(image.Pt(gtx.Dp(s.Width), gtx.Dp(s.Height))) width := gtx.Dp(s.ButtonWidth) diff --git a/tracker/gioui/oscilloscope.go b/tracker/gioui/oscilloscope.go index 37aeda0..fb423e5 100644 --- a/tracker/gioui/oscilloscope.go +++ b/tracker/gioui/oscilloscope.go @@ -10,6 +10,7 @@ import ( "gioui.org/layout" "gioui.org/op/clip" "gioui.org/op/paint" + "gioui.org/unit" "gioui.org/widget/material" "github.com/vsariola/sointu/tracker" ) @@ -54,20 +55,30 @@ func (s *OscilloscopeStyle) Layout(gtx C) D { onceBtnStyle := ToggleButton(gtx, s.Theme, s.Oscilloscope.onceBtn, "Once") triggerChannelStyle := NumericUpDown(s.Theme, s.Oscilloscope.triggerChannelNumber, "Trigger channel") lengthNumberStyle := NumericUpDown(s.Theme, s.Oscilloscope.lengthInBeatsNumber, "Buffer length in beats") + + leftSpacer := layout.Spacer{Width: unit.Dp(6), Height: unit.Dp(24)}.Layout + rightSpacer := layout.Spacer{Width: unit.Dp(6)}.Layout + return layout.Flex{Axis: layout.Vertical}.Layout(gtx, layout.Flexed(1, func(gtx C) D { return s.layoutWave(gtx) }), layout.Rigid(func(gtx C) D { return layout.Flex{Axis: layout.Horizontal, Alignment: layout.Middle}.Layout(gtx, - layout.Rigid(Label("TRG:", white, s.Theme.Shaper)), - layout.Rigid(triggerChannelStyle.Layout), + layout.Rigid(leftSpacer), + layout.Rigid(LabelStyle{Text: "Trigger", Color: disabledTextColor, Alignment: layout.W, FontSize: s.Theme.TextSize * 14.0 / 16.0, Shaper: s.Theme.Shaper}.Layout), + layout.Flexed(1, func(gtx C) D { return D{Size: gtx.Constraints.Min} }), layout.Rigid(onceBtnStyle.Layout), + layout.Rigid(triggerChannelStyle.Layout), + layout.Rigid(rightSpacer), ) }), layout.Rigid(func(gtx C) D { return layout.Flex{Axis: layout.Horizontal, Alignment: layout.Middle}.Layout(gtx, - layout.Rigid(Label("BUF:", white, s.Theme.Shaper)), - layout.Rigid(lengthNumberStyle.Layout), + layout.Rigid(leftSpacer), + layout.Rigid(LabelStyle{Text: "Buffer", Color: disabledTextColor, Alignment: layout.W, FontSize: s.Theme.TextSize * 14.0 / 16.0, Shaper: s.Theme.Shaper}.Layout), + layout.Flexed(1, func(gtx C) D { return D{Size: gtx.Constraints.Min} }), layout.Rigid(wrapBtnStyle.Layout), + layout.Rigid(lengthNumberStyle.Layout), + layout.Rigid(rightSpacer), ) }), ) diff --git a/tracker/gioui/songpanel.go b/tracker/gioui/songpanel.go index b3ddac8..ad88952 100644 --- a/tracker/gioui/songpanel.go +++ b/tracker/gioui/songpanel.go @@ -8,6 +8,7 @@ import ( "gioui.org/op/paint" "gioui.org/unit" "gioui.org/widget" + "gioui.org/widget/material" "github.com/vsariola/sointu/tracker" "github.com/vsariola/sointu/version" "golang.org/x/exp/shiny/materialdesign/icons" @@ -146,8 +147,6 @@ func (t *SongPanel) layoutMenuBar(gtx C, tr *Tracker) D { func (t *SongPanel) layoutSongOptions(gtx C, tr *Tracker) D { paint.FillShape(gtx.Ops, songSurfaceColor, clip.Rect(image.Rect(0, 0, gtx.Constraints.Max.X, gtx.Constraints.Max.Y)).Op()) - in := layout.UniformInset(unit.Dp(1)) - rewindBtnStyle := ActionIcon(gtx, tr.Theme, t.RewindBtn, icons.AVFastRewind, t.rewindHint) playBtnStyle := ToggleIcon(gtx, tr.Theme, t.PlayingBtn, icons.AVPlayArrow, icons.AVStop, t.playHint, t.stopHint) recordBtnStyle := ToggleIcon(gtx, tr.Theme, t.RecordBtn, icons.AVFiberManualRecord, icons.AVFiberSmartRecord, t.recordHint, t.stopRecordHint) @@ -157,64 +156,21 @@ func (t *SongPanel) layoutSongOptions(gtx C, tr *Tracker) D { scopeStyle := LineOscilloscope(t.Scope, tr.SignalAnalyzer().Waveform(), tr.Theme) return layout.Flex{Axis: layout.Vertical}.Layout(gtx, + layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout), layout.Rigid(func(gtx C) D { - return layout.Flex{Axis: layout.Horizontal}.Layout(gtx, - layout.Rigid(Label("LEN:", white, tr.Theme.Shaper)), - layout.Rigid(func(gtx layout.Context) layout.Dimensions { - numStyle := NumericUpDown(tr.Theme, t.SongLength, "Song length") - gtx.Constraints.Min.Y = gtx.Dp(unit.Dp(20)) - gtx.Constraints.Min.X = gtx.Dp(unit.Dp(70)) - dims := in.Layout(gtx, numStyle.Layout) - return dims - }), - ) + return layoutSongOptionRow(gtx, tr.Theme, "Song length", NumericUpDown(tr.Theme, t.SongLength, "Song Length").Layout) }), layout.Rigid(func(gtx C) D { - return layout.Flex{Axis: layout.Horizontal}.Layout(gtx, - layout.Rigid(Label("BPM:", white, tr.Theme.Shaper)), - layout.Rigid(func(gtx layout.Context) layout.Dimensions { - numStyle := NumericUpDown(tr.Theme, t.BPM, "Beats per minute") - gtx.Constraints.Min.Y = gtx.Dp(unit.Dp(20)) - gtx.Constraints.Min.X = gtx.Dp(unit.Dp(70)) - dims := in.Layout(gtx, numStyle.Layout) - return dims - }), - ) + return layoutSongOptionRow(gtx, tr.Theme, "BPM", NumericUpDown(tr.Theme, t.BPM, "Song Length").Layout) }), layout.Rigid(func(gtx C) D { - return layout.Flex{Axis: layout.Horizontal}.Layout(gtx, - layout.Rigid(Label("RPP:", white, tr.Theme.Shaper)), - layout.Rigid(func(gtx layout.Context) layout.Dimensions { - numStyle := NumericUpDown(tr.Theme, t.RowsPerPattern, "Rows per pattern") - gtx.Constraints.Min.Y = gtx.Dp(unit.Dp(20)) - gtx.Constraints.Min.X = gtx.Dp(unit.Dp(70)) - dims := in.Layout(gtx, numStyle.Layout) - return dims - }), - ) + return layoutSongOptionRow(gtx, tr.Theme, "Rows per pat", NumericUpDown(tr.Theme, t.RowsPerPattern, "Rows per pattern").Layout) }), layout.Rigid(func(gtx C) D { - return layout.Flex{Axis: layout.Horizontal}.Layout(gtx, - layout.Rigid(Label("RPB:", white, tr.Theme.Shaper)), - layout.Rigid(func(gtx layout.Context) layout.Dimensions { - numStyle := NumericUpDown(tr.Theme, t.RowsPerBeat, "Rows per beat") - gtx.Constraints.Min.Y = gtx.Dp(unit.Dp(20)) - gtx.Constraints.Min.X = gtx.Dp(unit.Dp(70)) - dims := in.Layout(gtx, numStyle.Layout) - return dims - }), - ) + return layoutSongOptionRow(gtx, tr.Theme, "Rows per beat", NumericUpDown(tr.Theme, t.RowsPerBeat, "Rows per beat").Layout) }), layout.Rigid(func(gtx C) D { - return layout.Flex{Axis: layout.Horizontal}.Layout(gtx, - layout.Rigid(Label("STP:", white, tr.Theme.Shaper)), - layout.Rigid(func(gtx layout.Context) layout.Dimensions { - numStyle := NumericUpDown(tr.Theme, t.Step, "Cursor step") - numStyle.UnitsPerStep = unit.Dp(20) - dims := in.Layout(gtx, numStyle.Layout) - return dims - }), - ) + return layoutSongOptionRow(gtx, tr.Theme, "Cursor step", NumericUpDown(tr.Theme, t.Step, "Cursor step").Layout) }), layout.Rigid(VuMeter{Loudness: tr.Model.DetectorResult().Loudness[tracker.LoudnessShortTerm], Peak: tr.Model.DetectorResult().Peaks[tracker.PeakMomentary], Range: 100}.Layout), layout.Rigid(func(gtx C) D { @@ -233,3 +189,16 @@ func (t *SongPanel) layoutSongOptions(gtx C, tr *Tracker) D { }), ) } + +func layoutSongOptionRow(gtx C, th *material.Theme, label string, widget layout.Widget) D { + leftSpacer := layout.Spacer{Width: unit.Dp(6), Height: unit.Dp(24)}.Layout + rightSpacer := layout.Spacer{Width: unit.Dp(6)}.Layout + + return layout.Flex{Axis: layout.Horizontal, Alignment: layout.Middle}.Layout(gtx, + layout.Rigid(leftSpacer), + layout.Rigid(LabelStyle{Text: label, Color: disabledTextColor, Alignment: layout.W, FontSize: th.TextSize * 14.0 / 16.0, Shaper: th.Shaper}.Layout), + layout.Flexed(1, func(gtx C) D { return D{Size: gtx.Constraints.Min} }), + layout.Rigid(widget), + layout.Rigid(rightSpacer), + ) +}