2018-07-25 16:03:49 +00:00
|
|
|
package ui
|
|
|
|
|
|
|
|
import "git.kirsle.net/apps/doodle/render"
|
|
|
|
|
|
|
|
// Widget is a user interface element.
|
|
|
|
type Widget interface {
|
|
|
|
Point() render.Point
|
2018-07-26 02:38:54 +00:00
|
|
|
MoveTo(render.Point)
|
|
|
|
MoveBy(render.Point)
|
2018-07-25 16:03:49 +00:00
|
|
|
Size() render.Rect // Return the Width and Height of the widget.
|
|
|
|
Resize(render.Rect)
|
|
|
|
|
2018-07-26 03:25:02 +00:00
|
|
|
Handle(string, func(render.Point))
|
|
|
|
Event(string, render.Point) // called internally to trigger an event
|
|
|
|
|
2018-07-25 16:03:49 +00:00
|
|
|
// 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 {
|
2018-07-26 03:25:02 +00:00
|
|
|
width int32
|
|
|
|
height int32
|
|
|
|
point render.Point
|
|
|
|
handlers map[string][]func(render.Point)
|
2018-07-25 16:03:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Point returns the X,Y position of the widget on the window.
|
|
|
|
func (w *BaseWidget) Point() render.Point {
|
|
|
|
return w.point
|
|
|
|
}
|
|
|
|
|
2018-07-26 02:38:54 +00:00
|
|
|
// MoveTo updates the X,Y position to the new point.
|
|
|
|
func (w *BaseWidget) MoveTo(v render.Point) {
|
2018-07-25 16:03:49 +00:00
|
|
|
w.point = v
|
|
|
|
}
|
|
|
|
|
2018-07-26 02:38:54 +00:00
|
|
|
// 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
|
|
|
|
}
|
|
|
|
|
2018-07-25 16:03:49 +00:00
|
|
|
// 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
|
|
|
|
}
|
2018-07-26 03:25:02 +00:00
|
|
|
|
|
|
|
// 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) {}
|