From 2a9284473a6e6c8a28f1c711d906259dd06f21ba Mon Sep 17 00:00:00 2001 From: vsariola <5684185+vsariola@users.noreply.github.com> Date: Sat, 17 Apr 2021 14:56:05 +0300 Subject: [PATCH] feat(tracker, gioui): add little "*" symbol to indicate if a pattern is unique --- tracker/gioui/track.go | 6 +++++- tracker/model.go | 43 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/tracker/gioui/track.go b/tracker/gioui/track.go index 5c9441c..d81226f 100644 --- a/tracker/gioui/track.go +++ b/tracker/gioui/track.go @@ -275,7 +275,7 @@ func (t *Tracker) layoutTracks(gtx C) D { lastRow = l - 1 } op.Offset(f32.Pt(0, float32(trackRowHeight*firstRow))).Add(gtx.Ops) - for _, trk := range t.Song().Score.Tracks { + for trkIndex, trk := range t.Song().Score.Tracks { stack := op.Save(gtx.Ops) for row := firstRow; row <= lastRow; row++ { pat := row / t.Song().Score.RowsPerPattern @@ -292,6 +292,10 @@ func (t *Tracker) layoutTracks(gtx C) D { paint.ColorOp{Color: trackerPatMarker}.Add(gtx.Ops) widget.Label{}.Layout(gtx, textShaper, trackerFont, trackerFontSize, patternIndexToString(s)) } + if s >= 0 && patRow == 1 && t.IsPatternUnique(trkIndex, s) { + paint.ColorOp{Color: mediumEmphasisTextColor}.Add(gtx.Ops) + widget.Label{}.Layout(gtx, textShaper, trackerFont, trackerFontSize, "*") + } op.Offset(f32.Pt(patmarkWidth, 0)).Add(gtx.Ops) if t.EditMode() == tracker.EditTracks && t.Cursor().Row == patRow && t.Cursor().Pattern == pat { paint.ColorOp{Color: trackerActiveTextColor}.Add(gtx.Ops) diff --git a/tracker/model.go b/tracker/model.go index b399644..7d899f5 100644 --- a/tracker/model.go +++ b/tracker/model.go @@ -31,6 +31,7 @@ type Model struct { maxID int filePath string changedSinceSave bool + patternUseCount [][]int prevUndoType string undoSkipCounter int @@ -238,6 +239,7 @@ func (m *Model) DeleteTrack(forward bool) { } m.selectionCorner = m.cursor m.clampPositions() + m.computePatternUseCounts() m.notifyScoreChange() } @@ -377,9 +379,21 @@ func (m *Model) SetCurrentPattern(pat int) { track.Order = append(track.Order, -1) } track.Order[m.cursor.Pattern] = pat + m.computePatternUseCounts() m.notifyScoreChange() } +func (m *Model) IsPatternUnique(track, pattern int) bool { + if track < 0 || track >= len(m.patternUseCount) { + return false + } + p := m.patternUseCount[track] + if pattern < 0 || pattern >= len(p) { + return false + } + return p[pattern] <= 1 +} + func (m *Model) SetSongLength(value int) { if value < 1 { value = 1 @@ -390,6 +404,7 @@ func (m *Model) SetSongLength(value int) { m.saveUndo("SetSongLength", 10) m.song.Score.Length = value m.clampPositions() + m.computePatternUseCounts() m.notifyScoreChange() } @@ -464,6 +479,7 @@ func (m *Model) AddOrderRow(after bool) { m.song.Score.Length++ m.selectionCorner = m.cursor m.clampPositions() + m.computePatternUseCounts() m.notifyScoreChange() } @@ -486,6 +502,7 @@ func (m *Model) DeleteOrderRow(forward bool) { m.song.Score.Length-- m.selectionCorner = m.cursor m.clampPositions() + m.computePatternUseCounts() m.notifyScoreChange() } @@ -668,6 +685,7 @@ func (m *Model) DeletePatternSelection() { } } } + m.computePatternUseCounts() m.notifyScoreChange() } @@ -987,6 +1005,7 @@ func (m *Model) setSongNoUndo(song sointu.Song) { m.assignUnitIDs(instr.Units) } m.clampPositions() + m.computePatternUseCounts() m.notifySamplesPerRowChange() m.notifyPatchChange() m.notifyScoreChange() @@ -1044,6 +1063,30 @@ func (m *Model) assignUnitIDs(units []sointu.Unit) { } } +func (m *Model) computePatternUseCounts() { + for i, track := range m.song.Score.Tracks { + for len(m.patternUseCount) <= i { + m.patternUseCount = append(m.patternUseCount, nil) + } + for j := range m.patternUseCount[i] { + m.patternUseCount[i][j] = 0 + } + for j := 0; j < m.song.Score.Length; j++ { + if j >= len(track.Order) { + break + } + p := track.Order[j] + for len(m.patternUseCount[i]) <= p { + m.patternUseCount[i] = append(m.patternUseCount[i], 0) + } + if p < 0 { + continue + } + m.patternUseCount[i][p]++ + } + } +} + func clamp(a, min, max int) int { if a < min { return min