mirror of
https://github.com/vsariola/sointu.git
synced 2025-05-28 03:10:24 -04:00
feat(tracker, gioui): add menu item to remove all unused data from song
Reorders patterns and cuts them short and the order list short to remove all unused / unuseful (all holds) patterns.
This commit is contained in:
parent
8a94058d44
commit
ede70380f2
@ -81,6 +81,8 @@ func (t *Tracker) layoutMenuBar(gtx C) D {
|
||||
}
|
||||
case 3:
|
||||
clipboard.ReadOp{Tag: &t.Menus[1]}.Add(gtx.Ops)
|
||||
case 4:
|
||||
t.RemoveUnusedData()
|
||||
}
|
||||
clickedItem, hasClicked = t.Menus[1].Clicked()
|
||||
}
|
||||
@ -98,11 +100,12 @@ func (t *Tracker) layoutMenuBar(gtx C) D {
|
||||
MenuItem{IconBytes: icons.ImageAudiotrack, Text: "Export Wav..."},
|
||||
MenuItem{IconBytes: icons.ActionExitToApp, Text: "Quit"},
|
||||
)),
|
||||
layout.Rigid(t.layoutMenu("Edit", &t.MenuBar[1], &t.Menus[1], unit.Dp(160),
|
||||
layout.Rigid(t.layoutMenu("Edit", &t.MenuBar[1], &t.Menus[1], unit.Dp(200),
|
||||
MenuItem{IconBytes: icons.ContentUndo, Text: "Undo", ShortcutText: shortcutKey + "Z", Disabled: !t.CanUndo()},
|
||||
MenuItem{IconBytes: icons.ContentRedo, Text: "Redo", ShortcutText: shortcutKey + "Y", Disabled: !t.CanRedo()},
|
||||
MenuItem{IconBytes: icons.ContentContentCopy, Text: "Copy", ShortcutText: shortcutKey + "C"},
|
||||
MenuItem{IconBytes: icons.ContentContentPaste, Text: "Paste", ShortcutText: shortcutKey + "V"},
|
||||
MenuItem{IconBytes: icons.ImageCrop, Text: "Remove unused data"},
|
||||
)),
|
||||
)
|
||||
}
|
||||
|
@ -913,6 +913,64 @@ func (m *Model) Param(index int) (Parameter, error) {
|
||||
return Parameter{}, errors.New("invalid parameter")
|
||||
}
|
||||
|
||||
func (m *Model) RemoveUnusedData() {
|
||||
m.saveUndo("RemoveUnusedData", 0)
|
||||
for trkIndex, trk := range m.song.Score.Tracks {
|
||||
// assign new indices to patterns
|
||||
newIndex := map[int]int{}
|
||||
runningIndex := 0
|
||||
length := 0
|
||||
if len(trk.Order) > m.song.Score.Length {
|
||||
trk.Order = trk.Order[:m.song.Score.Length]
|
||||
}
|
||||
for i, p := range trk.Order {
|
||||
// if the pattern hasn't been considered and is within limits
|
||||
if _, ok := newIndex[p]; !ok && p >= 0 && p < len(trk.Patterns) {
|
||||
pat := trk.Patterns[p]
|
||||
useful := false
|
||||
for _, n := range pat { // patterns that have anything else than all holds are useful and to be kept
|
||||
if n != 1 {
|
||||
useful = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if useful {
|
||||
newIndex[p] = runningIndex
|
||||
runningIndex++
|
||||
} else {
|
||||
newIndex[p] = -1
|
||||
}
|
||||
}
|
||||
if ind, ok := newIndex[p]; ok && ind > -1 {
|
||||
length = i + 1
|
||||
trk.Order[i] = ind
|
||||
} else {
|
||||
trk.Order[i] = -1
|
||||
}
|
||||
}
|
||||
trk.Order = trk.Order[:length]
|
||||
newPatterns := make([]sointu.Pattern, runningIndex)
|
||||
for i, pat := range trk.Patterns {
|
||||
if ind, ok := newIndex[i]; ok && ind > -1 {
|
||||
patLength := 0
|
||||
for j, note := range pat { // find last note that is something else that hold
|
||||
if note != 1 {
|
||||
patLength = j + 1
|
||||
}
|
||||
}
|
||||
if patLength > m.song.Score.RowsPerPattern {
|
||||
patLength = m.song.Score.RowsPerPattern
|
||||
}
|
||||
newPatterns[ind] = pat[:patLength] // crop to either RowsPerPattern or last row having something else than hold
|
||||
}
|
||||
}
|
||||
trk.Patterns = newPatterns
|
||||
m.song.Score.Tracks[trkIndex] = trk
|
||||
}
|
||||
m.computePatternUseCounts()
|
||||
m.notifyScoreChange()
|
||||
}
|
||||
|
||||
func (m *Model) SetParam(value int) {
|
||||
p, err := m.Param(m.paramIndex)
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user