Add gallery app, native window and architecture tests
This commit is contained in:
16 files changed
+1552
-5
No files matched your search
+125
@@ -0,0 +1,125 @@
|
||||
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
|
||||
}
|
||||
Reference in new issue
Block a user