Skip to content

Commit

Permalink
feat: units can have comments
Browse files Browse the repository at this point in the history
Closes #114
  • Loading branch information
vsariola committed Oct 13, 2024
1 parent 160eb8e commit 9779bee
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 9 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [Unreleased]
### Added
- Units can have comments, to make it easier to distinguish between units of
same type within an instrument. These comments are also shown when choosing
the send target. ([#114][i114])
- A toggle button for copying non-unique patterns before editing. When enabled
and if the pattern is used in multiple places, the pattern is copied first.
([#77][i77])
Expand Down Expand Up @@ -232,6 +235,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
[i77]: https://github.com/vsariola/sointu/issues/77
[i94]: https://github.com/vsariola/sointu/issues/94
[i112]: https://github.com/vsariola/sointu/issues/112
[i114]: https://github.com/vsariola/sointu/issues/114
[i116]: https://github.com/vsariola/sointu/issues/116
[i120]: https://github.com/vsariola/sointu/issues/120
[i121]: https://github.com/vsariola/sointu/issues/121
Expand Down
7 changes: 6 additions & 1 deletion patch.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ type (
// Disabled is a flag that can be set to true to disable the unit.
// Disabled units are considered to be not present in the patch.
Disabled bool `yaml:",omitempty"`

// Comment is a free-form comment about the unit that can be displayed
// instead of/besides the type of the unit in the GUI, to make it easier
// to track what the unit is doing & to make it easier to target sends.
Comment string `yaml:",omitempty"`
}

// UnitParameter documents one parameter that an unit takes
Expand Down Expand Up @@ -291,7 +296,7 @@ func (u *Unit) Copy() Unit {
}
varArgs := make([]int, len(u.VarArgs))
copy(varArgs, u.VarArgs)
return Unit{Type: u.Type, Parameters: parameters, VarArgs: varArgs, ID: u.ID, Disabled: u.Disabled}
return Unit{Type: u.Type, Parameters: parameters, VarArgs: varArgs, ID: u.ID, Disabled: u.Disabled, Comment: u.Comment}
}

// StackChange returns how this unit will affect the signal stack. "pop" and
Expand Down
12 changes: 9 additions & 3 deletions tracker/gioui/instrument_editor.go
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,8 @@ func (ie *InstrumentEditor) layoutUnitList(gtx C, t *Tracker) D {
count := intMin(ie.unitDragList.TrackerList.Count(), 256)

element := func(gtx C, i int) D {
gtx.Constraints = layout.Exact(image.Pt(gtx.Dp(unit.Dp(120)), gtx.Dp(unit.Dp(20))))
gtx.Constraints.Max.Y = gtx.Dp(20)
gtx.Constraints.Min.Y = gtx.Constraints.Max.Y
if i < 0 || i > 255 {
return layout.Dimensions{Size: gtx.Constraints.Min}
}
Expand All @@ -418,7 +419,7 @@ func (ie *InstrumentEditor) layoutUnitList(gtx C, t *Tracker) D {
stackLabel := LabelStyle{Text: stackText, ShadeColor: black, Color: mediumEmphasisTextColor, Font: labelDefaultFont, FontSize: unit.Sp(12), Shaper: t.Theme.Shaper}
rightMargin := layout.Inset{Right: unit.Dp(10)}
return layout.Flex{Axis: layout.Horizontal}.Layout(gtx,
layout.Flexed(1, func(gtx C) D {
layout.Rigid(func(gtx C) D {
if i == ie.unitDragList.TrackerList.Selected() {
editor := material.Editor(t.Theme, ie.searchEditor, "---")
editor.Color = color
Expand Down Expand Up @@ -473,6 +474,11 @@ func (ie *InstrumentEditor) layoutUnitList(gtx C, t *Tracker) D {
return unitNameLabel.Layout(gtx)
}
}),
layout.Flexed(1, func(gtx C) D {
unitNameLabel := LabelStyle{Text: u.Comment, ShadeColor: black, Color: mediumEmphasisTextColor, Font: f, FontSize: unit.Sp(12), Shaper: t.Theme.Shaper}
inset := layout.Inset{Left: unit.Dp(5)}
return inset.Layout(gtx, unitNameLabel.Layout)
}),
layout.Rigid(func(gtx C) D {
return rightMargin.Layout(gtx, stackLabel.Layout)
}),
Expand Down Expand Up @@ -517,7 +523,7 @@ func (ie *InstrumentEditor) layoutUnitList(gtx C, t *Tracker) D {
return layout.Stack{Alignment: layout.SE}.Layout(gtx,
layout.Expanded(func(gtx C) D {
defer clip.Rect(image.Rect(0, 0, gtx.Constraints.Max.X, gtx.Constraints.Max.Y)).Push(gtx.Ops).Pop()
gtx.Constraints = layout.Exact(image.Pt(gtx.Dp(unit.Dp(120)), gtx.Constraints.Max.Y))
gtx.Constraints = layout.Exact(image.Pt(gtx.Dp(140), gtx.Constraints.Max.Y))
dims := unitList.Layout(gtx)
unitList.LayoutScrollBar(gtx)
return dims
Expand Down
56 changes: 52 additions & 4 deletions tracker/gioui/unit_editor.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ type UnitEditor struct {
ClearUnitBtn *ActionClickable
DisableUnitBtn *BoolClickable
SelectTypeBtn *widget.Clickable
commentEditor *widget.Editor
caser cases.Caser
commentFilters []event.Filter

copyHint string
disableUnitHint string
Expand All @@ -46,10 +48,19 @@ func NewUnitEditor(m *tracker.Model) *UnitEditor {
DisableUnitBtn: NewBoolClickable(m.UnitDisabled().Bool()),
CopyUnitBtn: new(TipClickable),
SelectTypeBtn: new(widget.Clickable),
commentEditor: &widget.Editor{SingleLine: true, Submit: true, MaxLen: 16},
sliderList: NewDragList(m.Params().List(), layout.Vertical),
searchList: NewDragList(m.SearchResults().List(), layout.Vertical),
}
ret.caser = cases.Title(language.English)
for k, a := range keyBindingMap {
if len(a) < 4 || a[:4] != "Note" {
continue
}
ret.commentFilters = append(ret.commentFilters, key.Filter{Name: k.Name, Required: k.Modifiers, Focus: ret.commentEditor})
}
ret.commentFilters = append(ret.commentFilters, key.Filter{Name: key.NameSpace, Focus: ret.commentEditor})
ret.commentFilters = append(ret.commentFilters, key.Filter{Name: key.NameEscape, Focus: ret.commentEditor})
ret.copyHint = makeHint("Copy unit", " (%s)", "Copy")
ret.disableUnitHint = makeHint("Disable unit", " (%s)", "UnitDisabledToggle")
ret.enableUnitHint = makeHint("Enable unit", " (%s)", "UnitDisabledToggle")
Expand Down Expand Up @@ -139,6 +150,11 @@ func (pe *UnitEditor) layoutFooter(gtx C, t *Tracker) D {
text = pe.caser.String(text)
}
hintText := Label(text, white, t.Theme.Shaper)
commentStyle := material.Editor(t.Theme, pe.commentEditor, "---")
commentStyle.Font = labelDefaultFont
commentStyle.TextSize = labelDefaultFontSize
commentStyle.Color = mediumEmphasisTextColor
commentStyle.HintColor = mediumEmphasisTextColor
return layout.Flex{Axis: layout.Horizontal, Alignment: layout.Middle}.Layout(gtx,
layout.Rigid(deleteUnitBtnStyle.Layout),
layout.Rigid(copyUnitBtnStyle.Layout),
Expand All @@ -151,7 +167,39 @@ func (pe *UnitEditor) layoutFooter(gtx C, t *Tracker) D {
}
return D{Size: image.Pt(gtx.Dp(unit.Dp(48)), dims.Size.Y)}
}),
layout.Flexed(1, hintText),
layout.Rigid(func(gtx C) D {
gtx.Constraints.Min.X = gtx.Dp(120)
return hintText(gtx)
}),
layout.Flexed(1, func(gtx C) D {
s := t.UnitComment().String()
if pe.commentEditor.Text() != s.Value() {
pe.commentEditor.SetText(s.Value())
}
for {
ev, ok := pe.commentEditor.Update(gtx)
if !ok {
break
}
_, ok = ev.(widget.SubmitEvent)
if ok {
t.InstrumentEditor.Focus()
continue
}
}
for {
event, ok := gtx.Event(pe.commentFilters...)
if !ok {
break
}
if e, ok := event.(key.Event); ok && e.State == key.Press && e.Name == key.NameEscape {
t.InstrumentEditor.Focus()
}
}
ret := commentStyle.Layout(gtx)
s.Set(commentStyle.Editor.Text())
return ret
}),
)
}

Expand Down Expand Up @@ -317,11 +365,11 @@ func (p ParameterStyle) Layout(gtx C) D {
targetInstrument := p.tracker.Instrument(targetI)
instrName = targetInstrument.Name
units := targetInstrument.Units
unitName = fmt.Sprintf("%v: %v", targetU, units[targetU].Type)
unitName = fmt.Sprintf("%d: %s %s", targetU, units[targetU].Type, units[targetU].Comment)
unitItems = make([]MenuItem, len(units))
for j, unit := range units {
id := unit.ID
unitItems[j].Text = fmt.Sprintf("%v: %v", j, unit.Type)
unitItems[j].Text = fmt.Sprintf("%d: %s %s", j, unit.Type, unit.Comment)
unitItems[j].IconBytes = icons.NavigationChevronRight
unitItems[j].Doer = tracker.Allow(func() {
tracker.Int{IntData: p.w.Parameter}.Set(id)
Expand All @@ -333,7 +381,7 @@ func (p ParameterStyle) Layout(gtx C) D {
layout.Rigid(p.tracker.layoutMenu(gtx, instrName, &p.w.instrBtn, &p.w.instrMenu, unit.Dp(200),
instrItems...,
)),
layout.Rigid(p.tracker.layoutMenu(gtx, unitName, &p.w.unitBtn, &p.w.unitMenu, unit.Dp(200),
layout.Rigid(p.tracker.layoutMenu(gtx, unitName, &p.w.unitBtn, &p.w.unitMenu, unit.Dp(240),
unitItems...,
)),
)
Expand Down
3 changes: 2 additions & 1 deletion tracker/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ type (
}

UnitListItem struct {
Type string
Type, Comment string
Disabled bool
StackNeed, StackBefore, StackAfter int
}
Expand Down Expand Up @@ -332,6 +332,7 @@ func (v *Units) Iterate(yield UnitYieldFunc) {
stackAfter := stackBefore + unit.StackChange()
if !yield(UnitListItem{
Type: unit.Type,
Comment: unit.Comment,
Disabled: unit.Disabled,
StackNeed: unit.StackNeed(),
StackBefore: stackBefore,
Expand Down
25 changes: 25 additions & 0 deletions tracker/string.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type (
InstrumentName Model
InstrumentComment Model
UnitSearch Model
UnitComment Model
)

func (v String) Set(value string) {
Expand All @@ -30,6 +31,7 @@ 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) }

// FilePathString

Expand Down Expand Up @@ -108,3 +110,26 @@ func (v *InstrumentComment) setValue(value string) {
func (v *InstrumentComment) change(kind string) func() {
return (*Model)(v).change("InstrumentComment."+kind, PatchChange, MinorChange)
}

// 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) {
return ""
}
return v.d.Song.Patch[v.d.InstrIndex].Units[v.d.UnitIndex].Comment
}

func (v *UnitComment) setValue(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) {
return
}
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)
}

0 comments on commit 9779bee

Please sign in to comment.