mirror of
https://github.com/vsariola/sointu.git
synced 2025-07-20 05:54:34 -04:00
refactor(tracker/gioui): avoid heap escapes in NumericUpDown
This commit is contained in:
parent
db2ccf977d
commit
31007515b5
@ -23,33 +23,53 @@ import (
|
||||
"gioui.org/text"
|
||||
)
|
||||
|
||||
type NumericUpDown struct {
|
||||
DpPerStep unit.Dp
|
||||
type (
|
||||
NumericUpDownState struct {
|
||||
DpPerStep unit.Dp
|
||||
|
||||
dragStartValue int
|
||||
dragStartXY float32
|
||||
clickDecrease gesture.Click
|
||||
clickIncrease gesture.Click
|
||||
tipArea component.TipArea
|
||||
dragStartValue int
|
||||
dragStartXY float32
|
||||
clickDecrease gesture.Click
|
||||
clickIncrease gesture.Click
|
||||
tipArea component.TipArea
|
||||
}
|
||||
|
||||
NumericUpDownStyle struct {
|
||||
TextColor color.NRGBA `yaml:",flow"`
|
||||
IconColor color.NRGBA `yaml:",flow"`
|
||||
BgColor color.NRGBA `yaml:",flow"`
|
||||
CornerRadius unit.Dp
|
||||
ButtonWidth unit.Dp
|
||||
Width unit.Dp
|
||||
Height unit.Dp
|
||||
TextSize unit.Sp
|
||||
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)}
|
||||
}
|
||||
|
||||
type NumericUpDownStyle struct {
|
||||
TextColor color.NRGBA `yaml:",flow"`
|
||||
IconColor color.NRGBA `yaml:",flow"`
|
||||
BgColor color.NRGBA `yaml:",flow"`
|
||||
CornerRadius unit.Dp
|
||||
ButtonWidth unit.Dp
|
||||
Width unit.Dp
|
||||
Height unit.Dp
|
||||
TextSize unit.Sp
|
||||
Font font.Font
|
||||
func NumUpDown(v tracker.Int, th *Theme, n *NumericUpDownState, tip string) NumericUpDown {
|
||||
return NumericUpDown{
|
||||
Int: v,
|
||||
Theme: th,
|
||||
State: n,
|
||||
Style: &th.NumericUpDown,
|
||||
Tip: tip,
|
||||
}
|
||||
}
|
||||
|
||||
func NewNumericUpDown() *NumericUpDown {
|
||||
return &NumericUpDown{DpPerStep: unit.Dp(8)}
|
||||
}
|
||||
|
||||
func (s *NumericUpDown) Update(gtx layout.Context, v tracker.Int) {
|
||||
func (s *NumericUpDownState) Update(gtx layout.Context, v tracker.Int) {
|
||||
// handle dragging
|
||||
pxPerStep := float32(gtx.Dp(s.DpPerStep))
|
||||
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 {
|
||||
return func(gtx C) D {
|
||||
return s.Layout(gtx, v, th, st, tooltip)
|
||||
func (n *NumericUpDown) Layout(gtx C) D {
|
||||
n.State.Update(gtx, n.Int)
|
||||
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 {
|
||||
s.Update(gtx, v)
|
||||
if tooltip != "" {
|
||||
return s.tipArea.Layout(gtx, Tooltip(th, tooltip), func(gtx C) D {
|
||||
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)
|
||||
func (n *NumericUpDown) actualLayout(gtx C) D {
|
||||
gtx.Constraints = layout.Exact(image.Pt(gtx.Dp(n.Style.Width), gtx.Dp(n.Style.Height)))
|
||||
width := gtx.Dp(n.Style.ButtonWidth)
|
||||
height := gtx.Dp(n.Style.Height)
|
||||
return layout.Background{}.Layout(gtx,
|
||||
func(gtx C) D {
|
||||
defer clip.UniformRRect(image.Rectangle{Max: gtx.Constraints.Min}, gtx.Dp(st.CornerRadius)).Push(gtx.Ops).Pop()
|
||||
paint.Fill(gtx.Ops, st.BgColor)
|
||||
event.Op(gtx.Ops, s) // register drag inputs, if not hitting the clicks
|
||||
defer clip.UniformRRect(image.Rectangle{Max: gtx.Constraints.Min}, gtx.Dp(n.Style.CornerRadius)).Push(gtx.Ops).Pop()
|
||||
paint.Fill(gtx.Ops, n.Style.BgColor)
|
||||
event.Op(gtx.Ops, n.State) // register drag inputs, if not hitting the clicks
|
||||
return D{Size: gtx.Constraints.Min}
|
||||
},
|
||||
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,
|
||||
func(gtx C) D {
|
||||
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}
|
||||
},
|
||||
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 {
|
||||
paint.ColorOp{Color: st.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{})
|
||||
paint.ColorOp{Color: n.Style.TextColor}.Add(gtx.Ops)
|
||||
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 {
|
||||
gtx.Constraints = layout.Exact(image.Pt(width, height))
|
||||
return layout.Background{}.Layout(gtx,
|
||||
func(gtx C) D {
|
||||
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}
|
||||
},
|
||||
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) },
|
||||
)
|
||||
}),
|
||||
)
|
||||
|
Reference in New Issue
Block a user