User interface toolkit for Go with support for SDL2 and HTML Canvas render targets.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

124 lines
2.7 KiB

  1. package ui
  2. import (
  3. "fmt"
  4. "strconv"
  5. "git.kirsle.net/go/render"
  6. "git.kirsle.net/go/ui/theme"
  7. )
  8. // CheckButton implements a checkbox and radiobox widget. It's based on a
  9. // Button and holds a boolean or string pointer (boolean for checkbox,
  10. // string for radio).
  11. type CheckButton struct {
  12. Button
  13. BoolVar *bool
  14. StringVar *string
  15. Value string
  16. }
  17. // NewCheckButton creates a new CheckButton.
  18. func NewCheckButton(name string, boolVar *bool, child Widget) *CheckButton {
  19. w := &CheckButton{
  20. BoolVar: boolVar,
  21. }
  22. w.Button.child = child
  23. w.IDFunc(func() string {
  24. return fmt.Sprintf("CheckButton<%s %+v>", name, w.BoolVar)
  25. })
  26. w.setup()
  27. return w
  28. }
  29. // NewRadioButton creates a CheckButton bound to a string variable.
  30. func NewRadioButton(name string, stringVar *string, value string, child Widget) *CheckButton {
  31. w := &CheckButton{
  32. StringVar: stringVar,
  33. Value: value,
  34. }
  35. w.Button.child = child
  36. w.IDFunc(func() string {
  37. return fmt.Sprintf(`RadioButton<%s "%s" %s>`, name, w.Value, strconv.FormatBool(*w.StringVar == w.Value))
  38. })
  39. w.setup()
  40. return w
  41. }
  42. // Compute to re-evaluate the button state (in the case of radio buttons where
  43. // a different button will affect the state of this one when clicked).
  44. func (w *CheckButton) Compute(e render.Engine) {
  45. if w.StringVar != nil {
  46. // Radio button, always re-assign the border style in case a sister
  47. // radio button has changed the value.
  48. if *w.StringVar == w.Value {
  49. w.SetBorderStyle(BorderSunken)
  50. } else {
  51. w.SetBorderStyle(BorderRaised)
  52. }
  53. }
  54. w.Button.Compute(e)
  55. }
  56. // setup the common things between checkboxes and radioboxes.
  57. func (w *CheckButton) setup() {
  58. var borderStyle BorderStyle = BorderRaised
  59. if w.BoolVar != nil {
  60. if *w.BoolVar == true {
  61. borderStyle = BorderSunken
  62. }
  63. }
  64. w.Configure(Config{
  65. BorderSize: 2,
  66. BorderStyle: borderStyle,
  67. OutlineSize: 1,
  68. OutlineColor: theme.ButtonOutlineColor,
  69. Background: theme.ButtonBackgroundColor,
  70. })
  71. w.Handle(MouseOver, func(ed EventData) error {
  72. w.hovering = true
  73. w.SetBackground(theme.ButtonHoverColor)
  74. return nil
  75. })
  76. w.Handle(MouseOut, func(ed EventData) error {
  77. w.hovering = false
  78. w.SetBackground(theme.ButtonBackgroundColor)
  79. return nil
  80. })
  81. w.Handle(MouseDown, func(ed EventData) error {
  82. w.clicked = true
  83. w.SetBorderStyle(BorderSunken)
  84. return nil
  85. })
  86. w.Handle(MouseUp, func(ed EventData) error {
  87. w.clicked = false
  88. return nil
  89. })
  90. w.Handle(Click, func(ed EventData) error {
  91. var sunken bool
  92. if w.BoolVar != nil {
  93. if *w.BoolVar {
  94. *w.BoolVar = false
  95. } else {
  96. *w.BoolVar = true
  97. sunken = true
  98. }
  99. } else if w.StringVar != nil {
  100. *w.StringVar = w.Value
  101. sunken = true
  102. }
  103. if sunken {
  104. w.SetBorderStyle(BorderSunken)
  105. } else {
  106. w.SetBorderStyle(BorderRaised)
  107. }
  108. return nil
  109. })
  110. }