Files
8bitMyGoUI/layout/handheld.go
T

96 lines
3.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package layout
import (
"log/slog"
"github.com/egoist/mygo/ui"
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/pixel"
)
type HandheldOptions struct {
// ScreenW×ScreenH is the screen in dots; zero means 160×144.
ScreenW, ScreenH int
// Brand is micro text on the body.
Brand string
Label string
Disabled bool
}
type HandheldResult struct {
Element *ui.Element
Up, Down, Left, Right, A, B bool
}
const bezel = 8
// Handheld is a pocket console around screen; buttons report presses.
func Handheld(c *ui.Context, o HandheldOptions, screen func()) HandheldResult {
k := pixel.K(c)
sw, sh := orDef("Handheld ScreenW", o.ScreenW, 160), orDef("Handheld ScreenH", o.ScreenH, 144)
res := HandheldResult{}
res.Element = ui.Column(c).Width(k.D(sw + 2*bezel + 40)).Padding(k.D(10)).Gap(k.D(6)).AlignItems(ui.Center).Role(ui.RoleGroup).Label(o.Label).Draw(func(p *ui.Painter, r ui.Rect) {
g := k.Canvas(p, r)
box(g, pixel.Raised, pixel.Face)
g.Micro(10, g.H-9, o.Brand, pixel.Shade, 1)
}).Children(func() {
ui.Box(c).Padding(k.D(bezel), k.D(bezel+10), k.D(bezel), k.D(bezel+10)).Draw(func(p *ui.Painter, r ui.Rect) {
g := k.Canvas(p, r)
box(g, pixel.Sunken, pixel.Shade)
led := pixel.Good
if o.Disabled {
led = pixel.Faint
}
g.Rect(5, g.H/2-1, 3, 3, led)
}).Children(func() {
ui.Box(c).Size(k.D(sw), k.D(sh)).Children(screen)
})
ui.Box(c).Width(k.D(sw + 2*bezel + 20)).Height(k.D(44)).Draw(func(p *ui.Painter, r ui.Rect) {
g := k.Canvas(p, r)
g.Rect(15, 18, 9, 9, pixel.Edge)
}).Children(func() {
pad := func(name string, x, y, w, h int) bool { return key(c, k, name, x, y, w, h, false, o.Disabled) }
res.Up = pad(k.Msg("up"), 15, 7, 9, 11)
res.Left = pad(k.Msg("left"), 4, 18, 11, 9)
res.Right = pad(k.Msg("right"), 24, 18, 11, 9)
res.Down = pad(k.Msg("down"), 15, 27, 9, 11)
right := sw + 2*bezel + 20
res.B = key(c, k, "B", right-44, 18, 15, 15, true, o.Disabled)
res.A = key(c, k, "A", right-24, 10, 15, 15, true, o.Disabled)
})
})
for name, on := range map[string]bool{"up": res.Up, "down": res.Down, "left": res.Left, "right": res.Right, "a": res.A, "b": res.B} {
if on {
slog.Debug("8bit: handheld press", "button", name)
}
}
return res
}
// key is a d-pad arm, or a round button.
func key(c *ui.Context, k pixel.Kit, name string, x, y, w, h int, round, disabled bool) bool {
shell, base, st := pixel.Shell(c, func() *ui.Element { return ui.ButtonBase(c).Label(name).Disabled(disabled) })
shell.Absolute().Left(k.D(x)).Top(k.D(y)).Size(k.D(w), k.D(h)).Draw(func(p *ui.Painter, r ui.Rect) {
g := k.Canvas(p, r)
dy := 0
if st.Press {
dy = 1
}
if round {
g.Disc(w/2, h/2, w/2, pixel.Edge)
g.Disc(w/2, h/2-1+dy, w/2-1, pixel.Accent)
g.Micro(w/2-1, h/2-3+dy, name, pixel.AccentInk, 1)
} else {
g.Rect(0, dy, g.W, g.H-dy, pixel.Edge)
g.Rect(1, 1+dy, g.W-2, 1, pixel.Faint)
}
if st.Disabled {
g.Checker(0, 0, g.W, g.H, pixel.Face)
}
if st.Focus {
g.FocusMark(0, 0, g.W, g.H)
}
})
return base.Clicked()
}