mirror of
https://github.com/vsariola/sointu.git
synced 2025-07-14 02:54:37 -04:00
feat(tracker, gioui): add little "*" symbol to indicate if a pattern is unique
This commit is contained in:
@ -275,7 +275,7 @@ func (t *Tracker) layoutTracks(gtx C) D {
|
|||||||
lastRow = l - 1
|
lastRow = l - 1
|
||||||
}
|
}
|
||||||
op.Offset(f32.Pt(0, float32(trackRowHeight*firstRow))).Add(gtx.Ops)
|
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)
|
stack := op.Save(gtx.Ops)
|
||||||
for row := firstRow; row <= lastRow; row++ {
|
for row := firstRow; row <= lastRow; row++ {
|
||||||
pat := row / t.Song().Score.RowsPerPattern
|
pat := row / t.Song().Score.RowsPerPattern
|
||||||
@ -292,6 +292,10 @@ func (t *Tracker) layoutTracks(gtx C) D {
|
|||||||
paint.ColorOp{Color: trackerPatMarker}.Add(gtx.Ops)
|
paint.ColorOp{Color: trackerPatMarker}.Add(gtx.Ops)
|
||||||
widget.Label{}.Layout(gtx, textShaper, trackerFont, trackerFontSize, patternIndexToString(s))
|
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)
|
op.Offset(f32.Pt(patmarkWidth, 0)).Add(gtx.Ops)
|
||||||
if t.EditMode() == tracker.EditTracks && t.Cursor().Row == patRow && t.Cursor().Pattern == pat {
|
if t.EditMode() == tracker.EditTracks && t.Cursor().Row == patRow && t.Cursor().Pattern == pat {
|
||||||
paint.ColorOp{Color: trackerActiveTextColor}.Add(gtx.Ops)
|
paint.ColorOp{Color: trackerActiveTextColor}.Add(gtx.Ops)
|
||||||
|
@ -31,6 +31,7 @@ type Model struct {
|
|||||||
maxID int
|
maxID int
|
||||||
filePath string
|
filePath string
|
||||||
changedSinceSave bool
|
changedSinceSave bool
|
||||||
|
patternUseCount [][]int
|
||||||
|
|
||||||
prevUndoType string
|
prevUndoType string
|
||||||
undoSkipCounter int
|
undoSkipCounter int
|
||||||
@ -238,6 +239,7 @@ func (m *Model) DeleteTrack(forward bool) {
|
|||||||
}
|
}
|
||||||
m.selectionCorner = m.cursor
|
m.selectionCorner = m.cursor
|
||||||
m.clampPositions()
|
m.clampPositions()
|
||||||
|
m.computePatternUseCounts()
|
||||||
m.notifyScoreChange()
|
m.notifyScoreChange()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,9 +379,21 @@ func (m *Model) SetCurrentPattern(pat int) {
|
|||||||
track.Order = append(track.Order, -1)
|
track.Order = append(track.Order, -1)
|
||||||
}
|
}
|
||||||
track.Order[m.cursor.Pattern] = pat
|
track.Order[m.cursor.Pattern] = pat
|
||||||
|
m.computePatternUseCounts()
|
||||||
m.notifyScoreChange()
|
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) {
|
func (m *Model) SetSongLength(value int) {
|
||||||
if value < 1 {
|
if value < 1 {
|
||||||
value = 1
|
value = 1
|
||||||
@ -390,6 +404,7 @@ func (m *Model) SetSongLength(value int) {
|
|||||||
m.saveUndo("SetSongLength", 10)
|
m.saveUndo("SetSongLength", 10)
|
||||||
m.song.Score.Length = value
|
m.song.Score.Length = value
|
||||||
m.clampPositions()
|
m.clampPositions()
|
||||||
|
m.computePatternUseCounts()
|
||||||
m.notifyScoreChange()
|
m.notifyScoreChange()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -464,6 +479,7 @@ func (m *Model) AddOrderRow(after bool) {
|
|||||||
m.song.Score.Length++
|
m.song.Score.Length++
|
||||||
m.selectionCorner = m.cursor
|
m.selectionCorner = m.cursor
|
||||||
m.clampPositions()
|
m.clampPositions()
|
||||||
|
m.computePatternUseCounts()
|
||||||
m.notifyScoreChange()
|
m.notifyScoreChange()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,6 +502,7 @@ func (m *Model) DeleteOrderRow(forward bool) {
|
|||||||
m.song.Score.Length--
|
m.song.Score.Length--
|
||||||
m.selectionCorner = m.cursor
|
m.selectionCorner = m.cursor
|
||||||
m.clampPositions()
|
m.clampPositions()
|
||||||
|
m.computePatternUseCounts()
|
||||||
m.notifyScoreChange()
|
m.notifyScoreChange()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -668,6 +685,7 @@ func (m *Model) DeletePatternSelection() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m.computePatternUseCounts()
|
||||||
m.notifyScoreChange()
|
m.notifyScoreChange()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -987,6 +1005,7 @@ func (m *Model) setSongNoUndo(song sointu.Song) {
|
|||||||
m.assignUnitIDs(instr.Units)
|
m.assignUnitIDs(instr.Units)
|
||||||
}
|
}
|
||||||
m.clampPositions()
|
m.clampPositions()
|
||||||
|
m.computePatternUseCounts()
|
||||||
m.notifySamplesPerRowChange()
|
m.notifySamplesPerRowChange()
|
||||||
m.notifyPatchChange()
|
m.notifyPatchChange()
|
||||||
m.notifyScoreChange()
|
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 {
|
func clamp(a, min, max int) int {
|
||||||
if a < min {
|
if a < min {
|
||||||
return min
|
return min
|
||||||
|
Reference in New Issue
Block a user