zntg/ui/checkbox.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)
}