From 5a69c14f61e34867f05aed49ffb958459f3996fe Mon Sep 17 00:00:00 2001 From: vsariola <5684185+vsariola@users.noreply.github.com> Date: Tue, 12 Jan 2021 18:52:15 +0200 Subject: [PATCH] feat(tracker): only show either notes or hex for a track + checkbox to toggle --- tracker/keyevent.go | 16 +++++++++----- tracker/layout.go | 46 +++++++++++++++++++++++++++++--------- tracker/track.go | 33 ++++++++++++++++++--------- tracker/tracker.go | 54 +++++++++++++++++++++++---------------------- 4 files changed, 96 insertions(+), 53 deletions(-) diff --git a/tracker/keyevent.go b/tracker/keyevent.go index f3ded38..d147000 100644 --- a/tracker/keyevent.go +++ b/tracker/keyevent.go @@ -89,15 +89,19 @@ func (t *Tracker) KeyEvent(e key.Event) bool { t.NoteTracking = false return true case key.NameLeftArrow: - if t.CursorColumn == 0 { + if t.CursorColumn == 0 || !t.TrackShowHex[t.ActiveTrack] || e.Modifiers.Contain(key.ModCtrl) { t.ActiveTrack = (t.ActiveTrack + len(t.song.Tracks) - 1) % len(t.song.Tracks) - t.CursorColumn = 2 + if t.TrackShowHex[t.ActiveTrack] { + t.CursorColumn = 1 + } else { + t.CursorColumn = 0 + } } else { t.CursorColumn-- } return true case key.NameRightArrow: - if t.CursorColumn == 2 { + if t.CursorColumn == 1 || !t.TrackShowHex[t.ActiveTrack] || e.Modifiers.Contain(key.ModCtrl) { t.ActiveTrack = (t.ActiveTrack + 1) % len(t.song.Tracks) t.CursorColumn = 0 } else { @@ -119,7 +123,7 @@ func (t *Tracker) KeyEvent(e key.Event) bool { return true } } else { - if t.CursorColumn == 0 { + if !t.TrackShowHex[t.ActiveTrack] { if val, ok := noteMap[e.Name]; ok { t.NotePressed(val) return true @@ -163,9 +167,9 @@ func (t *Tracker) NotePressed(val int) { // NumberPressed handles incoming presses while in either of the hex number columns func (t *Tracker) NumberPressed(iv byte) { val := t.getCurrent() - if t.CursorColumn == 1 { + if t.CursorColumn == 0 { val = ((iv & 0xF) << 4) | (val & 0xF) - } else if t.CursorColumn == 2 { + } else if t.CursorColumn == 1 { val = (val & 0xF0) | (iv & 0xF) } t.SetCurrentNote(val) diff --git a/tracker/layout.go b/tracker/layout.go index b8a4f34..4a9af99 100644 --- a/tracker/layout.go +++ b/tracker/layout.go @@ -61,6 +61,15 @@ func enableButton(icStyle material.IconButtonStyle, enabled bool) material.IconB return icStyle } +func trackButton(t *material.Theme, w *widget.Clickable, text string, enabled bool) material.ButtonStyle { + ret := material.Button(t, w, text) + if !enabled { + ret.Background = disabledContainerColor + ret.Color = disabledTextColor + } + return ret +} + func (t *Tracker) Layout(gtx layout.Context) { paint.FillShape(gtx.Ops, backgroundColor, clip.Rect(image.Rect(0, 0, gtx.Constraints.Max.X, gtx.Constraints.Max.Y)).Op()) layout.UniformInset(unit.Dp(2)).Layout(gtx, func(gtx2 layout.Context) layout.Dimensions { @@ -95,17 +104,34 @@ func (t *Tracker) layoutTracker(gtx layout.Context) layout.Dimensions { for i, trk := range t.song.Tracks { i2 := i // avoids i being updated in the closure trk2 := trk // avoids trk being updated in the closure + if len(t.TrackHexCheckBoxes) <= i { + t.TrackHexCheckBoxes = append(t.TrackHexCheckBoxes, new(widget.Bool)) + } + if len(t.TrackShowHex) <= i { + t.TrackShowHex = append(t.TrackShowHex, false) + } flexTracks[i] = layout.Rigid(func(gtx layout.Context) layout.Dimensions { - return leftInset.Layout(gtx, t.layoutTrack( - trk2.Patterns, - trk2.Sequence, - t.ActiveTrack == i2, - t.CursorRow, - t.DisplayPattern, - t.CursorColumn, - t.PlayRow, - playPat, - )) + t.TrackHexCheckBoxes[i2].Value = t.TrackShowHex[i2] + cbStyle := material.CheckBox(t.Theme, t.TrackHexCheckBoxes[i2], "hex") + cbStyle.Color = white + ret := layout.Stack{}.Layout(gtx, + layout.Stacked(func(gtx layout.Context) D { + return leftInset.Layout(gtx, t.layoutTrack( + trk2.Patterns, + trk2.Sequence, + t.ActiveTrack == i2, + t.TrackShowHex[i2], + t.CursorRow, + t.DisplayPattern, + t.CursorColumn, + t.PlayRow, + playPat, + )) + }), + layout.Stacked(cbStyle.Layout), + ) + t.TrackShowHex[i2] = t.TrackHexCheckBoxes[i2].Value + return ret }) } in2 := layout.UniformInset(unit.Dp(8)) diff --git a/tracker/track.go b/tracker/track.go index f1208e7..80abcb1 100644 --- a/tracker/track.go +++ b/tracker/track.go @@ -14,10 +14,10 @@ import ( ) const trackRowHeight = 16 -const trackWidth = 84 +const trackWidth = 54 const patmarkWidth = 16 -func (t *Tracker) layoutTrack(patterns [][]byte, sequence []byte, active bool, cursorRow, cursorPattern, cursorCol, playRow, playPattern int) layout.Widget { +func (t *Tracker) layoutTrack(patterns [][]byte, sequence []byte, active bool, hex bool, cursorRow, cursorPattern, cursorCol, playRow, playPattern int) layout.Widget { return func(gtx layout.Context) layout.Dimensions { gtx.Constraints.Min.X = trackWidth gtx.Constraints.Max.X = trackWidth @@ -51,16 +51,27 @@ func (t *Tracker) layoutTrack(patterns [][]byte, sequence []byte, active bool, c paint.ColorOp{Color: trackerInactiveTextColor}.Add(gtx.Ops) } op.Offset(f32.Pt(patmarkWidth, 0)).Add(gtx.Ops) - widget.Label{}.Layout(gtx, textShaper, trackerFont, trackerFontSize, valueAsNote(c)) - if active && cursorCol == 0 && songRow == cursorSongRow { - paint.FillShape(gtx.Ops, trackerCursorColor, clip.Rect{Max: image.Pt(30, trackRowHeight)}.Op()) + if hex { + var text string + switch c { + case 0: + text = "--" + case 1: + text = ".." + default: + text = fmt.Sprintf("%02x", c) + } + widget.Label{}.Layout(gtx, textShaper, trackerFont, trackerFontSize, strings.ToUpper(text)) + if active && songRow == cursorSongRow { + paint.FillShape(gtx.Ops, trackerCursorColor, clip.Rect{Min: image.Pt(cursorCol*10, 0), Max: image.Pt(cursorCol*10+10, trackRowHeight)}.Op()) + } + } else { + widget.Label{}.Layout(gtx, textShaper, trackerFont, trackerFontSize, valueAsNote(c)) + if active && cursorCol == 0 && songRow == cursorSongRow { + paint.FillShape(gtx.Ops, trackerCursorColor, clip.Rect{Max: image.Pt(30, trackRowHeight)}.Op()) + } } - op.Offset(f32.Pt(trackWidth/2, 0)).Add(gtx.Ops) - widget.Label{}.Layout(gtx, textShaper, trackerFont, trackerFontSize, strings.ToUpper(fmt.Sprintf("%02x", c))) - if active && cursorCol > 0 && songRow == cursorSongRow { - paint.FillShape(gtx.Ops, trackerCursorColor, clip.Rect{Min: image.Pt((cursorCol-1)*10, 0), Max: image.Pt((cursorCol-1)*10+10, trackRowHeight)}.Op()) - } - op.Offset(f32.Pt(-trackWidth/2-patmarkWidth, trackRowHeight)).Add(gtx.Ops) + op.Offset(f32.Pt(-patmarkWidth, trackRowHeight)).Add(gtx.Ops) } } return layout.Dimensions{Size: gtx.Constraints.Max} diff --git a/tracker/tracker.go b/tracker/tracker.go index fce5006..9e5d8cf 100644 --- a/tracker/tracker.go +++ b/tracker/tracker.go @@ -18,32 +18,34 @@ type Tracker struct { song sointu.Song Playing bool // protects PlayPattern and PlayRow - playRowPatMutex sync.RWMutex // protects song and playing - PlayPattern int - PlayRow int - CursorRow int - CursorColumn int - DisplayPattern int - ActiveTrack int - CurrentInstrument int - CurrentUnit int - CurrentOctave byte - NoteTracking bool - Theme *material.Theme - OctaveUpBtn *widget.Clickable - OctaveDownBtn *widget.Clickable - BPMUpBtn *widget.Clickable - BPMDownBtn *widget.Clickable - NewTrackBtn *widget.Clickable - NewInstrumentBtn *widget.Clickable - LoadSongFileBtn *widget.Clickable - SongLengthUpBtn *widget.Clickable - SongLengthDownBtn *widget.Clickable - SaveSongFileBtn *widget.Clickable - ParameterSliders []*widget.Float - UnitBtns []*widget.Clickable - InstrumentBtns []*widget.Clickable - InstrumentList *layout.List + playRowPatMutex sync.RWMutex // protects song and playing + PlayPattern int + PlayRow int + CursorRow int + CursorColumn int + DisplayPattern int + ActiveTrack int + CurrentInstrument int + CurrentUnit int + CurrentOctave byte + NoteTracking bool + Theme *material.Theme + OctaveUpBtn *widget.Clickable + OctaveDownBtn *widget.Clickable + BPMUpBtn *widget.Clickable + BPMDownBtn *widget.Clickable + NewTrackBtn *widget.Clickable + NewInstrumentBtn *widget.Clickable + LoadSongFileBtn *widget.Clickable + SongLengthUpBtn *widget.Clickable + SongLengthDownBtn *widget.Clickable + SaveSongFileBtn *widget.Clickable + ParameterSliders []*widget.Float + UnitBtns []*widget.Clickable + InstrumentBtns []*widget.Clickable + InstrumentList *layout.List + TrackHexCheckBoxes []*widget.Bool + TrackShowHex []bool sequencer *Sequencer ticked chan struct{}