- Added Page state (BrowserPage/EditorPage) and SortMode - BrowserLayout with 30 static entries, sort toggle, search placeholder - ListView rows clickable via per-row RegisterClick - Scroll gesture registered at START of ListView.Draw (before clicks) so click gestures registered later are checked first during hit test - Unique IDs for interactive elements: editor_text, browser_list, search_bar - ListView.Interactions() filters out Scroll (registered in Draw, not registerInteraction) - RegisterScroll added to Renderer, called from element Draw methods - lastLineYChan frame loop fixed: only re-layout if value changed - Back icon added, editor status bar shows active filename
105 lines
1.9 KiB
Go
105 lines
1.9 KiB
Go
//go:build ignore
|
|
|
|
//go:generate go run gen_icons.go
|
|
|
|
// gen_icons reads SVG files and generates icons/embedded.go with go:embed directives.
|
|
// Run: go generate ./icons
|
|
|
|
// To regenerate: cd icons && go run gen_icons.go
|
|
|
|
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"go/format"
|
|
"io/fs"
|
|
"os"
|
|
"path/filepath"
|
|
"sort"
|
|
"strings"
|
|
"text/template"
|
|
)
|
|
|
|
const output = "icons.go"
|
|
|
|
var iconTemplate = template.Must(template.New("").Parse(`// Code generated by gen_icons.go; DO NOT EDIT.
|
|
|
|
package icons
|
|
|
|
import (
|
|
"embed"
|
|
)
|
|
|
|
//go:embed {{.Embeds}}
|
|
var svgFS embed.FS
|
|
|
|
{{range $name, $files := .Icons}}
|
|
// {{$name}}SVG contains the {{$name}} icon SVG source.
|
|
var {{$name}}SVG = ` + "`" + `{{.}}` + "`" + `
|
|
{{end}}
|
|
`))
|
|
|
|
type iconData struct {
|
|
Embeds string
|
|
Icons map[string]string
|
|
}
|
|
|
|
func main() {
|
|
icons := make(map[string]string)
|
|
var embeds []string
|
|
|
|
err := filepath.WalkDir(".", func(path string, d fs.DirEntry, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if d.IsDir() {
|
|
return nil
|
|
}
|
|
if !strings.HasSuffix(path, ".svg") {
|
|
return nil
|
|
}
|
|
|
|
data, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
name := strings.TrimSuffix(filepath.Base(path), ".svg")
|
|
icons[name] = string(data)
|
|
embeds = append(embeds, filepath.Base(path))
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "error: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
// Sort embeds for deterministic output
|
|
sort.Strings(embeds)
|
|
|
|
data := iconData{
|
|
Embeds: strings.Join(embeds, " "),
|
|
Icons: icons,
|
|
}
|
|
|
|
var buf bytes.Buffer
|
|
if err := iconTemplate.Execute(&buf, data); err != nil {
|
|
fmt.Fprintf(os.Stderr, "template error: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
src, err := format.Source(buf.Bytes())
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "format error: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
if err := os.WriteFile(output, src, 0644); err != nil {
|
|
fmt.Fprintf(os.Stderr, "write error: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
fmt.Println("generated icons.go")
|
|
}
|