Add text components 021-040 with demos and behavior tests
This commit is contained in:
30 files changed
+1702
-7
No files matched your search
@@ -0,0 +1,54 @@
|
||||
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
|
||||
}
|
||||
Reference in new issue
Block a user