refactor(tracker/gioui): make iconCache part of Theme

This commit is contained in:
5684185+vsariola@users.noreply.github.com
2025-06-20 19:05:40 +03:00
parent b291959a97
commit 4fa0e04788
6 changed files with 22 additions and 31 deletions

View File

@ -76,7 +76,7 @@ func ActionIcon(gtx C, th *Theme, w *ActionClickable, icon []byte, tip string) T
} }
func TipIcon(th *Theme, w *TipClickable, icon []byte, tip string) TipIconButtonStyle { func TipIcon(th *Theme, w *TipClickable, icon []byte, tip string) TipIconButtonStyle {
iconButtonStyle := IconButton(th, &w.Clickable, widgetForIcon(icon), "") iconButtonStyle := IconButton(th, &w.Clickable, th.Icon(icon), "")
iconButtonStyle.Color = th.Material.Palette.ContrastBg iconButtonStyle.Color = th.Material.Palette.ContrastBg
iconButtonStyle.Background = color.NRGBA{} iconButtonStyle.Background = color.NRGBA{}
iconButtonStyle.Inset = layout.UniformInset(unit.Dp(6)) iconButtonStyle.Inset = layout.UniformInset(unit.Dp(6))
@ -97,7 +97,7 @@ func ToggleIcon(gtx C, th *Theme, w *BoolClickable, offIcon, onIcon []byte, offT
for w.Clickable.Clicked(gtx) { for w.Clickable.Clicked(gtx) {
w.Bool.Toggle() w.Bool.Toggle()
} }
ibStyle := IconButton(th, &w.Clickable, widgetForIcon(icon), "") ibStyle := IconButton(th, &w.Clickable, th.Icon(icon), "")
ibStyle.Background = color.NRGBA{} ibStyle.Background = color.NRGBA{}
ibStyle.Inset = layout.UniformInset(unit.Dp(6)) ibStyle.Inset = layout.UniformInset(unit.Dp(6))
ibStyle.Color = th.Material.Palette.ContrastBg ibStyle.Color = th.Material.Palette.ContrastBg

View File

@ -1,22 +0,0 @@
package gioui
import (
"log"
"gioui.org/widget"
)
var iconCache = map[*byte]*widget.Icon{}
// widgetForIcon returns a widget for IconVG data, but caching the results
func widgetForIcon(icon []byte) *widget.Icon {
if widget, ok := iconCache[&icon[0]]; ok {
return widget
}
widget, err := widget.NewIcon(icon)
if err != nil {
log.Fatal(err)
}
iconCache[&icon[0]] = widget
return widget
}

View File

@ -96,7 +96,7 @@ func (m *MenuStyle) Layout(gtx C, items ...MenuItem) D {
if i == m.Menu.hover-1 && item.Doer.Enabled() { if i == m.Menu.hover-1 && item.Doer.Enabled() {
macro = op.Record(gtx.Ops) macro = op.Record(gtx.Ops)
} }
icon := widgetForIcon(item.IconBytes) icon := m.Theme.Icon(item.IconBytes)
iconColor := m.LabelStyle.Color iconColor := m.LabelStyle.Color
iconInset := layout.Inset{Left: unit.Dp(12), Right: unit.Dp(6)} iconInset := layout.Inset{Left: unit.Dp(12), Right: unit.Dp(6)}
textLabel := Label(m.Theme, &m.Theme.Menu.Text, item.Text) textLabel := Label(m.Theme, &m.Theme.Menu.Text, item.Text)

View File

@ -47,7 +47,7 @@ type NumericUpDownStyle struct {
type NumericUpDown struct { type NumericUpDown struct {
NumberInput *NumberInput NumberInput *NumberInput
Tooltip component.Tooltip Tooltip component.Tooltip
Shaper *text.Shaper Theme *Theme
Font font.Font Font font.Font
NumericUpDownStyle NumericUpDownStyle
} }
@ -59,7 +59,7 @@ func NewNumberInput(v tracker.Int) *NumberInput {
func NumUpDown(th *Theme, number *NumberInput, tooltip string) NumericUpDown { func NumUpDown(th *Theme, number *NumberInput, tooltip string) NumericUpDown {
return NumericUpDown{ return NumericUpDown{
NumberInput: number, NumberInput: number,
Shaper: th.Material.Shaper, Theme: th,
Tooltip: Tooltip(th, tooltip), Tooltip: Tooltip(th, tooltip),
NumericUpDownStyle: th.NumericUpDown, NumericUpDownStyle: th.NumericUpDown,
} }
@ -131,12 +131,12 @@ func (s *NumericUpDown) actualLayout(gtx C) D {
s.NumberInput.clickDecrease.Add(gtx.Ops) s.NumberInput.clickDecrease.Add(gtx.Ops)
return D{Size: gtx.Constraints.Min} return D{Size: gtx.Constraints.Min}
}, },
func(gtx C) D { return widgetForIcon(icons.ContentRemove).Layout(gtx, s.IconColor) }, func(gtx C) D { return s.Theme.Icon(icons.ContentRemove).Layout(gtx, s.IconColor) },
) )
}), }),
layout.Flexed(1, func(gtx C) D { layout.Flexed(1, func(gtx C) D {
paint.ColorOp{Color: s.TextColor}.Add(gtx.Ops) paint.ColorOp{Color: s.TextColor}.Add(gtx.Ops)
return widget.Label{Alignment: text.Middle}.Layout(gtx, s.Shaper, s.Font, s.TextSize, strconv.Itoa(s.NumberInput.Int.Value()), op.CallOp{}) return widget.Label{Alignment: text.Middle}.Layout(gtx, s.Theme.Material.Shaper, s.Font, s.TextSize, strconv.Itoa(s.NumberInput.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))
@ -146,7 +146,7 @@ func (s *NumericUpDown) actualLayout(gtx C) D {
s.NumberInput.clickIncrease.Add(gtx.Ops) s.NumberInput.clickIncrease.Add(gtx.Ops)
return D{Size: gtx.Constraints.Min} return D{Size: gtx.Constraints.Min}
}, },
func(gtx C) D { return widgetForIcon(icons.ContentAdd).Layout(gtx, s.IconColor) }, func(gtx C) D { return s.Theme.Icon(icons.ContentAdd).Layout(gtx, s.IconColor) },
) )
}), }),
) )

