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.
 
 
 
 
 

148 lines
3.1 KiB

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