refactor(tracker): Enabler is optionally implemented when needed

This commit is contained in:
5684185+vsariola@users.noreply.github.com
2026-01-21 19:53:24 +02:00
parent 810998d95b
commit 60222dded4
5 changed files with 70 additions and 87 deletions

View File

@ -14,13 +14,11 @@ type (
// can be initiated by calling the Do() method. It is usually initiated by a // can be initiated by calling the Do() method. It is usually initiated by a
// button press or a menu item. Action advertises whether it is enabled, so // button press or a menu item. Action advertises whether it is enabled, so
// UI can e.g. gray out buttons when the underlying action is not allowed. // UI can e.g. gray out buttons when the underlying action is not allowed.
// Action also implements the Doer and Enabler interfaces, but guarding that // The underlying Doer can optionally implement the Enabler interface to
// the underlying doer will never get called if enabler return false. That's // decide if the action is enabled or not; if it does not implement the
// why the doer and enabler are private fields, so that they cannot be // Enabler interface, the action is always allowed.
// called directly from outside, circumventing the Enabled() check.
Action struct { Action struct {
doer Doer doer Doer
enabler Enabler
} }
// Doer is an interface that defines a single Do() method, which is called // Doer is an interface that defines a single Do() method, which is called
@ -107,25 +105,13 @@ type (
// Action methods // Action methods
// simple version for when both doer and enabler are the same func MakeAction(doer Doer) Action {
func MakeAction(doerEnabler interface { return Action{doer: doer}
Doer
Enabler
}) Action {
return Action{doer: doerEnabler, enabler: doerEnabler}
}
// a version for cases where doer and enabler are different
func MakeAction2(doer Doer, enabler Enabler) Action {
return Action{doer: doer, enabler: enabler}
}
func MakeEnabledAction(doer Doer) Action {
return Action{doer: doer, enabler: nil}
} }
func (a Action) Do() { func (a Action) Do() {
if a.enabler != nil && !a.enabler.Enabled() { e, ok := a.doer.(Enabler)
if ok && !e.Enabled() {
return return
} }
if a.doer != nil { if a.doer != nil {
@ -137,10 +123,11 @@ func (a Action) Enabled() bool {
if a.doer == nil { if a.doer == nil {
return false // no doer, not allowed return false // no doer, not allowed
} }
if a.enabler == nil { e, ok := a.doer.(Enabler)
return true // no enabler, always allowed if !ok {
return true // not enabler, always allowed
} }
return a.enabler.Enabled() return e.Enabled()
} }
// DoFunc // DoFunc
@ -242,7 +229,7 @@ func (m *SplitInstrument) Do() {
// AddUnit // AddUnit
func (m *Model) AddUnit(before bool) Action { func (m *Model) AddUnit(before bool) Action {
return MakeEnabledAction(AddUnit{Before: before, Model: m}) return MakeAction(AddUnit{Before: before, Model: m})
} }
func (a AddUnit) Do() { func (a AddUnit) Do() {
m := (*Model)(a.Model) m := (*Model)(a.Model)
@ -334,32 +321,32 @@ func (m *Redo) Do() {
// AddSemiTone // AddSemiTone
func (m *Model) AddSemitone() Action { return MakeEnabledAction((*AddSemitone)(m)) } func (m *Model) AddSemitone() Action { return MakeAction((*AddSemitone)(m)) }
func (m *AddSemitone) Do() { Table{(*Notes)(m)}.Add(1, false) } func (m *AddSemitone) Do() { Table{(*Notes)(m)}.Add(1, false) }
// SubtractSemitone // SubtractSemitone
func (m *Model) SubtractSemitone() Action { return MakeEnabledAction((*SubtractSemitone)(m)) } func (m *Model) SubtractSemitone() Action { return MakeAction((*SubtractSemitone)(m)) }
func (m *SubtractSemitone) Do() { Table{(*Notes)(m)}.Add(-1, false) } func (m *SubtractSemitone) Do() { Table{(*Notes)(m)}.Add(-1, false) }
// AddOctave // AddOctave
func (m *Model) AddOctave() Action { return MakeEnabledAction((*AddOctave)(m)) } func (m *Model) AddOctave() Action { return MakeAction((*AddOctave)(m)) }
func (m *AddOctave) Do() { Table{(*Notes)(m)}.Add(1, true) } func (m *AddOctave) Do() { Table{(*Notes)(m)}.Add(1, true) }
// SubtractOctave // SubtractOctave
func (m *Model) SubtractOctave() Action { return MakeEnabledAction((*SubtractOctave)(m)) } func (m *Model) SubtractOctave() Action { return MakeAction((*SubtractOctave)(m)) }
func (m *SubtractOctave) Do() { Table{(*Notes)(m)}.Add(-1, true) } func (m *SubtractOctave) Do() { Table{(*Notes)(m)}.Add(-1, true) }
// EditNoteOff // EditNoteOff
func (m *Model) EditNoteOff() Action { return MakeEnabledAction((*EditNoteOff)(m)) } func (m *Model) EditNoteOff() Action { return MakeAction((*EditNoteOff)(m)) }
func (m *EditNoteOff) Do() { Table{(*Notes)(m)}.Fill(0) } func (m *EditNoteOff) Do() { Table{(*Notes)(m)}.Fill(0) }
// RemoveUnused // RemoveUnused
func (m *Model) RemoveUnused() Action { return MakeEnabledAction((*RemoveUnused)(m)) } func (m *Model) RemoveUnused() Action { return MakeAction((*RemoveUnused)(m)) }
func (m *RemoveUnused) Do() { func (m *RemoveUnused) Do() {
defer (*Model)(m).change("RemoveUnusedAction", ScoreChange, MajorChange)() defer (*Model)(m).change("RemoveUnusedAction", ScoreChange, MajorChange)()
for trkIndex, trk := range m.d.Song.Score.Tracks { for trkIndex, trk := range m.d.Song.Score.Tracks {
@ -468,7 +455,7 @@ func (m *PlayFromLoopStart) Do() {
// StopPlaying // StopPlaying
func (m *Model) StopPlaying() Action { return MakeEnabledAction((*StopPlaying)(m)) } func (m *Model) StopPlaying() Action { return MakeAction((*StopPlaying)(m)) }
func (m *StopPlaying) Do() { func (m *StopPlaying) Do() {
if !m.playing { if !m.playing {
(*Model)(m).setPanic(true) (*Model)(m).setPanic(true)
@ -482,7 +469,7 @@ func (m *StopPlaying) Do() {
// AddOrderRow // AddOrderRow
func (m *Model) AddOrderRow(before bool) Action { func (m *Model) AddOrderRow(before bool) Action {
return MakeEnabledAction(AddOrderRow{Before: before, Model: m}) return MakeAction(AddOrderRow{Before: before, Model: m})
} }
func (a AddOrderRow) Do() { func (a AddOrderRow) Do() {
m := a.Model m := a.Model
@ -506,7 +493,7 @@ func (a AddOrderRow) Do() {
// DeleteOrderRow // DeleteOrderRow
func (m *Model) DeleteOrderRow(backwards bool) Action { func (m *Model) DeleteOrderRow(backwards bool) Action {
return MakeEnabledAction(DeleteOrderRow{Backwards: backwards, Model: m}) return MakeAction(DeleteOrderRow{Backwards: backwards, Model: m})
} }
func (d DeleteOrderRow) Do() { func (d DeleteOrderRow) Do() {
m := d.Model m := d.Model
@ -535,7 +522,7 @@ func (m *Model) IsChoosingSendTarget() bool {
} }
func (m *Model) ChooseSendSource(id int) Action { func (m *Model) ChooseSendSource(id int) Action {
return MakeEnabledAction(ChooseSendSource{ID: id, Model: m}) return MakeAction(ChooseSendSource{ID: id, Model: m})
} }
func (s ChooseSendSource) Do() { func (s ChooseSendSource) Do() {
defer (*Model)(s.Model).change("ChooseSendSource", NoChange, MinorChange)() defer (*Model)(s.Model).change("ChooseSendSource", NoChange, MinorChange)()
@ -549,7 +536,7 @@ func (s ChooseSendSource) Do() {
// ChooseSendTarget // ChooseSendTarget
func (m *Model) ChooseSendTarget(id int, port int) Action { func (m *Model) ChooseSendTarget(id int, port int) Action {
return MakeEnabledAction(ChooseSendTarget{ID: id, Port: port, Model: m}) return MakeAction(ChooseSendTarget{ID: id, Port: port, Model: m})
} }
func (s ChooseSendTarget) Do() { func (s ChooseSendTarget) Do() {
defer (*Model)(s.Model).change("ChooseSendTarget", SongChange, MinorChange)() defer (*Model)(s.Model).change("ChooseSendTarget", SongChange, MinorChange)()
@ -568,7 +555,7 @@ func (s ChooseSendTarget) Do() {
// NewSong // NewSong
func (m *Model) NewSong() Action { return MakeEnabledAction((*NewSong)(m)) } func (m *Model) NewSong() Action { return MakeAction((*NewSong)(m)) }
func (m *NewSong) Do() { func (m *NewSong) Do() {
m.dialog = NewSongChanges m.dialog = NewSongChanges
(*Model)(m).completeAction(true) (*Model)(m).completeAction(true)
@ -576,7 +563,7 @@ func (m *NewSong) Do() {
// OpenSong // OpenSong
func (m *Model) OpenSong() Action { return MakeEnabledAction((*OpenSong)(m)) } func (m *Model) OpenSong() Action { return MakeAction((*OpenSong)(m)) }
func (m *OpenSong) Do() { func (m *OpenSong) Do() {
m.dialog = OpenSongChanges m.dialog = OpenSongChanges
(*Model)(m).completeAction(true) (*Model)(m).completeAction(true)
@ -584,7 +571,7 @@ func (m *OpenSong) Do() {
// RequestQuit // RequestQuit
func (m *Model) RequestQuit() Action { return MakeEnabledAction((*RequestQuit)(m)) } func (m *Model) RequestQuit() Action { return MakeAction((*RequestQuit)(m)) }
func (m *RequestQuit) Do() { func (m *RequestQuit) Do() {
if !m.quitted { if !m.quitted {
m.dialog = QuitChanges m.dialog = QuitChanges
@ -594,12 +581,12 @@ func (m *RequestQuit) Do() {
// ForceQuit // ForceQuit
func (m *Model) ForceQuit() Action { return MakeEnabledAction((*ForceQuit)(m)) } func (m *Model) ForceQuit() Action { return MakeAction((*ForceQuit)(m)) }
func (m *ForceQuit) Do() { m.quitted = true } func (m *ForceQuit) Do() { m.quitted = true }
// SaveSong // SaveSong
func (m *Model) SaveSong() Action { return MakeEnabledAction((*SaveSong)(m)) } func (m *Model) SaveSong() Action { return MakeAction((*SaveSong)(m)) }
func (m *SaveSong) Do() { func (m *SaveSong) Do() {
if m.d.FilePath == "" { if m.d.FilePath == "" {
switch m.dialog { switch m.dialog {
@ -623,29 +610,29 @@ func (m *SaveSong) Do() {
m.d.ChangedSinceSave = false m.d.ChangedSinceSave = false
} }
func (m *Model) DiscardSong() Action { return MakeEnabledAction((*DiscardSong)(m)) } func (m *Model) DiscardSong() Action { return MakeAction((*DiscardSong)(m)) }
func (m *DiscardSong) Do() { (*Model)(m).completeAction(false) } func (m *DiscardSong) Do() { (*Model)(m).completeAction(false) }
func (m *Model) SaveSongAs() Action { return MakeEnabledAction((*SaveSongAs)(m)) } func (m *Model) SaveSongAs() Action { return MakeAction((*SaveSongAs)(m)) }
func (m *SaveSongAs) Do() { m.dialog = SaveAsExplorer } func (m *SaveSongAs) Do() { m.dialog = SaveAsExplorer }
func (m *Model) Cancel() Action { return MakeEnabledAction((*Cancel)(m)) } func (m *Model) Cancel() Action { return MakeAction((*Cancel)(m)) }
func (m *Cancel) Do() { m.dialog = NoDialog } func (m *Cancel) Do() { m.dialog = NoDialog }
func (m *Model) Export() Action { return MakeEnabledAction((*ExportAction)(m)) } func (m *Model) Export() Action { return MakeAction((*ExportAction)(m)) }
func (m *ExportAction) Do() { m.dialog = Export } func (m *ExportAction) Do() { m.dialog = Export }
func (m *Model) ExportFloat() Action { return MakeEnabledAction((*ExportFloat)(m)) } func (m *Model) ExportFloat() Action { return MakeAction((*ExportFloat)(m)) }
func (m *ExportFloat) Do() { m.dialog = ExportFloatExplorer } func (m *ExportFloat) Do() { m.dialog = ExportFloatExplorer }
func (m *Model) ExportInt16() Action { return MakeEnabledAction((*ExportInt16)(m)) } func (m *Model) ExportInt16() Action { return MakeAction((*ExportInt16)(m)) }
func (m *ExportInt16) Do() { m.dialog = ExportInt16Explorer } func (m *ExportInt16) Do() { m.dialog = ExportInt16Explorer }
func (m *Model) ShowLicense() Action { return MakeEnabledAction((*ShowLicense)(m)) } func (m *Model) ShowLicense() Action { return MakeAction((*ShowLicense)(m)) }
func (m *ShowLicense) Do() { m.dialog = License } func (m *ShowLicense) Do() { m.dialog = License }
func (m *Model) SelectMidiInput(item MIDIDevice) Action { func (m *Model) SelectMidiInput(item MIDIDevice) Action {
return MakeEnabledAction(SelectMidiInput{Item: item, Model: m}) return MakeAction(SelectMidiInput{Item: item, Model: m})
} }
func (s SelectMidiInput) Do() { func (s SelectMidiInput) Do() {
m := s.Model m := s.Model

View File

@ -7,7 +7,6 @@ import (
type ( type (
Bool struct { Bool struct {
value BoolValue value BoolValue
enabler Enabler
} }
BoolValue interface { BoolValue interface {
@ -37,15 +36,8 @@ type (
simpleBool bool simpleBool bool
) )
func MakeBool(valueEnabler interface { func MakeBool(value BoolValue) Bool {
BoolValue return Bool{value: value}
Enabler
}) Bool {
return Bool{value: valueEnabler, enabler: valueEnabler}
}
func MakeEnabledBool(value BoolValue) Bool {
return Bool{value: value, enabler: nil}
} }
func (v Bool) Toggle() { func (v Bool) Toggle() {
@ -66,10 +58,14 @@ func (v Bool) Value() bool {
} }
func (v Bool) Enabled() bool { func (v Bool) Enabled() bool {
if v.enabler == nil { if v.value == nil {
return false
}
e, ok := v.value.(Enabler)
if !ok {
return true return true
} }
return v.enabler.Enabled() return e.Enabled()
} }
func (v *simpleBool) Value() bool { return bool(*v) } func (v *simpleBool) Value() bool { return bool(*v) }
@ -145,31 +141,31 @@ func (m *Model) warnNoThread() {
} }
func (m *Model) Thread1() Bool { return MakeEnabledBool((*Thread1)(m)) } func (m *Model) Thread1() Bool { return MakeBool((*Thread1)(m)) }
func (m *Thread1) Value() bool { return (*Model)(m).getThreadsBit(0) } func (m *Thread1) Value() bool { return (*Model)(m).getThreadsBit(0) }
func (m *Thread1) SetValue(val bool) { (*Model)(m).setThreadsBit(0, val) } func (m *Thread1) SetValue(val bool) { (*Model)(m).setThreadsBit(0, val) }
func (m *Model) Thread2() Bool { return MakeEnabledBool((*Thread2)(m)) } func (m *Model) Thread2() Bool { return MakeBool((*Thread2)(m)) }
func (m *Thread2) Value() bool { return (*Model)(m).getThreadsBit(1) } func (m *Thread2) Value() bool { return (*Model)(m).getThreadsBit(1) }
func (m *Thread2) SetValue(val bool) { (*Model)(m).setThreadsBit(1, val) } func (m *Thread2) SetValue(val bool) { (*Model)(m).setThreadsBit(1, val) }
func (m *Model) Thread3() Bool { return MakeEnabledBool((*Thread3)(m)) } func (m *Model) Thread3() Bool { return MakeBool((*Thread3)(m)) }
func (m *Thread3) Value() bool { return (*Model)(m).getThreadsBit(2) } func (m *Thread3) Value() bool { return (*Model)(m).getThreadsBit(2) }
func (m *Thread3) SetValue(val bool) { (*Model)(m).setThreadsBit(2, val) } func (m *Thread3) SetValue(val bool) { (*Model)(m).setThreadsBit(2, val) }
func (m *Model) Thread4() Bool { return MakeEnabledBool((*Thread4)(m)) } func (m *Model) Thread4() Bool { return MakeBool((*Thread4)(m)) }
func (m *Thread4) Value() bool { return (*Model)(m).getThreadsBit(3) } func (m *Thread4) Value() bool { return (*Model)(m).getThreadsBit(3) }
func (m *Thread4) SetValue(val bool) { (*Model)(m).setThreadsBit(3, val) } func (m *Thread4) SetValue(val bool) { (*Model)(m).setThreadsBit(3, val) }
// Panic methods // Panic methods
func (m *Model) Panic() Bool { return MakeEnabledBool((*Panic)(m)) } func (m *Model) Panic() Bool { return MakeBool((*Panic)(m)) }
func (m *Panic) Value() bool { return m.panic } func (m *Panic) Value() bool { return m.panic }
func (m *Panic) SetValue(val bool) { (*Model)(m).setPanic(val) } func (m *Panic) SetValue(val bool) { (*Model)(m).setPanic(val) }
// IsRecording methods // IsRecording methods
func (m *Model) IsRecording() Bool { return MakeEnabledBool((*IsRecording)(m)) } func (m *Model) IsRecording() Bool { return MakeBool((*IsRecording)(m)) }
func (m *IsRecording) Value() bool { return (*Model)(m).recording } func (m *IsRecording) Value() bool { return (*Model)(m).recording }
func (m *IsRecording) SetValue(val bool) { func (m *IsRecording) SetValue(val bool) {
m.recording = val m.recording = val
@ -194,11 +190,11 @@ func (m *Playing) Enabled() bool { return m.playing || !m.instrEnlarged }
// InstrEnlarged methods // InstrEnlarged methods
func (m *Model) InstrEnlarged() Bool { return MakeEnabledBool((*simpleBool)(&m.instrEnlarged)) } func (m *Model) InstrEnlarged() Bool { return MakeBool((*simpleBool)(&m.instrEnlarged)) }
// InstrEditor methods // InstrEditor methods
func (m *Model) InstrEditor() Bool { return MakeEnabledBool((*InstrEditor)(m)) } func (m *Model) InstrEditor() Bool { return MakeBool((*InstrEditor)(m)) }
func (m *InstrEditor) Value() bool { return m.d.InstrumentTab == InstrumentEditorTab } func (m *InstrEditor) Value() bool { return m.d.InstrumentTab == InstrumentEditorTab }
func (m *InstrEditor) SetValue(val bool) { func (m *InstrEditor) SetValue(val bool) {
if val { if val {
@ -206,7 +202,7 @@ func (m *InstrEditor) SetValue(val bool) {
} }
} }
func (m *Model) InstrComment() Bool { return MakeEnabledBool((*InstrComment)(m)) } func (m *Model) InstrComment() Bool { return MakeBool((*InstrComment)(m)) }
func (m *InstrComment) Value() bool { return m.d.InstrumentTab == InstrumentCommentTab } func (m *InstrComment) Value() bool { return m.d.InstrumentTab == InstrumentCommentTab }
func (m *InstrComment) SetValue(val bool) { func (m *InstrComment) SetValue(val bool) {
if val { if val {
@ -214,7 +210,7 @@ func (m *InstrComment) SetValue(val bool) {
} }
} }
func (m *Model) InstrPresets() Bool { return MakeEnabledBool((*InstrPresets)(m)) } func (m *Model) InstrPresets() Bool { return MakeBool((*InstrPresets)(m)) }
func (m *InstrPresets) Value() bool { return m.d.InstrumentTab == InstrumentPresetsTab } func (m *InstrPresets) Value() bool { return m.d.InstrumentTab == InstrumentPresetsTab }
func (m *InstrPresets) SetValue(val bool) { func (m *InstrPresets) SetValue(val bool) {
if val { if val {
@ -224,17 +220,17 @@ func (m *InstrPresets) SetValue(val bool) {
// Follow methods // Follow methods
func (m *Model) Follow() Bool { return MakeEnabledBool((*simpleBool)(&m.follow)) } func (m *Model) Follow() Bool { return MakeBool((*simpleBool)(&m.follow)) }
// TrackMidiIn (Midi Input for notes in the tracks) // TrackMidiIn (Midi Input for notes in the tracks)
func (m *Model) TrackMidiIn() Bool { return MakeEnabledBool((*TrackMidiIn)(m)) } func (m *Model) TrackMidiIn() Bool { return MakeBool((*TrackMidiIn)(m)) }
func (m *TrackMidiIn) Value() bool { return m.broker.mIDIEventsToGUI.Load() } func (m *TrackMidiIn) Value() bool { return m.broker.mIDIEventsToGUI.Load() }
func (m *TrackMidiIn) SetValue(val bool) { m.broker.mIDIEventsToGUI.Store(val) } func (m *TrackMidiIn) SetValue(val bool) { m.broker.mIDIEventsToGUI.Store(val) }
// Effect methods // Effect methods
func (m *Model) Effect() Bool { return MakeEnabledBool((*Effect)(m)) } func (m *Model) Effect() Bool { return MakeBool((*Effect)(m)) }
func (m *Effect) Value() bool { func (m *Effect) Value() bool {
if m.d.Cursor.Track < 0 || m.d.Cursor.Track >= len(m.d.Song.Score.Tracks) { if m.d.Cursor.Track < 0 || m.d.Cursor.Track >= len(m.d.Song.Score.Tracks) {
return false return false
@ -250,7 +246,7 @@ func (m *Effect) SetValue(val bool) {
// Oversampling methods // Oversampling methods
func (m *Model) Oversampling() Bool { return MakeEnabledBool((*Oversampling)(m)) } func (m *Model) Oversampling() Bool { return MakeBool((*Oversampling)(m)) }
func (m *Oversampling) Value() bool { return m.oversampling } func (m *Oversampling) Value() bool { return m.oversampling }
func (m *Oversampling) SetValue(val bool) { func (m *Oversampling) SetValue(val bool) {
m.oversampling = val m.oversampling = val
@ -259,7 +255,7 @@ func (m *Oversampling) SetValue(val bool) {
// UnitSearching methods // UnitSearching methods
func (m *Model) UnitSearching() Bool { return MakeEnabledBool((*UnitSearching)(m)) } func (m *Model) UnitSearching() Bool { return MakeBool((*UnitSearching)(m)) }
func (m *UnitSearching) Value() bool { return m.d.UnitSearching } func (m *UnitSearching) Value() bool { return m.d.UnitSearching }
func (m *UnitSearching) SetValue(val bool) { func (m *UnitSearching) SetValue(val bool) {
m.d.UnitSearching = val m.d.UnitSearching = val
@ -309,7 +305,7 @@ func (m *UnitDisabled) Enabled() bool {
// LoopToggle methods // LoopToggle methods
func (m *Model) LoopToggle() Bool { return MakeEnabledBool((*LoopToggle)(m)) } func (m *Model) LoopToggle() Bool { return MakeBool((*LoopToggle)(m)) }
func (m *LoopToggle) Value() bool { return m.loop.Length > 0 } func (m *LoopToggle) Value() bool { return m.loop.Length > 0 }
func (t *LoopToggle) SetValue(val bool) { func (t *LoopToggle) SetValue(val bool) {
m := (*Model)(t) m := (*Model)(t)
@ -324,7 +320,7 @@ func (t *LoopToggle) SetValue(val bool) {
// UniquePatterns methods // UniquePatterns methods
func (m *Model) UniquePatterns() Bool { return MakeEnabledBool((*simpleBool)(&m.uniquePatterns)) } func (m *Model) UniquePatterns() Bool { return MakeBool((*simpleBool)(&m.uniquePatterns)) }
// Mute methods // Mute methods
func (m *Model) Mute() Bool { return MakeBool((*Mute)(m)) } func (m *Model) Mute() Bool { return MakeBool((*Mute)(m)) }
@ -378,4 +374,4 @@ func (m *Solo) Enabled() bool { return m.d.InstrIndex >= 0 && m.d.InstrIndex < l
// LinkInstrTrack methods // LinkInstrTrack methods
func (m *Model) LinkInstrTrack() Bool { return MakeEnabledBool((*simpleBool)(&m.linkInstrTrack)) } func (m *Model) LinkInstrTrack() Bool { return MakeBool((*simpleBool)(&m.linkInstrTrack)) }

View File

@ -385,15 +385,15 @@ func (t *Tracker) layoutTop(gtx layout.Context) layout.Dimensions {
) )
} }
func (t *Tracker) ShowManual() tracker.Action { return tracker.MakeEnabledAction((*ShowManual)(t)) } func (t *Tracker) ShowManual() tracker.Action { return tracker.MakeAction((*ShowManual)(t)) }
func (t *ShowManual) Do() { (*Tracker)(t).openUrl("https://github.com/vsariola/sointu/wiki") } func (t *ShowManual) Do() { (*Tracker)(t).openUrl("https://github.com/vsariola/sointu/wiki") }
func (t *Tracker) AskHelp() tracker.Action { return tracker.MakeEnabledAction((*AskHelp)(t)) } func (t *Tracker) AskHelp() tracker.Action { return tracker.MakeAction((*AskHelp)(t)) }
func (t *AskHelp) Do() { func (t *AskHelp) Do() {
(*Tracker)(t).openUrl("https://github.com/vsariola/sointu/discussions/categories/help-needed") (*Tracker)(t).openUrl("https://github.com/vsariola/sointu/discussions/categories/help-needed")
} }
func (t *Tracker) ReportBug() tracker.Action { return tracker.MakeEnabledAction((*ReportBug)(t)) } func (t *Tracker) ReportBug() tracker.Action { return tracker.MakeAction((*ReportBug)(t)) }
func (t *ReportBug) Do() { (*Tracker)(t).openUrl("https://github.com/vsariola/sointu/issues") } func (t *ReportBug) Do() { (*Tracker)(t).openUrl("https://github.com/vsariola/sointu/issues") }
func (t *Tracker) openUrl(url string) { func (t *Tracker) openUrl(url string) {

View File

@ -64,8 +64,8 @@ func NewScopeModel(bpm int) *ScopeModel {
func (s *ScopeModel) Waveform() RingBuffer[[2]float32] { return s.waveForm } func (s *ScopeModel) Waveform() RingBuffer[[2]float32] { return s.waveForm }
func (s *ScopeModel) Once() Bool { return MakeEnabledBool((*SignalOnce)(s)) } func (s *ScopeModel) Once() Bool { return MakeBool((*SignalOnce)(s)) }
func (s *ScopeModel) Wrap() Bool { return MakeEnabledBool((*SignalWrap)(s)) } func (s *ScopeModel) Wrap() Bool { return MakeBool((*SignalWrap)(s)) }
func (s *ScopeModel) LengthInBeats() Int { return MakeInt((*SignalLengthInBeats)(s)) } func (s *ScopeModel) LengthInBeats() Int { return MakeInt((*SignalLengthInBeats)(s)) }
func (s *ScopeModel) TriggerChannel() Int { return MakeInt((*TriggerChannel)(s)) } func (s *ScopeModel) TriggerChannel() Int { return MakeInt((*TriggerChannel)(s)) }

View File

@ -58,7 +58,7 @@ const (
NumSpecChnModes NumSpecChnModes
) )
func (m *Model) SpecAnEnabled() Bool { return MakeEnabledBool((*simpleBool)(&m.specAnEnabled)) } func (m *Model) SpecAnEnabled() Bool { return MakeBool((*simpleBool)(&m.specAnEnabled)) }
func NewSpecAnalyzer(broker *Broker) *SpecAnalyzer { func NewSpecAnalyzer(broker *Broker) *SpecAnalyzer {
ret := &SpecAnalyzer{broker: broker} ret := &SpecAnalyzer{broker: broker}