126 lines
2.8 KiB
Go
126 lines
2.8 KiB
Go
package gallery
|
|
|
|
import (
|
|
"log/slog"
|
|
"strings"
|
|
|
|
"github.com/egoist/mygo/ui"
|
|
|
|
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/pixel"
|
|
)
|
|
|
|
// 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], 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
|
|
}
|