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
@@ -13,7 +13,7 @@ import (
type AgendaOptions struct{}
// Agenda groups events by day, earliest first.
func Agenda(c *ui.Context, events []Event, o AgendaOptions) *ui.Element {
func Agenda(c *ui.Context, events []Event, o AgendaOptions) ui.Element {
k := pixel.K(c)
sorted := slices.Clone(events)
slices.SortStableFunc(sorted, func(a, b Event) int { return a.Start.Compare(b.Start) })
+1 -1
View File
@@ -23,7 +23,7 @@ type AlarmOptions struct {
}
type AlarmResult struct {
Element *ui.Element
Element ui.Element
Changed bool
}
+1 -1
View File
@@ -15,7 +15,7 @@ type AnalogClockOptions struct {
}
// AnalogClock ticks each second; its hands are Bresenham lines.
func AnalogClock(c *ui.Context, o AnalogClockOptions) *ui.Element {
func AnalogClock(c *ui.Context, o AnalogClockOptions) ui.Element {
k := pixel.K(c)
size := pixel.Or("AnalogClock Size", o.Size, 48)
// Wake on the next whole second.
+1 -1
View File
@@ -12,7 +12,7 @@ type CalendarOptions struct {
}
type CalendarResult struct {
Element *ui.Element
Element ui.Element
// Picked is a click, Enter or Space on a day.
Changed, Picked bool
}
+1 -1
View File
@@ -169,7 +169,7 @@ func TestRelativeTimeAsksForTheNextMinute(t *testing.T) {
at := clk.t.Add(-90 * time.Second)
tt := view(300, 60, clk, false, func(c *ui.Context) { datetime.RelativeTime(c, at, datetime.RelativeTimeOptions{}) })
pixel.ResetDue()
before := time.Now()
before := tt.Now()
tt.Frame()
// The words change at two minutes: thirty seconds on.
if wait := pixel.Due().Sub(before); wait < 29*time.Second || wait > 31*time.Second {
+1 -1
View File
@@ -12,7 +12,7 @@ import (
type CountdownOptions struct{}
type CountdownResult struct {
Element *ui.Element
Element ui.Element
// Done is true in the frame time runs out.
Done bool
}
+3 -3
View File
@@ -15,7 +15,7 @@ type DateInputOptions struct {
}
type DateInputResult struct {
Element *ui.Element
Element ui.Element
Changed bool
}
@@ -28,7 +28,7 @@ type popping struct{ open, held bool }
func DateInput(c *ui.Context, text string, date *time.Time, o DateInputOptions) DateInputResult {
k := pixel.K(c)
old := *date
shell, base, st := pixel.Shell(c, func() *ui.Element {
shell, base, st := pixel.Shell(c, func() ui.Element {
return ui.ButtonBase(c).Role(ui.RolePopUpButton).Label(text).Disabled(o.Disabled)
})
pop := ui.Local(base, dateKey{}, func() popping { return popping{} })
@@ -53,7 +53,7 @@ func DateInput(c *ui.Context, text string, date *time.Time, o DateInputOptions)
g.Sprite(g.W-icon.Calendar.W-4, (g.H-icon.Calendar.H)/2, icon.Calendar, 0, pixel.Faint, 1)
g.Finish(st)
})
ui.PopoverBase(c, base, open, func(panel *ui.Element) {
ui.PopoverBase(c, base, open, func(panel ui.Element) {
panel.Padding(k.D(5)).Draw(func(p *ui.Painter, r ui.Rect) {
g := k.Canvas(p, r)
g.Frame(0, 0, g.W, g.H, pixel.Window, pixel.Face)
+1 -1
View File
@@ -12,7 +12,7 @@ type DateRangeOptions struct {
}
type DateRangeResult struct {
Element *ui.Element
Element ui.Element
Changed bool
}
+1 -1
View File
@@ -19,7 +19,7 @@ type DayScheduleOptions struct {
const hourH, gutter = pixel.LineHeight + 4, 24
// DaySchedule places events on hour rows by start and length.
func DaySchedule(c *ui.Context, events []Event, o DayScheduleOptions) *ui.Element {
func DaySchedule(c *ui.Context, events []Event, o DayScheduleOptions) ui.Element {
k := pixel.K(c)
from, to := o.From, o.To
if from == 0 && to == 0 {
+1 -1
View File
@@ -16,7 +16,7 @@ type DigitalClockOptions struct {
}
// DigitalClock shows HH:MM:SS in seven segments; colons blink.
func DigitalClock(c *ui.Context, o DigitalClockOptions) *ui.Element {
func DigitalClock(c *ui.Context, o DigitalClockOptions) ui.Element {
k := pixel.K(c)
sc := pixel.Or("DigitalClock Scale", o.Scale, 2)
if sc > 4 {
+1 -1
View File
@@ -12,7 +12,7 @@ type EventChipOptions struct {
}
// EventChip is a small chip with time and title.
func EventChip(c *ui.Context, e Event, o EventChipOptions) *ui.Element {
func EventChip(c *ui.Context, e Event, o EventChipOptions) ui.Element {
k := pixel.K(c)
edge := o.Slot
if edge == 0 {
+3 -3
View File
@@ -27,7 +27,7 @@ func addMonths(t time.Time, n int) time.Time {
}
// month moves *cur by keys; clicks, Enter and Space pick.
func month(c *ui.Context, text string, cur *time.Time, disabled, focus bool, mark func(time.Time) look) (e, grid *ui.Element, picked bool) {
func month(c *ui.Context, text string, cur *time.Time, disabled, focus bool, mark func(time.Time) look) (e, grid ui.Element, picked bool) {
k := pixel.K(c)
e = ui.Column(c).Gap(k.D(2)).Role(ui.RoleGroup).Label(text)
e.Children(func() {
@@ -54,12 +54,12 @@ func month(c *ui.Context, text string, cur *time.Time, disabled, focus bool, mar
}
}
})
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.RoleTable).Label(text).Disabled(disabled)
})
grid = base
if focus {
base.AutoFocus()
pixel.AutoFocus(c, base)
}
y, m, d := cur.Date()
for _, mv := range []struct {
+1 -1
View File
@@ -17,7 +17,7 @@ type MonthPickerOptions struct {
}
type MonthPickerResult struct {
Element *ui.Element
Element ui.Element
Changed bool
}
+1 -1
View File
@@ -15,7 +15,7 @@ type RelativeTimeOptions struct {
}
// RelativeTime says how long since or until t, each minute.
func RelativeTime(c *ui.Context, t time.Time, o RelativeTimeOptions) *ui.Element {
func RelativeTime(c *ui.Context, t time.Time, o RelativeTimeOptions) ui.Element {
k := pixel.K(c)
ink := o.Slot
if ink == 0 {
+2 -2
View File
@@ -15,7 +15,7 @@ type SeasonWheelOptions struct {
}
type SeasonWheelResult struct {
Element *ui.Element
Element ui.Element
Changed bool
}
@@ -32,7 +32,7 @@ func SeasonWheel(c *ui.Context, text string, season *pixel.Season, o SeasonWheel
panic(fmt.Sprintf("datetime: unknown Season %d", *season))
}
old := *season
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.RoleRadioGroup).Label(text).Disabled(o.Disabled)
})
if pixel.Shortcut(base, 0, ui.KeyRight) || pixel.Shortcut(base, 0, ui.KeyDown) {
+1 -1
View File
@@ -16,7 +16,7 @@ type StopwatchOptions struct {
}
type StopwatchResult struct {
Element *ui.Element
Element ui.Element
Started, Stopped, Lapped, Reset bool
}
+2 -2
View File
@@ -16,7 +16,7 @@ type SunDialOptions struct {
}
type SunDialResult struct {
Element *ui.Element
Element ui.Element
Changed bool
}
@@ -30,7 +30,7 @@ func SunDial(c *ui.Context, text string, hour *int, o SunDialOptions) SunDialRes
panic(fmt.Sprintf("datetime: SunDial hour %d outside 0–23", *hour))
}
old := *hour
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.RoleSlider).Label(text).Disabled(o.Disabled)
})
if pixel.Shortcut(base, 0, ui.KeyLeft) {
+2 -2
View File
@@ -15,7 +15,7 @@ type TimeInputOptions struct {
}
type TimeInputResult struct {
Element *ui.Element
Element ui.Element
Changed bool
}
@@ -30,7 +30,7 @@ type timing struct {
func TimeInput(c *ui.Context, text string, tm *time.Time, o TimeInputOptions) TimeInputResult {
k := pixel.K(c)
old := *tm
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.RoleTextField).Label(text).Disabled(o.Disabled)
})
s := ui.Local(base, timeKey{}, func() timing { return timing{first: -1} })
+1 -1
View File
@@ -16,7 +16,7 @@ type TimerOptions struct {
}
type TimerResult struct {
Element *ui.Element
Element ui.Element
// Done is true in the frame the time runs out.
Done bool
}
+2 -2
View File
@@ -238,7 +238,7 @@ func TestTodayMarksMoveAtMidnight(t *testing.T) {
} {
tt := view(600, 400, clk, false, build)
pixel.ResetDue()
before := time.Now()
before := tt.Now()
tt.Frame()
if due := pixel.Due(); due.IsZero() || due.Sub(before) > 2*time.Second {
t.Fatalf("%s: no rebuild asked for midnight, due %v", name, due)
@@ -264,7 +264,7 @@ func TestRelativeTimeRoundsTheFutureUp(t *testing.T) {
at := clk.t.Add(tc.ahead)
tt := view(300, 60, clk, false, func(c *ui.Context) { datetime.RelativeTime(c, at, datetime.RelativeTimeOptions{}) })
pixel.ResetDue()
before := time.Now()
before := tt.Now()
tt.Frame()
if wait := pixel.Due().Sub(before); !shows(tt, tc.words) || wait < tc.wait-time.Second || wait > tc.wait+time.Second {
t.Fatalf("%v ahead: %q, next repaint in %v", tc.ahead, tt.Texts(), wait)
+2 -2
View File
@@ -15,7 +15,7 @@ type WeekStripOptions struct {
}
type WeekStripResult struct {
Element *ui.Element
Element ui.Element
Changed bool
}
@@ -26,7 +26,7 @@ const dayW, dayH = 22, 2 * pixel.LineHeight
func WeekStrip(c *ui.Context, text string, date *time.Time, o WeekStripOptions) WeekStripResult {
k := pixel.K(c)
old := *date
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)
})
if pixel.Shortcut(base, 0, ui.KeyLeft) {
+1 -1
View File
@@ -15,7 +15,7 @@ type YearPickerOptions struct {
}
type YearPickerResult struct {
Element *ui.Element
Element ui.Element
Changed bool
}
+1 -1
View File
@@ -15,7 +15,7 @@ type YearViewOptions struct{}
const miniW, miniH, monthW, monthH = 10, 7, 7*miniW + 4, 6*miniH + pixel.LineHeight + 2
// YearView sets a year's twelve months small; today is marked.
func YearView(c *ui.Context, year int, o YearViewOptions) *ui.Element {
func YearView(c *ui.Context, year int, o YearViewOptions) ui.Element {
k := pixel.K(c)
now := today(c, k)
return ui.Box(c).Size(k.D(4*monthW), k.D(3*monthH)).Role(ui.RoleImage).Label(strconv.Itoa(year)).Draw(func(p *ui.Painter, r ui.Rect) {