refactor(tracker): rename SongPoint to ScorePoint etc.

This commit is contained in:
5684185+vsariola@users.noreply.github.com 2023-10-19 22:28:30 +03:00
parent 50ccfe03da
commit 453f45c48a
7 changed files with 63 additions and 58 deletions

View File

@ -102,12 +102,12 @@ func (t *Tracker) KeyEvent(e key.Event, o *op.Ops) {
return return
case "F5": case "F5":
t.SetNoteTracking(true) t.SetNoteTracking(true)
startRow := t.Cursor().SongRow startRow := t.Cursor().ScoreRow
t.PlayFromPosition(startRow) t.PlayFromPosition(startRow)
return return
case "F6": case "F6":
t.SetNoteTracking(false) t.SetNoteTracking(false)
startRow := t.Cursor().SongRow startRow := t.Cursor().ScoreRow
t.PlayFromPosition(startRow) t.PlayFromPosition(startRow)
return return
case "F8": case "F8":
@ -116,7 +116,7 @@ func (t *Tracker) KeyEvent(e key.Event, o *op.Ops) {
case "Space": case "Space":
if !t.Playing() && !t.InstrEnlarged() { if !t.Playing() && !t.InstrEnlarged() {
t.SetNoteTracking(!e.Modifiers.Contain(key.ModShortcut)) t.SetNoteTracking(!e.Modifiers.Contain(key.ModShortcut))
startRow := t.Cursor().SongRow startRow := t.Cursor().ScoreRow
t.PlayFromPosition(startRow) t.PlayFromPosition(startRow)
} else { } else {
t.SetPlaying(false) t.SetPlaying(false)

View File

@ -80,7 +80,7 @@ func (oe *OrderEditor) doLayout(gtx C, t *Tracker) D {
case "Space": case "Space":
if !t.Playing() { if !t.Playing() {
t.SetNoteTracking(!e.Modifiers.Contain(key.ModShortcut)) t.SetNoteTracking(!e.Modifiers.Contain(key.ModShortcut))
startRow := t.Cursor().SongRow startRow := t.Cursor().ScoreRow
startRow.Row = 0 startRow.Row = 0
t.PlayFromPosition(startRow) t.PlayFromPosition(startRow)
} else { } else {
@ -91,7 +91,7 @@ func (oe *OrderEditor) doLayout(gtx C, t *Tracker) D {
case key.NameUpArrow: case key.NameUpArrow:
cursor := t.Cursor() cursor := t.Cursor()
if e.Modifiers.Contain(key.ModShortcut) { if e.Modifiers.Contain(key.ModShortcut) {
cursor.SongRow = tracker.SongRow{} cursor.ScoreRow = tracker.ScoreRow{}
} else { } else {
cursor.Row -= t.Song().Score.RowsPerPattern cursor.Row -= t.Song().Score.RowsPerPattern
} }
@ -175,9 +175,9 @@ func (oe *OrderEditor) doLayout(gtx C, t *Tracker) D {
key.InputOp{Tag: &oe.tag, Keys: "←|→|↑|↓|Shift-←|Shift-→|Shift-↑|Shift-↓|⏎|⇱|⇲|⌫|⌦|Ctrl-⌫|Ctrl-⌦|+|-|Space|0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z"}.Add(gtx.Ops) key.InputOp{Tag: &oe.tag, Keys: "←|→|↑|↓|Shift-←|Shift-→|Shift-↑|Shift-↓|⏎|⇱|⇲|⌫|⌦|Ctrl-⌫|Ctrl-⌦|+|-|Space|0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z"}.Add(gtx.Ops)
patternRect := tracker.SongRect{ patternRect := tracker.ScoreRect{
Corner1: tracker.SongPoint{SongRow: tracker.SongRow{Pattern: t.Cursor().Pattern}, Track: t.Cursor().Track}, Corner1: tracker.ScorePoint{ScoreRow: tracker.ScoreRow{Pattern: t.Cursor().Pattern}, Track: t.Cursor().Track},
Corner2: tracker.SongPoint{SongRow: tracker.SongRow{Pattern: t.SelectionCorner().Pattern}, Track: t.SelectionCorner().Track}, Corner2: tracker.ScorePoint{ScoreRow: tracker.ScoreRow{Pattern: t.SelectionCorner().Pattern}, Track: t.SelectionCorner().Track},
} }
// draw the single letter titles for tracks // draw the single letter titles for tracks
@ -223,7 +223,7 @@ func (oe *OrderEditor) doLayout(gtx C, t *Tracker) D {
widget.Label{Alignment: text.Middle}.Layout(gtx, textShaper, trackerFont, trackerFontSize, patternIndexToString(track.Order[j]), op.CallOp{}) widget.Label{Alignment: text.Middle}.Layout(gtx, textShaper, trackerFont, trackerFontSize, patternIndexToString(track.Order[j]), op.CallOp{})
op.Offset(image.Pt(0, 2)).Add(gtx.Ops) op.Offset(image.Pt(0, 2)).Add(gtx.Ops)
} }
point := tracker.SongPoint{Track: i, SongRow: tracker.SongRow{Pattern: j}} point := tracker.ScorePoint{Track: i, ScoreRow: tracker.ScoreRow{Pattern: j}}
if oe.focused || t.TrackEditor.Focused() { if oe.focused || t.TrackEditor.Focused() {
if patternRect.Contains(point) { if patternRect.Contains(point) {
color := inactiveSelectionColor color := inactiveSelectionColor

View File

@ -302,7 +302,7 @@ func (te *TrackEditor) layoutTracks(gtx C, t *Tracker) D {
te.Focus() te.Focus()
track := int(e.Position.X) / trackColWidth track := int(e.Position.X) / trackColWidth
row := int((e.Position.Y-float32(gtx.Constraints.Max.Y-trackRowHeight)/2)/trackRowHeight + float32(cursorSongRow)) row := int((e.Position.Y-float32(gtx.Constraints.Max.Y-trackRowHeight)/2)/trackRowHeight + float32(cursorSongRow))
cursor := tracker.SongPoint{Track: track, SongRow: tracker.SongRow{Row: row}}.Clamp(t.Song().Score) cursor := tracker.ScorePoint{Track: track, ScoreRow: tracker.ScoreRow{Row: row}}.Clamp(t.Song().Score)
t.SetCursor(cursor) t.SetCursor(cursor)
t.SetSelectionCorner(cursor) t.SetSelectionCorner(cursor)
cursorSongRow = cursor.Pattern*t.Song().Score.RowsPerPattern + cursor.Row cursorSongRow = cursor.Pattern*t.Song().Score.RowsPerPattern + cursor.Row

View File

@ -173,7 +173,7 @@ mainloop:
for { for {
if pos, playing := t.PlayPosition(), t.Playing(); t.NoteTracking() && playing { if pos, playing := t.PlayPosition(), t.Playing(); t.NoteTracking() && playing {
cursor := t.Cursor() cursor := t.Cursor()
cursor.SongRow = pos cursor.ScoreRow = pos
t.SetCursor(cursor) t.SetCursor(cursor)
t.SetSelectionCorner(cursor) t.SetSelectionCorner(cursor)
} }

View File

@ -26,8 +26,8 @@ type (
// modelData is the part of the model that gets save to recovery file // modelData is the part of the model that gets save to recovery file
modelData struct { modelData struct {
Song sointu.Song Song sointu.Song
SelectionCorner SongPoint SelectionCorner ScorePoint
Cursor SongPoint Cursor ScorePoint
LowNibble bool LowNibble bool
InstrIndex int InstrIndex int
UnitIndex int UnitIndex int
@ -42,7 +42,7 @@ type (
Panic bool Panic bool
Playing bool Playing bool
Recording bool Recording bool
PlayPosition SongRow PlayPosition ScoreRow
InstrEnlarged bool InstrEnlarged bool
RecoveryFilePath string RecoveryFilePath string
ChangedSinceRecovery bool ChangedSinceRecovery bool
@ -72,7 +72,7 @@ type (
} }
ModelPlayFromPositionMessage struct { ModelPlayFromPositionMessage struct {
SongRow ScoreRow
} }
ModelSamplesPerRowChangedMessage struct { ModelSamplesPerRowChangedMessage struct {
@ -460,7 +460,7 @@ func (m *Model) SetPlaying(val bool) {
} }
} }
func (m *Model) PlayPosition() SongRow { func (m *Model) PlayPosition() ScoreRow {
return m.d.PlayPosition return m.d.PlayPosition
} }
@ -647,7 +647,7 @@ func (m *Model) InstrEnlarged() bool {
return m.d.InstrEnlarged return m.d.InstrEnlarged
} }
func (m *Model) PlayFromPosition(sr SongRow) { func (m *Model) PlayFromPosition(sr ScoreRow) {
m.d.Playing = true m.d.Playing = true
m.modelMessages <- ModelPlayFromPositionMessage{sr} m.modelMessages <- ModelPlayFromPositionMessage{sr}
} }
@ -937,7 +937,7 @@ func (m *Model) AdjustSelectionPitch(delta int) {
Row int Row int
}]bool{} }]bool{}
for r := r1; r <= r2; r++ { for r := r1; r <= r2; r++ {
s := SongRow{Row: r}.Wrap(m.d.Song.Score) s := ScoreRow{Row: r}.Wrap(m.d.Song.Score)
if s.Pattern >= len(m.d.Song.Score.Tracks[c].Order) { if s.Pattern >= len(m.d.Song.Score.Tracks[c].Order) {
break break
} }
@ -978,7 +978,7 @@ func (m *Model) DeleteSelection() {
m.saveUndo("DeleteSelection", 0) m.saveUndo("DeleteSelection", 0)
r1, r2, t1, t2 := m.getSelectionRange() r1, r2, t1, t2 := m.getSelectionRange()
for r := r1; r <= r2; r++ { for r := r1; r <= r2; r++ {
s := SongRow{Row: r}.Wrap(m.d.Song.Score) s := ScoreRow{Row: r}.Wrap(m.d.Song.Score)
for c := t1; c <= t2; c++ { for c := t1; c <= t2; c++ {
if len(m.d.Song.Score.Tracks[c].Order) <= s.Pattern { if len(m.d.Song.Score.Tracks[c].Order) <= s.Pattern {
continue continue
@ -1004,8 +1004,8 @@ func (m *Model) DeleteSelection() {
func (m *Model) DeletePatternSelection() { func (m *Model) DeletePatternSelection() {
m.saveUndo("DeletePatternSelection", 0) m.saveUndo("DeletePatternSelection", 0)
r1, r2, t1, t2 := m.getSelectionRange() r1, r2, t1, t2 := m.getSelectionRange()
p1 := SongRow{Row: r1}.Wrap(m.d.Song.Score).Pattern p1 := ScoreRow{Row: r1}.Wrap(m.d.Song.Score).Pattern
p2 := SongRow{Row: r2}.Wrap(m.d.Song.Score).Pattern p2 := ScoreRow{Row: r2}.Wrap(m.d.Song.Score).Pattern
for p := p1; p <= p2; p++ { for p := p1; p <= p2; p++ {
for c := t1; c <= t2; c++ { for c := t1; c <= t2; c++ {
if p < len(m.d.Song.Score.Tracks[c].Order) { if p < len(m.d.Song.Score.Tracks[c].Order) {
@ -1073,20 +1073,20 @@ func (m *Model) Song() sointu.Song {
return m.d.Song return m.d.Song
} }
func (m *Model) SelectionCorner() SongPoint { func (m *Model) SelectionCorner() ScorePoint {
return m.d.SelectionCorner return m.d.SelectionCorner
} }
func (m *Model) SetSelectionCorner(value SongPoint) { func (m *Model) SetSelectionCorner(value ScorePoint) {
m.d.SelectionCorner = value m.d.SelectionCorner = value
m.clampPositions() m.clampPositions()
} }
func (m *Model) Cursor() SongPoint { func (m *Model) Cursor() ScorePoint {
return m.d.Cursor return m.d.Cursor
} }
func (m *Model) SetCursor(value SongPoint) { func (m *Model) SetCursor(value ScorePoint) {
m.d.Cursor = value m.d.Cursor = value
m.clampPositions() m.clampPositions()
} }

View File

@ -17,7 +17,7 @@ type (
score sointu.Score score sointu.Score
playing bool playing bool
rowtime int rowtime int
position SongRow position ScoreRow
samplesSinceEvent []int samplesSinceEvent []int
samplesPerRow int samplesPerRow int
bpm int bpm int
@ -62,7 +62,7 @@ type (
PlayerMessage struct { PlayerMessage struct {
AverageVolume Volume AverageVolume Volume
PeakVolume Volume PeakVolume Volume
SongRow SongRow SongRow ScoreRow
VoiceStates [vm.MAX_VOICES]float32 VoiceStates [vm.MAX_VOICES]float32
Inner interface{} Inner interface{}
} }
@ -255,7 +255,7 @@ loop:
p.compileOrUpdateSynth() p.compileOrUpdateSynth()
case ModelPlayFromPositionMessage: case ModelPlayFromPositionMessage:
p.playing = true p.playing = true
p.position = m.SongRow p.position = m.ScoreRow
p.position.Row-- p.position.Row--
p.rowtime = math.MaxInt p.rowtime = math.MaxInt
for i, t := range p.score.Tracks { for i, t := range p.score.Tracks {

View File

@ -2,37 +2,42 @@ package tracker
import "github.com/vsariola/sointu" import "github.com/vsariola/sointu"
type SongRow struct { type (
Pattern int // ScoreRow identifies a row of the song score.
Row int ScoreRow struct {
Pattern int
Row int
}
// ScorePoint identifies a row and a track in a song score.
ScorePoint struct {
Track int
ScoreRow
}
// ScoreRect identifies a rectangular area in a song score.
ScoreRect struct {
Corner1 ScorePoint
Corner2 ScorePoint
}
)
func (r ScoreRow) AddRows(rows int) ScoreRow {
return ScoreRow{Row: r.Row + rows, Pattern: r.Pattern}
} }
type SongPoint struct { func (r ScoreRow) AddPatterns(patterns int) ScoreRow {
Track int return ScoreRow{Row: r.Row, Pattern: r.Pattern + patterns}
SongRow
} }
type SongRect struct { func (r ScoreRow) Wrap(score sointu.Score) ScoreRow {
Corner1 SongPoint
Corner2 SongPoint
}
func (r SongRow) AddRows(rows int) SongRow {
return SongRow{Row: r.Row + rows, Pattern: r.Pattern}
}
func (r SongRow) AddPatterns(patterns int) SongRow {
return SongRow{Row: r.Row, Pattern: r.Pattern + patterns}
}
func (r SongRow) Wrap(score sointu.Score) SongRow {
totalRow := r.Pattern*score.RowsPerPattern + r.Row totalRow := r.Pattern*score.RowsPerPattern + r.Row
r.Row = mod(totalRow, score.RowsPerPattern) r.Row = mod(totalRow, score.RowsPerPattern)
r.Pattern = mod((totalRow-r.Row)/score.RowsPerPattern, score.Length) r.Pattern = mod((totalRow-r.Row)/score.RowsPerPattern, score.Length)
return r return r
} }
func (r SongRow) Clamp(score sointu.Score) SongRow { func (r ScoreRow) Clamp(score sointu.Score) ScoreRow {
totalRow := r.Pattern*score.RowsPerPattern + r.Row totalRow := r.Pattern*score.RowsPerPattern + r.Row
if totalRow < 0 { if totalRow < 0 {
totalRow = 0 totalRow = 0
@ -45,31 +50,31 @@ func (r SongRow) Clamp(score sointu.Score) SongRow {
return r return r
} }
func (r SongPoint) AddRows(rows int) SongPoint { func (r ScorePoint) AddRows(rows int) ScorePoint {
return SongPoint{Track: r.Track, SongRow: r.SongRow.AddRows(rows)} return ScorePoint{Track: r.Track, ScoreRow: r.ScoreRow.AddRows(rows)}
} }
func (r SongPoint) AddPatterns(patterns int) SongPoint { func (r ScorePoint) AddPatterns(patterns int) ScorePoint {
return SongPoint{Track: r.Track, SongRow: r.SongRow.AddPatterns(patterns)} return ScorePoint{Track: r.Track, ScoreRow: r.ScoreRow.AddPatterns(patterns)}
} }
func (p SongPoint) Wrap(score sointu.Score) SongPoint { func (p ScorePoint) Wrap(score sointu.Score) ScorePoint {
p.Track = mod(p.Track, len(score.Tracks)) p.Track = mod(p.Track, len(score.Tracks))
p.SongRow = p.SongRow.Wrap(score) p.ScoreRow = p.ScoreRow.Wrap(score)
return p return p
} }
func (p SongPoint) Clamp(score sointu.Score) SongPoint { func (p ScorePoint) Clamp(score sointu.Score) ScorePoint {
if p.Track < 0 { if p.Track < 0 {
p.Track = 0 p.Track = 0
} else if l := len(score.Tracks); p.Track >= l { } else if l := len(score.Tracks); p.Track >= l {
p.Track = l - 1 p.Track = l - 1
} }
p.SongRow = p.SongRow.Clamp(score) p.ScoreRow = p.ScoreRow.Clamp(score)
return p return p
} }
func (r *SongRect) Contains(p SongPoint) bool { func (r *ScoreRect) Contains(p ScorePoint) bool {
track1, track2 := r.Corner1.Track, r.Corner2.Track track1, track2 := r.Corner1.Track, r.Corner2.Track
if track2 < track1 { if track2 < track1 {
track1, track2 = track2, track1 track1, track2 = track2, track1