mirror of
https://github.com/vsariola/sointu.git
synced 2025-07-18 21:14:31 -04:00
feat(tracker): adding, setting, unsetting and deleting units
This commit is contained in:
132
tracker/uniteditor.go
Normal file
132
tracker/uniteditor.go
Normal file
@ -0,0 +1,132 @@
|
||||
package tracker
|
||||
|
||||
import (
|
||||
"image"
|
||||
"image/color"
|
||||
"sort"
|
||||
|
||||
"gioui.org/layout"
|
||||
"gioui.org/op"
|
||||
"gioui.org/op/clip"
|
||||
"gioui.org/op/paint"
|
||||
"gioui.org/unit"
|
||||
"gioui.org/widget"
|
||||
"gioui.org/widget/material"
|
||||
"golang.org/x/exp/shiny/materialdesign/icons"
|
||||
)
|
||||
|
||||
func (t *Tracker) layoutUnitEditor() layout.Widget {
|
||||
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()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
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...)
|
||||
}
|
||||
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 {
|
||||
return func(gtx C) D {
|
||||
for t.ClearUnitBtn.Clicked() {
|
||||
t.ClearUnit()
|
||||
op.InvalidateOp{}.Add(gtx.Ops)
|
||||
}
|
||||
for t.DeleteUnitBtn.Clicked() {
|
||||
t.DeleteUnit()
|
||||
op.InvalidateOp{}.Add(gtx.Ops)
|
||||
}
|
||||
deleteUnitBtnStyle := material.IconButton(t.Theme, t.DeleteUnitBtn, widgetForIcon(icons.ActionDelete))
|
||||
deleteUnitBtnStyle.Background = transparent
|
||||
deleteUnitBtnStyle.Inset = layout.UniformInset(unit.Dp(6))
|
||||
if len(t.song.Patch.Instruments[t.CurrentInstrument].Units) > 1 {
|
||||
deleteUnitBtnStyle.Color = primaryColor
|
||||
} else {
|
||||
deleteUnitBtnStyle.Color = disabledTextColor
|
||||
}
|
||||
if t.song.Patch.Instruments[t.CurrentInstrument].Units[t.CurrentUnit].Type == "" {
|
||||
return layout.Flex{Axis: layout.Horizontal}.Layout(gtx,
|
||||
layout.Flexed(1, func(gtx C) D { return layout.Dimensions{Size: gtx.Constraints.Min} }),
|
||||
layout.Rigid(deleteUnitBtnStyle.Layout))
|
||||
}
|
||||
clearUnitBtnStyle := material.IconButton(t.Theme, t.ClearUnitBtn, widgetForIcon(icons.ContentClear))
|
||||
clearUnitBtnStyle.Color = primaryColor
|
||||
clearUnitBtnStyle.Background = transparent
|
||||
clearUnitBtnStyle.Inset = layout.UniformInset(unit.Dp(6))
|
||||
return layout.Flex{Axis: layout.Horizontal}.Layout(gtx,
|
||||
layout.Flexed(1, func(gtx C) D { return layout.Dimensions{Size: gtx.Constraints.Min} }),
|
||||
layout.Rigid(clearUnitBtnStyle.Layout),
|
||||
layout.Rigid(deleteUnitBtnStyle.Layout))
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
u := defaultUnits[allUnits[i]]
|
||||
t.song.Patch.Instruments[t.CurrentInstrument].Units[t.CurrentUnit] = (&u).Copy()
|
||||
}
|
||||
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)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user