Add navigation components 131-150; pixel Pad, Finish, Park, Since

This commit is contained in:
ZacharyZhang-NY committed 2026-10-11 21:27:09 -04:00
1 parent bd3877e1b1
commit f587d25a5a
63 files changed
+2776 -87

No files matched your search

+1 -1
View File
@@ -66,7 +66,7 @@ func Button(c *ui.Context, text string, o ButtonOptions) ButtonResult {
if text != "" {
g.Text(x, top+dy, text, ink, sc)
}
finish(g, st)
g.Finish(st)
})
res := ButtonResult{Element: shell, Clicked: base.Clicked()}
if res.Clicked {
+1 -1
View File
@@ -38,7 +38,7 @@ func ButtonGroup(c *ui.Context, labels []string, o ButtonGroupOptions) ButtonGro
g := k.Canvas(p, r)
ink, dy := face(g, o.Variant, st, false)
g.Text(pad, top+dy, l, ink, sc)
finish(g, st)
g.Finish(st)
})
if base.Clicked() {
res.Clicked = i
+1 -1
View File
@@ -82,7 +82,7 @@ func CheatCode(c *ui.Context, text string, o CheatCodeOptions) CheatCodeResult {
}
glyph(g, 2+i*10, 4, key, kink)
}
finish(g, st)
g.Finish(st)
})
return res
}
+1 -1
View File
@@ -64,5 +64,5 @@ func box(g pixel.Canvas, text string, mark *pixel.Sprite, st pixel.State) {
ink = pixel.Faint
}
g.Text(12, 0, text, ink, 1)
finish(g, st)
g.Finish(st)
}
+2 -2
View File
@@ -21,7 +21,7 @@ type ColorSlotResult struct {
func ColorSlot(c *ui.Context, text string, value *pixel.Slot, o ColorSlotOptions) ColorSlotResult {
k := pixel.K(c)
cur := int(*value)
shell, base, st, _ := pad(c, text, 8, pixel.Slots, 12, 12, &cur, o.Disabled)
shell, base, st, _ := pixel.Pad(c, text, 8, pixel.Slots, 12, 12, &cur, o.Disabled)
res := ColorSlotResult{Element: shell, Changed: pixel.Slot(cur) != *value}
*value = pixel.Slot(cur)
base.Description(value.String())
@@ -36,7 +36,7 @@ func ColorSlot(c *ui.Context, text string, value *pixel.Slot, o ColorSlotOptions
g.Rect(x+2, y+2, 8, 8, pixel.Edge)
g.Rect(x+3, y+3, 6, 6, pixel.Slot(i))
}
finish(g, st)
g.Finish(st)
})
if res.Changed {
slog.Debug("8bit: color slot", "label", text, "slot", *value)
+1 -1
View File
@@ -95,7 +95,7 @@ func DPad(c *ui.Context, text string, o DPadOptions) DPadResult {
g.Sprite(a.x+(a.w-a.sp.W)/2, a.y+(a.h-a.sp.H)/2+dy, a.sp, 0, pixel.Ink, 1)
}
g.Rect(13, 13, 10, 10, pixel.Shade)
finish(g, st)
g.Finish(st)
})
return res
}
+1 -1
View File
@@ -73,7 +73,7 @@ func EditableText(c *ui.Context, text string, value *string, o EditableTextOptio
}
g.Text(4, 3, shown, ink, 1)
g.Veil(0, g.H-1, g.W, 1, pixel.Faint, 8)
finish(g, st)
g.Finish(st)
})
})
if res.Changed {
+1 -1
View File
@@ -33,7 +33,7 @@ func Fader(c *ui.Context, text string, value *float64, o FaderOptions) FaderResu
g.Rect(7, y+3, 2, g.H-y-4, pixel.Accent)
g.Frame(2, y, 12, 7, pixel.Raised, pixel.Face)
g.HLine(4, y+3, 8, pixel.Edge)
finish(g, st)
g.Finish(st)
})
return report(shell, changed, "fader", text, *value)
}
+1 -1
View File
@@ -93,7 +93,7 @@ func HoldButton(c *ui.Context, text string, o HoldButtonOptions) HoldButtonResul
g.Rect(1, 1+dy, w, g.H-2-dy, fill)
g.Text(8, 2+dy, text, ink, 1)
g.Clip(1, 0, w, g.H, func() { g.Text(8, 2+dy, text, pixel.AccentInk, 1) })
finish(g, st)
g.Finish(st)
})
return res
}
-10
View File
@@ -78,16 +78,6 @@ func face(g pixel.Canvas, v Variant, st pixel.State, on bool) (ink pixel.Slot, d
return ink, dy
}
// finish dithers out a disabled control and marks focus.
func finish(g pixel.Canvas, st pixel.State) {
if st.Disabled {
g.Checker(0, 0, g.W, g.H, pixel.Face)
}
if st.Focus {
g.FocusMark(0, 0, g.W, g.H)
}
}
// label is s, or the fallback when s is empty.
func label(s, fallback string) string {
if s != "" {
+1 -1
View File
@@ -79,7 +79,7 @@ func Joystick(c *ui.Context, text string, o JoystickOptions) JoystickResult {
g.Disc(x, y, 7, pixel.Edge)
g.Disc(x, y, 6, pixel.Accent)
g.Disc(x-2, y-2, 2, pixel.AccentLit)
finish(g, st)
g.Finish(st)
})
return JoystickResult{Element: shell, X: s.x, Y: s.y, Moved: s.x != ox || s.y != oy}
}
+1 -1
View File
@@ -49,7 +49,7 @@ func Knob(c *ui.Context, text string, value *float64, o KnobOptions) KnobResult
x, y := 12+int(math.Round(7*math.Sin(a))), 12-int(math.Round(7*math.Cos(a)))
g.Line(12, 12, x, y, pixel.Accent)
g.Dot(x, y, pixel.Ink)
finish(g, st)
g.Finish(st)
})
return report(shell, *value != old, "knob", text, *value)
}
+1 -1
View File
@@ -49,7 +49,7 @@ func MultiSelect(c *ui.Context, text string, chosen *[]string, options []string,
}
tags(g, *chosen, 3, 2+dy, g.W-14)
g.Sprite(g.W-10, (g.H-tinyDown.H)/2+dy, tinyDown, 0, ink, 1)
finish(g, st)
g.Finish(st)
})
res := MultiSelectResult{Element: shell}
ui.PopoverBase(c, base, open, func(panel *ui.Element) {
+3 -3
View File
@@ -47,7 +47,7 @@ func NameEntry(c *ui.Context, text string, name *string, o NameEntryOptions) Nam
g.Rect(x, 14, 12, 2, ink)
}
})
shell, base, st, picked := pad(c, text, 7, nameEnd+1, 14, pixel.LineHeight, cur, o.Disabled)
shell, base, st, picked := pixel.Pad(c, text, 7, nameEnd+1, 14, pixel.LineHeight, cur, o.Disabled)
switch {
case picked == nameDel && len(*name) > 0:
*name, res.Changed = (*name)[:len(*name)-1], true
@@ -66,7 +66,7 @@ func NameEntry(c *ui.Context, text string, name *string, o NameEntryOptions) Nam
for i := range nameEnd + 1 {
x, y := i%7*14, i/7*pixel.LineHeight
if focused && i == *cur {
cursor(g, x, y, 14, pixel.LineHeight)
g.Cursor(x, y, 14, pixel.LineHeight)
}
switch i {
case nameDel:
@@ -78,7 +78,7 @@ func NameEntry(c *ui.Context, text string, name *string, o NameEntryOptions) Nam
g.Text(x+(14-pixel.Measure(l))/2, y, l, pixel.Ink, 1)
}
}
finish(g, st)
g.Finish(st)
})
})
if res.Confirmed {
-47
View File
@@ -1,47 +0,0 @@
package input
import (
"github.com/egoist/mygo/ui"
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/pixel"
)
// pad is a focusable grid returning the picked cell.
func pad(c *ui.Context, text string, cols, n, cw, ch int, cur *int, disabled bool) (shell, base *ui.Element, st pixel.State, picked int) {
k := pixel.K(c)
shell, base, st = pixel.Shell(c, func() *ui.Element {
return ui.Box(c).Focusable().Role(ui.RoleGroup).Label(text).Disabled(disabled)
})
shell.Size(k.D(cols*cw), k.D((n+cols-1)/cols*ch))
for _, m := range []struct {
key ui.Key
to func() int
}{
{ui.KeyLeft, func() int { return *cur - 1 }}, {ui.KeyRight, func() int { return *cur + 1 }},
{ui.KeyUp, func() int { return *cur - cols }}, {ui.KeyDown, func() int { return *cur + cols }},
{ui.KeyHome, func() int { return 0 }}, {ui.KeyEnd, func() int { return n - 1 }},
} {
if to := m.to(); base.Shortcut(0, m.key) && to >= 0 && to < n {
*cur = to
}
}
picked = -1
enter, space := base.Shortcut(0, ui.KeyEnter), base.Shortcut(0, ui.KeySpace)
if enter || space {
picked = *cur
}
// Enter and Space are taken, so clicks come from pointers.
if base.Clicked() {
x, y, _ := base.PointerPosition()
if col, i := int(x/k.D(cw)), int(y/k.D(ch))*cols+int(x/k.D(cw)); x >= 0 && y >= 0 && col < cols && i < n {
*cur, picked = i, i
}
}
return shell, base, st, picked
}
// cursor lights a cell with an Accent ring.
func cursor(g pixel.Canvas, x, y, w, h int) {
g.Rect(x, y, w, h, pixel.Accent)
g.Rect(x+1, y+1, w-2, h-2, pixel.Lit)
}
+1 -1
View File
@@ -73,7 +73,7 @@ func PinInput(c *ui.Context, text string, value *string, o PinInputOptions) PinI
g.HLine(x+2, h-4, pinBox-4, pixel.Accent)
}
}
finish(g, st)
g.Finish(st)
})
if res.Complete {
slog.Debug("8bit: pin complete", "label", text)
+1 -1
View File
@@ -58,5 +58,5 @@ func dot(g pixel.Canvas, text string, on bool, st pixel.State) {
ink = pixel.Faint
}
g.Text(12, 0, text, ink, 1)
finish(g, st)
g.Finish(st)
}
+1 -1
View File
@@ -66,6 +66,6 @@ func knob(c *ui.Context, k pixel.Kit, track *ui.Element, v *float64, r rail, lo,
shell.Absolute().Left(k.D(knobAt(*v, lo, hi, w-6))).Top(k.D(1)).Size(k.D(6), k.D(10)).Draw(func(p *ui.Painter, r ui.Rect) {
g := k.Canvas(p, r)
g.Frame(0, 0, 6, 10, pixel.Raised, pixel.Face)
finish(g, st)
g.Finish(st)
})
}
+1 -1
View File
@@ -61,7 +61,7 @@ func Rating(c *ui.Context, text string, value *int, o RatingOptions) RatingResul
sp, ink = full, pixel.Accent
}
g.Sprite(1, 1, sp, 0, ink, 1)
finish(g, st)
g.Finish(st)
})
}
})
+1 -1
View File
@@ -45,7 +45,7 @@ func Segmented(c *ui.Context, text string, labels []string, selected *int, o Seg
g.VLine(0, 1, g.H-2, pixel.Edge)
}
g.Text(6, 2, l, ink, 1)
finish(g, st)
g.Finish(st)
})
}
})
+1 -1
View File
@@ -38,7 +38,7 @@ func Select(c *ui.Context, text string, value *string, options []string, o Selec
ink, dy := face(g, Normal, st, sel.Open() && !off)
g.Text(6, 2+dy, *value, ink, 1)
g.Sprite(g.W-10, (g.H-tinyDown.H)/2+dy, tinyDown, 0, ink, 1)
finish(g, st)
g.Finish(st)
})
if !off {
sel.Popup(func(panel *ui.Element) {
+1 -1
View File
@@ -34,7 +34,7 @@ func Slider(c *ui.Context, text string, value *float64, o SliderOptions) SliderR
x := knobAt(*value, lo, hi, g.W-6)
groove(g, x+3, 4)
g.Frame(x, 1, 6, 10, pixel.Raised, pixel.Face)
finish(g, st)
g.Finish(st)
})
return report(shell, changed, "slider", text, *value)
}
+1 -1
View File
@@ -86,7 +86,7 @@ func SlotPicker(c *ui.Context, text string, value *int, options []string, o Slot
mid := 2 + pixel.LineHeight + (pixel.LineHeight-tinyRight.H)/2
g.Sprite(3, mid, tinyRight, 0, pixel.Accent, 1)
g.Sprite(g.W-6, mid, tinyLeft, 0, pixel.Accent, 1)
finish(g, st)
g.Finish(st)
})
return res
}
+1 -1
View File
@@ -51,7 +51,7 @@ func Stepper(c *ui.Context, text string, value *int, o StepperOptions) StepperRe
shown := strconv.Itoa(*value)
g.Frame(0, 0, g.W, g.H, pixel.Sunken, pixel.Well)
g.Text((g.W-pixel.Measure(shown))/2, 2, shown, pixel.Ink, 1)
finish(g, st)
g.Finish(st)
})
set(*value + step*held(c, k, tinyRight, o.Disabled))
base.Description(strconv.Itoa(*value))
+1 -1
View File
@@ -36,7 +36,7 @@ func StepSlider(c *ui.Context, text string, value *float64, o StepSliderOptions)
g.Dot(knobAt(v, lo, hi, w-6)+3, 13, pixel.Faint)
}
g.Frame(x, 1, 6, 10, pixel.Raised, pixel.Face)
finish(g, st)
g.Finish(st)
})
res = report(shell, changed, "step slider", text, *value)
pixel.Text(c, fmtValue(*value), pixel.TextOptions{})
+1 -1
View File
@@ -39,7 +39,7 @@ func Switch(c *ui.Context, text string, on *bool, o SwitchOptions) SwitchResult
ink = pixel.Faint
}
g.Text(32, 0, text, ink, 1)
finish(g, st)
g.Finish(st)
})
res := SwitchResult{Element: shell, Changed: base.Changed()}
if res.Changed {
+1 -1
View File
@@ -42,7 +42,7 @@ func Toggle(c *ui.Context, text string, on *bool, o ToggleOptions) ToggleResult
g.Sprite(pad, (h-o.Icon.H)/2+dy, o.Icon, 0, ink, 1)
}
g.Text(pad+lead, top+dy, text, ink, sc)
finish(g, st)
g.Finish(st)
})
res := ToggleResult{Element: shell, Changed: base.Changed()}
if res.Changed {
+1 -1
View File
@@ -40,7 +40,7 @@ func ToggleGroup(c *ui.Context, labels []string, on []bool, o ToggleGroupOptions
g := k.Canvas(p, r)
ink, dy := face(g, Normal, st, on[i])
g.Text(pad, top+dy, l, ink, sc)
finish(g, st)
g.Finish(st)
})
if base.Changed() {
res.Changed = true
+2 -2
View File
@@ -57,7 +57,7 @@ func VirtualKeyboard(c *ui.Context, text string, value *string, o VirtualKeyboar
g.Text(3, 2, string(rs), pixel.Ink, 1)
g.Rect(4+pixel.Measure(string(rs)), 4, 5, 12, pixel.Accent)
})
shell, base, st, picked := pad(c, text, 10, len(caps), 14, pixel.LineHeight, cur, o.Disabled)
shell, base, st, picked := pixel.Pad(c, text, 10, len(caps), 14, pixel.LineHeight, cur, o.Disabled)
if picked >= 0 {
switch r := caps[picked]; r {
case '\b':
@@ -95,7 +95,7 @@ func VirtualKeyboard(c *ui.Context, text string, value *string, o VirtualKeyboar
g.Text(x+(13-pixel.Measure(l))/2, y, l, pixel.Ink, 1)
}
}
finish(g, st)
g.Finish(st)
})
})
if res.Submitted {