View File

@ -286,7 +286,7 @@ func (e *Expander) layoutHeader(gtx C, th *Theme, title string, smallWidget layo
icon = icons.NavigationExpandLess icon = icons.NavigationExpandLess
} }
gtx.Constraints.Min = image.Pt(gtx.Dp(unit.Dp(24)), gtx.Dp(unit.Dp(24))) gtx.Constraints.Min = image.Pt(gtx.Dp(unit.Dp(24)), gtx.Dp(unit.Dp(24)))
return widgetForIcon(icon).Layout(gtx, th.SongPanel.Expander.Color) return th.Icon(icon).Layout(gtx, th.SongPanel.Expander.Color)
}), }),
) )
}, },

View File

@ -107,6 +107,9 @@ type Theme struct {
Shadow color.NRGBA Shadow color.NRGBA
} }
ScrollBar ScrollBarStyle ScrollBar ScrollBarStyle
// iconCache is used to cache the icons created from iconvg data
iconCache map[*byte]*widget.Icon
} }
type CursorStyle struct { type CursorStyle struct {
@ -127,9 +130,19 @@ func NewTheme() (*Theme, error) {
ret.Material.Icon.CheckBoxUnchecked = must(widget.NewIcon(icons.ToggleCheckBoxOutlineBlank)) ret.Material.Icon.CheckBoxUnchecked = must(widget.NewIcon(icons.ToggleCheckBoxOutlineBlank))
ret.Material.Icon.RadioChecked = must(widget.NewIcon(icons.ToggleRadioButtonChecked)) ret.Material.Icon.RadioChecked = must(widget.NewIcon(icons.ToggleRadioButtonChecked))
ret.Material.Icon.RadioUnchecked = must(widget.NewIcon(icons.ToggleRadioButtonUnchecked)) ret.Material.Icon.RadioUnchecked = must(widget.NewIcon(icons.ToggleRadioButtonUnchecked))
ret.iconCache = make(map[*byte]*widget.Icon)
return &ret, warn return &ret, warn
} }
func (th *Theme) Icon(data []byte) *widget.Icon {
if icon, ok := th.iconCache[&data[0]]; ok {
return icon
}
icon := must(widget.NewIcon(data))
th.iconCache[&data[0]] = icon
return icon
}
func must[T any](ic T, err error) T { func must[T any](ic T, err error) T {
if err != nil { if err != nil {
panic(err) panic(err)