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

+2 -2
View File
@@ -20,7 +20,7 @@ type AppWindowOptions struct {
}
type AppWindowResult struct {
Element *ui.Element
Element ui.Element
// Closed is the close box; Moved, a drag or arrow.
Closed, Moved bool
}
@@ -64,7 +64,7 @@ func AppWindow(c *ui.Context, title string, x, y *int, o AppWindowOptions, conte
g.Frame(0, 0, g.W, g.H, pixel.Raised, pixel.Face)
}).Children(func() {
ui.Row(c).FillWidth().Gap(k.D(2)).AlignItems(ui.Center).Children(func() {
shell, base, st := pixel.Shell(c, func() *ui.Element {
shell, base, st := pixel.Shell(c, func() ui.Element {
return ui.Box(c).Focusable().Role(ui.RoleGroup).Label(title).Description(k.Msg("arrows_move")).Disabled(o.Disabled)
})
if !base.IsDisabled() {
+1 -1
View File
@@ -19,7 +19,7 @@ type BootScreenOptions struct {
}
type BootScreenResult struct {
Element *ui.Element
Element ui.Element
// Done is the frame the last line shows.
Done bool
}
+1 -1
View File
@@ -16,7 +16,7 @@ type CalculatorOptions struct {
}
type CalculatorResult struct {
Element *ui.Element
Element ui.Element
// Changed is a key pressed this frame.
Changed bool
}
+2 -2
View File
@@ -18,7 +18,7 @@ type ClipboardPanelOptions struct {
}
type ClipboardPanelResult struct {
Element *ui.Element
Element ui.Element
// Copied is the clip copied this frame, else -1.
Copied int
}
@@ -58,7 +58,7 @@ func ClipboardPanel(c *ui.Context, text string, clips []string, o ClipboardPanel
for i, clip := range clips {
// Keyed by the clip: new ones come in on top.
ui.Box(c).Key(clip).FillWidth().Children(func() {
shell, base, st := pixel.Shell(c, func() *ui.Element {
shell, base, st := pixel.Shell(c, func() ui.Element {
return ui.Box(c).Focusable().Role(ui.RoleButton).Label(clip).Description(k.Msg("copy")).Disabled(o.Disabled)
})
if !base.IsDisabled() && base.Clicked() {
+1 -1
View File
@@ -20,7 +20,7 @@ type ControlPanelOptions struct {
}
type ControlPanelResult struct {
Element *ui.Element
Element ui.Element
// Opened is the applet opened this frame, else -1.
Opened int
}
+1 -1
View File
@@ -13,7 +13,7 @@ type DesktopOptions struct {
}
// Desktop lays icons down a dithered wallpaper, column by column.
func Desktop(c *ui.Context, text string, o DesktopOptions, icons func()) *ui.Element {
func Desktop(c *ui.Context, text string, o DesktopOptions, icons func()) ui.Element {
k := pixel.K(c)
o.Wallpaper.name(k)
w, h := pixel.Or("Desktop Width", o.Width, 320), pixel.Or("Desktop Height", o.Height, 200)
+2 -2
View File
@@ -15,7 +15,7 @@ type DesktopIconOptions struct {
}
type DesktopIconResult struct {
Element *ui.Element
Element ui.Element
// Clicked chooses it; Opened is a double click or Enter.
Clicked, Opened bool
}
@@ -29,7 +29,7 @@ func DesktopIcon(c *ui.Context, label string, icon *pixel.Sprite, o DesktopIconO
if label == "" {
panic("desk: DesktopIcon has no label")
}
shell, base, st := pixel.Shell(c, func() *ui.Element {
shell, base, st := pixel.Shell(c, func() ui.Element {
return ui.Box(c).Focusable().Role(ui.RoleButton).Label(label).Disabled(o.Disabled)
})
res := DesktopIconResult{Element: shell}
+1 -1
View File
@@ -19,7 +19,7 @@ type DiskDefragOptions struct {
}
type DiskDefragResult struct {
Element *ui.Element
Element ui.Element
// Done is the frame the last block falls in place.
Done bool
}
+2 -2
View File
@@ -20,7 +20,7 @@ type DockOptions struct {
}
type DockResult struct {
Element *ui.Element
Element ui.Element
// Launched is the app pressed this frame, else -1.
Launched int
}
@@ -68,7 +68,7 @@ func Dock(c *ui.Context, text string, apps []DockApp, o DockOptions) DockResult
for i, a := range apps {
// Keyed by name: apps come and go.
ui.Box(c).Key(a.Name).Children(func() {
shell, base, st := pixel.Shell(c, func() *ui.Element {
shell, base, st := pixel.Shell(c, func() ui.Element {
return ui.Box(c).Focusable().Role(ui.RoleButton).Label(a.Name).Disabled(o.Disabled)
})
up := st.Hover || st.Focus
+2 -2
View File
@@ -14,7 +14,7 @@ import (
type LockScreenOptions struct{}
type LockScreenResult struct {
Element *ui.Element
Element ui.Element
// Unlocked is a key or click opening it this frame.
Unlocked bool
}
@@ -40,7 +40,7 @@ func LockScreen(c *ui.Context, text string, open *bool, o LockScreenOptions) Loc
g.Text((g.W-pixel.Measure(press))/2, g.H-3*pixel.LineHeight, press, pixel.Accent, 1)
}
})
if panel != nil {
if panel.Valid() {
panel.Description(clock + ", " + date + ", " + press)
}
if woke {
+1 -1
View File
@@ -23,7 +23,7 @@ type MinesweeperOptions struct {
}
type MinesweeperResult struct {
Element *ui.Element
Element ui.Element
// Won or Lost is the game ending this frame.
Won, Lost bool
// Flagged is a flag set or lifted; Restarted, the face.
+1 -1
View File
@@ -18,7 +18,7 @@ type NotepadOptions struct {
}
type NotepadResult struct {
Element *ui.Element
Element ui.Element
// Saved is FILE, SAVE chosen this frame.
Changed, Saved bool
}
+1 -1
View File
@@ -19,7 +19,7 @@ type RunDialogOptions struct {
}
type RunDialogResult struct {
Element *ui.Element
Element ui.Element
// Canceled is CANCEL, the close box or Escape.
Changed, Submitted, Canceled bool
}
+1 -1
View File
@@ -13,7 +13,7 @@ import (
type ScreensaverOptions struct{}
type ScreensaverResult struct {
Element *ui.Element
Element ui.Element
// Woke is the input that ended it this frame.
Woke bool
}
+1 -1
View File
@@ -14,7 +14,7 @@ type ShutdownScreenOptions struct {
}
// ShutdownScreen says it is safe to turn off the computer.
func ShutdownScreen(c *ui.Context, o ShutdownScreenOptions) *ui.Element {
func ShutdownScreen(c *ui.Context, o ShutdownScreenOptions) ui.Element {
k := pixel.K(c)
w, h := pixel.Or("ShutdownScreen Width", o.Width, 320), pixel.Or("ShutdownScreen Height", o.Height, 200)
s := k.Msg("safe_to_turn_off")
+2 -2
View File
@@ -20,7 +20,7 @@ type SnakeOptions struct {
}
type SnakeResult struct {
Element *ui.Element
Element ui.Element
// Score is food eaten; Started and Over are this frame's.
Score int
Started, Over bool
@@ -47,7 +47,7 @@ func Snake(c *ui.Context, text string, o SnakeOptions) SnakeResult {
if cols < 6 || rows < 4 {
panic(fmt.Sprintf("desk: Snake %d×%d is too small", cols, rows))
}
shell, base, st := pixel.Shell(c, func() *ui.Element {
shell, base, st := pixel.Shell(c, func() ui.Element {
return ui.Box(c).Focusable().Role(ui.RoleGroup).Label(text).Disabled(o.Disabled)
})
s := ui.Local(shell, snakeKey{}, func() pit { return pit{} })
+3 -3
View File
@@ -25,7 +25,7 @@ type StartMenuOptions struct {
}
type StartMenuResult struct {
Element *ui.Element
Element ui.Element
// Launched is the program run this frame, as "GAMES/SNAKE".
Launched string
}
@@ -148,9 +148,9 @@ func (m *start) keys(short func(ui.Modifiers, ui.Key) bool, ps []Program) string
}
// list shows each open level beside its parent row.
func (m *start) list(c *ui.Context, k pixel.Kit, anchor *ui.Element, ps []Program) string {
func (m *start) list(c *ui.Context, k pixel.Kit, anchor ui.Element, ps []Program) string {
run := ""
ui.PopoverBase(c, anchor, &m.open, func(panel *ui.Element) {
ui.PopoverBase(c, anchor, &m.open, func(panel ui.Element) {
// Only a pointer that moves lights the row under it.
px, py, over := panel.PointerPosition()
moved := over && [2]float32{px, py} != m.ptr
+1 -1
View File
@@ -21,7 +21,7 @@ type TaskbarOptions struct {
}
type TaskbarResult struct {
Element *ui.Element
Element ui.Element
// Changed is a window button pressed; Launched a program.
Changed bool
Launched string
+2 -2
View File
@@ -21,7 +21,7 @@ type TrayIconsOptions struct {
}
type TrayIconsResult struct {
Element *ui.Element
Element ui.Element
// Clicked is the icon pressed this frame, else -1.
Clicked int
}
@@ -43,7 +43,7 @@ func TrayIcons(c *ui.Context, text string, icons []TrayIcon, o TrayIconsOptions)
// Keyed by tip: icons come and go.
ui.Box(c).Key(t.Tip).Children(func() {
overlay.Tooltip(c, t.Tip, overlay.TooltipOptions{}, func() {
shell, base, st := pixel.Shell(c, func() *ui.Element {
shell, base, st := pixel.Shell(c, func() ui.Element {
return ui.Box(c).Focusable().Role(ui.RoleButton).Label(t.Tip).Disabled(o.Disabled)
})
if !base.IsDisabled() && base.Clicked() {
+2 -2
View File
@@ -15,7 +15,7 @@ type wake struct {
}
// cover fills the window; keys, clicks, long moves end it.
func cover(c *ui.Context, k pixel.Kit, text string, open *bool, moves bool, draw func(g pixel.Canvas)) (anchor, panel *ui.Element, woke bool) {
func cover(c *ui.Context, k pixel.Kit, text string, open *bool, moves bool, draw func(g pixel.Canvas)) (anchor, panel ui.Element, woke bool) {
anchor = ui.Box(c).Role(ui.RoleNone)
st := ui.Local(anchor, wakeKey{}, func() wake { return wake{} })
was := *open
@@ -25,7 +25,7 @@ func cover(c *ui.Context, k pixel.Kit, text string, open *bool, moves bool, draw
if !*open {
*st = wake{}
}
panel = ui.DialogBase(c, open, func(back, panel *ui.Element) {
panel = ui.DialogBase(c, open, func(back, panel ui.Element) {
back.Draw(func(p *ui.Painter, r ui.Rect) { draw(k.Canvas(p, r)) })
back.HandleInput(func(ev ui.InputEvent) bool {
// Any button and the wheel end it, as keys do.
+1 -1
View File
@@ -13,7 +13,7 @@ type WallpaperPickerOptions struct {
}
type WallpaperPickerResult struct {
Element *ui.Element
Element ui.Element
Changed bool
}