Files
8bitMyGoUI/gallery/app.go
T

129 lines
2.8 KiB
Go

package gallery
import (
"log/slog"
"strings"
"github.com/egoist/mygo/ui"
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/pixel"
)
// Dot is the gallery's DIPs per dot.
const Dot = 2
// App is the gallery that native and web share.
type App struct {
router *ui.Router
palette int
locale pixel.Locale
started bool
query string
search pixel.Edit
logs map[string][]string
}
// New starts at path; the boot screen shows first.
func New(path string) *App {
r := ui.NewRouter(path)
r.Transition = ui.TransitionNone
return &App{router: r, logs: map[string][]string{}}
}
// Path is the page shown, for the web address bar.
func (a *App) Path() string { return a.router.Location() }
// Go opens path, skipping boot and clearing search.
func (a *App) Go(path string) {
a.started, a.query = true, ""
if path != a.router.Location() {
slog.Debug("8bit: gallery go", "path", path)
a.router.Push(path)
}
}
func (a *App) View(c *ui.Context) {
pixel.Use(c, pixel.Settings{Palette: pixel.Palettes[a.palette], Dot: Dot, Locale: a.locale})
if !a.started {
a.boot(c)
return
}
ui.Column(c).Fill().Children(func() {
a.topBar(c)
ui.Row(c).Grow(1).AlignItems(ui.Stretch).Children(func() {
a.sidebar(c)
ui.Column(c).Grow(1).Children(func() { a.content(c) })
})
a.statusBar(c)
})
a.keys(c)
}
// keys leaves single keys to a field being typed in.
func (a *App) keys(c *ui.Context) {
if a.search.Focused && c.Shortcut(0, ui.KeyEscape) {
a.query = ""
}
if pixel.Typing(c) {
return
}
switch {
case c.Shortcut(0, ui.KeySlash):
a.search.Input.Focus()
case c.Shortcut(0, ui.KeyP):
a.setPalette(a.palette + 1)
case c.Shortcut(ui.Shift, ui.KeyP):
a.setPalette(a.palette - 1)
case c.Shortcut(0, ui.KeyBracketLeft):
a.step(-1)
case c.Shortcut(0, ui.KeyBracketRight):
a.step(1)
}
}
func (a *App) setPalette(i int) {
n := len(pixel.Palettes)
a.palette = (i%n + n) % n
slog.Debug("8bit: gallery palette", "name", pixel.Palettes[a.palette].Name)
}
// step moves to the previous or next entry.
func (a *App) step(d int) {
all := Entries()
for i, e := range all {
if e.Path() == a.router.Path() {
a.Go(all[((i+d)%len(all)+len(all))%len(all)].Path())
return
}
}
}
// logger records a demo's events for the log panel.
func (a *App) logger(e Entry) func(string) {
return func(ev string) {
slog.Debug("8bit: demo", "entry", e.Slug(), "event", ev)
l := append(a.logs[e.Slug()], ev)
a.logs[e.Slug()] = l[max(0, len(l)-8):]
}
}
func find(slug string) (Entry, bool) {
for _, e := range Entries() {
if e.Slug() == slug {
return e, true
}
}
return Entry{}, false
}
func matches(q string) []Entry {
q = strings.ToLower(strings.TrimSpace(q))
var out []Entry
for _, e := range Entries() {
if strings.Contains(strings.ToLower(e.Name+" "+e.Zh+" "+e.Slug()), q) {
out = append(out, e)
}
}
return out
}