Upgrade MyGo to v0.5.5

Elements are now pass-scoped value handles: tests that read bounds
after a frame bind a ui.Handle. pixel tells frames apart by the build
pass's root, since the Tester clock no longer moves on its own.

Fix the regressions the upgrade brought:
- Clipboard reads in input handlers go through c.Services().
- MyGo notes an overlay's opener after building it, so AutoFocus
  inside lost it; pixel.AutoFocus focuses through a Handle, and
  archtest bans the raw call. Dialogs hand the focus back again.
- Elements around a press stay hovered: Tooltip tells a press-given
  focus by focus arriving under the pointer.
- The web host moves the Tester clock with real time, at most 500 ms
  a call, and gives components the real clock.

The gallery's source index also accepts CRLF checkouts.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude Opus 5.5 committed 2026-10-17 01:31:08 -04:00
1 parent 1f3d38110e
commit 03e1f91706
532 files changed
+828 -735

No files matched your search

+1 -1
View File
@@ -15,7 +15,7 @@ type AchievementOptions struct {
}
// Achievement slides a trophy card in, holds it, then out.
func Achievement(c *ui.Context, title string, o AchievementOptions) *ui.Element {
func Achievement(c *ui.Context, title string, o AchievementOptions) ui.Element {
k := pixel.K(c)
w := pixel.Or("Achievement Width", o.Width, 200)
e := ui.Box(c)
+1 -1
View File
@@ -46,7 +46,7 @@ type AlertOptions struct {
}
type AlertResult struct {
Element *ui.Element
Element ui.Element
Closed bool
}
+1 -1
View File
@@ -22,7 +22,7 @@ type BannerOptions struct {
}
type BannerResult struct {
Element *ui.Element
Element ui.Element
Action string
Dismissed bool
}
+1 -1
View File
@@ -12,7 +12,7 @@ type BarsLoaderOptions struct{}
var heights = [8]int{3, 6, 9, 12, 9, 6, 3, 3}
// BarsLoader raises and drops five bars.
func BarsLoader(c *ui.Context, text string, o BarsLoaderOptions) *ui.Element {
func BarsLoader(c *ui.Context, text string, o BarsLoaderOptions) ui.Element {
k := pixel.K(c)
return ui.Box(c).Role(ui.RoleProgress).Label(text).Size(k.D(23), k.D(12)).Draw(func(p *ui.Painter, r ui.Rect) {
g := k.Canvas(p, r)
+2 -2
View File
@@ -11,7 +11,7 @@ type BusyOverlayOptions struct{}
type busyKey struct{}
// BusyOverlay veils busy content, whose controls then take no input.
func BusyOverlay(c *ui.Context, busy bool, o BusyOverlayOptions, content func()) *ui.Element {
func BusyOverlay(c *ui.Context, busy bool, o BusyOverlayOptions, content func()) ui.Element {
k := pixel.K(c)
outer := ui.Box(c)
// held is whether the veil had the focus last frame.
@@ -29,7 +29,7 @@ func BusyOverlay(c *ui.Context, busy bool, o BusyOverlayOptions, content func())
s := pixel.Current(c)
s.Inert = s.Inert || busy
before := c.Root().Focused()
var body *ui.Element
var body ui.Element
pixel.Scope(c, s, func() { body = ui.Box(c).Children(content) })
if !busy {
return
+1 -1
View File
@@ -13,7 +13,7 @@ type ComboCounterOptions struct{}
type comboKey struct{}
// ComboCounter shows ×n COMBO!, popping bigger as n rises.
func ComboCounter(c *ui.Context, count int, o ComboCounterOptions) *ui.Element {
func ComboCounter(c *ui.Context, count int, o ComboCounterOptions) ui.Element {
k := pixel.K(c)
e := ui.Box(c)
s := ui.Local(e, comboKey{}, func() rise { return rise{level: count} })
+1 -1
View File
@@ -19,7 +19,7 @@ type ContinuePromptOptions struct {
}
type ContinuePromptResult struct {
Element *ui.Element
Element ui.Element
Yes, No, TimedOut bool
}
+1 -1
View File
@@ -24,7 +24,7 @@ type counting struct {
}
// CountUp counts to a new value in eight steps.
func CountUp(c *ui.Context, value int, o CountUpOptions) *ui.Element {
func CountUp(c *ui.Context, value int, o CountUpOptions) ui.Element {
k := pixel.K(c)
sc := pixel.Or("CountUp Scale", o.Scale, 1)
e := ui.Box(c).Role(ui.RoleText).Label(strconv.Itoa(value))
+1 -1
View File
@@ -9,7 +9,7 @@ import (
type DotsLoaderOptions struct{}
// DotsLoader bounces three dots in turn.
func DotsLoader(c *ui.Context, text string, o DotsLoaderOptions) *ui.Element {
func DotsLoader(c *ui.Context, text string, o DotsLoaderOptions) ui.Element {
k := pixel.K(c)
return ui.Box(c).Role(ui.RoleProgress).Label(text).Size(k.D(18), k.D(8)).Draw(func(p *ui.Painter, r ui.Rect) {
g := k.Canvas(p, r)
+1 -1
View File
@@ -31,7 +31,7 @@ type EmptyStateOptions struct {
}
type EmptyStateResult struct {
Element *ui.Element
Element ui.Element
Acted bool
}
+1 -1
View File
@@ -19,7 +19,7 @@ type ErrorStateOptions struct {
}
type ErrorStateResult struct {
Element *ui.Element
Element ui.Element
Continue bool
}
+1 -1
View File
@@ -29,7 +29,7 @@ var glass = []string{
}
// Hourglass drains in steps, then flips.
func Hourglass(c *ui.Context, text string, o HourglassOptions) *ui.Element {
func Hourglass(c *ui.Context, text string, o HourglassOptions) ui.Element {
k := pixel.K(c)
return ui.Box(c).Role(ui.RoleProgress).Label(text).Size(k.D(14), k.D(14)).Draw(func(p *ui.Painter, r ui.Rect) {
g := k.Canvas(p, r)
+1 -1
View File
@@ -32,7 +32,7 @@ type InlineMessageOptions struct {
}
// InlineMessage is a small ✓ or ! field note.
func InlineMessage(c *ui.Context, message string, o InlineMessageOptions) *ui.Element {
func InlineMessage(c *ui.Context, message string, o InlineMessageOptions) ui.Element {
k := pixel.K(c)
slot, _ := o.Kind.look()
sp := bang
+1 -1
View File
@@ -21,7 +21,7 @@ type rise struct {
}
// LevelUp slides in LEVEL UP! with sparkles when level rises.
func LevelUp(c *ui.Context, level int, o LevelUpOptions) *ui.Element {
func LevelUp(c *ui.Context, level int, o LevelUpOptions) ui.Element {
k := pixel.K(c)
e := ui.Box(c)
s := ui.Local(e, levelKey{}, func() rise { return rise{level: level} })
+1 -1
View File
@@ -16,7 +16,7 @@ type LoadingScreenOptions struct {
}
// LoadingScreen shows NOW LOADING, stepping dots and a tip.
func LoadingScreen(c *ui.Context, o LoadingScreenOptions) *ui.Element {
func LoadingScreen(c *ui.Context, o LoadingScreenOptions) ui.Element {
k := pixel.K(c)
w := pixel.Or("LoadingScreen Width", o.Width, 240)
title := k.Msg("loading")
+1 -1
View File
@@ -16,7 +16,7 @@ type MeterOptions struct {
}
// Meter shows a level in Good, Warn or Bad.
func Meter(c *ui.Context, text string, value float64, o MeterOptions) *ui.Element {
func Meter(c *ui.Context, text string, value float64, o MeterOptions) ui.Element {
k := pixel.K(c)
lo, hi := o.Min, o.Max
if lo == 0 && hi == 0 {
+1 -1
View File
@@ -18,7 +18,7 @@ type ProgressOptions struct {
}
// Progress fills chunk by chunk; below zero a block runs.
func Progress(c *ui.Context, text string, value float64, o ProgressOptions) *ui.Element {
func Progress(c *ui.Context, text string, value float64, o ProgressOptions) ui.Element {
k := pixel.K(c)
if value > 1 || math.IsNaN(value) {
panic(fmt.Sprintf("feedback: Progress value %v is past 1", value))
+1 -1
View File
@@ -12,7 +12,7 @@ type PulseOptions struct {
}
// Pulse rings its child with a ring growing in steps.
func Pulse(c *ui.Context, o PulseOptions, content func()) *ui.Element {
func Pulse(c *ui.Context, o PulseOptions, content func()) ui.Element {
k := pixel.K(c)
slot := o.Slot
if slot == 0 {
+1 -1
View File
@@ -15,7 +15,7 @@ type ReadyGoOptions struct {
}
type ReadyGoResult struct {
Element *ui.Element
Element ui.Element
// Done comes once, as GO! shows.
Done bool
}
+1 -1
View File
@@ -15,7 +15,7 @@ type saveKey struct{}
var spin = [4]int{12, 8, 2, 8}
// SaveIndicator spins a floppy while saving, then shows SAVED ✓.
func SaveIndicator(c *ui.Context, saving bool, o SaveIndicatorOptions) *ui.Element {
func SaveIndicator(c *ui.Context, saving bool, o SaveIndicatorOptions) ui.Element {
k := pixel.K(c)
e := ui.Row(c).Gap(k.D(4)).AlignItems(ui.Center)
ever := ui.Local(e, saveKey{}, func() bool { return false })
+1 -1
View File
@@ -15,7 +15,7 @@ type ShakeOptions struct {
var shakes = [...]int{2, -2, 2, -2, 1, -1, 0}
// Shake jolts its child side to side briefly.
func Shake(c *ui.Context, o ShakeOptions, content func()) *ui.Element {
func Shake(c *ui.Context, o ShakeOptions, content func()) ui.Element {
k := pixel.K(c)
e := ui.Box(c)
dx := shakes[k.Shot(c, e, o.Cue, 15, len(shakes)-1)]
+1 -1
View File
@@ -16,7 +16,7 @@ type SkeletonOptions struct {
}
// Skeleton stands in for content; a dithered shine sweeps it.
func Skeleton(c *ui.Context, o SkeletonOptions) *ui.Element {
func Skeleton(c *ui.Context, o SkeletonOptions) ui.Element {
k := pixel.K(c)
n := pixel.Or("Skeleton Lines", o.Lines, 3)
w := pixel.Or("Skeleton Width", o.Width, 160)
+1 -1
View File
@@ -15,7 +15,7 @@ type SpinnerOptions struct {
var ring = [8][2]int{{5, 1}, {8, 2}, {9, 5}, {8, 8}, {5, 9}, {2, 8}, {1, 5}, {2, 2}}
// Spinner turns through eight frames, even under Reduce Motion.
func Spinner(c *ui.Context, text string, o SpinnerOptions) *ui.Element {
func Spinner(c *ui.Context, text string, o SpinnerOptions) ui.Element {
k := pixel.K(c)
s := pixel.Or("Spinner Scale", o.Scale, 1)
if s > 4 {
+1 -1
View File
@@ -16,7 +16,7 @@ type SuccessStateOptions struct {
}
// SuccessState is STAGE CLEAR! with stars popping in steps.
func SuccessState(c *ui.Context, message string, o SuccessStateOptions) *ui.Element {
func SuccessState(c *ui.Context, message string, o SuccessStateOptions) ui.Element {
k := pixel.K(c)
n := pixel.Or("SuccessState Stars", o.Stars, 3)
col := ui.Column(c).Gap(k.D(8)).Padding(k.D(16)).AlignItems(ui.Center).Role(ui.RoleStatus).Label(k.Msg("stage_clear"))
+1 -1
View File
@@ -30,7 +30,7 @@ type ToastsOptions struct {
type ToastsResult struct {
// Element holds the toasts on screen.
Element *ui.Element
Element ui.Element
// Acted is the toast whose action was clicked, else nil.
Acted *Toast
}