diff --git a/tracker/gioui/instrument_editor.go b/tracker/gioui/instrument_editor.go index a851f05..3863f9d 100644 --- a/tracker/gioui/instrument_editor.go +++ b/tracker/gioui/instrument_editor.go @@ -84,8 +84,8 @@ func NewInstrumentEditor(model *tracker.Model) *InstrumentEditor { commentEditor: NewEditor(widget.Editor{}), nameEditor: NewEditor(widget.Editor{SingleLine: true, Submit: true, Alignment: text.Middle}), searchEditor: NewEditor(widget.Editor{SingleLine: true, Submit: true, Alignment: text.Start}), - commentString: model.InstrumentComment().String(), - nameString: model.InstrumentName().String(), + commentString: model.InstrumentComment(), + nameString: model.InstrumentName(), instrumentDragList: NewDragList(model.Instruments().List(), layout.Horizontal), unitDragList: NewDragList(model.Units().List(), layout.Vertical), unitEditor: NewUnitEditor(model), @@ -271,7 +271,7 @@ func (ie *InstrumentEditor) layoutInstrumentHeader(gtx C, t *Tracker) D { } style := MaterialEditor(t.Theme, &t.Theme.InstrumentEditor.InstrumentComment, ie.commentEditor, "Comment") ret := layout.UniformInset(unit.Dp(6)).Layout(gtx, style.Layout) - ie.commentString.Set(ie.commentEditor.Text()) + ie.commentString.SetValue(ie.commentEditor.Text()) return ret }), ) @@ -311,7 +311,7 @@ func (ie *InstrumentEditor) layoutInstrumentList(gtx C, t *Tracker) D { defer clip.Rect(image.Rect(0, 0, gtx.Constraints.Max.X, gtx.Constraints.Max.Y)).Push(gtx.Ops).Pop() return style.Layout(gtx) }) - ie.nameString.Set(ie.nameEditor.Text()) + ie.nameString.SetValue(ie.nameEditor.Text()) return dims } if name == "" { @@ -417,7 +417,7 @@ func (ie *InstrumentEditor) layoutUnitList(gtx C, t *Tracker) D { layout.Rigid(func(gtx C) D { if i == ie.unitDragList.TrackerList.Selected() { defer clip.Rect(image.Rect(0, 0, gtx.Constraints.Max.X, gtx.Constraints.Max.Y)).Push(gtx.Ops).Pop() - str := tracker.String{StringData: (*tracker.UnitSearch)(t.Model)} + str := t.Model.UnitSearch() ie.searchEditor.SetText(str.Value()) for ie.searchEditor.Submitted(gtx) { ie.unitDragList.Focus() @@ -439,7 +439,7 @@ func (ie *InstrumentEditor) layoutUnitList(gtx C, t *Tracker) D { } style := MaterialEditor(t.Theme, &editorStyle, ie.searchEditor, "---") ret := style.Layout(gtx) - str.Set(ie.searchEditor.Text()) + str.SetValue(ie.searchEditor.Text()) return ret } else { text := u.Type diff --git a/tracker/gioui/tracker.go b/tracker/gioui/tracker.go index 81b67d0..d19e6e8 100644 --- a/tracker/gioui/tracker.go +++ b/tracker/gioui/tracker.go @@ -91,7 +91,7 @@ func NewTracker(model *tracker.Model) *Tracker { Model: model, - filePathString: model.FilePath().String(), + filePathString: model.FilePath(), } t.PopupAlert = NewPopupAlert(model.Alerts()) var warn error diff --git a/tracker/gioui/unit_editor.go b/tracker/gioui/unit_editor.go index 37d7205..bd0cc19 100644 --- a/tracker/gioui/unit_editor.go +++ b/tracker/gioui/unit_editor.go @@ -159,14 +159,14 @@ func (pe *UnitEditor) layoutFooter(gtx C, t *Tracker) D { return hintText.Layout(gtx) }), layout.Flexed(1, func(gtx C) D { - s := t.UnitComment().String() + s := t.UnitComment() pe.commentEditor.SetText(s.Value()) for pe.commentEditor.Submitted(gtx) || pe.commentEditor.Cancelled(gtx) { t.InstrumentEditor.Focus() } commentStyle := MaterialEditor(t.Theme, &t.Theme.InstrumentEditor.UnitComment, pe.commentEditor, "---") ret := commentStyle.Layout(gtx) - s.Set(pe.commentEditor.Text()) + s.SetValue(pe.commentEditor.Text()) return ret }), ) diff --git a/tracker/model_test.go b/tracker/model_test.go index 65ab4bc..ca6f03e 100644 --- a/tracker/model_test.go +++ b/tracker/model_test.go @@ -71,10 +71,10 @@ func (s *modelFuzzState) Iterate(yield func(string, func(p string, t *testing.T) s.IterateBool("UniquePatterns", s.model.UniquePatterns(), yield, seed) s.IterateBool("LinkInstrTrack", s.model.LinkInstrTrack(), yield, seed) // Strings - s.IterateString("FilePath", s.model.FilePath().String(), yield, seed) - s.IterateString("InstrumentName", s.model.InstrumentName().String(), yield, seed) - s.IterateString("InstrumentComment", s.model.InstrumentComment().String(), yield, seed) - s.IterateString("UnitSearchText", s.model.UnitSearch().String(), yield, seed) + s.IterateString("FilePath", s.model.FilePath(), yield, seed) + s.IterateString("InstrumentName", s.model.InstrumentName(), yield, seed) + s.IterateString("InstrumentComment", s.model.InstrumentComment(), yield, seed) + s.IterateString("UnitSearchText", s.model.UnitSearch(), yield, seed) // Actions s.IterateAction("AddTrack", s.model.AddTrack(), yield, seed) s.IterateAction("DeleteTrack", s.model.DeleteTrack(), yield, seed) @@ -162,7 +162,7 @@ func (s *modelFuzzState) IterateBool(name string, b tracker.Bool, yield func(str func (s *modelFuzzState) IterateString(name string, str tracker.String, yield func(string, func(p string, t *testing.T)) bool, seed int) { yield(name+".Set", func(p string, t *testing.T) { - str.Set(fmt.Sprintf("%d", seed)) + str.SetValue(fmt.Sprintf("%d", seed)) }) } diff --git a/tracker/string.go b/tracker/string.go index 34e5b0c..55a8b42 100644 --- a/tracker/string.go +++ b/tracker/string.go @@ -2,13 +2,12 @@ package tracker type ( String struct { - StringData + value StringValue } - StringData interface { + StringValue interface { Value() string - setValue(string) - change(kind string) func() + SetValue(string) bool } FilePath Model @@ -18,31 +17,39 @@ type ( UnitComment Model ) -func (v String) Set(value string) { - if v.Value() != value { - defer v.change("Set")() - v.setValue(value) +func MakeString(value StringValue) String { + return String{value: value} +} + +func (v String) SetValue(value string) bool { + if v.value == nil || v.value.Value() == value { + return false } + return v.value.SetValue(value) +} + +func (v String) Value() string { + if v.value == nil { + return "" + } + return v.value.Value() } // Model methods -func (m *Model) FilePath() *FilePath { return (*FilePath)(m) } -func (m *Model) InstrumentName() *InstrumentName { return (*InstrumentName)(m) } -func (m *Model) InstrumentComment() *InstrumentComment { return (*InstrumentComment)(m) } -func (m *Model) UnitSearch() *UnitSearch { return (*UnitSearch)(m) } -func (m *Model) UnitComment() *UnitComment { return (*UnitComment)(m) } +func (m *Model) FilePath() String { return MakeString((*FilePath)(m)) } +func (m *Model) InstrumentName() String { return MakeString((*InstrumentName)(m)) } +func (m *Model) InstrumentComment() String { return MakeString((*InstrumentComment)(m)) } +func (m *Model) UnitSearch() String { return MakeString((*UnitSearch)(m)) } +func (m *Model) UnitComment() String { return MakeString((*UnitComment)(m)) } // FilePathString -func (v *FilePath) String() String { return String{v} } -func (v *FilePath) Value() string { return v.d.FilePath } -func (v *FilePath) setValue(value string) { v.d.FilePath = value } -func (v *FilePath) change(kind string) func() { return func() {} } +func (v *FilePath) Value() string { return v.d.FilePath } +func (v *FilePath) SetValue(value string) bool { v.d.FilePath = value; return true } // UnitSearchString -func (v *UnitSearch) String() String { return String{v} } func (v *UnitSearch) Value() string { // return current unit type string if not searching if !v.d.UnitSearching { @@ -57,18 +64,14 @@ func (v *UnitSearch) Value() string { return v.d.UnitSearchString } } -func (v *UnitSearch) setValue(value string) { +func (v *UnitSearch) SetValue(value string) bool { v.d.UnitSearchString = value v.d.UnitSearching = true + return true } -func (v *UnitSearch) change(kind string) func() { return func() {} } // InstrumentNameString -func (v *InstrumentName) String() String { - return String{v} -} - func (v *InstrumentName) Value() string { if v.d.InstrIndex < 0 || v.d.InstrIndex >= len(v.d.Song.Patch) { return "" @@ -76,23 +79,17 @@ func (v *InstrumentName) Value() string { return v.d.Song.Patch[v.d.InstrIndex].Name } -func (v *InstrumentName) setValue(value string) { +func (v *InstrumentName) SetValue(value string) bool { if v.d.InstrIndex < 0 || v.d.InstrIndex >= len(v.d.Song.Patch) { - return + return false } + defer (*Model)(v).change("InstrumentNameString", PatchChange, MinorChange)() v.d.Song.Patch[v.d.InstrIndex].Name = value -} - -func (v *InstrumentName) change(kind string) func() { - return (*Model)(v).change("InstrumentNameString."+kind, PatchChange, MinorChange) + return true } // InstrumentComment -func (v *InstrumentComment) String() String { - return String{v} -} - func (v *InstrumentComment) Value() string { if v.d.InstrIndex < 0 || v.d.InstrIndex >= len(v.d.Song.Patch) { return "" @@ -100,20 +97,17 @@ func (v *InstrumentComment) Value() string { return v.d.Song.Patch[v.d.InstrIndex].Comment } -func (v *InstrumentComment) setValue(value string) { +func (v *InstrumentComment) SetValue(value string) bool { if v.d.InstrIndex < 0 || v.d.InstrIndex >= len(v.d.Song.Patch) { - return + return false } + defer (*Model)(v).change("InstrumentComment", PatchChange, MinorChange)() v.d.Song.Patch[v.d.InstrIndex].Comment = value -} - -func (v *InstrumentComment) change(kind string) func() { - return (*Model)(v).change("InstrumentComment."+kind, PatchChange, MinorChange) + return true } // UnitComment -func (v *UnitComment) String() String { return String{v} } func (v *UnitComment) Value() string { if v.d.InstrIndex < 0 || v.d.InstrIndex >= len(v.d.Song.Patch) || v.d.UnitIndex < 0 || v.d.UnitIndex >= len(v.d.Song.Patch[v.d.InstrIndex].Units) { @@ -122,14 +116,12 @@ func (v *UnitComment) Value() string { return v.d.Song.Patch[v.d.InstrIndex].Units[v.d.UnitIndex].Comment } -func (v *UnitComment) setValue(value string) { +func (v *UnitComment) SetValue(value string) bool { if v.d.InstrIndex < 0 || v.d.InstrIndex >= len(v.d.Song.Patch) || v.d.UnitIndex < 0 || v.d.UnitIndex >= len(v.d.Song.Patch[v.d.InstrIndex].Units) { - return + return false } + defer (*Model)(v).change("UnitComment", PatchChange, MinorChange)() v.d.Song.Patch[v.d.InstrIndex].Units[v.d.UnitIndex].Comment = value -} - -func (v *UnitComment) change(kind string) func() { - return (*Model)(v).change("UnitComment."+kind, PatchChange, MinorChange) + return true }