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
@@ -90,7 +90,7 @@ type AvatarOptions struct {
}
// Avatar draws a face seeded by name, or a picture.
func Avatar(c *ui.Context, name string, o AvatarOptions) *ui.Element {
func Avatar(c *ui.Context, name string, o AvatarOptions) ui.Element {
k, sc := pixel.K(c), scale(o.Scale)
if o.Picture != nil {
return Picture(c, o.Picture, PictureOptions{W: 16 * sc, H: 16 * sc, Label: name})
+1 -1
View File
@@ -15,7 +15,7 @@ type AvatarGroupOptions struct {
}
// AvatarGroup overlaps faces and counts the rest in a chip.
func AvatarGroup(c *ui.Context, names []string, o AvatarGroupOptions) *ui.Element {
func AvatarGroup(c *ui.Context, names []string, o AvatarGroupOptions) ui.Element {
k, sc := pixel.K(c), scale(o.Scale)
shown := names[:min(len(names), pixel.Or("AvatarGroup Max", o.Max, 4))]
rest := len(names) - len(shown)
+1 -1
View File
@@ -14,7 +14,7 @@ type BadgeOptions struct {
}
// Badge shows n, capped at 99+, or text.
func Badge(c *ui.Context, n int, o BadgeOptions) *ui.Element {
func Badge(c *ui.Context, n int, o BadgeOptions) ui.Element {
k := pixel.K(c)
s := o.Text
if s == "" {
+1 -1
View File
@@ -29,7 +29,7 @@ type BubbleOptions struct {
const tailLen = 5
// Bubble is a speech bubble with a tail around children.
func Bubble(c *ui.Context, o BubbleOptions, children func()) *ui.Element {
func Bubble(c *ui.Context, o BubbleOptions, children func()) ui.Element {
if o.Tail > Right {
panic(fmt.Sprintf("display: unknown Side %d", o.Tail))
}
+1 -1
View File
@@ -10,7 +10,7 @@ import (
)
// art is a labeled w×h dot image that fn draws.
func art(c *ui.Context, k pixel.Kit, label string, w, h int, fn func(g pixel.Canvas)) *ui.Element {
func art(c *ui.Context, k pixel.Kit, label string, w, h int, fn func(g pixel.Canvas)) ui.Element {
e := ui.Box(c).Size(k.D(w), k.D(h))
if label != "" {
e.Label(label).Role(ui.RoleImage)
+1 -1
View File
@@ -71,7 +71,7 @@ type EmojiOptions struct {
}
// Emoji draws one of sixteen hand-placed faces by name.
func Emoji(c *ui.Context, name string, o EmojiOptions) *ui.Element {
func Emoji(c *ui.Context, name string, o EmojiOptions) ui.Element {
return Icon(c, EmojiSprite(name), IconOptions{Scale: o.Scale, Label: name})
}
+1 -1
View File
@@ -12,7 +12,7 @@ type FigureOptions struct {
}
// Figure shows content over a centered caption.
func Figure(c *ui.Context, caption string, o FigureOptions, content func()) *ui.Element {
func Figure(c *ui.Context, caption string, o FigureOptions, content func()) ui.Element {
k := pixel.K(c)
return ui.Column(c).Gap(k.D(3)).AlignItems(ui.Center).Role(ui.RoleGroup).Label(caption).Children(func() {
content()
+1 -1
View File
@@ -14,7 +14,7 @@ type FlagOptions struct {
}
// Flag waves on its pole, stepped at 6 fps.
func Flag(c *ui.Context, o FlagOptions) *ui.Element {
func Flag(c *ui.Context, o FlagOptions) ui.Element {
k, sc := pixel.K(c), scale(o.Scale)
cloth := slotOr(o.Slot, pixel.Bad)
return art(c, k, o.Label, 20*sc, 26*sc, func(g pixel.Canvas) {
+1 -1
View File
@@ -63,7 +63,7 @@ type GemOptions struct {
}
// Gem is a cut gem by rarity, sparkling in steps.
func Gem(c *ui.Context, r Rarity, o GemOptions) *ui.Element {
func Gem(c *ui.Context, r Rarity, o GemOptions) ui.Element {
k, sc := pixel.K(c), scale(o.Scale)
ink := r.Slot()
return art(c, k, r.name(k), (gem.W+3)*sc, (gem.H+2)*sc, func(g pixel.Canvas) {
+1 -1
View File
@@ -14,7 +14,7 @@ type IconOptions struct {
}
// Icon draws a sprite at ×1–×4 in an ink slot.
func Icon(c *ui.Context, sp *pixel.Sprite, o IconOptions) *ui.Element {
func Icon(c *ui.Context, sp *pixel.Sprite, o IconOptions) ui.Element {
k, sc := pixel.K(c), scale(o.Scale)
return art(c, k, o.Label, sp.W*sc, sp.H*sc, func(g pixel.Canvas) { g.Sprite(0, 0, sp, 0, o.Slot, sc) })
}
+1 -1
View File
@@ -12,7 +12,7 @@ type KeyValueOptions struct {
}
// KeyValue joins key and value with a dotted leader.
func KeyValue(c *ui.Context, key, value string, o KeyValueOptions) *ui.Element {
func KeyValue(c *ui.Context, key, value string, o KeyValueOptions) ui.Element {
k := pixel.K(c)
kw, vw := pixel.Measure(key), pixel.Measure(value)
return ui.Box(c).FillWidth().MinWidth(k.D(kw + vw + 8)).Height(k.D(pixel.LineHeight)).Role(ui.RoleText).Label(key + " " + value).Draw(func(p *ui.Painter, r ui.Rect) {
+1 -1
View File
@@ -30,7 +30,7 @@ type MedalOptions struct {
}
// Medal is a ribboned medal showing its rank.
func Medal(c *ui.Context, r Rank, o MedalOptions) *ui.Element {
func Medal(c *ui.Context, r Rank, o MedalOptions) ui.Element {
if r > Bronze {
panic(fmt.Sprintf("display: unknown Rank %d", r))
}
+1 -1
View File
@@ -24,7 +24,7 @@ type pictureCache struct {
}
// Picture reduces img to the palette with Bayer dither.
func Picture(c *ui.Context, img image.Image, o PictureOptions) *ui.Element {
func Picture(c *ui.Context, img image.Image, o PictureOptions) ui.Element {
k := pixel.K(c)
b := img.Bounds()
w, h := pixel.Or("Picture W", o.W, b.Dx()), pixel.Or("Picture H", o.H, b.Dy())
+1 -1
View File
@@ -14,7 +14,7 @@ type PlaceholderOptions struct {
}
// Placeholder is a dithered box with a cross and size.
func Placeholder(c *ui.Context, o PlaceholderOptions) *ui.Element {
func Placeholder(c *ui.Context, o PlaceholderOptions) ui.Element {
k := pixel.K(c)
w, h := pixel.Or("Placeholder W", o.W, 64), pixel.Or("Placeholder H", o.H, 48)
size := fmt.Sprintf("%d×%d", w, h)
+1 -1
View File
@@ -12,7 +12,7 @@ type PortraitOptions struct {
}
// Portrait frames a character's picture over a nameplate.
func Portrait(c *ui.Context, name string, o PortraitOptions, picture func()) *ui.Element {
func Portrait(c *ui.Context, name string, o PortraitOptions, picture func()) ui.Element {
k := pixel.K(c)
size := pixel.Or("Portrait Size", o.Size, 48)
return ui.Column(c).Width(k.D(size + 6)).Role(ui.RoleGroup).Label(name).Children(func() {
+1 -1
View File
@@ -22,7 +22,7 @@ type qrCache struct {
}
// QRCode encodes s at level M, with a quiet zone.
func QRCode(c *ui.Context, s string, o QRCodeOptions) *ui.Element {
func QRCode(c *ui.Context, s string, o QRCodeOptions) ui.Element {
k := pixel.K(c)
sc := pixel.Or("QRCode Scale", o.Scale, 2)
e := ui.Box(c)
+1 -1
View File
@@ -12,7 +12,7 @@ type RarityFrameOptions struct {
}
// RarityFrame borders children by rarity; legendary carries a glint.
func RarityFrame(c *ui.Context, r Rarity, o RarityFrameOptions, children func()) *ui.Element {
func RarityFrame(c *ui.Context, r Rarity, o RarityFrameOptions, children func()) ui.Element {
k := pixel.K(c)
ink := r.Slot()
pad := 3 + pixel.Or("RarityFrame Padding", o.Padding, 4)
+1 -1
View File
@@ -14,7 +14,7 @@ type RibbonOptions struct {
const tail = 12
// Ribbon is a title banner with notched, folded tails.
func Ribbon(c *ui.Context, title string, o RibbonOptions) *ui.Element {
func Ribbon(c *ui.Context, title string, o RibbonOptions) ui.Element {
k := pixel.K(c)
band := slotOr(o.Slot, pixel.Accent)
tw := pixel.Measure(title)
+2 -2
View File
@@ -14,7 +14,7 @@ type SignpostOptions struct {
}
type SignpostResult struct {
Element *ui.Element
Element ui.Element
// Clicked is the board clicked this frame, or -1.
Clicked int
}
@@ -51,7 +51,7 @@ func Signpost(c *ui.Context, boards []string, o SignpostOptions) SignpostResult
// board is one wooden arrow, pointing left if asked.
func board(c *ui.Context, k pixel.Kit, label string, w int, left, disabled bool) bool {
shell, base, st := pixel.Shell(c, func() *ui.Element { return ui.ButtonBase(c).Label(label).Disabled(disabled) })
shell, base, st := pixel.Shell(c, func() ui.Element { return ui.ButtonBase(c).Label(label).Disabled(disabled) })
h := pixel.LineHeight + 2
shell.Size(k.D(w), k.D(h)).Draw(func(p *ui.Painter, r ui.Rect) {
g := k.Canvas(p, r)
+1 -1
View File
@@ -16,7 +16,7 @@ type SpriteOptions struct {
}
// Sprite plays a multi-slot sprite, mirrored when asked.
func Sprite(c *ui.Context, sp *pixel.Sprite, o SpriteOptions) *ui.Element {
func Sprite(c *ui.Context, sp *pixel.Sprite, o SpriteOptions) ui.Element {
k, sc := pixel.K(c), scale(o.Scale)
fps := pixel.Or("Sprite FPS", o.FPS, 0)
if o.Mirror {
+1 -1
View File
@@ -13,7 +13,7 @@ type StampOptions struct {
}
// Stamp is a rubber-stamp mark whose border wears unevenly.
func Stamp(c *ui.Context, s string, o StampOptions) *ui.Element {
func Stamp(c *ui.Context, s string, o StampOptions) ui.Element {
k := pixel.K(c)
ink := slotOr(o.Slot, pixel.Bad)
w, h := pixel.Measure(s)+12, pixel.LineHeight+8
+1 -1
View File
@@ -27,7 +27,7 @@ type StatOptions struct {
}
// Stat is a big value with a label and delta.
func Stat(c *ui.Context, label, value string, o StatOptions) *ui.Element {
func Stat(c *ui.Context, label, value string, o StatOptions) ui.Element {
k := pixel.K(c)
return ui.Column(c).Gap(k.D(1)).Role(ui.RoleGroup).Label(label).Children(func() {
pixel.Text(c, label, pixel.TextOptions{Slot: pixel.Faint})
+1 -1
View File
@@ -29,7 +29,7 @@ type StatusDotOptions struct {
}
// StatusDot is a 7-dot status light.
func StatusDot(c *ui.Context, s Status, o StatusDotOptions) *ui.Element {
func StatusDot(c *ui.Context, s Status, o StatusDotOptions) ui.Element {
if int(s) >= len(statusSlots) {
panic(fmt.Sprintf("display: unknown Status %d", s))
}
+1 -1
View File
@@ -12,7 +12,7 @@ type SwatchOptions struct {
}
// Swatch shows the active palette's sixteen slots with names.
func Swatch(c *ui.Context, o SwatchOptions) *ui.Element {
func Swatch(c *ui.Context, o SwatchOptions) ui.Element {
k := pixel.K(c)
cols := pixel.Or("Swatch Columns", o.Columns, 4)
cell := 14 + pixel.Measure("AccentLit")
+2 -2
View File
@@ -25,7 +25,7 @@ type TagOptions struct {
}
type TagResult struct {
Element *ui.Element
Element ui.Element
Removed bool
}
@@ -61,7 +61,7 @@ func Tag(c *ui.Context, label string, o TagOptions) TagResult {
// removeBox is the × that removes a tag.
func removeBox(c *ui.Context, k pixel.Kit, name string, disabled bool) bool {
shell, base, st := pixel.Shell(c, func() *ui.Element { return ui.ButtonBase(c).Label(name).Disabled(disabled) })
shell, base, st := pixel.Shell(c, func() ui.Element { return ui.ButtonBase(c).Label(name).Disabled(disabled) })
shell.Size(k.D(9), k.D(9)).Draw(func(p *ui.Painter, r ui.Rect) {
g := k.Canvas(p, r)
if st.Hover || st.Press {
+1 -1
View File
@@ -29,7 +29,7 @@ type TrophyOptions struct {
}
// Trophy is a gold cup over an engraved plaque.
func Trophy(c *ui.Context, plaque string, o TrophyOptions) *ui.Element {
func Trophy(c *ui.Context, plaque string, o TrophyOptions) ui.Element {
k, sc := pixel.K(c), scale(o.Scale)
up := strings.ToUpper(plaque)
micro := pixel.MicroOK(up)