Add code components 366-385; ScrollArea Follow, editor sync

A terminal with history, a Go-colored code block, a log viewer that
follows, a hex viewer, a memory map, a JSON tree, a line diff, a GAME
OVER crash screen, an FPS meter, profiler bars, breakpoints,
variables, command history, a shortcut list, a debug grid, a pixel
editor that exports string art, a palette editor, a sprite sheet, a
glyph map and a 6502 register view.

layout.ScrollArea takes Follow, and ChatLog now uses it. data.TreeNode
takes a Value drawn in its Slot. pixel gains Has, and Sprite.Art
writes MustSprite art. pixel.Editor takes the caller's value at each
input event, so a value changed between frames is never typed onto.
This commit is contained in:
ZacharyZhang-NY committed 2026-10-12 07:18:30 -04:00
1 parent 0e21870b64
commit 51af14709d
42 files changed
+3415 -37

No files matched your search

+78
View File
@@ -0,0 +1,78 @@
package code
import (
"fmt"
"github.com/egoist/mygo/ui"
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/pixel"
)
type DebugGridOptions struct {
// Step is dots between lines, 2–32; zero means 8.
Step int
}
// DebugGrid rules content with the dot grid and rulers.
func DebugGrid(c *ui.Context, o DebugGridOptions, content func()) *ui.Element {
k := pixel.K(c)
step := pixel.Or("DebugGrid Step", o.Step, 8)
if step < 2 || step > 32 {
panic(fmt.Sprintf("code: DebugGrid Step %d outside 2–32", step))
}
// ruler ticks every two dots; steps are long, some numbered.
ruler := func(across bool) func(p *ui.Painter, r ui.Rect) {
return func(p *ui.Painter, r ui.Rect) {
g := k.Canvas(p, r)
g.Rect(0, 0, g.W, g.H, pixel.Face)
n := g.H
if across {
n = g.W
}
for i := 0; i < n; i += 2 {
l := 2
if i%step == 0 {
l = 4
}
if across {
g.VLine(i, 10-l, l, pixel.Ink)
} else {
g.HLine(10-l, i, l, pixel.Ink)
}
if s := fmt.Sprint(i); i%(4*step) == 0 && i > 0 {
if across {
g.Micro(i+1, 0, s, pixel.Faint, 1)
} else if pixel.MicroWidth(s) <= 6 {
g.Micro(0, i+1, s, pixel.Faint, 1)
}
}
}
}
}
// The rulers stretch to the content, no further.
return ui.Column(c).AlignSelf(ui.Start).AlignItems(ui.Stretch).Children(func() {
ui.Row(c).Children(func() {
ui.Box(c).Size(k.D(10), k.D(10)).Draw(func(p *ui.Painter, r ui.Rect) {
k.Canvas(p, r).Rect(0, 0, 10, 10, pixel.Shade)
})
ui.Box(c).Height(k.D(10)).Grow(1).Draw(ruler(true))
})
ui.Row(c).AlignItems(ui.Stretch).Children(func() {
ui.Box(c).Width(k.D(10)).Draw(ruler(false))
ui.Box(c).Children(content).DrawOver(func(p *ui.Painter, r ui.Rect) {
g := k.Canvas(p, r)
// Dotted lines every step, every other dot lit.
for x := 0; x < g.W; x += step {
for y := 0; y < g.H; y += 2 {
g.Dot(x, y, pixel.Accent)
}
}
for y := 0; y < g.H; y += step {
for x := 0; x < g.W; x += 2 {
g.Dot(x, y, pixel.Accent)
}
}
})
})
})
}