Added checkbox.
Added utility methods for generating icons.
This commit is contained in:
parent
15f02d4d0e
commit
d072e202ab
114
ui/checkbox.go
Normal file
114
ui/checkbox.go
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
package ui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"opslag.de/schobers/geom"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Checkbox struct {
|
||||||
|
ControlBase
|
||||||
|
|
||||||
|
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.Renderer().Font(c.FontName(ctx))
|
||||||
|
var w, h float32 = 0, font.Height()
|
||||||
|
if len(c.Text) != 0 {
|
||||||
|
w += pad + font.WidthOf(c.Text)
|
||||||
|
}
|
||||||
|
icon, _ := ctx.Images().ScaledHeight(c.icon(ctx, false), h)
|
||||||
|
w += pad + icon.Width()
|
||||||
|
return geom.PtF32(w+pad, pad+h+pad)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Checkbox) icon(ctx Context, selected bool) Image {
|
||||||
|
if selected {
|
||||||
|
return GetOrCreateIcon(ctx, "ui-default-checkbox-selected", c.selectedIcon)
|
||||||
|
}
|
||||||
|
return GetOrCreateIcon(ctx, "ui-default-checkbox", c.normalIcon)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Checkbox) iconBorder() geom.PolygonF32 {
|
||||||
|
return geom.PolF32(
|
||||||
|
geom.PtF32(48, 80),
|
||||||
|
geom.PtF32(400, 80),
|
||||||
|
geom.PtF32(400, 432),
|
||||||
|
geom.PtF32(48, 432),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Checkbox) normalIcon() IconPixelTestFn {
|
||||||
|
border := c.iconBorder()
|
||||||
|
return func(pt geom.PointF32) bool {
|
||||||
|
return pt.DistanceToPolygon(border) < 48 && !pt.InPolygon(border)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Checkbox) selectedIcon() IconPixelTestFn {
|
||||||
|
border := c.iconBorder()
|
||||||
|
check := geom.PointsF32{
|
||||||
|
geom.PtF32(84, 256),
|
||||||
|
geom.PtF32(180, 352),
|
||||||
|
geom.PtF32(352, 150),
|
||||||
|
}
|
||||||
|
return func(pt geom.PointF32) bool {
|
||||||
|
if pt.DistanceToPolygon(border) < 48 || pt.InPolygon(border) {
|
||||||
|
return pt.DistanceToLines(check) > 24
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Checkbox) DesiredSize(ctx Context) geom.PointF32 { return c.desiredSize(ctx) }
|
||||||
|
|
||||||
|
func (c *Checkbox) Handle(ctx Context, e Event) {
|
||||||
|
switch e := e.(type) {
|
||||||
|
case *MouseButtonDownEvent:
|
||||||
|
if e.Button == MouseButtonLeft && c.over {
|
||||||
|
c.Selected = !c.Selected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.ControlBase.Handle(ctx, e)
|
||||||
|
if c.over {
|
||||||
|
ctx.Renderer().SetMouseCursor(MouseCursorPointer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Checkbox) Render(ctx Context) {
|
||||||
|
var style = ctx.Style()
|
||||||
|
var palette = style.Palette
|
||||||
|
fore := c.FontColor(ctx)
|
||||||
|
size := c.desiredSize(ctx)
|
||||||
|
bounds := c.bounds
|
||||||
|
deltaX, deltaY := bounds.Dx()-size.X, bounds.Dy()-size.Y
|
||||||
|
bounds.Min.X += .5 * deltaX
|
||||||
|
bounds.Min.Y += .5 * deltaY
|
||||||
|
|
||||||
|
var pad = style.Dimensions.TextPadding
|
||||||
|
bounds = bounds.Inset(pad)
|
||||||
|
pos := bounds.Min
|
||||||
|
icon, _ := ctx.Images().ScaledHeight(c.icon(ctx, c.Selected), bounds.Dy())
|
||||||
|
if icon != nil {
|
||||||
|
iconColor := fore
|
||||||
|
if c.Selected {
|
||||||
|
iconColor = palette.Primary
|
||||||
|
}
|
||||||
|
ctx.Renderer().DrawImageOptions(icon, geom.PtF32(pos.X, pos.Y+.5*(bounds.Dy()-icon.Height())), DrawOptions{Tint: iconColor})
|
||||||
|
pos.X += icon.Width() + pad
|
||||||
|
}
|
||||||
|
if len(c.Text) != 0 {
|
||||||
|
var fontName = c.FontName(ctx)
|
||||||
|
var font = ctx.Renderer().Font(fontName)
|
||||||
|
ctx.Renderer().Text(geom.PtF32(pos.X, pos.Y+.5*(bounds.Dy()-font.Height())), fontName, fore, c.Text)
|
||||||
|
}
|
||||||
|
}
|
@ -55,6 +55,12 @@ func run() error {
|
|||||||
ctx.Quit()
|
ctx.Quit()
|
||||||
})
|
})
|
||||||
}), 8),
|
}), 8),
|
||||||
|
ui.BuildStackPanel(ui.OrientationHorizontal, func(p *ui.StackPanel) {
|
||||||
|
p.Children = []ui.Control{
|
||||||
|
&ui.Checkbox{},
|
||||||
|
ui.BuildCheckbox("Check me!", nil),
|
||||||
|
}
|
||||||
|
}),
|
||||||
ui.Stretch(&ui.Label{Text: "Content"}),
|
ui.Stretch(&ui.Label{Text: "Content"}),
|
||||||
ui.StretchWidth(ui.BuildTextBox(func(b *ui.TextBox) {
|
ui.StretchWidth(ui.BuildTextBox(func(b *ui.TextBox) {
|
||||||
b.Text = "Type here..."
|
b.Text = "Type here..."
|
||||||
|
52
ui/icon.go
Normal file
52
ui/icon.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package ui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image"
|
||||||
|
"image/color"
|
||||||
|
|
||||||
|
"opslag.de/schobers/geom"
|
||||||
|
)
|
||||||
|
|
||||||
|
type IconPixelTestFn func(geom.PointF32) bool
|
||||||
|
|
||||||
|
func IconSize() geom.Point {
|
||||||
|
return geom.Pt(448, 512)
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateIcon(ctx Context, test IconPixelTestFn) Image {
|
||||||
|
icon := DrawIcon(test)
|
||||||
|
im, err := ctx.Renderer().CreateImage(icon)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return im
|
||||||
|
}
|
||||||
|
|
||||||
|
func DrawIcon(test IconPixelTestFn) image.Image {
|
||||||
|
size := IconSize()
|
||||||
|
r := image.Rect(0, 0, size.X, size.Y)
|
||||||
|
icon := image.NewRGBA(r)
|
||||||
|
for y := 0; y < size.Y; y++ {
|
||||||
|
for x := 0; x < size.X; x++ {
|
||||||
|
pt := geom.PtF32(float32(x), float32(y))
|
||||||
|
if test(pt) {
|
||||||
|
icon.Set(x, y, color.White)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return icon
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetOrCreateIcon(ctx Context, name string, testFactory func() IconPixelTestFn) Image {
|
||||||
|
im := ctx.Images().Image(name)
|
||||||
|
if im != nil {
|
||||||
|
return im
|
||||||
|
}
|
||||||
|
test := testFactory()
|
||||||
|
im = CreateIcon(ctx, test)
|
||||||
|
if im == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
ctx.Images().AddImage(name, im)
|
||||||
|
return im
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user