package ui import ( "time" "opslag.de/schobers/zntg/allg5" "opslag.de/schobers/geom" ) type Control interface { Created(Context, Container) error Destroyed(Context) Update(Context, time.Duration) Handle(Context, allg5.Event) DesiredSize(Context) geom.PointF Rect() geom.RectangleF SetRect(geom.RectangleF) Render(Context) } type MouseClickFn func(Control) var _ Control = &ControlBase{} type ControlBase struct { Parent Container Bounds geom.RectangleF Disabled bool IsOver bool IsPressed bool OnClick MouseClickFn MinSize geom.PointF Background *allg5.Color } func (c *ControlBase) Created(_ Context, p Container) error { c.Parent = p return nil } func (c *ControlBase) Destroyed(Context) {} func (c *ControlBase) Update(Context, time.Duration) {} func (c *ControlBase) Handle(ctx Context, ev allg5.Event) { switch e := ev.(type) { case *allg5.MouseMoveEvent: c.IsOver = c.IsInRect(float64(e.X), float64(e.Y)) case *allg5.MouseButtonDownEvent: if c.IsOver { c.IsPressed = true } case *allg5.MouseButtonUpEvent: if c.IsPressed && c.IsOver { var onClick = c.OnClick if nil != onClick { onClick(c) } } c.IsPressed = false } } func (c *ControlBase) DesiredSize(Context) geom.PointF { return c.MinSize } func (c *ControlBase) SetRect(rect geom.RectangleF) { c.Bounds = rect } func (c *ControlBase) Render(ctx Context) { var min = c.Bounds.Min.To32() var max = c.Bounds.Max.To32() if nil != c.Background { allg5.DrawFilledRectangle(min.X, min.Y, max.X, max.Y, *c.Background) } if ctx.Debug().IsEnabled() { allg5.DrawRectangle(min.X, min.Y, max.X, max.Y, ctx.Debug().Rainbow(), 5) } } func (c *ControlBase) Rect() geom.RectangleF { return c.Bounds } func (c *ControlBase) IsInRect(x, y float64) bool { return geom.PtF(x, y).In(c.Bounds) }