zntg/ui/controlbase.go
2019-03-06 18:22:30 +01:00

134 lines
2.9 KiB
Go

package ui
import (
"image/color"
"opslag.de/schobers/geom"
)
type ClickFn func(ctx Context, c Control, pos geom.PointF32, btn MouseButton)
type DragEndFn func(ctx Context, c Control, start, end geom.PointF32)
type DragMoveFn func(ctx Context, c Control, start, move geom.PointF32)
type DragStartFn func(ctx Context, c Control, start geom.PointF32)
type MouseEnterFn func(ctx Context, c Control)
type MouseLeaveFn func(ctx Context, c Control)
var _ Control = &ControlBase{}
type ControlBase struct {
bounds geom.RectangleF32
offset geom.PointF32
dragStart *geom.PointF32
over bool
pressed bool
onClick ClickFn
onDragEnd DragEndFn
onDragMove DragMoveFn
onDragStart DragStartFn
Background color.Color
FontName string
FontColor color.Color
}
func (c *ControlBase) Arrange(ctx Context, bounds geom.RectangleF32, offset geom.PointF32) {
c.bounds = bounds
c.offset = offset
}
func (c *ControlBase) Bounds() geom.RectangleF32 {
return c.bounds
}
func (c *ControlBase) DesiredSize(Context) geom.PointF32 {
return geom.ZeroPtF32
}
func (c *ControlBase) Handle(ctx Context, e Event) {
var pos = func(e MouseEvent) geom.PointF32 { return e.Pos().Sub(c.offset) }
var over = func(e MouseEvent) bool {
c.over = pos(e).In(c.bounds)
return c.over
}
switch e := e.(type) {
case *MouseMoveEvent:
over(e.MouseEvent)
if c.pressed {
if c.dragStart == nil {
var start = pos(e.MouseEvent)
c.dragStart = &start
if c.onDragStart != nil {
c.onDragStart(ctx, c, start)
}
} else {
var start = *c.dragStart
var move = pos(e.MouseEvent)
if c.onDragMove != nil {
c.onDragMove(ctx, c, start, move)
}
}
}
case *MouseButtonDownEvent:
if over(e.MouseEvent) && 1 == e.Button {
c.pressed = true
}
case *MouseButtonUpEvent:
if 1 == e.Button {
if c.dragStart != nil {
var start = *c.dragStart
var end = pos(e.MouseEvent)
c.dragStart = nil
if c.onDragEnd != nil {
c.onDragEnd(ctx, c, start, end)
}
}
if c.pressed {
if c.onClick != nil {
c.onClick(ctx, c, pos(e.MouseEvent), e.Button)
}
}
c.pressed = false
}
}
}
func (c *ControlBase) IsOver() bool { return c.over }
func (c *ControlBase) IsPressed() bool { return c.pressed }
func (c *ControlBase) Offset() geom.PointF32 { return c.offset }
func (c *ControlBase) OnClick(fn ClickFn) {
c.onClick = fn
}
func (c *ControlBase) OnDragStart(fn DragStartFn) {
c.onDragStart = fn
}
func (c *ControlBase) OnDragMove(fn DragMoveFn) {
c.onDragMove = fn
}
func (c *ControlBase) OnDragEnd(fn DragEndFn) {
c.onDragEnd = fn
}
func (c *ControlBase) RenderBackground(ctx Context) {
if c.Background != nil {
ctx.Renderer().FillRectangle(c.bounds, c.Background)
}
}
func (c *ControlBase) Render(Context) {
}
func (c *ControlBase) fontName(ctx Context) string {
var name = c.FontName
if len(name) == 0 {
name = ctx.Style().Fonts.Default
}
return name
}