mirror of
https://github.com/vsariola/sointu.git
synced 2025-07-20 14:04:34 -04:00
refactor(tracker/gioui): avoid heap escapes in NumericUpDown
This commit is contained in:
parent
db2ccf977d
commit
31007515b5
@ -142,9 +142,8 @@ func (ie *InstrumentEditor) Layout(gtx C, t *Tracker) D {
|
|||||||
|
|
||||||
octave := func(gtx C) D {
|
octave := func(gtx C) D {
|
||||||
in := layout.UniformInset(unit.Dp(1))
|
in := layout.UniformInset(unit.Dp(1))
|
||||||
return in.Layout(gtx, func(gtx C) D {
|
octave := NumUpDown(t.Model.Octave(), t.Theme, t.OctaveNumberInput, "Octave")
|
||||||
return t.OctaveNumberInput.Layout(gtx, t.Octave(), t.Theme, &t.Theme.NumericUpDown, "Octave")
|
return in.Layout(gtx, octave.Layout)
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret := layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
ret := layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
||||||
@ -223,15 +222,14 @@ func (ie *InstrumentEditor) layoutInstrumentHeader(gtx C, t *Tracker) D {
|
|||||||
loadInstrumentBtn := IconBtn(t.Theme, &t.Theme.IconButton.Enabled, ie.loadInstrumentBtn, icons.FileFolderOpen, "Load instrument")
|
loadInstrumentBtn := IconBtn(t.Theme, &t.Theme.IconButton.Enabled, ie.loadInstrumentBtn, icons.FileFolderOpen, "Load instrument")
|
||||||
copyInstrumentBtn := IconBtn(t.Theme, &t.Theme.IconButton.Enabled, ie.copyInstrumentBtn, icons.ContentContentCopy, "Copy instrument")
|
copyInstrumentBtn := IconBtn(t.Theme, &t.Theme.IconButton.Enabled, ie.copyInstrumentBtn, icons.ContentContentCopy, "Copy instrument")
|
||||||
deleteInstrumentBtn := ActionIconBtn(t.DeleteInstrument(), t.Theme, ie.deleteInstrumentBtn, icons.ActionDelete, ie.deleteInstrumentHint)
|
deleteInstrumentBtn := ActionIconBtn(t.DeleteInstrument(), t.Theme, ie.deleteInstrumentBtn, icons.ActionDelete, ie.deleteInstrumentHint)
|
||||||
|
instrumentVoices := NumUpDown(t.Model.InstrumentVoices(), t.Theme, t.InstrumentVoices, "Number of voices for this instrument")
|
||||||
|
|
||||||
header := func(gtx C) D {
|
header := func(gtx C) D {
|
||||||
return layout.Flex{Axis: layout.Horizontal, Alignment: layout.Middle}.Layout(gtx,
|
return layout.Flex{Axis: layout.Horizontal, Alignment: layout.Middle}.Layout(gtx,
|
||||||
layout.Rigid(layout.Spacer{Width: 6}.Layout),
|
layout.Rigid(layout.Spacer{Width: 6}.Layout),
|
||||||
layout.Rigid(Label(t.Theme, &t.Theme.InstrumentEditor.Voices, "Voices").Layout),
|
layout.Rigid(Label(t.Theme, &t.Theme.InstrumentEditor.Voices, "Voices").Layout),
|
||||||
layout.Rigid(layout.Spacer{Width: 4}.Layout),
|
layout.Rigid(layout.Spacer{Width: 4}.Layout),
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
layout.Rigid(instrumentVoices.Layout),
|
||||||
return t.InstrumentVoices.Layout(gtx, t.Model.InstrumentVoices(), t.Theme, &t.Theme.NumericUpDown, "Number of voices for this instrument")
|
|
||||||
}),
|
|
||||||
layout.Rigid(splitInstrumentBtn.Layout),
|
layout.Rigid(splitInstrumentBtn.Layout),
|
||||||
layout.Flexed(1, func(gtx C) D { return layout.Dimensions{Size: gtx.Constraints.Min} }),
|
layout.Flexed(1, func(gtx C) D { return layout.Dimensions{Size: gtx.Constraints.Min} }),
|
||||||
layout.Rigid(commentExpandedBtn.Layout),
|
layout.Rigid(commentExpandedBtn.Layout),
|
||||||
|
@ -51,7 +51,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type NoteEditor struct {
|
type NoteEditor struct {
|
||||||
TrackVoices *NumericUpDown
|
TrackVoices *NumericUpDownState
|
||||||
NewTrackBtn *Clickable
|
NewTrackBtn *Clickable
|
||||||
DeleteTrackBtn *Clickable
|
DeleteTrackBtn *Clickable
|
||||||
SplitTrackBtn *Clickable
|
SplitTrackBtn *Clickable
|
||||||
@ -76,7 +76,7 @@ type NoteEditor struct {
|
|||||||
|
|
||||||
func NewNoteEditor(model *tracker.Model) *NoteEditor {
|
func NewNoteEditor(model *tracker.Model) *NoteEditor {
|
||||||
ret := &NoteEditor{
|
ret := &NoteEditor{
|
||||||
TrackVoices: NewNumericUpDown(),
|
TrackVoices: NewNumericUpDownState(),
|
||||||
NewTrackBtn: new(Clickable),
|
NewTrackBtn: new(Clickable),
|
||||||
DeleteTrackBtn: new(Clickable),
|
DeleteTrackBtn: new(Clickable),
|
||||||
SplitTrackBtn: new(Clickable),
|
SplitTrackBtn: new(Clickable),
|
||||||
@ -172,11 +172,10 @@ func (te *NoteEditor) layoutButtons(gtx C, t *Tracker) D {
|
|||||||
deleteTrackBtn := ActionIconBtn(t.DeleteTrack(), t.Theme, te.DeleteTrackBtn, icons.ActionDelete, te.deleteTrackHint)
|
deleteTrackBtn := ActionIconBtn(t.DeleteTrack(), t.Theme, te.DeleteTrackBtn, icons.ActionDelete, te.deleteTrackHint)
|
||||||
splitTrackBtn := ActionIconBtn(t.SplitTrack(), t.Theme, te.SplitTrackBtn, icons.CommunicationCallSplit, te.splitTrackHint)
|
splitTrackBtn := ActionIconBtn(t.SplitTrack(), t.Theme, te.SplitTrackBtn, icons.CommunicationCallSplit, te.splitTrackHint)
|
||||||
newTrackBtn := ActionIconBtn(t.AddTrack(), t.Theme, te.NewTrackBtn, icons.ContentAdd, te.addTrackHint)
|
newTrackBtn := ActionIconBtn(t.AddTrack(), t.Theme, te.NewTrackBtn, icons.ContentAdd, te.addTrackHint)
|
||||||
|
trackVoices := NumUpDown(t.Model.TrackVoices(), t.Theme, te.TrackVoices, "Track voices")
|
||||||
in := layout.UniformInset(unit.Dp(1))
|
in := layout.UniformInset(unit.Dp(1))
|
||||||
voiceUpDown := func(gtx C) D {
|
trackVoicesInsetted := func(gtx C) D {
|
||||||
return in.Layout(gtx, func(gtx C) D {
|
return in.Layout(gtx, trackVoices.Layout)
|
||||||
return te.TrackVoices.Layout(gtx, t.Model.TrackVoices(), t.Theme, &t.Theme.NumericUpDown, "Track voices")
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
effectBtn := ToggleBtn(t.Effect(), t.Theme, te.EffectBtn, "Hex", "Input notes as hex values")
|
effectBtn := ToggleBtn(t.Effect(), t.Theme, te.EffectBtn, "Hex", "Input notes as hex values")
|
||||||
uniqueBtn := ToggleIconBtn(t.UniquePatterns(), t.Theme, te.UniqueBtn, icons.ToggleStarBorder, icons.ToggleStar, te.uniqueOffTip, te.uniqueOnTip)
|
uniqueBtn := ToggleIconBtn(t.UniquePatterns(), t.Theme, te.UniqueBtn, icons.ToggleStarBorder, icons.ToggleStar, te.uniqueOffTip, te.uniqueOnTip)
|
||||||
@ -193,7 +192,7 @@ func (te *NoteEditor) layoutButtons(gtx C, t *Tracker) D {
|
|||||||
layout.Rigid(layout.Spacer{Width: 10}.Layout),
|
layout.Rigid(layout.Spacer{Width: 10}.Layout),
|
||||||
layout.Rigid(Label(t.Theme, &t.Theme.NoteEditor.Header, "Voices").Layout),
|
layout.Rigid(Label(t.Theme, &t.Theme.NoteEditor.Header, "Voices").Layout),
|
||||||
layout.Rigid(layout.Spacer{Width: 4}.Layout),
|
layout.Rigid(layout.Spacer{Width: 4}.Layout),
|
||||||
layout.Rigid(voiceUpDown),
|
layout.Rigid(trackVoicesInsetted),
|
||||||
layout.Rigid(splitTrackBtn.Layout),
|
layout.Rigid(splitTrackBtn.Layout),
|
||||||
layout.Rigid(midiInBtn.Layout),
|
layout.Rigid(midiInBtn.Layout),
|
||||||
layout.Flexed(1, func(gtx C) D { return layout.Dimensions{Size: gtx.Constraints.Min} }),
|
layout.Flexed(1, func(gtx C) D { return layout.Dimensions{Size: gtx.Constraints.Min} }),
|
||||||
|
@ -23,7 +23,8 @@ import (
|
|||||||
"gioui.org/text"
|
"gioui.org/text"
|
||||||
)
|
)
|
||||||
|
|
||||||
type NumericUpDown struct {
|
type (
|
||||||
|
NumericUpDownState struct {
|
||||||
DpPerStep unit.Dp
|
DpPerStep unit.Dp
|
||||||
|
|
||||||
dragStartValue int
|
dragStartValue int
|
||||||
@ -31,9 +32,9 @@ type NumericUpDown struct {
|
|||||||
clickDecrease gesture.Click
|
clickDecrease gesture.Click
|
||||||
clickIncrease gesture.Click
|
clickIncrease gesture.Click
|
||||||
tipArea component.TipArea
|
tipArea component.TipArea
|
||||||
}
|
}
|
||||||
|
|
||||||
type NumericUpDownStyle struct {
|
NumericUpDownStyle struct {
|
||||||
TextColor color.NRGBA `yaml:",flow"`
|
TextColor color.NRGBA `yaml:",flow"`
|
||||||
IconColor color.NRGBA `yaml:",flow"`
|
IconColor color.NRGBA `yaml:",flow"`
|
||||||
BgColor color.NRGBA `yaml:",flow"`
|
BgColor color.NRGBA `yaml:",flow"`
|
||||||
@ -43,13 +44,32 @@ type NumericUpDownStyle struct {
|
|||||||
Height unit.Dp
|
Height unit.Dp
|
||||||
TextSize unit.Sp
|
TextSize unit.Sp
|
||||||
Font font.Font
|
Font font.Font
|
||||||
|
}
|
||||||
|
|
||||||
|
NumericUpDown struct {
|
||||||
|
Int tracker.Int
|
||||||
|
Theme *Theme
|
||||||
|
State *NumericUpDownState
|
||||||
|
Style *NumericUpDownStyle
|
||||||
|
Tip string
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewNumericUpDownState() *NumericUpDownState {
|
||||||
|
return &NumericUpDownState{DpPerStep: unit.Dp(8)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNumericUpDown() *NumericUpDown {
|
func NumUpDown(v tracker.Int, th *Theme, n *NumericUpDownState, tip string) NumericUpDown {
|
||||||
return &NumericUpDown{DpPerStep: unit.Dp(8)}
|
return NumericUpDown{
|
||||||
|
Int: v,
|
||||||
|
Theme: th,
|
||||||
|
State: n,
|
||||||
|
Style: &th.NumericUpDown,
|
||||||
|
Tip: tip,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *NumericUpDown) Update(gtx layout.Context, v tracker.Int) {
|
func (s *NumericUpDownState) Update(gtx layout.Context, v tracker.Int) {
|
||||||
// handle dragging
|
// handle dragging
|
||||||
pxPerStep := float32(gtx.Dp(s.DpPerStep))
|
pxPerStep := float32(gtx.Dp(s.DpPerStep))
|
||||||
for {
|
for {
|
||||||
@ -86,31 +106,23 @@ func (s *NumericUpDown) Update(gtx layout.Context, v tracker.Int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *NumericUpDown) Widget(v tracker.Int, th *Theme, st *NumericUpDownStyle, tooltip string) func(gtx C) D {
|
func (n *NumericUpDown) Layout(gtx C) D {
|
||||||
return func(gtx C) D {
|
n.State.Update(gtx, n.Int)
|
||||||
return s.Layout(gtx, v, th, st, tooltip)
|
if n.Tip != "" {
|
||||||
|
return n.State.tipArea.Layout(gtx, Tooltip(n.Theme, n.Tip), n.actualLayout)
|
||||||
}
|
}
|
||||||
|
return n.actualLayout(gtx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *NumericUpDown) Layout(gtx C, v tracker.Int, th *Theme, st *NumericUpDownStyle, tooltip string) D {
|
func (n *NumericUpDown) actualLayout(gtx C) D {
|
||||||
s.Update(gtx, v)
|
gtx.Constraints = layout.Exact(image.Pt(gtx.Dp(n.Style.Width), gtx.Dp(n.Style.Height)))
|
||||||
if tooltip != "" {
|
width := gtx.Dp(n.Style.ButtonWidth)
|
||||||
return s.tipArea.Layout(gtx, Tooltip(th, tooltip), func(gtx C) D {
|
height := gtx.Dp(n.Style.Height)
|
||||||
return s.actualLayout(gtx, v, th, st)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return s.actualLayout(gtx, v, th, st)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *NumericUpDown) actualLayout(gtx C, v tracker.Int, th *Theme, st *NumericUpDownStyle) D {
|
|
||||||
gtx.Constraints = layout.Exact(image.Pt(gtx.Dp(st.Width), gtx.Dp(st.Height)))
|
|
||||||
width := gtx.Dp(st.ButtonWidth)
|
|
||||||
height := gtx.Dp(st.Height)
|
|
||||||
return layout.Background{}.Layout(gtx,
|
return layout.Background{}.Layout(gtx,
|
||||||
func(gtx C) D {
|
func(gtx C) D {
|
||||||
defer clip.UniformRRect(image.Rectangle{Max: gtx.Constraints.Min}, gtx.Dp(st.CornerRadius)).Push(gtx.Ops).Pop()
|
defer clip.UniformRRect(image.Rectangle{Max: gtx.Constraints.Min}, gtx.Dp(n.Style.CornerRadius)).Push(gtx.Ops).Pop()
|
||||||
paint.Fill(gtx.Ops, st.BgColor)
|
paint.Fill(gtx.Ops, n.Style.BgColor)
|
||||||
event.Op(gtx.Ops, s) // register drag inputs, if not hitting the clicks
|
event.Op(gtx.Ops, n.State) // register drag inputs, if not hitting the clicks
|
||||||
return D{Size: gtx.Constraints.Min}
|
return D{Size: gtx.Constraints.Min}
|
||||||
},
|
},
|
||||||
func(gtx C) D {
|
func(gtx C) D {
|
||||||
@ -120,25 +132,25 @@ func (s *NumericUpDown) actualLayout(gtx C, v tracker.Int, th *Theme, st *Numeri
|
|||||||
return layout.Background{}.Layout(gtx,
|
return layout.Background{}.Layout(gtx,
|
||||||
func(gtx C) D {
|
func(gtx C) D {
|
||||||
defer clip.Rect(image.Rectangle{Max: gtx.Constraints.Min}).Push(gtx.Ops).Pop()
|
defer clip.Rect(image.Rectangle{Max: gtx.Constraints.Min}).Push(gtx.Ops).Pop()
|
||||||
s.clickDecrease.Add(gtx.Ops)
|
n.State.clickDecrease.Add(gtx.Ops)
|
||||||
return D{Size: gtx.Constraints.Min}
|
return D{Size: gtx.Constraints.Min}
|
||||||
},
|
},
|
||||||
func(gtx C) D { return th.Icon(icons.ContentRemove).Layout(gtx, st.IconColor) },
|
func(gtx C) D { return n.Theme.Icon(icons.ContentRemove).Layout(gtx, n.Style.IconColor) },
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
layout.Flexed(1, func(gtx C) D {
|
layout.Flexed(1, func(gtx C) D {
|
||||||
paint.ColorOp{Color: st.TextColor}.Add(gtx.Ops)
|
paint.ColorOp{Color: n.Style.TextColor}.Add(gtx.Ops)
|
||||||
return widget.Label{Alignment: text.Middle}.Layout(gtx, th.Material.Shaper, st.Font, st.TextSize, strconv.Itoa(v.Value()), op.CallOp{})
|
return widget.Label{Alignment: text.Middle}.Layout(gtx, n.Theme.Material.Shaper, n.Style.Font, n.Style.TextSize, strconv.Itoa(n.Int.Value()), op.CallOp{})
|
||||||
}),
|
}),
|
||||||
layout.Rigid(func(gtx C) D {
|
layout.Rigid(func(gtx C) D {
|
||||||
gtx.Constraints = layout.Exact(image.Pt(width, height))
|
gtx.Constraints = layout.Exact(image.Pt(width, height))
|
||||||
return layout.Background{}.Layout(gtx,
|
return layout.Background{}.Layout(gtx,
|
||||||
func(gtx C) D {
|
func(gtx C) D {
|
||||||
defer clip.Rect(image.Rectangle{Max: gtx.Constraints.Min}).Push(gtx.Ops).Pop()
|
defer clip.Rect(image.Rectangle{Max: gtx.Constraints.Min}).Push(gtx.Ops).Pop()
|
||||||
s.clickIncrease.Add(gtx.Ops)
|
n.State.clickIncrease.Add(gtx.Ops)
|
||||||
return D{Size: gtx.Constraints.Min}
|
return D{Size: gtx.Constraints.Min}
|
||||||
},
|
},
|
||||||
func(gtx C) D { return th.Icon(icons.ContentAdd).Layout(gtx, st.IconColor) },
|
func(gtx C) D { return n.Theme.Icon(icons.ContentAdd).Layout(gtx, n.Style.IconColor) },
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
@ -19,8 +19,8 @@ type (
|
|||||||
OscilloscopeState struct {
|
OscilloscopeState struct {
|
||||||
onceBtn *Clickable
|
onceBtn *Clickable
|
||||||
wrapBtn *Clickable
|
wrapBtn *Clickable
|
||||||
lengthInBeatsNumber *NumericUpDown
|
lengthInBeatsNumber *NumericUpDownState
|
||||||
triggerChannelNumber *NumericUpDown
|
triggerChannelNumber *NumericUpDownState
|
||||||
xScale int
|
xScale int
|
||||||
xOffset float32
|
xOffset float32
|
||||||
yScale float64
|
yScale float64
|
||||||
@ -40,8 +40,8 @@ func NewOscilloscope(model *tracker.Model) *OscilloscopeState {
|
|||||||
return &OscilloscopeState{
|
return &OscilloscopeState{
|
||||||
onceBtn: new(Clickable),
|
onceBtn: new(Clickable),
|
||||||
wrapBtn: new(Clickable),
|
wrapBtn: new(Clickable),
|
||||||
lengthInBeatsNumber: NewNumericUpDown(),
|
lengthInBeatsNumber: NewNumericUpDownState(),
|
||||||
triggerChannelNumber: NewNumericUpDown(),
|
triggerChannelNumber: NewNumericUpDownState(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,6 +49,9 @@ func (s *OscilloscopeState) Layout(gtx C, vtrig, vlen tracker.Int, once, wrap tr
|
|||||||
leftSpacer := layout.Spacer{Width: unit.Dp(6), Height: unit.Dp(24)}.Layout
|
leftSpacer := layout.Spacer{Width: unit.Dp(6), Height: unit.Dp(24)}.Layout
|
||||||
rightSpacer := layout.Spacer{Width: unit.Dp(6)}.Layout
|
rightSpacer := layout.Spacer{Width: unit.Dp(6)}.Layout
|
||||||
|
|
||||||
|
triggerChannel := NumUpDown(vtrig, th, s.triggerChannelNumber, "Trigger channel")
|
||||||
|
lengthInBeats := NumUpDown(vlen, th, s.lengthInBeatsNumber, "Buffer length in beats")
|
||||||
|
|
||||||
onceBtn := ToggleBtn(once, th, s.onceBtn, "Once", "Trigger once on next event")
|
onceBtn := ToggleBtn(once, th, s.onceBtn, "Once", "Trigger once on next event")
|
||||||
wrapBtn := ToggleBtn(wrap, th, s.wrapBtn, "Wrap", "Wrap buffer when full")
|
wrapBtn := ToggleBtn(wrap, th, s.wrapBtn, "Wrap", "Wrap buffer when full")
|
||||||
|
|
||||||
@ -60,9 +63,7 @@ func (s *OscilloscopeState) Layout(gtx C, vtrig, vlen tracker.Int, once, wrap tr
|
|||||||
layout.Rigid(Label(th, &th.SongPanel.RowHeader, "Trigger").Layout),
|
layout.Rigid(Label(th, &th.SongPanel.RowHeader, "Trigger").Layout),
|
||||||
layout.Flexed(1, func(gtx C) D { return D{Size: gtx.Constraints.Min} }),
|
layout.Flexed(1, func(gtx C) D { return D{Size: gtx.Constraints.Min} }),
|
||||||
layout.Rigid(onceBtn.Layout),
|
layout.Rigid(onceBtn.Layout),
|
||||||
layout.Rigid(func(gtx C) D {
|
layout.Rigid(triggerChannel.Layout),
|
||||||
return s.triggerChannelNumber.Layout(gtx, vtrig, th, &th.NumericUpDown, "Trigger channel")
|
|
||||||
}),
|
|
||||||
layout.Rigid(rightSpacer),
|
layout.Rigid(rightSpacer),
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
@ -72,9 +73,7 @@ func (s *OscilloscopeState) Layout(gtx C, vtrig, vlen tracker.Int, once, wrap tr
|
|||||||
layout.Rigid(Label(th, &th.SongPanel.RowHeader, "Buffer").Layout),
|
layout.Rigid(Label(th, &th.SongPanel.RowHeader, "Buffer").Layout),
|
||||||
layout.Flexed(1, func(gtx C) D { return D{Size: gtx.Constraints.Min} }),
|
layout.Flexed(1, func(gtx C) D { return D{Size: gtx.Constraints.Min} }),
|
||||||
layout.Rigid(wrapBtn.Layout),
|
layout.Rigid(wrapBtn.Layout),
|
||||||
layout.Rigid(func(gtx C) D {
|
layout.Rigid(lengthInBeats.Layout),
|
||||||
return s.lengthInBeatsNumber.Layout(gtx, vlen, th, &th.NumericUpDown, "Buffer length in beats")
|
|
||||||
}),
|
|
||||||
layout.Rigid(rightSpacer),
|
layout.Rigid(rightSpacer),
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
|
@ -25,11 +25,11 @@ type SongPanel struct {
|
|||||||
WeightingTypeBtn *Clickable
|
WeightingTypeBtn *Clickable
|
||||||
OversamplingBtn *Clickable
|
OversamplingBtn *Clickable
|
||||||
|
|
||||||
BPM *NumericUpDown
|
BPM *NumericUpDownState
|
||||||
RowsPerPattern *NumericUpDown
|
RowsPerPattern *NumericUpDownState
|
||||||
RowsPerBeat *NumericUpDown
|
RowsPerBeat *NumericUpDownState
|
||||||
Step *NumericUpDown
|
Step *NumericUpDownState
|
||||||
SongLength *NumericUpDown
|
SongLength *NumericUpDownState
|
||||||
|
|
||||||
Scope *OscilloscopeState
|
Scope *OscilloscopeState
|
||||||
|
|
||||||
@ -39,11 +39,11 @@ type SongPanel struct {
|
|||||||
|
|
||||||
func NewSongPanel(model *tracker.Model) *SongPanel {
|
func NewSongPanel(model *tracker.Model) *SongPanel {
|
||||||
ret := &SongPanel{
|
ret := &SongPanel{
|
||||||
BPM: NewNumericUpDown(),
|
BPM: NewNumericUpDownState(),
|
||||||
RowsPerPattern: NewNumericUpDown(),
|
RowsPerPattern: NewNumericUpDownState(),
|
||||||
RowsPerBeat: NewNumericUpDown(),
|
RowsPerBeat: NewNumericUpDownState(),
|
||||||
Step: NewNumericUpDown(),
|
Step: NewNumericUpDownState(),
|
||||||
SongLength: NewNumericUpDown(),
|
SongLength: NewNumericUpDownState(),
|
||||||
Scope: NewOscilloscope(model),
|
Scope: NewOscilloscope(model),
|
||||||
MenuBar: NewMenuBar(model),
|
MenuBar: NewMenuBar(model),
|
||||||
PlayBar: NewPlayBar(),
|
PlayBar: NewPlayBar(),
|
||||||
@ -115,19 +115,24 @@ func (t *SongPanel) layoutSongOptions(gtx C, tr *Tracker) D {
|
|||||||
func(gtx C) D {
|
func(gtx C) D {
|
||||||
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
||||||
layout.Rigid(func(gtx C) D {
|
layout.Rigid(func(gtx C) D {
|
||||||
return layoutSongOptionRow(gtx, tr.Theme, "BPM", t.BPM.Widget(tr.Model.BPM(), tr.Theme, &tr.Theme.NumericUpDown, "BPM"))
|
bpm := NumUpDown(tr.BPM(), tr.Theme, t.BPM, "BPM")
|
||||||
|
return layoutSongOptionRow(gtx, tr.Theme, "BPM", bpm.Layout)
|
||||||
}),
|
}),
|
||||||
layout.Rigid(func(gtx C) D {
|
layout.Rigid(func(gtx C) D {
|
||||||
return layoutSongOptionRow(gtx, tr.Theme, "Song length", t.SongLength.Widget(tr.Model.SongLength(), tr.Theme, &tr.Theme.NumericUpDown, "Song length"))
|
songLength := NumUpDown(tr.SongLength(), tr.Theme, t.SongLength, "Song length")
|
||||||
|
return layoutSongOptionRow(gtx, tr.Theme, "Song length", songLength.Layout)
|
||||||
}),
|
}),
|
||||||
layout.Rigid(func(gtx C) D {
|
layout.Rigid(func(gtx C) D {
|
||||||
return layoutSongOptionRow(gtx, tr.Theme, "Rows per pat", t.RowsPerPattern.Widget(tr.Model.RowsPerPattern(), tr.Theme, &tr.Theme.NumericUpDown, "Rows per pattern"))
|
rowsPerPattern := NumUpDown(tr.RowsPerPattern(), tr.Theme, t.RowsPerPattern, "Rows per pattern")
|
||||||
|
return layoutSongOptionRow(gtx, tr.Theme, "Rows per pat", rowsPerPattern.Layout)
|
||||||
}),
|
}),
|
||||||
layout.Rigid(func(gtx C) D {
|
layout.Rigid(func(gtx C) D {
|
||||||
return layoutSongOptionRow(gtx, tr.Theme, "Rows per beat", t.RowsPerBeat.Widget(tr.Model.RowsPerBeat(), tr.Theme, &tr.Theme.NumericUpDown, "Rows per beat"))
|
rowsPerBeat := NumUpDown(tr.RowsPerBeat(), tr.Theme, t.RowsPerBeat, "Rows per beat")
|
||||||
|
return layoutSongOptionRow(gtx, tr.Theme, "Rows per beat", rowsPerBeat.Layout)
|
||||||
}),
|
}),
|
||||||
layout.Rigid(func(gtx C) D {
|
layout.Rigid(func(gtx C) D {
|
||||||
return layoutSongOptionRow(gtx, tr.Theme, "Cursor step", t.Step.Widget(tr.Model.Step(), tr.Theme, &tr.Theme.NumericUpDown, "Cursor step"))
|
step := NumUpDown(tr.Step(), tr.Theme, t.Step, "Cursor step")
|
||||||
|
return layoutSongOptionRow(gtx, tr.Theme, "Cursor step", step.Layout)
|
||||||
}),
|
}),
|
||||||
layout.Rigid(func(gtx C) D {
|
layout.Rigid(func(gtx C) D {
|
||||||
cpuload := tr.Model.CPULoad()
|
cpuload := tr.Model.CPULoad()
|
||||||
|
@ -28,8 +28,8 @@ var canQuit = true // set to false in init() if plugin tag is enabled
|
|||||||
type (
|
type (
|
||||||
Tracker struct {
|
Tracker struct {
|
||||||
Theme *Theme
|
Theme *Theme
|
||||||
OctaveNumberInput *NumericUpDown
|
OctaveNumberInput *NumericUpDownState
|
||||||
InstrumentVoices *NumericUpDown
|
InstrumentVoices *NumericUpDownState
|
||||||
TopHorizontalSplit *Split
|
TopHorizontalSplit *Split
|
||||||
BottomHorizontalSplit *Split
|
BottomHorizontalSplit *Split
|
||||||
VerticalSplit *Split
|
VerticalSplit *Split
|
||||||
@ -70,8 +70,8 @@ var ZoomFactors = []float32{.25, 1. / 3, .5, 2. / 3, .75, .8, 1, 1.1, 1.25, 1.5,
|
|||||||
|
|
||||||
func NewTracker(model *tracker.Model) *Tracker {
|
func NewTracker(model *tracker.Model) *Tracker {
|
||||||
t := &Tracker{
|
t := &Tracker{
|
||||||
OctaveNumberInput: NewNumericUpDown(),
|
OctaveNumberInput: NewNumericUpDownState(),
|
||||||
InstrumentVoices: NewNumericUpDown(),
|
InstrumentVoices: NewNumericUpDownState(),
|
||||||
|
|
||||||
TopHorizontalSplit: &Split{Ratio: -.5, MinSize1: 180, MinSize2: 180},
|
TopHorizontalSplit: &Split{Ratio: -.5, MinSize1: 180, MinSize2: 180},
|
||||||
BottomHorizontalSplit: &Split{Ratio: -.6, MinSize1: 180, MinSize2: 180},
|
BottomHorizontalSplit: &Split{Ratio: -.6, MinSize1: 180, MinSize2: 180},
|
||||||
|
Reference in New Issue
Block a user