doodle/ui/button.go
Noah Petherbridge 11df6cbda9 Move most properties from Button to parent Widget
These properties will be globally useful to all sorts of Widgets and
have been moved from the Button up into the Common widget, and its
interface extended to configure these:
* Padding int32
* Background color
* Foreground color
* Border size, color and style (default solid; raised; sunken)
* Outline size and color

The button adjusts its border style from "raised" to "sunken" for
MouseDown events and its Background color for MouseOver events. Other
widgets such as Labels and Frames will be able to have borders, paddings
and outlines too, but they will be off by default.
2018-07-25 21:24:37 -07:00

89 lines
1.8 KiB
Go

package ui
import (
"git.kirsle.net/apps/doodle/render"
"git.kirsle.net/apps/doodle/ui/theme"
)
// Button is a clickable button.
type Button struct {
BaseWidget
Label Label
// Private options.
hovering bool
clicked bool
}
// NewButton creates a new Button.
func NewButton(label Label) *Button {
w := &Button{
Label: label,
}
w.SetPadding(4)
w.SetBorderSize(2)
w.SetBorderStyle(BorderRaised)
w.SetOutlineSize(1)
w.SetOutlineColor(theme.ButtonOutlineColor)
w.SetBackground(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.SetBorderStyle(BorderRaised)
})
return w
}
// SetText quickly changes the text of the label.
func (w *Button) SetText(text string) {
w.Label.Text.Text = text
}
// Compute the size of the button.
func (w *Button) Compute(e render.Engine) {
// Compute the size of the inner widget first.
w.Label.Compute(e)
size := w.Label.Size()
w.Resize(render.Rect{
W: size.W + w.BoxThickness(2),
H: size.H + w.BoxThickness(2),
})
}
// Present the button.
func (w *Button) Present(e render.Engine) {
w.Compute(e)
P := w.Point()
// Draw the widget's border and everything.
w.DrawBox(e)
// Offset further if we are currently sunken.
var clickOffset int32
if w.clicked {
clickOffset++
}
// Draw the text label inside.
w.Label.MoveTo(render.Point{
X: P.X + w.BoxThickness(1) + clickOffset,
Y: P.Y + w.BoxThickness(1) + clickOffset,
})
w.Label.Present(e)
}