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:
Chris Waldon
2020-12-05 21:59:49 -05:00
committed by Elias Naur
parent 47ba975899
commit a87a520ae8
10 changed files with 57 additions and 35 deletions
+5 -5
View File
@@ -52,9 +52,9 @@ type IconButtonStyle struct {
func Button(th *Theme, button *widget.Clickable, txt string) ButtonStyle {
return ButtonStyle{
Text: txt,
Color: rgb(0xffffff),
Color: th.Palette.ContrastFg,
CornerRadius: unit.Dp(4),
Background: th.Color.Primary,
Background: th.Palette.ContrastBg,
TextSize: th.TextSize.Scale(14.0 / 16.0),
Inset: layout.Inset{
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 {
return ButtonLayoutStyle{
Button: button,
Background: th.Color.Primary,
Background: th.Palette.ContrastBg,
CornerRadius: unit.Dp(4),
}
}
func IconButton(th *Theme, button *widget.Clickable, icon *widget.Icon) IconButtonStyle {
return IconButtonStyle{
Background: th.Color.Primary,
Color: th.Color.InvText,
Background: th.Palette.ContrastBg,
Color: th.Palette.ContrastFg,
Icon: icon,
Size: unit.Dp(24),
Inset: layout.UniformInset(unit.Dp(12)),
+2 -2
View File
@@ -18,8 +18,8 @@ func CheckBox(th *Theme, checkBox *widget.Bool, label string) CheckBoxStyle {
CheckBox: checkBox,
checkable: checkable{
Label: label,
Color: th.Color.Text,
IconColor: th.Color.Primary,
Color: th.Palette.Fg,
IconColor: th.Palette.ContrastBg,
TextSize: th.TextSize.Scale(14.0 / 16.0),
Size: unit.Dp(26),
shaper: th.Shaper,
+2 -2
View File
@@ -32,10 +32,10 @@ func Editor(th *Theme, editor *widget.Editor, hint string) EditorStyle {
return EditorStyle{
Editor: editor,
TextSize: th.TextSize,
Color: th.Color.Text,
Color: th.Palette.Fg,
shaper: th.Shaper,
Hint: hint,
HintColor: th.Color.Hint,
HintColor: f32color.MulAlpha(th.Palette.Fg, 0xbb),
}
}
+1 -1
View File
@@ -66,7 +66,7 @@ func Caption(th *Theme, txt string) LabelStyle {
func Label(th *Theme, size unit.Value, txt string) LabelStyle {
return LabelStyle{
Text: txt,
Color: th.Color.Text,
Color: th.Palette.Fg,
TextSize: size,
shaper: th.Shaper,
}
+1 -1
View File
@@ -22,7 +22,7 @@ type LoaderStyle struct {
func Loader(th *Theme) LoaderStyle {
return LoaderStyle{
Color: th.Color.Primary,
Color: th.Palette.ContrastBg,
}
}
+7 -8
View File
@@ -15,14 +15,16 @@ import (
)
type ProgressBarStyle struct {
Color color.NRGBA
Progress int
Color color.NRGBA
TrackColor color.NRGBA
Progress int
}
func ProgressBar(th *Theme, progress int) ProgressBarStyle {
return ProgressBarStyle{
Progress: progress,
Color: th.Color.Primary,
Progress: progress,
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,
layout.Stacked(func(gtx layout.Context) layout.Dimensions {
// Use a transparent equivalent of progress color.
bgCol := f32color.MulAlpha(p.Color, 150)
return shader(progressBarWidth, bgCol)
return shader(progressBarWidth, p.TrackColor)
}),
layout.Stacked(func(gtx layout.Context) layout.Dimensions {
fillWidth := (progressBarWidth / 100) * float32(progress)
+2 -2
View File
@@ -22,8 +22,8 @@ func RadioButton(th *Theme, group *widget.Enum, key, label string) RadioButtonSt
checkable: checkable{
Label: label,
Color: th.Color.Text,
IconColor: th.Color.Primary,
Color: th.Palette.Fg,
IconColor: th.Palette.ContrastBg,
TextSize: th.TextSize.Scale(14.0 / 16.0),
Size: unit.Dp(26),
shaper: th.Shaper,
+1 -1
View File
@@ -21,7 +21,7 @@ func Slider(th *Theme, float *widget.Float, min, max float32) SliderStyle {
return SliderStyle{
Min: min,
Max: max,
Color: th.Color.Primary,
Color: th.Palette.ContrastBg,
Float: float,
}
}
+5 -3
View File
@@ -21,6 +21,7 @@ type SwitchStyle struct {
Color struct {
Enabled color.NRGBA
Disabled color.NRGBA
Track color.NRGBA
}
Switch *widget.Bool
}
@@ -29,8 +30,9 @@ func Switch(th *Theme, swtch *widget.Bool) SwitchStyle {
sw := SwitchStyle{
Switch: swtch,
}
sw.Color.Enabled = th.Color.Primary
sw.Color.Disabled = rgb(0xffffff)
sw.Color.Enabled = th.Palette.ContrastBg
sw.Color.Disabled = th.Palette.Bg
sw.Color.Track = f32color.MulAlpha(th.Palette.Fg, 0x88)
return sw
}
@@ -55,7 +57,7 @@ func (s SwitchStyle) Layout(gtx layout.Context) layout.Dimensions {
if gtx.Queue == nil {
col = f32color.MulAlpha(col, 150)
}
trackColor := f32color.MulAlpha(col, 150)
trackColor := s.Color.Track
op.Offset(f32.Point{Y: trackOff}).Add(gtx.Ops)
clip.RRect{
Rect: trackRect,
+31 -10
View File
@@ -11,14 +11,28 @@ import (
"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 {
Shaper text.Shaper
Color struct {
Primary color.NRGBA
Text color.NRGBA
Hint color.NRGBA
InvText color.NRGBA
}
Palette
TextSize unit.Value
Icon struct {
CheckBoxChecked *widget.Icon
@@ -32,10 +46,12 @@ func NewTheme(fontCollection []text.FontFace) *Theme {
t := &Theme{
Shaper: text.NewCache(fontCollection),
}
t.Color.Primary = rgb(0x3f51b5)
t.Color.Text = rgb(0x000000)
t.Color.Hint = rgb(0xbbbbbb)
t.Color.InvText = rgb(0xffffff)
t.Palette = Palette{
Fg: rgb(0x000000),
Bg: rgb(0xffffff),
ContrastBg: rgb(0x3f51b5),
ContrastFg: rgb(0xffffff),
}
t.TextSize = unit.Sp(16)
t.Icon.CheckBoxChecked = mustIcon(widget.NewIcon(icons.ToggleCheckBox))
@@ -46,6 +62,11 @@ func NewTheme(fontCollection []text.FontFace) *Theme {
return t
}
func (t Theme) WithPalette(p Palette) Theme {
t.Palette = p
return t
}
func mustIcon(ic *widget.Icon, err error) *widget.Icon {
if err != nil {
panic(err)