theme.go 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. // SPDX-License-Identifier: Unlicense OR MIT
  2. package material
  3. import (
  4. "image/color"
  5. "golang.org/x/exp/shiny/materialdesign/icons"
  6. "gioui.org/font"
  7. "gioui.org/text"
  8. "gioui.org/unit"
  9. "gioui.org/widget"
  10. )
  11. // Palette contains the minimal set of colors that a widget may need to
  12. // draw itself.
  13. type Palette struct {
  14. // Bg is the background color atop which content is currently being
  15. // drawn.
  16. Bg color.NRGBA
  17. // Fg is a color suitable for drawing on top of Bg.
  18. Fg color.NRGBA
  19. // ContrastBg is a color used to draw attention to active,
  20. // important, interactive widgets such as buttons.
  21. ContrastBg color.NRGBA
  22. // ContrastFg is a color suitable for content drawn on top of
  23. // ContrastBg.
  24. ContrastFg color.NRGBA
  25. }
  26. // Theme holds the general theme of an app or window. Different top-level
  27. // windows should have different instances of Theme (with different Shapers;
  28. // see the godoc for [text.Shaper]), though their other fields can be equal.
  29. type Theme struct {
  30. Shaper *text.Shaper
  31. Palette
  32. TextSize unit.Sp
  33. Icon struct {
  34. CheckBoxChecked *widget.Icon
  35. CheckBoxUnchecked *widget.Icon
  36. RadioChecked *widget.Icon
  37. RadioUnchecked *widget.Icon
  38. }
  39. // Face selects the default typeface for text.
  40. Face font.Typeface
  41. // FingerSize is the minimum touch target size.
  42. FingerSize unit.Dp
  43. }
  44. // NewTheme constructs a theme (and underlying text shaper).
  45. func NewTheme() *Theme {
  46. t := &Theme{Shaper: &text.Shaper{}}
  47. t.Palette = Palette{
  48. Fg: rgb(0x000000),
  49. Bg: rgb(0xffffff),
  50. ContrastBg: rgb(0x3f51b5),
  51. ContrastFg: rgb(0xffffff),
  52. }
  53. t.TextSize = 16
  54. t.Icon.CheckBoxChecked = mustIcon(widget.NewIcon(icons.ToggleCheckBox))
  55. t.Icon.CheckBoxUnchecked = mustIcon(widget.NewIcon(icons.ToggleCheckBoxOutlineBlank))
  56. t.Icon.RadioChecked = mustIcon(widget.NewIcon(icons.ToggleRadioButtonChecked))
  57. t.Icon.RadioUnchecked = mustIcon(widget.NewIcon(icons.ToggleRadioButtonUnchecked))
  58. // 38dp is on the lower end of possible finger size.
  59. t.FingerSize = 38
  60. return t
  61. }
  62. func (t Theme) WithPalette(p Palette) Theme {
  63. t.Palette = p
  64. return t
  65. }
  66. func mustIcon(ic *widget.Icon, err error) *widget.Icon {
  67. if err != nil {
  68. panic(err)
  69. }
  70. return ic
  71. }
  72. func rgb(c uint32) color.NRGBA {
  73. return argb(0xff000000 | c)
  74. }
  75. func argb(c uint32) color.NRGBA {
  76. return color.NRGBA{A: uint8(c >> 24), R: uint8(c >> 16), G: uint8(c >> 8), B: uint8(c)}
  77. }