Noah Petherbridge
e1cbff8c3f
* Add ui.Window to easily create reusable windows with titles. * Add a palette window (panel) to the right edge of the Edit Mode. * Has Radio Buttons listing the colors available in the palette. * Add palette support to Edit Mode so when you draw pixels, they take on the color and attributes of the currently selected Swatch in your palette. * Revise the on-disk format to better serialize the Palette object to JSON. * Break Play Mode: collision detection fails because the Grid key elements are now full Pixel objects (which retain their Palette and Swatch properties). * The Grid will need to be re-worked to separate X,Y coordinates from the Pixel metadata to just test "is something there, and what is it?"
119 lines
2.7 KiB
Go
119 lines
2.7 KiB
Go
package ui
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
|
|
"git.kirsle.net/apps/doodle/render"
|
|
"git.kirsle.net/apps/doodle/ui/theme"
|
|
)
|
|
|
|
// CheckButton implements a checkbox and radiobox widget. It's based on a
|
|
// Button and holds a boolean or string pointer (boolean for checkbox,
|
|
// string for radio).
|
|
type CheckButton struct {
|
|
Button
|
|
BoolVar *bool
|
|
StringVar *string
|
|
Value string
|
|
}
|
|
|
|
// NewCheckButton creates a new CheckButton.
|
|
func NewCheckButton(name string, boolVar *bool, child Widget) *CheckButton {
|
|
w := &CheckButton{
|
|
BoolVar: boolVar,
|
|
}
|
|
w.Button.child = child
|
|
w.IDFunc(func() string {
|
|
return fmt.Sprintf("CheckButton<%s %+v>", name, w.BoolVar)
|
|
})
|
|
|
|
w.setup()
|
|
return w
|
|
}
|
|
|
|
// NewRadioButton creates a CheckButton bound to a string variable.
|
|
func NewRadioButton(name string, stringVar *string, value string, child Widget) *CheckButton {
|
|
w := &CheckButton{
|
|
StringVar: stringVar,
|
|
Value: value,
|
|
}
|
|
w.Button.child = child
|
|
w.IDFunc(func() string {
|
|
return fmt.Sprintf(`RadioButton<%s "%s" %s>`, name, w.Value, strconv.FormatBool(*w.StringVar == w.Value))
|
|
})
|
|
w.setup()
|
|
return w
|
|
}
|
|
|
|
// Compute to re-evaluate the button state (in the case of radio buttons where
|
|
// a different button will affect the state of this one when clicked).
|
|
func (w *CheckButton) Compute(e render.Engine) {
|
|
if w.StringVar != nil {
|
|
// Radio button, always re-assign the border style in case a sister
|
|
// radio button has changed the value.
|
|
if *w.StringVar == w.Value {
|
|
w.SetBorderStyle(BorderSunken)
|
|
} else {
|
|
w.SetBorderStyle(BorderRaised)
|
|
}
|
|
}
|
|
w.Button.Compute(e)
|
|
}
|
|
|
|
// setup the common things between checkboxes and radioboxes.
|
|
func (w *CheckButton) setup() {
|
|
var borderStyle BorderStyle = BorderRaised
|
|
if w.BoolVar != nil {
|
|
if *w.BoolVar == true {
|
|
borderStyle = BorderSunken
|
|
}
|
|
}
|
|
|
|
w.Configure(Config{
|
|
BorderSize: 2,
|
|
BorderStyle: borderStyle,
|
|
OutlineSize: 1,
|
|
OutlineColor: theme.ButtonOutlineColor,
|
|
Background: theme.ButtonBackgroundColor,
|
|
})
|
|
|
|
w.Handle("MouseOver", func(p render.Point) {
|
|
w.hovering = true
|
|
w.SetBackground(theme.ButtonHoverColor)
|
|
})
|
|
w.Handle("MouseOut", func(p render.Point) {
|
|
w.hovering = false
|
|
w.SetBackground(theme.ButtonBackgroundColor)
|
|
})
|
|
|
|
w.Handle("MouseDown", func(p render.Point) {
|
|
w.clicked = true
|
|
w.SetBorderStyle(BorderSunken)
|
|
})
|
|
w.Handle("MouseUp", func(p render.Point) {
|
|
w.clicked = false
|
|
})
|
|
|
|
w.Handle("MouseDown", func(p render.Point) {
|
|
var sunken bool
|
|
if w.BoolVar != nil {
|
|
if *w.BoolVar {
|
|
*w.BoolVar = false
|
|
} else {
|
|
*w.BoolVar = true
|
|
sunken = true
|
|
}
|
|
} else if w.StringVar != nil {
|
|
*w.StringVar = w.Value
|
|
sunken = true
|
|
}
|
|
|
|
if sunken {
|
|
w.SetBorderStyle(BorderSunken)
|
|
} else {
|
|
w.SetBorderStyle(BorderRaised)
|
|
}
|
|
})
|
|
}
|