mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-06 18:05:35 +00:00
widget/material: manage widget colors with Palette type
This introduces a new material.Palette type that captures the color information necessary to render a widget. This type is embedded in the material.Theme to make it easier to swap to a different palette for part of the UI by reassinging the Palette field. Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
This commit is contained in:
@@ -52,9 +52,9 @@ type IconButtonStyle struct {
|
|||||||
func Button(th *Theme, button *widget.Clickable, txt string) ButtonStyle {
|
func Button(th *Theme, button *widget.Clickable, txt string) ButtonStyle {
|
||||||
return ButtonStyle{
|
return ButtonStyle{
|
||||||
Text: txt,
|
Text: txt,
|
||||||
Color: rgb(0xffffff),
|
Color: th.Palette.ContrastFg,
|
||||||
CornerRadius: unit.Dp(4),
|
CornerRadius: unit.Dp(4),
|
||||||
Background: th.Color.Primary,
|
Background: th.Palette.ContrastBg,
|
||||||
TextSize: th.TextSize.Scale(14.0 / 16.0),
|
TextSize: th.TextSize.Scale(14.0 / 16.0),
|
||||||
Inset: layout.Inset{
|
Inset: layout.Inset{
|
||||||
Top: unit.Dp(10), Bottom: unit.Dp(10),
|
Top: unit.Dp(10), Bottom: unit.Dp(10),
|
||||||
@@ -68,15 +68,15 @@ func Button(th *Theme, button *widget.Clickable, txt string) ButtonStyle {
|
|||||||
func ButtonLayout(th *Theme, button *widget.Clickable) ButtonLayoutStyle {
|
func ButtonLayout(th *Theme, button *widget.Clickable) ButtonLayoutStyle {
|
||||||
return ButtonLayoutStyle{
|
return ButtonLayoutStyle{
|
||||||
Button: button,
|
Button: button,
|
||||||
Background: th.Color.Primary,
|
Background: th.Palette.ContrastBg,
|
||||||
CornerRadius: unit.Dp(4),
|
CornerRadius: unit.Dp(4),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func IconButton(th *Theme, button *widget.Clickable, icon *widget.Icon) IconButtonStyle {
|
func IconButton(th *Theme, button *widget.Clickable, icon *widget.Icon) IconButtonStyle {
|
||||||
return IconButtonStyle{
|
return IconButtonStyle{
|
||||||
Background: th.Color.Primary,
|
Background: th.Palette.ContrastBg,
|
||||||
Color: th.Color.InvText,
|
Color: th.Palette.ContrastFg,
|
||||||
Icon: icon,
|
Icon: icon,
|
||||||
Size: unit.Dp(24),
|
Size: unit.Dp(24),
|
||||||
Inset: layout.UniformInset(unit.Dp(12)),
|
Inset: layout.UniformInset(unit.Dp(12)),
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ func CheckBox(th *Theme, checkBox *widget.Bool, label string) CheckBoxStyle {
|
|||||||
CheckBox: checkBox,
|
CheckBox: checkBox,
|
||||||
checkable: checkable{
|
checkable: checkable{
|
||||||
Label: label,
|
Label: label,
|
||||||
Color: th.Color.Text,
|
Color: th.Palette.Fg,
|
||||||
IconColor: th.Color.Primary,
|
IconColor: th.Palette.ContrastBg,
|
||||||
TextSize: th.TextSize.Scale(14.0 / 16.0),
|
TextSize: th.TextSize.Scale(14.0 / 16.0),
|
||||||
Size: unit.Dp(26),
|
Size: unit.Dp(26),
|
||||||
shaper: th.Shaper,
|
shaper: th.Shaper,
|
||||||
|
|||||||
@@ -32,10 +32,10 @@ func Editor(th *Theme, editor *widget.Editor, hint string) EditorStyle {
|
|||||||
return EditorStyle{
|
return EditorStyle{
|
||||||
Editor: editor,
|
Editor: editor,
|
||||||
TextSize: th.TextSize,
|
TextSize: th.TextSize,
|
||||||
Color: th.Color.Text,
|
Color: th.Palette.Fg,
|
||||||
shaper: th.Shaper,
|
shaper: th.Shaper,
|
||||||
Hint: hint,
|
Hint: hint,
|
||||||
HintColor: th.Color.Hint,
|
HintColor: f32color.MulAlpha(th.Palette.Fg, 0xbb),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ func Caption(th *Theme, txt string) LabelStyle {
|
|||||||
func Label(th *Theme, size unit.Value, txt string) LabelStyle {
|
func Label(th *Theme, size unit.Value, txt string) LabelStyle {
|
||||||
return LabelStyle{
|
return LabelStyle{
|
||||||
Text: txt,
|
Text: txt,
|
||||||
Color: th.Color.Text,
|
Color: th.Palette.Fg,
|
||||||
TextSize: size,
|
TextSize: size,
|
||||||
shaper: th.Shaper,
|
shaper: th.Shaper,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ type LoaderStyle struct {
|
|||||||
|
|
||||||
func Loader(th *Theme) LoaderStyle {
|
func Loader(th *Theme) LoaderStyle {
|
||||||
return LoaderStyle{
|
return LoaderStyle{
|
||||||
Color: th.Color.Primary,
|
Color: th.Palette.ContrastBg,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,14 +15,16 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ProgressBarStyle struct {
|
type ProgressBarStyle struct {
|
||||||
Color color.NRGBA
|
Color color.NRGBA
|
||||||
Progress int
|
TrackColor color.NRGBA
|
||||||
|
Progress int
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProgressBar(th *Theme, progress int) ProgressBarStyle {
|
func ProgressBar(th *Theme, progress int) ProgressBarStyle {
|
||||||
return ProgressBarStyle{
|
return ProgressBarStyle{
|
||||||
Progress: progress,
|
Progress: progress,
|
||||||
Color: th.Color.Primary,
|
Color: th.Palette.ContrastBg,
|
||||||
|
TrackColor: f32color.MulAlpha(th.Palette.Fg, 0x88),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,10 +57,7 @@ func (p ProgressBarStyle) Layout(gtx layout.Context) layout.Dimensions {
|
|||||||
|
|
||||||
return layout.Stack{Alignment: layout.W}.Layout(gtx,
|
return layout.Stack{Alignment: layout.W}.Layout(gtx,
|
||||||
layout.Stacked(func(gtx layout.Context) layout.Dimensions {
|
layout.Stacked(func(gtx layout.Context) layout.Dimensions {
|
||||||
// Use a transparent equivalent of progress color.
|
return shader(progressBarWidth, p.TrackColor)
|
||||||
bgCol := f32color.MulAlpha(p.Color, 150)
|
|
||||||
|
|
||||||
return shader(progressBarWidth, bgCol)
|
|
||||||
}),
|
}),
|
||||||
layout.Stacked(func(gtx layout.Context) layout.Dimensions {
|
layout.Stacked(func(gtx layout.Context) layout.Dimensions {
|
||||||
fillWidth := (progressBarWidth / 100) * float32(progress)
|
fillWidth := (progressBarWidth / 100) * float32(progress)
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ func RadioButton(th *Theme, group *widget.Enum, key, label string) RadioButtonSt
|
|||||||
checkable: checkable{
|
checkable: checkable{
|
||||||
Label: label,
|
Label: label,
|
||||||
|
|
||||||
Color: th.Color.Text,
|
Color: th.Palette.Fg,
|
||||||
IconColor: th.Color.Primary,
|
IconColor: th.Palette.ContrastBg,
|
||||||
TextSize: th.TextSize.Scale(14.0 / 16.0),
|
TextSize: th.TextSize.Scale(14.0 / 16.0),
|
||||||
Size: unit.Dp(26),
|
Size: unit.Dp(26),
|
||||||
shaper: th.Shaper,
|
shaper: th.Shaper,
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ func Slider(th *Theme, float *widget.Float, min, max float32) SliderStyle {
|
|||||||
return SliderStyle{
|
return SliderStyle{
|
||||||
Min: min,
|
Min: min,
|
||||||
Max: max,
|
Max: max,
|
||||||
Color: th.Color.Primary,
|
Color: th.Palette.ContrastBg,
|
||||||
Float: float,
|
Float: float,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ type SwitchStyle struct {
|
|||||||
Color struct {
|
Color struct {
|
||||||
Enabled color.NRGBA
|
Enabled color.NRGBA
|
||||||
Disabled color.NRGBA
|
Disabled color.NRGBA
|
||||||
|
Track color.NRGBA
|
||||||
}
|
}
|
||||||
Switch *widget.Bool
|
Switch *widget.Bool
|
||||||
}
|
}
|
||||||
@@ -29,8 +30,9 @@ func Switch(th *Theme, swtch *widget.Bool) SwitchStyle {
|
|||||||
sw := SwitchStyle{
|
sw := SwitchStyle{
|
||||||
Switch: swtch,
|
Switch: swtch,
|
||||||
}
|
}
|
||||||
sw.Color.Enabled = th.Color.Primary
|
sw.Color.Enabled = th.Palette.ContrastBg
|
||||||
sw.Color.Disabled = rgb(0xffffff)
|
sw.Color.Disabled = th.Palette.Bg
|
||||||
|
sw.Color.Track = f32color.MulAlpha(th.Palette.Fg, 0x88)
|
||||||
return sw
|
return sw
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,7 +57,7 @@ func (s SwitchStyle) Layout(gtx layout.Context) layout.Dimensions {
|
|||||||
if gtx.Queue == nil {
|
if gtx.Queue == nil {
|
||||||
col = f32color.MulAlpha(col, 150)
|
col = f32color.MulAlpha(col, 150)
|
||||||
}
|
}
|
||||||
trackColor := f32color.MulAlpha(col, 150)
|
trackColor := s.Color.Track
|
||||||
op.Offset(f32.Point{Y: trackOff}).Add(gtx.Ops)
|
op.Offset(f32.Point{Y: trackOff}).Add(gtx.Ops)
|
||||||
clip.RRect{
|
clip.RRect{
|
||||||
Rect: trackRect,
|
Rect: trackRect,
|
||||||
|
|||||||
+31
-10
@@ -11,14 +11,28 @@ import (
|
|||||||
"golang.org/x/exp/shiny/materialdesign/icons"
|
"golang.org/x/exp/shiny/materialdesign/icons"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Palette contains the minimal set of colors that a widget may need to
|
||||||
|
// draw itself.
|
||||||
|
type Palette struct {
|
||||||
|
// Bg is the background color atop which content is currently being
|
||||||
|
// drawn.
|
||||||
|
Bg color.NRGBA
|
||||||
|
|
||||||
|
// Fg is a color suitable for drawing on top of Bg.
|
||||||
|
Fg color.NRGBA
|
||||||
|
|
||||||
|
// ContrastBg is a color used to draw attention to active,
|
||||||
|
// important, interactive widgets such as buttons.
|
||||||
|
ContrastBg color.NRGBA
|
||||||
|
|
||||||
|
// ContrastFg is a color suitable for content drawn on top of
|
||||||
|
// ContrastBg.
|
||||||
|
ContrastFg color.NRGBA
|
||||||
|
}
|
||||||
|
|
||||||
type Theme struct {
|
type Theme struct {
|
||||||
Shaper text.Shaper
|
Shaper text.Shaper
|
||||||
Color struct {
|
Palette
|
||||||
Primary color.NRGBA
|
|
||||||
Text color.NRGBA
|
|
||||||
Hint color.NRGBA
|
|
||||||
InvText color.NRGBA
|
|
||||||
}
|
|
||||||
TextSize unit.Value
|
TextSize unit.Value
|
||||||
Icon struct {
|
Icon struct {
|
||||||
CheckBoxChecked *widget.Icon
|
CheckBoxChecked *widget.Icon
|
||||||
@@ -32,10 +46,12 @@ func NewTheme(fontCollection []text.FontFace) *Theme {
|
|||||||
t := &Theme{
|
t := &Theme{
|
||||||
Shaper: text.NewCache(fontCollection),
|
Shaper: text.NewCache(fontCollection),
|
||||||
}
|
}
|
||||||
t.Color.Primary = rgb(0x3f51b5)
|
t.Palette = Palette{
|
||||||
t.Color.Text = rgb(0x000000)
|
Fg: rgb(0x000000),
|
||||||
t.Color.Hint = rgb(0xbbbbbb)
|
Bg: rgb(0xffffff),
|
||||||
t.Color.InvText = rgb(0xffffff)
|
ContrastBg: rgb(0x3f51b5),
|
||||||
|
ContrastFg: rgb(0xffffff),
|
||||||
|
}
|
||||||
t.TextSize = unit.Sp(16)
|
t.TextSize = unit.Sp(16)
|
||||||
|
|
||||||
t.Icon.CheckBoxChecked = mustIcon(widget.NewIcon(icons.ToggleCheckBox))
|
t.Icon.CheckBoxChecked = mustIcon(widget.NewIcon(icons.ToggleCheckBox))
|
||||||
@@ -46,6 +62,11 @@ func NewTheme(fontCollection []text.FontFace) *Theme {
|
|||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t Theme) WithPalette(p Palette) Theme {
|
||||||
|
t.Palette = p
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
func mustIcon(ic *widget.Icon, err error) *widget.Icon {
|
func mustIcon(ic *widget.Icon, err error) *widget.Icon {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|||||||
Reference in New Issue
Block a user