74 lines
1.4 KiB
Go
74 lines
1.4 KiB
Go
|
package alui
|
||
|
|
||
|
import (
|
||
|
"opslag.de/schobers/allg5"
|
||
|
"opslag.de/schobers/geom"
|
||
|
)
|
||
|
|
||
|
type Control interface {
|
||
|
Bounds() geom.RectangleF32
|
||
|
|
||
|
Handle(allg5.Event)
|
||
|
|
||
|
DesiredSize(*Context) geom.PointF32
|
||
|
Layout(*Context, geom.RectangleF32)
|
||
|
Render(*Context, geom.RectangleF32)
|
||
|
}
|
||
|
|
||
|
type Bounds struct {
|
||
|
value geom.RectangleF32
|
||
|
}
|
||
|
|
||
|
var _ Control = &ControlBase{}
|
||
|
|
||
|
type ControlBase struct {
|
||
|
_Bounds geom.RectangleF32
|
||
|
Over bool
|
||
|
Font string
|
||
|
Foreground *allg5.Color
|
||
|
Background *allg5.Color
|
||
|
|
||
|
OnClick func()
|
||
|
OnEnter func()
|
||
|
OnLeave func()
|
||
|
}
|
||
|
|
||
|
func MouseEventToPos(e allg5.MouseEvent) geom.PointF32 { return geom.PtF32(float32(e.X), float32(e.Y)) }
|
||
|
|
||
|
func (b *ControlBase) DesiredSize(*Context) geom.PointF32 { return geom.ZeroPtF32 }
|
||
|
|
||
|
func (b *ControlBase) Handle(e allg5.Event) {
|
||
|
switch e := e.(type) {
|
||
|
case *allg5.MouseMoveEvent:
|
||
|
pos := MouseEventToPos(e.MouseEvent)
|
||
|
over := pos.In(b._Bounds)
|
||
|
if over != b.Over {
|
||
|
b.Over = over
|
||
|
if over {
|
||
|
if b.OnEnter != nil {
|
||
|
b.OnEnter()
|
||
|
}
|
||
|
} else {
|
||
|
if b.OnLeave != nil {
|
||
|
b.OnLeave()
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
case *allg5.MouseButtonDownEvent:
|
||
|
if !b.Over {
|
||
|
break
|
||
|
}
|
||
|
if e.Button == allg5.MouseButtonLeft {
|
||
|
if b.OnClick != nil {
|
||
|
b.OnClick()
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (b *ControlBase) Layout(_ *Context, bounds geom.RectangleF32) { b._Bounds = bounds }
|
||
|
|
||
|
func (b *ControlBase) Render(*Context, geom.RectangleF32) {}
|
||
|
|
||
|
func (b *ControlBase) Bounds() geom.RectangleF32 { return b._Bounds }
|