feat(tracker): make instrument names use draglist

This commit is contained in:
vsariola
2021-02-06 18:35:42 +02:00
parent 73cbc4314f
commit b34161b173
6 changed files with 132 additions and 147 deletions

View File

@ -15,59 +15,55 @@ import (
"golang.org/x/exp/shiny/materialdesign/icons"
)
func (t *Tracker) layoutUnitEditor() layout.Widget {
func (t *Tracker) layoutUnitEditor(gtx C) D {
editorFunc := t.layoutUnitSliders
if t.song.Patch.Instruments[t.CurrentInstrument].Units[t.CurrentUnit].Type == "" {
editorFunc = t.layoutUnitTypeChooser
}
return func(gtx C) D {
paint.FillShape(gtx.Ops, unitSurfaceColor, clip.Rect{Max: image.Pt(gtx.Constraints.Max.X, gtx.Constraints.Max.Y)}.Op())
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
layout.Flexed(1, editorFunc()),
layout.Rigid(t.layoutUnitFooter()),
)
}
paint.FillShape(gtx.Ops, unitSurfaceColor, clip.Rect{Max: image.Pt(gtx.Constraints.Max.X, gtx.Constraints.Max.Y)}.Op())
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
layout.Flexed(1, editorFunc),
layout.Rigid(t.layoutUnitFooter()),
)
}
func (t *Tracker) layoutUnitSliders() layout.Widget {
return func(gtx C) D {
params := t.song.Patch.Instruments[t.CurrentInstrument].Units[t.CurrentUnit].Parameters
count := len(params)
children := make([]layout.FlexChild, 0, count)
if len(t.ParameterSliders) < count {
tail := make([]*widget.Float, count-len(t.ParameterSliders))
for t := range tail {
tail[t] = new(widget.Float)
}
t.ParameterSliders = append(t.ParameterSliders, tail...)
func (t *Tracker) layoutUnitSliders(gtx C) D {
params := t.song.Patch.Instruments[t.CurrentInstrument].Units[t.CurrentUnit].Parameters
count := len(params)
children := make([]layout.FlexChild, 0, count)
if len(t.ParameterSliders) < count {
tail := make([]*widget.Float, count-len(t.ParameterSliders))
for t := range tail {
tail[t] = new(widget.Float)
}
keys := make([]string, 0, len(params))
for k := range params {
keys = append(keys, k)
}
sort.Strings(keys)
for i, k := range keys {
for t.ParameterSliders[i].Changed() {
params[k] = int(t.ParameterSliders[i].Value)
// TODO: tracker should have functions to update parameters and
// to do this efficiently i.e. not compile the whole patch again
t.LoadSong(t.song)
}
t.ParameterSliders[i].Value = float32(params[k])
sliderStyle := material.Slider(t.Theme, t.ParameterSliders[i], 0, 128)
sliderStyle.Color = t.Theme.Fg
k2 := k // avoid k changing in the closure
children = append(children, layout.Rigid(func(gtx C) D {
return layout.Flex{Axis: layout.Horizontal}.Layout(gtx,
layout.Rigid(Label(k2, white)),
layout.Rigid(func(gtx C) D {
gtx.Constraints.Min.X = 200
return sliderStyle.Layout(gtx)
}))
}))
}
return layout.Flex{Axis: layout.Vertical}.Layout(gtx, children...)
t.ParameterSliders = append(t.ParameterSliders, tail...)
}
keys := make([]string, 0, len(params))
for k := range params {
keys = append(keys, k)
}
sort.Strings(keys)
for i, k := range keys {
for t.ParameterSliders[i].Changed() {
params[k] = int(t.ParameterSliders[i].Value)
// TODO: tracker should have functions to update parameters and
// to do this efficiently i.e. not compile the whole patch again
t.LoadSong(t.song)
}
t.ParameterSliders[i].Value = float32(params[k])
sliderStyle := material.Slider(t.Theme, t.ParameterSliders[i], 0, 128)
sliderStyle.Color = t.Theme.Fg
k2 := k // avoid k changing in the closure
children = append(children, layout.Rigid(func(gtx C) D {
return layout.Flex{Axis: layout.Horizontal}.Layout(gtx,
layout.Rigid(Label(k2, white)),
layout.Rigid(func(gtx C) D {
gtx.Constraints.Min.X = 200
return sliderStyle.Layout(gtx)
}))
}))
}
return layout.Flex{Axis: layout.Vertical}.Layout(gtx, children...)
}
func (t *Tracker) layoutUnitFooter() layout.Widget {
@ -104,28 +100,26 @@ func (t *Tracker) layoutUnitFooter() layout.Widget {
}
}
func (t *Tracker) layoutUnitTypeChooser() layout.Widget {
return func(gtx C) D {
paint.FillShape(gtx.Ops, unitSurfaceColor, clip.Rect{Max: image.Pt(gtx.Constraints.Max.X, gtx.Constraints.Max.Y)}.Op())
listElem := func(gtx C, i int) D {
for t.ChooseUnitTypeBtns[i].Clicked() {
t.SetUnit(allUnits[i])
}
labelStyle := LabelStyle{Text: allUnits[i], ShadeColor: black, Color: white, Font: labelDefaultFont, FontSize: unit.Sp(12)}
bg := func(gtx C) D {
gtx.Constraints = layout.Exact(image.Pt(120, 20))
var color color.NRGBA
if t.ChooseUnitTypeBtns[i].Hovered() {
color = unitTypeListHighlightColor
}
paint.FillShape(gtx.Ops, color, clip.Rect{Max: image.Pt(gtx.Constraints.Min.X, gtx.Constraints.Min.Y)}.Op())
return D{Size: gtx.Constraints.Min}
}
return layout.Stack{Alignment: layout.W}.Layout(gtx,
layout.Stacked(bg),
layout.Expanded(labelStyle.Layout),
layout.Expanded(t.ChooseUnitTypeBtns[i].Layout))
func (t *Tracker) layoutUnitTypeChooser(gtx C) D {
paint.FillShape(gtx.Ops, unitSurfaceColor, clip.Rect{Max: image.Pt(gtx.Constraints.Max.X, gtx.Constraints.Max.Y)}.Op())
listElem := func(gtx C, i int) D {
for t.ChooseUnitTypeBtns[i].Clicked() {
t.SetUnit(allUnits[i])
}
return t.ChooseUnitTypeList.Layout(gtx, len(allUnits), listElem)
labelStyle := LabelStyle{Text: allUnits[i], ShadeColor: black, Color: white, Font: labelDefaultFont, FontSize: unit.Sp(12)}
bg := func(gtx C) D {
gtx.Constraints = layout.Exact(image.Pt(120, 20))
var color color.NRGBA
if t.ChooseUnitTypeBtns[i].Hovered() {
color = unitTypeListHighlightColor
}
paint.FillShape(gtx.Ops, color, clip.Rect{Max: image.Pt(gtx.Constraints.Min.X, gtx.Constraints.Min.Y)}.Op())
return D{Size: gtx.Constraints.Min}
}
return layout.Stack{Alignment: layout.W}.Layout(gtx,
layout.Stacked(bg),
layout.Expanded(labelStyle.Layout),
layout.Expanded(t.ChooseUnitTypeBtns[i].Layout))
}
return t.ChooseUnitTypeList.Layout(gtx, len(allUnits), listElem)
}