gioui.org@v0.6.1-0.20240506124620-7a9ce51988ce/widget/material/checkable.go (about) 1 // SPDX-License-Identifier: Unlicense OR MIT 2 3 package material 4 5 import ( 6 "image" 7 "image/color" 8 9 "gioui.org/font" 10 "gioui.org/internal/f32color" 11 "gioui.org/layout" 12 "gioui.org/op" 13 "gioui.org/op/clip" 14 "gioui.org/op/paint" 15 "gioui.org/text" 16 "gioui.org/unit" 17 "gioui.org/widget" 18 ) 19 20 type checkable struct { 21 Label string 22 Color color.NRGBA 23 Font font.Font 24 TextSize unit.Sp 25 IconColor color.NRGBA 26 Size unit.Dp 27 shaper *text.Shaper 28 checkedStateIcon *widget.Icon 29 uncheckedStateIcon *widget.Icon 30 } 31 32 func (c *checkable) layout(gtx layout.Context, checked, hovered bool) layout.Dimensions { 33 var icon *widget.Icon 34 if checked { 35 icon = c.checkedStateIcon 36 } else { 37 icon = c.uncheckedStateIcon 38 } 39 40 dims := layout.Flex{Alignment: layout.Middle}.Layout(gtx, 41 layout.Rigid(func(gtx layout.Context) layout.Dimensions { 42 return layout.Stack{Alignment: layout.Center}.Layout(gtx, 43 layout.Stacked(func(gtx layout.Context) layout.Dimensions { 44 size := gtx.Dp(c.Size) * 4 / 3 45 dims := layout.Dimensions{ 46 Size: image.Point{X: size, Y: size}, 47 } 48 if !hovered { 49 return dims 50 } 51 52 background := f32color.MulAlpha(c.IconColor, 70) 53 54 b := image.Rectangle{Max: image.Pt(size, size)} 55 paint.FillShape(gtx.Ops, background, clip.Ellipse(b).Op(gtx.Ops)) 56 57 return dims 58 }), 59 layout.Stacked(func(gtx layout.Context) layout.Dimensions { 60 return layout.UniformInset(2).Layout(gtx, func(gtx layout.Context) layout.Dimensions { 61 size := gtx.Dp(c.Size) 62 col := c.IconColor 63 if !gtx.Enabled() { 64 col = f32color.Disabled(col) 65 } 66 gtx.Constraints.Min = image.Point{X: size} 67 icon.Layout(gtx, col) 68 return layout.Dimensions{ 69 Size: image.Point{X: size, Y: size}, 70 } 71 }) 72 }), 73 ) 74 }), 75 76 layout.Rigid(func(gtx layout.Context) layout.Dimensions { 77 return layout.UniformInset(2).Layout(gtx, func(gtx layout.Context) layout.Dimensions { 78 colMacro := op.Record(gtx.Ops) 79 paint.ColorOp{Color: c.Color}.Add(gtx.Ops) 80 return widget.Label{}.Layout(gtx, c.shaper, c.Font, c.TextSize, c.Label, colMacro.Stop()) 81 }) 82 }), 83 ) 84 return dims 85 }