Noah Petherbridge
602273aa16
The Buttons can now be managed by a ui.Supervisor and be notified when the mouse enters or leaves their bounding box and handle click events. Current event handlers supported: * MouseOver * MouseOut * MouseDown * MouseUp * Click Each of those events are only fired when the state of the event has changed, i.e. the first time the mouse enters the widget MouseOver is called and then when the mouse leaves later, MouseOut is called. A completed click event (mouse was released while pressed and hovering the button) triggers both MouseOut and Click, so the button can pop itself out and also run the click handler.
89 lines
2.3 KiB
Go
89 lines
2.3 KiB
Go
package ui
|
|
|
|
import "git.kirsle.net/apps/doodle/render"
|
|
|
|
// Widget is a user interface element.
|
|
type Widget interface {
|
|
Point() render.Point
|
|
MoveTo(render.Point)
|
|
MoveBy(render.Point)
|
|
Size() render.Rect // Return the Width and Height of the widget.
|
|
Resize(render.Rect)
|
|
|
|
Handle(string, func(render.Point))
|
|
Event(string, render.Point) // called internally to trigger an event
|
|
|
|
// Run any render computations; by the end the widget must know its
|
|
// Width and Height. For example the Label widget will render itself onto
|
|
// an SDL Surface and then it will know its bounding box, but not before.
|
|
Compute(render.Engine)
|
|
|
|
// Render the final widget onto the drawing engine.
|
|
Present(render.Engine)
|
|
}
|
|
|
|
// BaseWidget holds common functionality for all widgets, such as managing
|
|
// their widths and heights.
|
|
type BaseWidget struct {
|
|
width int32
|
|
height int32
|
|
point render.Point
|
|
handlers map[string][]func(render.Point)
|
|
}
|
|
|
|
// Point returns the X,Y position of the widget on the window.
|
|
func (w *BaseWidget) Point() render.Point {
|
|
return w.point
|
|
}
|
|
|
|
// MoveTo updates the X,Y position to the new point.
|
|
func (w *BaseWidget) MoveTo(v render.Point) {
|
|
w.point = v
|
|
}
|
|
|
|
// MoveBy adds the X,Y values to the widget's current position.
|
|
func (w *BaseWidget) MoveBy(v render.Point) {
|
|
w.point.X += v.X
|
|
w.point.Y += v.Y
|
|
}
|
|
|
|
// Size returns the box with W and H attributes containing the size of the
|
|
// widget. The X,Y attributes of the box are ignored and zero.
|
|
func (w *BaseWidget) Size() render.Rect {
|
|
return render.Rect{
|
|
W: w.width,
|
|
H: w.height,
|
|
}
|
|
}
|
|
|
|
// Resize sets the size of the widget to the .W and .H attributes of a rect.
|
|
func (w *BaseWidget) Resize(v render.Rect) {
|
|
w.width = v.W
|
|
w.height = v.H
|
|
}
|
|
|
|
// Event is called internally by Doodle to trigger an event.
|
|
func (w *BaseWidget) Event(name string, p render.Point) {
|
|
if handlers, ok := w.handlers[name]; ok {
|
|
for _, fn := range handlers {
|
|
fn(p)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Handle an event in the widget.
|
|
func (w *BaseWidget) Handle(name string, fn func(render.Point)) {
|
|
if w.handlers == nil {
|
|
w.handlers = map[string][]func(render.Point){}
|
|
}
|
|
|
|
if _, ok := w.handlers[name]; !ok {
|
|
w.handlers[name] = []func(render.Point){}
|
|
}
|
|
|
|
w.handlers[name] = append(w.handlers[name], fn)
|
|
}
|
|
|
|
// OnMouseOut should be overridden on widgets who want this event.
|
|
func (w *BaseWidget) OnMouseOut(render.Point) {}
|