mirror of
https://github.com/vsariola/sointu.git
synced 2025-06-03 00:58:26 -04:00
fix(tracker): unit search gains focus when adding a unit on last row
This commit is contained in:
parent
877556b428
commit
6fc9277113
@ -9,6 +9,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||||||
resized ([#145][i145])
|
resized ([#145][i145])
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
- When adding a unit on the last row of the unit list, the editor for entering
|
||||||
|
the type of the unit by text did gain focus.
|
||||||
- When inputting a note to the note editor, advance the cursor by step
|
- When inputting a note to the note editor, advance the cursor by step
|
||||||
([#144][i144])
|
([#144][i144])
|
||||||
- When loading an instrument, make sure the total number of voices does not go
|
- When loading an instrument, make sure the total number of voices does not go
|
||||||
|
@ -125,9 +125,15 @@ func (m *UnitSearching) Bool() Bool { return Bool{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
|
||||||
if !val {
|
if m.d.InstrIndex < 0 || m.d.InstrIndex >= len(m.d.Song.Patch) {
|
||||||
m.d.UnitSearchString = ""
|
m.d.UnitSearchString = ""
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
if m.d.UnitIndex < 0 || m.d.UnitIndex >= len(m.d.Song.Patch[m.d.InstrIndex].Units) {
|
||||||
|
m.d.UnitSearchString = ""
|
||||||
|
return
|
||||||
|
}
|
||||||
|
m.d.UnitSearchString = m.d.Song.Patch[m.d.InstrIndex].Units[m.d.UnitIndex].Type
|
||||||
}
|
}
|
||||||
func (m *UnitSearching) Enabled() bool { return true }
|
func (m *UnitSearching) Enabled() bool { return true }
|
||||||
|
|
||||||
|
@ -380,7 +380,7 @@ func (ie *InstrumentEditor) layoutUnitList(gtx C, t *Tracker) D {
|
|||||||
|
|
||||||
element := func(gtx C, i int) D {
|
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 = layout.Exact(image.Pt(gtx.Dp(unit.Dp(120)), gtx.Dp(unit.Dp(20))))
|
||||||
if i < 0 || i >= count {
|
if i < 0 || i > 255 {
|
||||||
return layout.Dimensions{Size: gtx.Constraints.Min}
|
return layout.Dimensions{Size: gtx.Constraints.Min}
|
||||||
}
|
}
|
||||||
u := units[i]
|
u := units[i]
|
||||||
@ -412,13 +412,9 @@ func (ie *InstrumentEditor) layoutUnitList(gtx C, t *Tracker) D {
|
|||||||
editor.TextSize = unit.Sp(12)
|
editor.TextSize = unit.Sp(12)
|
||||||
editor.Font = f
|
editor.Font = f
|
||||||
defer clip.Rect(image.Rect(0, 0, gtx.Constraints.Max.X, gtx.Constraints.Max.Y)).Push(gtx.Ops).Pop()
|
defer clip.Rect(image.Rect(0, 0, gtx.Constraints.Max.X, gtx.Constraints.Max.Y)).Push(gtx.Ops).Pop()
|
||||||
txt := u.Type
|
|
||||||
str := tracker.String{StringData: (*tracker.UnitSearch)(t.Model)}
|
str := tracker.String{StringData: (*tracker.UnitSearch)(t.Model)}
|
||||||
if t.UnitSearching().Value() {
|
if ie.searchEditor.Text() != str.Value() {
|
||||||
txt = str.Value()
|
ie.searchEditor.SetText(str.Value())
|
||||||
}
|
|
||||||
if ie.searchEditor.Text() != txt {
|
|
||||||
ie.searchEditor.SetText(txt)
|
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
ev, ok := ie.searchEditor.Update(gtx)
|
ev, ok := ie.searchEditor.Update(gtx)
|
||||||
@ -427,18 +423,17 @@ func (ie *InstrumentEditor) layoutUnitList(gtx C, t *Tracker) D {
|
|||||||
}
|
}
|
||||||
_, ok = ev.(widget.SubmitEvent)
|
_, ok = ev.(widget.SubmitEvent)
|
||||||
if ok {
|
if ok {
|
||||||
txt := ""
|
|
||||||
ie.unitDragList.Focus()
|
ie.unitDragList.Focus()
|
||||||
if text := ie.searchEditor.Text(); text != "" {
|
if text := ie.searchEditor.Text(); text != "" {
|
||||||
for _, n := range sointu.UnitNames {
|
for _, n := range sointu.UnitNames {
|
||||||
if strings.HasPrefix(n, ie.searchEditor.Text()) {
|
if strings.HasPrefix(n, ie.searchEditor.Text()) {
|
||||||
txt = n
|
t.Units().SetSelectedType(n)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t.Units().SetSelectedType(txt)
|
|
||||||
t.UnitSearching().Bool().Set(false)
|
t.UnitSearching().Bool().Set(false)
|
||||||
|
ie.searchEditor.SetText(str.Value())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -452,7 +447,7 @@ func (ie *InstrumentEditor) layoutUnitList(gtx C, t *Tracker) D {
|
|||||||
ie.instrumentDragList.Focus()
|
ie.instrumentDragList.Focus()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ie.searchEditor.Text() != txt {
|
if ie.searchEditor.Text() != str.Value() {
|
||||||
str.Set(ie.searchEditor.Text())
|
str.Set(ie.searchEditor.Text())
|
||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
@ -472,46 +467,42 @@ func (ie *InstrumentEditor) layoutUnitList(gtx C, t *Tracker) D {
|
|||||||
|
|
||||||
defer op.Offset(image.Point{}).Push(gtx.Ops).Pop()
|
defer op.Offset(image.Point{}).Push(gtx.Ops).Pop()
|
||||||
unitList := FilledDragList(t.Theme, ie.unitDragList, element, nil)
|
unitList := FilledDragList(t.Theme, ie.unitDragList, element, nil)
|
||||||
|
for {
|
||||||
|
event, ok := gtx.Event(
|
||||||
|
key.Filter{Focus: ie.unitDragList, Name: key.NameRightArrow},
|
||||||
|
key.Filter{Focus: ie.unitDragList, Name: key.NameEnter, Optional: key.ModCtrl},
|
||||||
|
key.Filter{Focus: ie.unitDragList, Name: key.NameReturn, Optional: key.ModCtrl},
|
||||||
|
key.Filter{Focus: ie.unitDragList, Name: key.NameDeleteBackward},
|
||||||
|
key.Filter{Focus: ie.unitDragList, Name: key.NameEscape},
|
||||||
|
)
|
||||||
|
if !ok {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
switch e := event.(type) {
|
||||||
|
case key.Event:
|
||||||
|
switch e.State {
|
||||||
|
case key.Press:
|
||||||
|
switch e.Name {
|
||||||
|
case key.NameEscape:
|
||||||
|
ie.instrumentDragList.Focus()
|
||||||
|
case key.NameRightArrow:
|
||||||
|
ie.unitEditor.sliderList.Focus()
|
||||||
|
case key.NameDeleteBackward:
|
||||||
|
t.Units().SetSelectedType("")
|
||||||
|
t.UnitSearching().Bool().Set(true)
|
||||||
|
gtx.Execute(key.FocusCmd{Tag: ie.searchEditor})
|
||||||
|
case key.NameEnter, key.NameReturn:
|
||||||
|
t.Model.AddUnit(e.Modifiers.Contain(key.ModCtrl)).Do()
|
||||||
|
t.UnitSearching().Bool().Set(true)
|
||||||
|
gtx.Execute(key.FocusCmd{Tag: ie.searchEditor})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return Surface{Gray: 30, Focus: ie.wasFocused}.Layout(gtx, func(gtx C) D {
|
return Surface{Gray: 30, Focus: ie.wasFocused}.Layout(gtx, func(gtx C) D {
|
||||||
return layout.Stack{Alignment: layout.SE}.Layout(gtx,
|
return layout.Stack{Alignment: layout.SE}.Layout(gtx,
|
||||||
layout.Expanded(func(gtx C) D {
|
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()
|
defer clip.Rect(image.Rect(0, 0, gtx.Constraints.Max.X, gtx.Constraints.Max.Y)).Push(gtx.Ops).Pop()
|
||||||
for {
|
|
||||||
event, ok := gtx.Event(
|
|
||||||
key.Filter{Focus: ie.unitDragList, Name: key.NameRightArrow},
|
|
||||||
key.Filter{Focus: ie.unitDragList, Name: key.NameEnter, Optional: key.ModCtrl},
|
|
||||||
key.Filter{Focus: ie.unitDragList, Name: key.NameReturn, Optional: key.ModCtrl},
|
|
||||||
key.Filter{Focus: ie.unitDragList, Name: key.NameDeleteBackward},
|
|
||||||
key.Filter{Focus: ie.unitDragList, Name: key.NameEscape},
|
|
||||||
)
|
|
||||||
if !ok {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
switch e := event.(type) {
|
|
||||||
case key.Event:
|
|
||||||
switch e.State {
|
|
||||||
case key.Press:
|
|
||||||
switch e.Name {
|
|
||||||
case key.NameEscape:
|
|
||||||
ie.instrumentDragList.Focus()
|
|
||||||
case key.NameRightArrow:
|
|
||||||
ie.unitEditor.sliderList.Focus()
|
|
||||||
case key.NameDeleteBackward:
|
|
||||||
t.Units().SetSelectedType("")
|
|
||||||
gtx.Execute(key.FocusCmd{Tag: ie.searchEditor})
|
|
||||||
l := len(ie.searchEditor.Text())
|
|
||||||
ie.searchEditor.SetCaret(l, l)
|
|
||||||
case key.NameEnter, key.NameReturn:
|
|
||||||
t.Model.AddUnit(e.Modifiers.Contain(key.ModCtrl)).Do()
|
|
||||||
ie.searchEditor.SetText("")
|
|
||||||
gtx.Execute(key.FocusCmd{Tag: ie.searchEditor})
|
|
||||||
l := len(ie.searchEditor.Text())
|
|
||||||
ie.searchEditor.SetCaret(l, l)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
gtx.Constraints = layout.Exact(image.Pt(gtx.Dp(unit.Dp(120)), gtx.Constraints.Max.Y))
|
gtx.Constraints = layout.Exact(image.Pt(gtx.Dp(unit.Dp(120)), gtx.Constraints.Max.Y))
|
||||||
dims := unitList.Layout(gtx)
|
dims := unitList.Layout(gtx)
|
||||||
unitList.LayoutScrollBar(gtx)
|
unitList.LayoutScrollBar(gtx)
|
||||||
|
@ -299,11 +299,15 @@ func (m *Units) SelectedType() string {
|
|||||||
|
|
||||||
func (m *Units) SetSelectedType(t string) {
|
func (m *Units) SetSelectedType(t string) {
|
||||||
if m.d.InstrIndex < 0 ||
|
if m.d.InstrIndex < 0 ||
|
||||||
m.d.InstrIndex >= len(m.d.Song.Patch) ||
|
m.d.InstrIndex >= len(m.d.Song.Patch) {
|
||||||
m.d.UnitIndex < 0 ||
|
|
||||||
m.d.UnitIndex >= len(m.d.Song.Patch[m.d.InstrIndex].Units) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if m.d.UnitIndex < 0 {
|
||||||
|
m.d.UnitIndex = 0
|
||||||
|
}
|
||||||
|
for len(m.d.Song.Patch[m.d.InstrIndex].Units) <= m.d.UnitIndex {
|
||||||
|
m.d.Song.Patch[m.d.InstrIndex].Units = append(m.d.Song.Patch[m.d.InstrIndex].Units, sointu.Unit{})
|
||||||
|
}
|
||||||
unit, ok := defaultUnits[t]
|
unit, ok := defaultUnits[t]
|
||||||
if !ok { // if the type is invalid, we just set it to empty unit
|
if !ok { // if the type is invalid, we just set it to empty unit
|
||||||
unit = sointu.Unit{Parameters: make(map[string]int)}
|
unit = sointu.Unit{Parameters: make(map[string]int)}
|
||||||
|
@ -41,7 +41,20 @@ func (v *FilePath) change(kind string) func() { return func() {} }
|
|||||||
// UnitSearchString
|
// UnitSearchString
|
||||||
|
|
||||||
func (v *UnitSearch) String() String { return String{v} }
|
func (v *UnitSearch) String() String { return String{v} }
|
||||||
func (v *UnitSearch) Value() string { return v.d.UnitSearchString }
|
func (v *UnitSearch) Value() string {
|
||||||
|
// return current unit type string if not searching
|
||||||
|
if !v.d.UnitSearching {
|
||||||
|
if v.d.InstrIndex < 0 || v.d.InstrIndex >= len(v.d.Song.Patch) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if 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].Type
|
||||||
|
} else {
|
||||||
|
return v.d.UnitSearchString
|
||||||
|
}
|
||||||
|
}
|
||||||
func (v *UnitSearch) setValue(value string) {
|
func (v *UnitSearch) setValue(value string) {
|
||||||
v.d.UnitSearchString = value
|
v.d.UnitSearchString = value
|
||||||
v.d.UnitSearching = true
|
v.d.UnitSearching = true
|
||||||
|
Loading…
x
Reference in New Issue
Block a user