zntg/ui/checkbox.go
Sander Schobers 0f03760e66 Added Resize & SetIcon to Renderer.
Refactored Size (on Renderer) to return geom.Point instead of geom.PointF32.
Refactored Width and Height (on Texture) to return int instead of float32.

Refactored texture dimensions to be represented by ints instead of float32s.
2020-12-13 07:40:19 +01:00

136 lines
3.5 KiB
Go

package ui
import (
"opslag.de/schobers/geom"
)
type Checkbox struct {
ControlBase
selectedChanged Events
Selected bool
Text string
}
func BuildCheckbox(text string, fn func(c *Checkbox)) *Checkbox {
var c = &Checkbox{Text: text}
if fn != nil {
fn(c)
}
return c
}
func (c *Checkbox) desiredSize(ctx Context) geom.PointF32 {
var pad = ctx.Style().Dimensions.TextPadding
var font = ctx.Fonts().Font(c.FontName(ctx))
var w, h float32 = 0, font.Height()
if len(c.Text) != 0 {
w += pad + font.WidthOf(c.Text)
}
icon := c.getOrCreateNormalIcon(ctx)
_, iconWidth := ScaleToHeight(SizeOfTexture(icon).ToF32(), h)
w += pad + iconWidth
return geom.PtF32(w+pad, pad+h+pad)
}
func (c *Checkbox) icon(ctx Context) Texture {
if c.Selected {
return GetOrCreateIcon(ctx, "ui-default-checkbox-selected", c.selectedIcon)
} else if c.over && !c.Disabled {
return GetOrCreateIcon(ctx, "ui-default-checkbox-hover", c.hoverIcon)
}
return c.getOrCreateNormalIcon(ctx)
}
func (c *Checkbox) getOrCreateNormalIcon(ctx Context) Texture {
return GetOrCreateIcon(ctx, "ui-default-checkbox", c.normalIcon)
}
var checkBoxIconBorder = geom.PolF32(
geom.PtF32(48, 80),
geom.PtF32(400, 80),
geom.PtF32(400, 432),
geom.PtF32(48, 432),
)
var checkBoxCheckMark = geom.PointsF32{
geom.PtF32(96, 256),
geom.PtF32(180, 340),
geom.PtF32(340, 150),
}
func (c *Checkbox) hoverIcon(pt geom.PointF32) bool {
return (pt.DistanceToPolygon(checkBoxIconBorder) < 48 && !pt.InPolygon(checkBoxIconBorder)) || pt.DistanceToLines(checkBoxCheckMark) < 24
}
func (c *Checkbox) normalIcon(pt geom.PointF32) bool {
return pt.DistanceToPolygon(checkBoxIconBorder) < 48 && !pt.InPolygon(checkBoxIconBorder)
}
func (c *Checkbox) selectedIcon(pt geom.PointF32) bool {
if pt.DistanceToPolygon(checkBoxIconBorder) < 48 || pt.InPolygon(checkBoxIconBorder) {
return pt.DistanceToLines(checkBoxCheckMark) > 24
}
return false
}
func (c *Checkbox) DesiredSize(ctx Context, _ geom.PointF32) geom.PointF32 { return c.desiredSize(ctx) }
func (c *Checkbox) Handle(ctx Context, e Event) bool {
result := c.ControlBase.Handle(ctx, e)
if c.over {
if c.Disabled {
return true
}
ctx.Renderer().SetMouseCursor(MouseCursorPointer)
}
if result {
return true
}
switch e := e.(type) {
case *MouseButtonDownEvent:
if e.Button == MouseButtonLeft && c.over {
c.Selected = !c.Selected
return c.selectedChanged.Notify(ctx, c.Selected)
}
}
return false
}
func (c *Checkbox) SelectedChanged() EventHandler { return &c.selectedChanged }
func (c *Checkbox) Render(ctx Context) {
c.RenderBackground(ctx)
var style = ctx.Style()
var palette = style.Palette
fore := c.TextColor(ctx)
bounds := c.bounds
var pad = style.Dimensions.TextPadding
bounds = bounds.Inset(pad)
boundsH := bounds.Dy()
pos := bounds.Min
icon := c.icon(ctx)
if icon != nil {
iconColor := fore
if c.Selected {
iconColor = c.FontColor(ctx, palette.Primary)
}
scaledIcon, _ := ctx.Textures().ScaledHeight(icon, boundsH) // try to pre-scale icon
if scaledIcon == nil { // let the renderer scale
scaledIcon = icon
}
_, iconWidth := ScaleToHeight(SizeOfTexture(scaledIcon).ToF32(), boundsH)
rect := geom.RectRelF32(pos.X, pos.Y, iconWidth, boundsH)
ctx.Renderer().DrawTextureOptions(scaledIcon, rect, DrawOptions{Tint: iconColor})
pos.X += iconWidth + pad
}
if len(c.Text) != 0 {
var fontName = c.FontName(ctx)
var font = ctx.Fonts().Font(fontName)
ctx.Renderer().Text(font, geom.PtF32(pos.X, pos.Y+.5*(boundsH-font.Height())), fore, c.Text)
}
}