mirror of
https://github.com/vsariola/sointu.git
synced 2025-11-13 05:12:47 -05:00
refactor(tracker): Make Action have separate Doer and Enabler
This commit is contained in:
parent
d6badb97be
commit
036cb1f34d
File diff suppressed because it is too large
Load Diff
@ -69,7 +69,7 @@ func ActionIcon(gtx C, th *Theme, w *ActionClickable, icon []byte, tip string) T
|
|||||||
for w.Clickable.Clicked(gtx) {
|
for w.Clickable.Clicked(gtx) {
|
||||||
w.Action.Do()
|
w.Action.Do()
|
||||||
}
|
}
|
||||||
if !w.Action.Allowed() {
|
if !w.Action.Enabled() {
|
||||||
ret.IconButtonStyle.Color = th.Button.Disabled.Color
|
ret.IconButtonStyle.Color = th.Button.Disabled.Color
|
||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
@ -119,7 +119,7 @@ func ActionButton(gtx C, th *Theme, style *ButtonStyle, w *ActionClickable, text
|
|||||||
for w.Clickable.Clicked(gtx) {
|
for w.Clickable.Clicked(gtx) {
|
||||||
w.Action.Do()
|
w.Action.Do()
|
||||||
}
|
}
|
||||||
if !w.Action.Allowed() {
|
if !w.Action.Enabled() {
|
||||||
return Btn(th, &th.Button.Disabled, &w.Clickable, text)
|
return Btn(th, &th.Button.Disabled, &w.Clickable, text)
|
||||||
}
|
}
|
||||||
return Btn(th, style, &w.Clickable, text)
|
return Btn(th, style, &w.Clickable, text)
|
||||||
|
|||||||
@ -92,7 +92,7 @@ func (d *Dialog) handleKeys(gtx C) {
|
|||||||
for d.BtnCancel.Clicked(gtx) {
|
for d.BtnCancel.Clicked(gtx) {
|
||||||
d.cancel.Do()
|
d.cancel.Do()
|
||||||
}
|
}
|
||||||
if d.alt.Allowed() {
|
if d.alt.Enabled() {
|
||||||
d.handleKeysForButton(gtx, &d.BtnAlt, &d.BtnCancel, &d.BtnOk)
|
d.handleKeysForButton(gtx, &d.BtnAlt, &d.BtnCancel, &d.BtnOk)
|
||||||
d.handleKeysForButton(gtx, &d.BtnCancel, &d.BtnOk, &d.BtnAlt)
|
d.handleKeysForButton(gtx, &d.BtnCancel, &d.BtnOk, &d.BtnAlt)
|
||||||
d.handleKeysForButton(gtx, &d.BtnOk, &d.BtnAlt, &d.BtnCancel)
|
d.handleKeysForButton(gtx, &d.BtnOk, &d.BtnAlt, &d.BtnCancel)
|
||||||
@ -118,7 +118,7 @@ func (d *DialogStyle) Layout(gtx C) D {
|
|||||||
layout.Rigid(func(gtx C) D {
|
layout.Rigid(func(gtx C) D {
|
||||||
return layout.E.Layout(gtx, func(gtx C) D {
|
return layout.E.Layout(gtx, func(gtx C) D {
|
||||||
gtx.Constraints.Min.X = gtx.Dp(unit.Dp(120))
|
gtx.Constraints.Min.X = gtx.Dp(unit.Dp(120))
|
||||||
if d.dialog.alt.Allowed() {
|
if d.dialog.alt.Enabled() {
|
||||||
return layout.Flex{Axis: layout.Horizontal, Spacing: layout.SpaceBetween}.Layout(gtx,
|
return layout.Flex{Axis: layout.Horizontal, Spacing: layout.SpaceBetween}.Layout(gtx,
|
||||||
layout.Rigid(d.OkStyle.Layout),
|
layout.Rigid(d.OkStyle.Layout),
|
||||||
layout.Rigid(d.AltStyle.Layout),
|
layout.Rigid(d.AltStyle.Layout),
|
||||||
|
|||||||
@ -22,44 +22,50 @@ import (
|
|||||||
"golang.org/x/exp/shiny/materialdesign/icons"
|
"golang.org/x/exp/shiny/materialdesign/icons"
|
||||||
)
|
)
|
||||||
|
|
||||||
type InstrumentEditor struct {
|
type (
|
||||||
newInstrumentBtn *ActionClickable
|
InstrumentEditor struct {
|
||||||
enlargeBtn *BoolClickable
|
newInstrumentBtn *ActionClickable
|
||||||
deleteInstrumentBtn *ActionClickable
|
enlargeBtn *BoolClickable
|
||||||
linkInstrTrackBtn *BoolClickable
|
deleteInstrumentBtn *ActionClickable
|
||||||
splitInstrumentBtn *ActionClickable
|
linkInstrTrackBtn *BoolClickable
|
||||||
copyInstrumentBtn *TipClickable
|
splitInstrumentBtn *ActionClickable
|
||||||
saveInstrumentBtn *TipClickable
|
copyInstrumentBtn *TipClickable
|
||||||
loadInstrumentBtn *TipClickable
|
saveInstrumentBtn *TipClickable
|
||||||
addUnitBtn *ActionClickable
|
loadInstrumentBtn *TipClickable
|
||||||
presetMenuBtn *TipClickable
|
addUnitBtn *ActionClickable
|
||||||
commentExpandBtn *BoolClickable
|
presetMenuBtn *TipClickable
|
||||||
soloBtn *BoolClickable
|
commentExpandBtn *BoolClickable
|
||||||
muteBtn *BoolClickable
|
soloBtn *BoolClickable
|
||||||
commentEditor *Editor
|
muteBtn *BoolClickable
|
||||||
commentString tracker.String
|
commentEditor *Editor
|
||||||
nameEditor *Editor
|
commentString tracker.String
|
||||||
nameString tracker.String
|
nameEditor *Editor
|
||||||
searchEditor *Editor
|
nameString tracker.String
|
||||||
instrumentDragList *DragList
|
searchEditor *Editor
|
||||||
unitDragList *DragList
|
instrumentDragList *DragList
|
||||||
unitEditor *UnitEditor
|
unitDragList *DragList
|
||||||
wasFocused bool
|
unitEditor *UnitEditor
|
||||||
presetMenuItems []MenuItem
|
wasFocused bool
|
||||||
presetMenu Menu
|
presetMenuItems []MenuItem
|
||||||
|
presetMenu Menu
|
||||||
|
|
||||||
enlargeHint, shrinkHint string
|
addUnit tracker.Action
|
||||||
addInstrumentHint string
|
|
||||||
octaveHint string
|
enlargeHint, shrinkHint string
|
||||||
expandCommentHint string
|
addInstrumentHint string
|
||||||
collapseCommentHint string
|
octaveHint string
|
||||||
deleteInstrumentHint string
|
expandCommentHint string
|
||||||
muteHint, unmuteHint string
|
collapseCommentHint string
|
||||||
soloHint, unsoloHint string
|
deleteInstrumentHint string
|
||||||
linkDisabledHint string
|
muteHint, unmuteHint string
|
||||||
linkEnabledHint string
|
soloHint, unsoloHint string
|
||||||
splitInstrumentHint string
|
linkDisabledHint string
|
||||||
}
|
linkEnabledHint string
|
||||||
|
splitInstrumentHint string
|
||||||
|
}
|
||||||
|
|
||||||
|
AddUnitThenFocus InstrumentEditor
|
||||||
|
)
|
||||||
|
|
||||||
func NewInstrumentEditor(model *tracker.Model) *InstrumentEditor {
|
func NewInstrumentEditor(model *tracker.Model) *InstrumentEditor {
|
||||||
ret := &InstrumentEditor{
|
ret := &InstrumentEditor{
|
||||||
@ -89,7 +95,8 @@ func NewInstrumentEditor(model *tracker.Model) *InstrumentEditor {
|
|||||||
ret.presetMenuItems = append(ret.presetMenuItems, MenuItem{Text: name, IconBytes: icons.ImageAudiotrack, Doer: model.LoadPreset(index)})
|
ret.presetMenuItems = append(ret.presetMenuItems, MenuItem{Text: name, IconBytes: icons.ImageAudiotrack, Doer: model.LoadPreset(index)})
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
ret.addUnitBtn = NewActionClickable(model.AddUnitAndThen(func() { ret.searchEditor.Focus() }))
|
ret.addUnit = model.AddUnit(false)
|
||||||
|
ret.addUnitBtn = NewActionClickable(tracker.MakeEnabledAction(ret.AddUnitThenFocus()))
|
||||||
ret.enlargeHint = makeHint("Enlarge", " (%s)", "InstrEnlargedToggle")
|
ret.enlargeHint = makeHint("Enlarge", " (%s)", "InstrEnlargedToggle")
|
||||||
ret.shrinkHint = makeHint("Shrink", " (%s)", "InstrEnlargedToggle")
|
ret.shrinkHint = makeHint("Shrink", " (%s)", "InstrEnlargedToggle")
|
||||||
ret.addInstrumentHint = makeHint("Add\ninstrument", "\n(%s)", "AddInstrument")
|
ret.addInstrumentHint = makeHint("Add\ninstrument", "\n(%s)", "AddInstrument")
|
||||||
@ -107,6 +114,15 @@ func NewInstrumentEditor(model *tracker.Model) *InstrumentEditor {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ie *InstrumentEditor) AddUnitThenFocus() tracker.Action {
|
||||||
|
return tracker.MakeAction((*AddUnitThenFocus)(ie))
|
||||||
|
}
|
||||||
|
func (a *AddUnitThenFocus) Enabled() bool { return a.addUnit.Enabled() }
|
||||||
|
func (a *AddUnitThenFocus) Do() {
|
||||||
|
a.addUnit.Do()
|
||||||
|
a.searchEditor.Focus()
|
||||||
|
}
|
||||||
|
|
||||||
func (ie *InstrumentEditor) Focus() {
|
func (ie *InstrumentEditor) Focus() {
|
||||||
ie.unitDragList.Focus()
|
ie.unitDragList.Focus()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -93,7 +93,7 @@ func (m *MenuStyle) Layout(gtx C, items ...MenuItem) D {
|
|||||||
defer op.Offset(image.Point{}).Push(gtx.Ops).Pop()
|
defer op.Offset(image.Point{}).Push(gtx.Ops).Pop()
|
||||||
var macro op.MacroOp
|
var macro op.MacroOp
|
||||||
item := &items[i]
|
item := &items[i]
|
||||||
if i == m.Menu.hover-1 && item.Doer.Allowed() {
|
if i == m.Menu.hover-1 && item.Doer.Enabled() {
|
||||||
macro = op.Record(gtx.Ops)
|
macro = op.Record(gtx.Ops)
|
||||||
}
|
}
|
||||||
icon := widgetForIcon(item.IconBytes)
|
icon := widgetForIcon(item.IconBytes)
|
||||||
@ -102,7 +102,7 @@ func (m *MenuStyle) Layout(gtx C, items ...MenuItem) D {
|
|||||||
textLabel := Label(m.Theme, &m.Theme.Menu.Text, item.Text)
|
textLabel := Label(m.Theme, &m.Theme.Menu.Text, item.Text)
|
||||||
shortcutLabel := Label(m.Theme, &m.Theme.Menu.Text, item.ShortcutText)
|
shortcutLabel := Label(m.Theme, &m.Theme.Menu.Text, item.ShortcutText)
|
||||||
shortcutLabel.Color = m.ShortCutColor
|
shortcutLabel.Color = m.ShortCutColor
|
||||||
if !item.Doer.Allowed() {
|
if !item.Doer.Enabled() {
|
||||||
iconColor = m.Disabled
|
iconColor = m.Disabled
|
||||||
textLabel.Color = m.Disabled
|
textLabel.Color = m.Disabled
|
||||||
shortcutLabel.Color = m.Disabled
|
shortcutLabel.Color = m.Disabled
|
||||||
@ -122,14 +122,14 @@ func (m *MenuStyle) Layout(gtx C, items ...MenuItem) D {
|
|||||||
return shortcutInset.Layout(gtx, shortcutLabel.Layout)
|
return shortcutInset.Layout(gtx, shortcutLabel.Layout)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
if i == m.Menu.hover-1 && item.Doer.Allowed() {
|
if i == m.Menu.hover-1 && item.Doer.Enabled() {
|
||||||
recording := macro.Stop()
|
recording := macro.Stop()
|
||||||
paint.FillShape(gtx.Ops, m.HoverColor, clip.Rect{
|
paint.FillShape(gtx.Ops, m.HoverColor, clip.Rect{
|
||||||
Max: image.Pt(dims.Size.X, dims.Size.Y),
|
Max: image.Pt(dims.Size.X, dims.Size.Y),
|
||||||
}.Op())
|
}.Op())
|
||||||
recording.Add(gtx.Ops)
|
recording.Add(gtx.Ops)
|
||||||
}
|
}
|
||||||
if item.Doer.Allowed() {
|
if item.Doer.Enabled() {
|
||||||
rect := image.Rect(0, 0, dims.Size.X, dims.Size.Y)
|
rect := image.Rect(0, 0, dims.Size.X, dims.Size.Y)
|
||||||
area := clip.Rect(rect).Push(gtx.Ops)
|
area := clip.Rect(rect).Push(gtx.Ops)
|
||||||
event.Op(gtx.Ops, &m.Menu.tags[i])
|
event.Op(gtx.Ops, &m.Menu.tags[i])
|
||||||
|
|||||||
@ -332,11 +332,11 @@ func (p ParameterStyle) Layout(gtx C) D {
|
|||||||
name, _, _, _ := p.tracker.Instruments().Item(i)
|
name, _, _, _ := p.tracker.Instruments().Item(i)
|
||||||
instrItems[i].Text = name
|
instrItems[i].Text = name
|
||||||
instrItems[i].IconBytes = icons.NavigationChevronRight
|
instrItems[i].IconBytes = icons.NavigationChevronRight
|
||||||
instrItems[i].Doer = tracker.Allow(func() {
|
instrItems[i].Doer = tracker.MakeEnabledAction((tracker.DoFunc)(func() {
|
||||||
if id, ok := p.tracker.Instruments().FirstID(i); ok {
|
if id, ok := p.tracker.Instruments().FirstID(i); ok {
|
||||||
tracker.Int{IntData: p.w.Parameter}.Set(id)
|
tracker.Int{IntData: p.w.Parameter}.Set(id)
|
||||||
}
|
}
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
var unitItems []MenuItem
|
var unitItems []MenuItem
|
||||||
instrName := "<instr>"
|
instrName := "<instr>"
|
||||||
@ -350,9 +350,9 @@ func (p ParameterStyle) Layout(gtx C) D {
|
|||||||
id := unit.ID
|
id := unit.ID
|
||||||
unitItems[j].Text = buildUnitLabel(j, unit)
|
unitItems[j].Text = buildUnitLabel(j, unit)
|
||||||
unitItems[j].IconBytes = icons.NavigationChevronRight
|
unitItems[j].IconBytes = icons.NavigationChevronRight
|
||||||
unitItems[j].Doer = tracker.Allow(func() {
|
unitItems[j].Doer = tracker.MakeEnabledAction((tracker.DoFunc)(func() {
|
||||||
tracker.Int{IntData: p.w.Parameter}.Set(id)
|
tracker.Int{IntData: p.w.Parameter}.Set(id)
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
defer pointer.PassOp{}.Push(gtx.Ops).Pop()
|
defer pointer.PassOp{}.Push(gtx.Ops).Pop()
|
||||||
|
|||||||
@ -143,22 +143,22 @@ func NumPresets() int {
|
|||||||
|
|
||||||
// LoadPreset loads a preset from the list of instrument presets. The index
|
// LoadPreset loads a preset from the list of instrument presets. The index
|
||||||
// should be within the range of 0 to NumPresets()-1.
|
// should be within the range of 0 to NumPresets()-1.
|
||||||
|
|
||||||
func (m *Model) LoadPreset(index int) Action {
|
func (m *Model) LoadPreset(index int) Action {
|
||||||
return Action{do: func() {
|
return MakeEnabledAction(LoadPreset{Index: index, Model: m})
|
||||||
defer m.change("LoadPreset", PatchChange, MajorChange)()
|
}
|
||||||
if m.d.InstrIndex < 0 {
|
func (m LoadPreset) Do() {
|
||||||
m.d.InstrIndex = 0
|
defer m.change("LoadPreset", PatchChange, MajorChange)()
|
||||||
}
|
if m.d.InstrIndex < 0 {
|
||||||
m.d.InstrIndex2 = m.d.InstrIndex
|
m.d.InstrIndex = 0
|
||||||
for m.d.InstrIndex >= len(m.d.Song.Patch) {
|
}
|
||||||
m.d.Song.Patch = append(m.d.Song.Patch, defaultInstrument.Copy())
|
m.d.InstrIndex2 = m.d.InstrIndex
|
||||||
}
|
for m.d.InstrIndex >= len(m.d.Song.Patch) {
|
||||||
newInstr := instrumentPresets[index].Copy()
|
m.d.Song.Patch = append(m.d.Song.Patch, defaultInstrument.Copy())
|
||||||
(*Model)(m).assignUnitIDs(newInstr.Units)
|
}
|
||||||
m.d.Song.Patch[m.d.InstrIndex] = newInstr
|
newInstr := instrumentPresets[m.Index].Copy()
|
||||||
}, allowed: func() bool {
|
m.Model.assignUnitIDs(newInstr.Units)
|
||||||
return true
|
m.d.Song.Patch[m.d.InstrIndex] = newInstr
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type instrumentPresetsSlice []sointu.Instrument
|
type instrumentPresetsSlice []sointu.Instrument
|
||||||
|
|||||||
Reference in New Issue
Block a user