Files
ZacharyZhang-NYandClaude Opus 5.5 03e1f91706 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>
2026-10-17 01:31:08 -04:00

55 lines
1.1 KiB
Go

package text
import (
"unicode"
"github.com/egoist/mygo/ui"
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/pixel"
)
type HighlightOptions struct {
Slot pixel.Slot
// Mark is the marker slot; zero means Warn.
Mark pixel.Slot
}
// Highlight marks each match of query in s, ignoring case.
func Highlight(c *ui.Context, s, query string, o HighlightOptions) ui.Element {
k := pixel.K(c)
mark := slotOr(o.Mark, pixel.Warn)
rs := []rune(s)
spans := matches(rs, []rune(query))
return block(c, k, s, pixel.Measure(s), pixel.LineHeight, func(g pixel.Canvas) {
for _, sp := range spans {
x0, x1 := pixel.Measure(string(rs[:sp[0]])), pixel.Measure(string(rs[:sp[1]]))
g.Veil(x0, 2, x1-x0, pixel.LineHeight-4, mark, 10)
}
g.Text(0, 0, s, o.Slot, 1)
})
}
// matches are the rune spans of q in s.
func matches(s, q []rune) [][2]int {
var out [][2]int
if len(q) == 0 {
return nil
}
for i := 0; i+len(q) <= len(s); {
same := true
for j := range q {
if unicode.ToLower(s[i+j]) != unicode.ToLower(q[j]) {
same = false
break
}
}
if same {
out = append(out, [2]int{i, i + len(q)})
i += len(q)
} else {
i++
}
}
return out
}