From 6e9bb7b91ce5be81b46ac246af6aa5b1f1e816dc Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Wed, 28 Jul 2021 14:19:39 +0200 Subject: [PATCH] widget,widget/material: remove Color field from Icon Icons are meant to be shared among multiple widgets, but their Color state may end up with unexpected values after use. Replace the state with and explicit argument to Layout. Signed-off-by: Elias Naur --- widget/icon.go | 17 ++++++++--------- widget/icon_test.go | 6 +++--- widget/material/button.go | 3 +-- widget/material/checkable.go | 6 +++--- 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/widget/icon.go b/widget/icon.go index 6c01b184..ed3b1b1e 100644 --- a/widget/icon.go +++ b/widget/icon.go @@ -18,8 +18,7 @@ import ( ) type Icon struct { - Color color.NRGBA - src []byte + src []byte // Cached values. op paint.ImageOp imgSize int @@ -34,11 +33,11 @@ func NewIcon(data []byte) (*Icon, error) { if err != nil { return nil, err } - return &Icon{src: data, Color: color.NRGBA{A: 0xff}}, nil + return &Icon{src: data}, nil } // Layout displays the icon with its size set to the X minimum constraint. -func (ic *Icon) Layout(gtx layout.Context) layout.Dimensions { +func (ic *Icon) Layout(gtx layout.Context, color color.NRGBA) layout.Dimensions { sz := gtx.Constraints.Min.X if sz == 0 { sz = gtx.Metric.Px(defaultIconSize) @@ -47,7 +46,7 @@ func (ic *Icon) Layout(gtx layout.Context) layout.Dimensions { defer op.Save(gtx.Ops).Load() clip.Rect{Max: size}.Add(gtx.Ops) - ico := ic.image(size.X) + ico := ic.image(size.X, color) ico.Add(gtx.Ops) paint.PaintOp{}.Add(gtx.Ops) return layout.Dimensions{ @@ -55,8 +54,8 @@ func (ic *Icon) Layout(gtx layout.Context) layout.Dimensions { } } -func (ic *Icon) image(sz int) paint.ImageOp { - if sz == ic.imgSize && ic.Color == ic.imgColor { +func (ic *Icon) image(sz int, color color.NRGBA) paint.ImageOp { + if sz == ic.imgSize && color == ic.imgColor { return ic.op } m, _ := iconvg.DecodeMetadata(ic.src) @@ -64,12 +63,12 @@ func (ic *Icon) image(sz int) paint.ImageOp { img := image.NewRGBA(image.Rectangle{Max: image.Point{X: sz, Y: int(float32(sz) * dy / dx)}}) var ico iconvg.Rasterizer ico.SetDstImage(img, img.Bounds(), draw.Src) - m.Palette[0] = f32color.NRGBAToLinearRGBA(ic.Color) + m.Palette[0] = f32color.NRGBAToLinearRGBA(color) iconvg.Decode(&ico, ic.src, &iconvg.DecodeOptions{ Palette: &m.Palette, }) ic.op = paint.NewImageOp(img) ic.imgSize = sz - ic.imgColor = ic.Color + ic.imgColor = color return ic.op } diff --git a/widget/icon_test.go b/widget/icon_test.go index 6bc56ba4..2f9a3337 100644 --- a/widget/icon_test.go +++ b/widget/icon_test.go @@ -19,14 +19,14 @@ func TestIcon_Alpha(t *testing.T) { t.Fatal(err) } - icon.Color = color.NRGBA{B: 0xff, A: 0x40} + col := color.NRGBA{B: 0xff, A: 0x40} gtx := layout.Context{ Ops: new(op.Ops), Constraints: layout.Exact(image.Pt(100, 100)), } - _ = icon.Layout(gtx) + _ = icon.Layout(gtx, col) } // TestWidgetConstraints tests that widgets returns dimensions within their constraints. @@ -41,7 +41,7 @@ func TestWidgetConstraints(t *testing.T) { label: "Icon", widget: func(gtx layout.Context) layout.Dimensions { ic, _ := NewIcon(icons.ToggleCheckBox) - return ic.Layout(gtx) + return ic.Layout(gtx, color.NRGBA{A: 0xff}) }, constraints: _cs( layout.Constraints{ diff --git a/widget/material/button.go b/widget/material/button.go index 7228238b..02a443c3 100644 --- a/widget/material/button.go +++ b/widget/material/button.go @@ -169,9 +169,8 @@ func (b IconButtonStyle) Layout(gtx layout.Context) layout.Dimensions { return b.Inset.Layout(gtx, func(gtx layout.Context) layout.Dimensions { size := gtx.Px(b.Size) if b.Icon != nil { - b.Icon.Color = b.Color gtx.Constraints.Min = image.Point{X: size} - b.Icon.Layout(gtx) + b.Icon.Layout(gtx, b.Color) } return layout.Dimensions{ Size: image.Point{X: size, Y: size}, diff --git a/widget/material/checkable.go b/widget/material/checkable.go index 08935a33..6f85214e 100644 --- a/widget/material/checkable.go +++ b/widget/material/checkable.go @@ -63,12 +63,12 @@ func (c *checkable) layout(gtx layout.Context, checked, hovered bool) layout.Dim layout.Stacked(func(gtx layout.Context) layout.Dimensions { return layout.UniformInset(unit.Dp(2)).Layout(gtx, func(gtx layout.Context) layout.Dimensions { size := gtx.Px(c.Size) - icon.Color = c.IconColor + col := c.IconColor if gtx.Queue == nil { - icon.Color = f32color.Disabled(icon.Color) + col = f32color.Disabled(col) } gtx.Constraints.Min = image.Point{X: size} - icon.Layout(gtx) + icon.Layout(gtx, col) return layout.Dimensions{ Size: image.Point{X: size, Y: size}, }