checkable.go 2.2 KB

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