From 98c8d18a3ee3139016572f192b84c0d1ee6fbbfb Mon Sep 17 00:00:00 2001 From: vsariola <5684185+vsariola@users.noreply.github.com> Date: Sat, 30 Jan 2021 23:22:31 +0200 Subject: [PATCH] feat(tracker): add numeric updown to adjust RowsPerPattern --- tracker/layout.go | 2 +- tracker/songpanel.go | 14 ++++++++++++++ tracker/track.go | 3 ++- tracker/tracker.go | 39 ++++++++++++++++++++++++++++++++++++--- 4 files changed, 53 insertions(+), 5 deletions(-) diff --git a/tracker/layout.go b/tracker/layout.go index 01e7c6c..29acbfc 100644 --- a/tracker/layout.go +++ b/tracker/layout.go @@ -107,7 +107,7 @@ func (t *Tracker) layoutTracks(gtx layout.Context) layout.Dimensions { } rowMarkers := layout.Rigid(t.layoutRowMarkers( - len(t.song.Tracks[0].Patterns[0]), + t.song.RowsPerPattern, len(t.song.Tracks[0].Sequence), t.Cursor.Row, t.Cursor.Pattern, diff --git a/tracker/songpanel.go b/tracker/songpanel.go index c195728..5fc1803 100644 --- a/tracker/songpanel.go +++ b/tracker/songpanel.go @@ -95,5 +95,19 @@ func (t *Tracker) layoutSongOptions(gtx C) D { }), ) }), + layout.Rigid(func(gtx C) D { + return layout.Flex{Axis: layout.Horizontal}.Layout(gtx, + layout.Rigid(Label("RPP:", white)), + layout.Rigid(func(gtx layout.Context) layout.Dimensions { + t.RowsPerPattern.Value = t.song.RowsPerPattern + numStyle := NumericUpDown(t.Theme, t.RowsPerPattern, 1, 255) + gtx.Constraints.Min.Y = gtx.Px(unit.Dp(20)) + gtx.Constraints.Min.X = gtx.Px(unit.Dp(70)) + dims := in.Layout(gtx, numStyle.Layout) + t.SetRowsPerPattern(t.RowsPerPattern.Value) + return dims + }), + ) + }), ) } diff --git a/tracker/track.go b/tracker/track.go index dae2cd8..f77dc0c 100644 --- a/tracker/track.go +++ b/tracker/track.go @@ -40,7 +40,8 @@ func (t *Tracker) layoutTrack(trackNo int) layout.Widget { if patternRect.Contains(SongPoint{Track: trackNo, SongRow: SongRow{Pattern: i}}) { paint.FillShape(gtx.Ops, activeTrackColor, clip.Rect{Max: image.Pt(trackWidth, trackRowHeight*t.song.RowsPerPattern)}.Op()) } - for j, c := range t.song.Tracks[trackNo].Patterns[s] { + for j := 0; j < t.song.RowsPerPattern; j++ { + c := t.song.Tracks[trackNo].Patterns[s][j] songRow := SongRow{Pattern: i, Row: j} songPoint := SongPoint{Track: trackNo, SongRow: songRow} if songRow == t.PlayPosition && t.Playing { diff --git a/tracker/tracker.go b/tracker/tracker.go index 6567661..312ed12 100644 --- a/tracker/tracker.go +++ b/tracker/tracker.go @@ -29,6 +29,7 @@ type Tracker struct { Theme *material.Theme Octave *NumberInput BPM *NumberInput + RowsPerPattern *NumberInput NewTrackBtn *widget.Clickable NewInstrumentBtn *widget.Clickable DeleteInstrumentBtn *widget.Clickable @@ -70,9 +71,7 @@ func (t *Tracker) LoadSong(song sointu.Song) error { t.songPlayMutex.Lock() defer t.songPlayMutex.Unlock() t.song = song - t.PlayPosition.Clamp(song) - t.Cursor.Clamp(song) - t.SelectionCorner.Clamp(song) + t.ClampPositions() if t.sequencer != nil { t.sequencer.SetPatch(song.Patch) } @@ -259,9 +258,42 @@ func (t *Tracker) SetSongLength(value int) { } } + t.ClampPositions() } } +func (t *Tracker) SetRowsPerPattern(value int) { + if value < 1 { + value = 1 + } + if value > 255 { + value = 255 + } + if value != t.song.RowsPerPattern { + t.SaveUndo() + for i := range t.song.Tracks { + for j := range t.song.Tracks[i].Patterns { + pat := t.song.Tracks[i].Patterns[j] + if l := len(pat); l < value { + tail := make([]byte, value-l) + for k := range tail { + tail[k] = 1 + } + t.song.Tracks[i].Patterns[j] = append(pat, tail...) + } + } + } + t.song.RowsPerPattern = value + t.ClampPositions() + } +} + +func (t *Tracker) ClampPositions() { + t.PlayPosition.Clamp(t.song) + t.Cursor.Clamp(t.song) + t.SelectionCorner.Clamp(t.song) +} + func (t *Tracker) getSelectionRange() (int, int, int, int) { r1 := t.Cursor.Pattern*t.song.RowsPerPattern + t.Cursor.Row r2 := t.SelectionCorner.Pattern*t.song.RowsPerPattern + t.SelectionCorner.Row @@ -329,6 +361,7 @@ func New(audioContext sointu.AudioContext) *Tracker { BPM: new(NumberInput), Octave: new(NumberInput), SongLength: new(NumberInput), + RowsPerPattern: new(NumberInput), NewTrackBtn: new(widget.Clickable), NewInstrumentBtn: new(widget.Clickable), DeleteInstrumentBtn: new(widget.Clickable),