134 lines
3.0 KiB
Go
134 lines
3.0 KiB
Go
|
package ui
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"image"
|
||
|
"image/color"
|
||
|
|
||
|
"github.com/llgcode/draw2d/draw2dimg"
|
||
|
"github.com/llgcode/draw2d/draw2dkit"
|
||
|
"opslag.de/schobers/galleg/allegro5"
|
||
|
"opslag.de/schobers/geom"
|
||
|
)
|
||
|
|
||
|
type CheckboxValueChangedFn func(bool)
|
||
|
|
||
|
func createOnBitmap(fill, stroke color.Color) *allegro5.Bitmap {
|
||
|
var sz = float64(checkboxSize)
|
||
|
on := image.NewRGBA(image.Rect(0, 0, checkboxSize, checkboxSize))
|
||
|
|
||
|
gc := draw2dimg.NewGraphicContext(on)
|
||
|
gc.SetFillColor(color.Transparent)
|
||
|
gc.Clear()
|
||
|
gc.SetFillColor(fill)
|
||
|
draw2dkit.RoundedRectangle(gc, 0, 0, sz, sz, 3, 3)
|
||
|
gc.Fill()
|
||
|
|
||
|
gc.SetStrokeColor(stroke)
|
||
|
gc.SetLineWidth(2)
|
||
|
gc.MoveTo(2.5, 5.5)
|
||
|
gc.LineTo(5.5, 8.5)
|
||
|
gc.LineTo(10, 3.5)
|
||
|
gc.Stroke()
|
||
|
|
||
|
bmp, err := allegro5.NewBitmapFromImage(on, false)
|
||
|
if nil != err {
|
||
|
return nil
|
||
|
}
|
||
|
return bmp
|
||
|
}
|
||
|
|
||
|
func createOffBitmap(fill, stroke color.Color) *allegro5.Bitmap {
|
||
|
var sz = float64(checkboxSize)
|
||
|
off := image.NewRGBA(image.Rect(0, 0, checkboxSize, checkboxSize))
|
||
|
|
||
|
gc := draw2dimg.NewGraphicContext(off)
|
||
|
gc.SetFillColor(color.Transparent)
|
||
|
gc.Clear()
|
||
|
gc.SetFillColor(stroke)
|
||
|
draw2dkit.RoundedRectangle(gc, 0, 0, sz, sz, 4, 4)
|
||
|
gc.Fill()
|
||
|
gc.SetFillColor(fill)
|
||
|
draw2dkit.RoundedRectangle(gc, 1, 1, sz-1, sz-1, 3, 3)
|
||
|
gc.Fill()
|
||
|
|
||
|
bmp, err := allegro5.NewBitmapFromImage(off, false)
|
||
|
if nil != err {
|
||
|
return nil
|
||
|
}
|
||
|
return bmp
|
||
|
}
|
||
|
|
||
|
type Checkbox struct {
|
||
|
ControlBase
|
||
|
Value bool
|
||
|
Text string
|
||
|
OnChanged CheckboxValueChangedFn
|
||
|
on *allegro5.Bitmap
|
||
|
off *allegro5.Bitmap
|
||
|
}
|
||
|
|
||
|
func (c *Checkbox) Created(ctx Context, p Container) error {
|
||
|
var err = c.ControlBase.Created(ctx, p)
|
||
|
if nil != err {
|
||
|
return err
|
||
|
}
|
||
|
var plt = ctx.Palette()
|
||
|
c.on = createOnBitmap(plt.Primary(), plt.White())
|
||
|
c.off = createOffBitmap(plt.White(), plt.Black())
|
||
|
if nil == c.on || nil == c.off {
|
||
|
return fmt.Errorf("error creating checkboxes")
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (c *Checkbox) Handle(ctx Context, ev allegro5.Event) {
|
||
|
var pressed = c.IsPressed
|
||
|
c.ControlBase.Handle(ctx, ev)
|
||
|
switch ev.(type) {
|
||
|
case *allegro5.MouseButtonUpEvent:
|
||
|
if !c.Disabled && pressed && c.IsOver {
|
||
|
c.Value = !c.Value
|
||
|
var onChanged = c.OnChanged
|
||
|
if nil != onChanged {
|
||
|
onChanged(c.Value)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (c *Checkbox) DesiredSize(ctx Context) geom.PointF {
|
||
|
var fonts = ctx.Fonts()
|
||
|
var fnt = fonts.Get("default")
|
||
|
var w = fnt.TextWidth(c.Text)
|
||
|
return geom.PtF(float64(w+2*leftMargin+checkboxSize), 24)
|
||
|
}
|
||
|
|
||
|
func (c *Checkbox) box() *allegro5.Bitmap {
|
||
|
if c.Value {
|
||
|
return c.on
|
||
|
}
|
||
|
return c.off
|
||
|
}
|
||
|
|
||
|
func (c *Checkbox) Render(ctx Context) {
|
||
|
var fonts = ctx.Fonts()
|
||
|
|
||
|
var min = c.Bounds.Min.To32()
|
||
|
min = geom.PointF32{X: min.X + leftMargin, Y: min.Y + topMargin}
|
||
|
|
||
|
var fnt = fonts.Get("default")
|
||
|
|
||
|
var _, textY, _, textH = fnt.TextDims(c.Text)
|
||
|
fnt.Draw(min.X+leftMargin+checkboxSize, min.Y-textY, ctx.Palette().Black(), allegro5.AlignLeft, c.Text)
|
||
|
var checkboxTop = min.Y + textH - checkboxSize
|
||
|
if c.Disabled {
|
||
|
var disabled = ctx.Palette().Disabled()
|
||
|
c.box().DrawOptions(min.X, checkboxTop, allegro5.DrawOptions{Tint: &disabled})
|
||
|
} else {
|
||
|
c.box().Draw(min.X, checkboxTop)
|
||
|
}
|
||
|
|
||
|
c.ControlBase.Render(ctx)
|
||
|
}
|