463 lines
19 KiB
Go
463 lines
19 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"math"
|
|
|
|
"github.com/egoist/mygo/ui"
|
|
|
|
mujica "mujicaui"
|
|
"mujicaui/icons"
|
|
)
|
|
|
|
var navigationPages = []page{
|
|
{ID: "059", Name: "Tabs", ZhName: "标签页", Category: "Navigation", Demo: navigationTabsDemo, Code: navigationTabsCode,
|
|
Keys: "Tab enters the tab list at the chosen tab. Left/Right (Up/Down when vertical) choose the next enabled tab, skipping disabled ones and wrapping; Home and End choose the first and last."},
|
|
{ID: "060", Name: "SegmentedControl", ZhName: "分段控件", Category: "Navigation", Demo: navigationSegmentedDemo, Code: navigationSegmentedCode,
|
|
Keys: "One Tab stop. Arrow keys choose the previous or next segment and wrap; Home and End choose the ends."},
|
|
{ID: "061", Name: "Breadcrumb", ZhName: "面包屑", Category: "Navigation", Demo: navigationBreadcrumbDemo, Code: navigationBreadcrumbCode,
|
|
Keys: "Tab moves through the links and the fold button; Enter or Space activates. In the fold menu, Tab moves between items and Escape closes it, returning focus to the button."},
|
|
{ID: "062", Name: "Pagination", ZhName: "分页", Category: "Navigation", Demo: navigationPaginationDemo, Code: navigationPaginationCode,
|
|
Keys: "The page buttons are one Tab stop: Left/Right move, Home/End jump to the ends, Enter or Space goes to the page. The size select opens with Up/Down; the jump field goes on Enter."},
|
|
{ID: "063", Name: "Steps", ZhName: "步骤条", Category: "Navigation", Demo: navigationStepsDemo, Code: navigationStepsCode,
|
|
Keys: "Clickable steps are one Tab stop; arrow keys move between them and Enter or Space goes to the step."},
|
|
{ID: "064", Name: "Sidebar", ZhName: "侧边栏", Category: "Navigation", Demo: navigationSidebarDemo, Code: navigationSidebarCode,
|
|
Keys: "One Tab stop. Up/Down choose the previous or next item, Home/End the ends, typing the first letters of a label jumps to it. Section and group titles open and close with a click."},
|
|
{ID: "065", Name: "NavigationMenu", ZhName: "导航菜单", Category: "Navigation", Demo: navigationMenuDemo, Code: navigationMenuCode,
|
|
Keys: "Left/Right move between top links; Down or Enter opens a group with focus on its first link, Up/Down move inside, Escape closes. Back/Forward also answer Cmd+[ / Cmd+] (Alt+Left/Right off macOS)."},
|
|
{ID: "066", Name: "Menubar", ZhName: "菜单栏", Category: "Navigation", Demo: navigationMenubarDemo, Code: navigationMenubarCode,
|
|
Keys: "Tab reaches the bar; Left/Right move between menus, Down opens one. Up/Down/Home/End move through items, Right opens a submenu (or the next menu), Left closes it, Enter/Space chooses, Escape closes one level."},
|
|
{ID: "067", Name: "Toolbar", ZhName: "工具栏", Category: "Navigation", Demo: navigationToolbarDemo, Code: navigationToolbarCode,
|
|
Keys: "One Tab stop. Left/Right move between actions, Home/End to the ends, Enter or Space runs one. Actions that do not fit move to the » menu at the end."},
|
|
{ID: "068", Name: "CommandPalette", ZhName: "命令面板", Category: "Navigation", Demo: navigationPaletteDemo, Code: navigationPaletteCode,
|
|
Keys: "Cmd+K (Ctrl+K off macOS) opens it with focus in the search. Type to filter, Up/Down choose (wrapping), Enter runs and closes, Escape closes without running."},
|
|
}
|
|
|
|
// navigationCheck is a check box that logs its changes.
|
|
func navigationCheck(c *ui.Context, v *bool, label string, log func(string)) {
|
|
was := *v
|
|
ui.Checkbox(c, v, label)
|
|
if *v != was {
|
|
log(fmt.Sprintf("%s: %v", label, *v))
|
|
}
|
|
}
|
|
|
|
// navigationSlider is a labeled whole-number slider that logs its changes.
|
|
func navigationSlider(c *ui.Context, v *float64, label string, lo, hi float64, log func(string)) {
|
|
was := math.Round(*v)
|
|
ui.Row(c).Gap(8).AlignItems(ui.Center).Children(func() {
|
|
ui.Text(c, fmt.Sprintf("%s %.0f", label, math.Round(*v)))
|
|
ui.StepSlider(c, v, lo, hi, 1).Width(160)
|
|
})
|
|
if math.Round(*v) != was {
|
|
log(fmt.Sprintf("%s: %.0f", label, math.Round(*v)))
|
|
}
|
|
}
|
|
|
|
func navigationControls(c *ui.Context, fn func()) { ui.Row(c).Wrap().Gap(16).Children(fn) }
|
|
|
|
func navigationDemo(c *ui.Context, controls, body func()) {
|
|
ui.Column(c).Gap(20).AlignItems(ui.Stretch).Children(func() {
|
|
navigationControls(c, controls)
|
|
body()
|
|
})
|
|
}
|
|
|
|
const navigationTabsCode = `mujica.Tabs(c, &tab, []mujica.Tab{
|
|
{Label: "General", Panel: func() { ui.Text(c, "General settings") }},
|
|
{Label: "Fonts", Icon: icons.Must("italic"), Panel: func() { ui.Text(c, "Fonts") }},
|
|
{Label: "Archive", Disabled: true},
|
|
}, mujica.TabsOptions{Label: "Settings"})`
|
|
|
|
func navigationTabsDemo(c *ui.Context, log func(string)) {
|
|
type state struct {
|
|
tab int
|
|
vertical, archive, many bool
|
|
}
|
|
s := ui.Local(c.Root(), "059", func() state { return state{archive: true} })
|
|
navigationDemo(c, func() {
|
|
navigationCheck(c, &s.vertical, "Vertical", log)
|
|
navigationCheck(c, &s.archive, "Disable Archive", log)
|
|
navigationCheck(c, &s.many, "Many tabs (overflow)", log)
|
|
}, func() {
|
|
names := []string{"General", "Fonts", "Archive", "Advanced"}
|
|
if s.many {
|
|
names = append(names, "Seals", "Heraldry", "Ledgers", "Envoys", "Banquets", "Chapel")
|
|
}
|
|
var tabs []mujica.Tab
|
|
for i, n := range names {
|
|
tabs = append(tabs, mujica.Tab{Label: n, Disabled: n == "Archive" && s.archive, Panel: func() {
|
|
ui.Text(c, fmt.Sprintf("The %s panel (tab %d).", n, i+1))
|
|
}})
|
|
}
|
|
tabs[1].Icon = icons.Must("italic")
|
|
s.tab = min(s.tab, len(tabs)-1)
|
|
if tabs[s.tab].Disabled {
|
|
s.tab = 0
|
|
}
|
|
ui.Column(c).Width(420).Children(func() {
|
|
if mujica.Tabs(c, &s.tab, tabs, mujica.TabsOptions{Vertical: s.vertical, Label: "Settings"}).Changed() {
|
|
log("Changed: tab " + names[s.tab])
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
const navigationSegmentedCode = `mujica.SegmentedControl(c, &view, []mujica.Segment{
|
|
{Label: "List", Icon: icons.Must("list"), HideLabel: true},
|
|
{Label: "Grid", Icon: icons.Must("layout-grid"), HideLabel: true},
|
|
}, mujica.SegmentedControlOptions{Label: "View"})`
|
|
|
|
func navigationSegmentedDemo(c *ui.Context, log func(string)) {
|
|
type state struct {
|
|
text, icon int
|
|
equal, iconOnly, disab bool
|
|
}
|
|
s := ui.Local(c.Root(), "060", func() state { return state{} })
|
|
navigationDemo(c, func() {
|
|
navigationCheck(c, &s.equal, "Equal widths", log)
|
|
navigationCheck(c, &s.iconOnly, "Icons only", log)
|
|
navigationCheck(c, &s.disab, "Disabled", log)
|
|
}, func() {
|
|
opts := mujica.SegmentedControlOptions{Equal: s.equal, Disabled: s.disab, Label: "Range"}
|
|
ui.Row(c).Gap(24).AlignItems(ui.Center).Children(func() {
|
|
if mujica.SegmentedControl(c, &s.text, []mujica.Segment{{Label: "Day"}, {Label: "Week"}, {Label: "Fortnight"}}, opts).Changed() {
|
|
log(fmt.Sprintf("Changed: range %d", s.text))
|
|
}
|
|
opts.Label = "View"
|
|
if mujica.SegmentedControl(c, &s.icon, []mujica.Segment{
|
|
{Label: "List", Icon: icons.Must("list"), HideLabel: s.iconOnly},
|
|
{Label: "Grid", Icon: icons.Must("layout-grid"), HideLabel: s.iconOnly},
|
|
}, opts).Changed() {
|
|
log(fmt.Sprintf("Changed: view %d", s.icon))
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
const navigationBreadcrumbCode = `if i, ok := mujica.Breadcrumb(c, path, mujica.BreadcrumbOptions{}).Chosen(); ok {
|
|
path = path[:i+1]
|
|
}`
|
|
|
|
var navigationBreadcrumbNames = []string{"Home", "Library", "Manuscripts", "Seventeenth century", "Correspondence of the court", "Letters to the Duchess", "Draft of the winter decree"}
|
|
|
|
func navigationBreadcrumbDemo(c *ui.Context, log func(string)) {
|
|
type state struct{ depth, max float64 }
|
|
s := ui.Local(c.Root(), "061", func() state { return state{depth: 6, max: 4} })
|
|
navigationDemo(c, func() {
|
|
navigationSlider(c, &s.depth, "Depth", 1, 7, log)
|
|
navigationSlider(c, &s.max, "MaxItems", 3, 7, log)
|
|
}, func() {
|
|
var path []mujica.BreadcrumbItem
|
|
for i, n := range navigationBreadcrumbNames[:int(s.depth)] {
|
|
it := mujica.BreadcrumbItem{Label: n}
|
|
if i == 0 {
|
|
it.Icon = icons.Must("house")
|
|
}
|
|
path = append(path, it)
|
|
}
|
|
if i, ok := mujica.Breadcrumb(c, path, mujica.BreadcrumbOptions{MaxItems: int(s.max)}).Chosen(); ok {
|
|
log("Chosen: " + path[i].Label)
|
|
s.depth = float64(i + 1)
|
|
}
|
|
})
|
|
}
|
|
|
|
const navigationPaginationCode = `if mujica.Pagination(c, &page, &size, mujica.PaginationOptions{Total: 420, PageSizes: []int{10, 20, 50}, Jump: true}).Changed() {
|
|
load(page, size)
|
|
}`
|
|
|
|
func navigationPaginationDemo(c *ui.Context, log func(string)) {
|
|
type state struct {
|
|
page, size int
|
|
total float64
|
|
sizes, jump, disab bool
|
|
}
|
|
s := ui.Local(c.Root(), "062", func() state { return state{page: 1, size: 20, total: 420, sizes: true, jump: true} })
|
|
navigationDemo(c, func() {
|
|
navigationSlider(c, &s.total, "Total", 0, 1000, log)
|
|
navigationCheck(c, &s.sizes, "Page sizes", log)
|
|
navigationCheck(c, &s.jump, "Jump", log)
|
|
navigationCheck(c, &s.disab, "Disabled", log)
|
|
}, func() {
|
|
opts := mujica.PaginationOptions{Total: int(s.total), Jump: s.jump, Disabled: s.disab}
|
|
if s.sizes {
|
|
opts.PageSizes = []int{10, 20, 50}
|
|
} else {
|
|
s.size = 20
|
|
}
|
|
if mujica.Pagination(c, &s.page, &s.size, opts).Changed() {
|
|
log(fmt.Sprintf("Changed: page %d, size %d", s.page, s.size))
|
|
}
|
|
})
|
|
}
|
|
|
|
const navigationStepsCode = `mujica.Steps(c, ¤t, []mujica.Step{
|
|
{Title: "Account", Clickable: true},
|
|
{Title: "Profile", Description: "Name and seal"},
|
|
{Title: "Confirm"},
|
|
}, mujica.StepsOptions{Label: "Sign-up"})`
|
|
|
|
func navigationStepsDemo(c *ui.Context, log func(string)) {
|
|
type state struct {
|
|
current int
|
|
vertical, failed, clickOK bool
|
|
}
|
|
s := ui.Local(c.Root(), "063", func() state { return state{current: 1, clickOK: true} })
|
|
steps := []mujica.Step{
|
|
{Title: "Account", Description: "Name and seal"},
|
|
{Title: "Profile", Description: "Titles and house"},
|
|
{Title: "Payment", Description: "Treasury"},
|
|
{Title: "Confirm"},
|
|
}
|
|
navigationDemo(c, func() {
|
|
navigationCheck(c, &s.vertical, "Vertical", log)
|
|
navigationCheck(c, &s.failed, "Payment failed", log)
|
|
navigationCheck(c, &s.clickOK, "Done steps clickable", log)
|
|
if mujica.Button(c, "Back", mujica.ButtonOptions{Variant: mujica.Secondary, Disabled: s.current == 0}).Clicked() {
|
|
s.current--
|
|
log(fmt.Sprintf("Back: step %d", s.current+1))
|
|
}
|
|
if mujica.Button(c, "Next", mujica.ButtonOptions{Disabled: s.current == len(steps)}).Clicked() {
|
|
s.current++
|
|
log(fmt.Sprintf("Next: step %d", s.current+1))
|
|
}
|
|
}, func() {
|
|
for i := range steps {
|
|
steps[i].Clickable = s.clickOK && i < s.current
|
|
}
|
|
steps[2].Error = s.failed
|
|
if mujica.Steps(c, &s.current, steps, mujica.StepsOptions{Vertical: s.vertical, Label: "Sign-up"}).Changed() {
|
|
log("Changed: step " + steps[s.current].Title)
|
|
}
|
|
})
|
|
}
|
|
|
|
const navigationSidebarCode = `mujica.Sidebar(c, &selected, []mujica.SidebarSection{
|
|
{Title: "Mail", Items: []mujica.SidebarItem{
|
|
{ID: "inbox", Label: "Inbox", Icon: icons.Must("inbox"), Count: 3},
|
|
{Label: "Folders", Items: []mujica.SidebarItem{{ID: "work", Label: "Work", Icon: icons.Must("folder")}}},
|
|
}},
|
|
}, mujica.SidebarOptions{})`
|
|
|
|
func navigationSidebarDemo(c *ui.Context, log func(string)) {
|
|
type state struct {
|
|
selected string
|
|
compact bool
|
|
unread float64
|
|
}
|
|
s := ui.Local(c.Root(), "064", func() state { return state{selected: "inbox", unread: 12} })
|
|
navigationDemo(c, func() {
|
|
navigationCheck(c, &s.compact, "Compact", log)
|
|
navigationSlider(c, &s.unread, "Unread", 0, 1200, log)
|
|
}, func() {
|
|
sections := []mujica.SidebarSection{
|
|
{Title: "Library", Items: []mujica.SidebarItem{
|
|
{ID: "inbox", Label: "Inbox", Icon: icons.Must("inbox"), Count: int(s.unread)},
|
|
{ID: "starred", Label: "Starred", Icon: icons.Must("star")},
|
|
{Label: "Projects", Items: []mujica.SidebarItem{
|
|
{ID: "opera", Label: "Opera", Icon: icons.Must("folder")},
|
|
{ID: "ballet", Label: "Ballet", Icon: icons.Must("folder")},
|
|
}},
|
|
}},
|
|
{Title: "System", Items: []mujica.SidebarItem{
|
|
{ID: "settings", Label: "Settings", Icon: icons.Must("settings")},
|
|
{ID: "trash", Label: "Trash", Icon: icons.Must("trash-2")},
|
|
}},
|
|
}
|
|
ui.Row(c).Height(360).Border(1, mujica.Tokens(c).Border).Radius(4).Clip().Children(func() {
|
|
if mujica.Sidebar(c, &s.selected, sections, mujica.SidebarOptions{Compact: s.compact}).Changed() {
|
|
log("Changed: " + s.selected)
|
|
}
|
|
ui.Text(c, "Showing "+s.selected).Padding(24)
|
|
})
|
|
})
|
|
}
|
|
|
|
const navigationMenuCode = `mujica.NavigationMenu(c, router, []mujica.NavigationLink{
|
|
{Label: "Home", Path: "/"},
|
|
{Label: "Library", Items: []mujica.NavigationLink{
|
|
{Label: "Poems", Path: "/library/poems", Description: "Verse of the court"},
|
|
}},
|
|
}, mujica.NavigationMenuOptions{History: true})
|
|
router.View(c, func(r *ui.Route) { ui.Text(c, r.Path()) })`
|
|
|
|
func navigationMenuDemo(c *ui.Context, log func(string)) {
|
|
type state struct {
|
|
router *ui.Router
|
|
history bool
|
|
last string
|
|
}
|
|
s := ui.Local(c.Root(), "065", func() state { return state{router: ui.NewRouter("/"), history: true, last: "/"} })
|
|
navigationDemo(c, func() {
|
|
navigationCheck(c, &s.history, "Back and forward", log)
|
|
}, func() {
|
|
mujica.NavigationMenu(c, s.router, []mujica.NavigationLink{
|
|
{Label: "Home", Path: "/", Icon: icons.Must("house")},
|
|
{Label: "Library", Items: []mujica.NavigationLink{
|
|
{Label: "Poems", Path: "/library/poems", Description: "Verse of the court"},
|
|
{Label: "Letters", Path: "/library/letters", Description: "Correspondence"},
|
|
{Label: "Archive", Items: []mujica.NavigationLink{
|
|
{Label: "Older letters", Path: "/archive/letters"},
|
|
}},
|
|
}},
|
|
{Label: "About", Path: "/about"},
|
|
}, mujica.NavigationMenuOptions{History: s.history})
|
|
if p := s.router.Path(); p != s.last {
|
|
log(fmt.Sprintf("Path: %s → %s", s.last, p))
|
|
s.last = p
|
|
}
|
|
ui.Column(c).Height(120).Children(func() {
|
|
s.router.View(c, func(r *ui.Route) {
|
|
r.Title(r.Path())
|
|
ui.Text(c, "Page "+r.Path()).Padding(16)
|
|
})
|
|
})
|
|
})
|
|
}
|
|
|
|
const navigationMenubarCode = `res := mujica.Menubar(c, []mujica.MenubarMenu{
|
|
{Label: "File", Items: []mujica.MenubarItem{
|
|
{ID: "new", Label: "New", Shortcut: mujica.MenubarShortcut{Mods: ui.Cmd, Key: ui.KeyN}},
|
|
{Label: "Export", Items: []mujica.MenubarItem{{ID: "pdf", Label: "PDF"}}},
|
|
}},
|
|
{Label: "View", Items: []mujica.MenubarItem{
|
|
{ID: "wrap", Label: "Word wrap", Kind: mujica.MenubarCheck, Checked: wrap},
|
|
}},
|
|
}, mujica.MenubarOptions{})
|
|
if id, ok := res.Chosen(); ok && id == "wrap" {
|
|
wrap = !wrap
|
|
}`
|
|
|
|
func navigationMenubarDemo(c *ui.Context, log func(string)) {
|
|
type state struct {
|
|
wrap, ruler, locked bool
|
|
zoom string
|
|
}
|
|
s := ui.Local(c.Root(), "066", func() state { return state{wrap: true, zoom: "fit"} })
|
|
navigationDemo(c, func() {
|
|
navigationCheck(c, &s.locked, "Lock editing (disables Edit items)", log)
|
|
}, func() {
|
|
menus := []mujica.MenubarMenu{
|
|
{Label: "File", Items: []mujica.MenubarItem{
|
|
{ID: "new", Label: "New", Shortcut: mujica.MenubarShortcut{Mods: ui.Cmd, Key: ui.KeyN}},
|
|
{ID: "open", Label: "Open…", Shortcut: mujica.MenubarShortcut{Mods: ui.Cmd, Key: ui.KeyO}},
|
|
{Label: "Export", Items: []mujica.MenubarItem{
|
|
{ID: "pdf", Label: "PDF"},
|
|
{ID: "png", Label: "Image"},
|
|
{Label: "Archive", Items: []mujica.MenubarItem{{ID: "zip", Label: "Zip"}, {ID: "tar", Label: "Tarball"}}},
|
|
}},
|
|
{Kind: mujica.MenubarSeparator},
|
|
{ID: "quit", Label: "Quit", Shortcut: mujica.MenubarShortcut{Mods: ui.Cmd, Key: ui.KeyQ}},
|
|
}},
|
|
{Label: "Edit", Items: []mujica.MenubarItem{
|
|
{ID: "undo", Label: "Undo", Disabled: s.locked, Shortcut: mujica.MenubarShortcut{Mods: ui.Cmd, Key: ui.KeyZ}},
|
|
{ID: "redo", Label: "Redo", Disabled: s.locked, Shortcut: mujica.MenubarShortcut{Mods: ui.Cmd | ui.Shift, Key: ui.KeyZ}},
|
|
}},
|
|
{Label: "View", Items: []mujica.MenubarItem{
|
|
{ID: "wrap", Label: "Word wrap", Kind: mujica.MenubarCheck, Checked: s.wrap},
|
|
{ID: "ruler", Label: "Ruler", Kind: mujica.MenubarCheck, Checked: s.ruler},
|
|
{Kind: mujica.MenubarSeparator},
|
|
{ID: "fit", Label: "Fit to window", Kind: mujica.MenubarRadio, Checked: s.zoom == "fit"},
|
|
{ID: "actual", Label: "Actual size", Kind: mujica.MenubarRadio, Checked: s.zoom == "actual"},
|
|
}},
|
|
}
|
|
ui.Column(c).Height(260).Border(1, mujica.Tokens(c).Border).Radius(4).Clip().Children(func() {
|
|
if id, ok := mujica.Menubar(c, menus, mujica.MenubarOptions{}).Chosen(); ok {
|
|
switch id {
|
|
case "wrap":
|
|
s.wrap = !s.wrap
|
|
case "ruler":
|
|
s.ruler = !s.ruler
|
|
case "fit", "actual":
|
|
s.zoom = id
|
|
}
|
|
log("Chosen: " + id)
|
|
}
|
|
ui.Text(c, fmt.Sprintf("Word wrap %v · Ruler %v · Zoom %s", s.wrap, s.ruler, s.zoom)).Padding(16)
|
|
})
|
|
})
|
|
}
|
|
|
|
const navigationToolbarCode = `mujica.Toolbar(c, mujica.ToolbarOptions{Label: "Format"}, func() {
|
|
mujica.ToolbarGroup(c, func() {
|
|
mujica.ToolbarButton(c, "Bold", mujica.ToolbarButtonOptions{Icon: icons.Must("bold")})
|
|
mujica.ToolbarButton(c, "Italic", mujica.ToolbarButtonOptions{Icon: icons.Must("italic")})
|
|
})
|
|
mujica.ToolbarSeparator(c)
|
|
if mujica.ToolbarButton(c, "Copy", mujica.ToolbarButtonOptions{Icon: icons.Must("copy"), ShowLabel: true}).Clicked() {
|
|
copySelection()
|
|
}
|
|
})`
|
|
|
|
func navigationToolbarDemo(c *ui.Context, log func(string)) {
|
|
type state struct {
|
|
width float64
|
|
labels bool
|
|
noDeletes bool
|
|
}
|
|
s := ui.Local(c.Root(), "067", func() state { return state{width: 520, noDeletes: true} })
|
|
navigationDemo(c, func() {
|
|
navigationSlider(c, &s.width, "Width", 120, 640, log)
|
|
navigationCheck(c, &s.labels, "Show labels", log)
|
|
navigationCheck(c, &s.noDeletes, "Disable Delete", log)
|
|
}, func() {
|
|
ui.Column(c).Width(float32(s.width)).Children(func() {
|
|
mujica.Toolbar(c, mujica.ToolbarOptions{Label: "Format"}, func() {
|
|
button := func(label, icon string, disabled bool) {
|
|
if mujica.ToolbarButton(c, label, mujica.ToolbarButtonOptions{Icon: icons.Must(icon), ShowLabel: s.labels, Disabled: disabled}).Clicked() {
|
|
log("Clicked: " + label)
|
|
}
|
|
}
|
|
mujica.ToolbarGroup(c, func() {
|
|
button("Bold", "bold", false)
|
|
button("Italic", "italic", false)
|
|
button("Underline", "underline", false)
|
|
})
|
|
mujica.ToolbarSeparator(c)
|
|
button("Copy", "copy", false)
|
|
button("Image", "image", false)
|
|
button("Delete", "trash-2", s.noDeletes)
|
|
mujica.ToolbarSeparator(c)
|
|
button("Settings", "settings", false)
|
|
})
|
|
})
|
|
})
|
|
}
|
|
|
|
const navigationPaletteCode = `res := mujica.CommandPalette(c, &open, []mujica.Command{
|
|
{ID: "new", Label: "New document", Group: "File"},
|
|
{ID: "theme", Label: "Toggle dark mode", Group: "View", Keywords: []string{"night"}},
|
|
}, mujica.CommandPaletteOptions{})
|
|
if id, ok := res.Chosen(); ok {
|
|
run(id)
|
|
}`
|
|
|
|
func navigationPaletteDemo(c *ui.Context, log func(string)) {
|
|
type state struct{ open, wasOpen bool }
|
|
s := ui.Local(c.Root(), "068", func() state { return state{} })
|
|
navigationDemo(c, func() {
|
|
if mujica.Button(c, "Open command palette", mujica.ButtonOptions{Icon: icons.Must("command")}).Clicked() {
|
|
s.open = true
|
|
}
|
|
ui.Text(c, "or press Cmd+K / Ctrl+K").TextColor(mujica.Tokens(c).TextMuted)
|
|
}, func() {
|
|
res := mujica.CommandPalette(c, &s.open, []mujica.Command{
|
|
{ID: "new", Label: "New document", Group: "File", Icon: icons.Must("file")},
|
|
{ID: "open", Label: "Open recent", Group: "File", Icon: icons.Must("folder")},
|
|
{ID: "save", Label: "Save all", Group: "File", Icon: icons.Must("file-text")},
|
|
{ID: "theme", Label: "Toggle dark mode", Group: "View", Keywords: []string{"theme", "night"}, Icon: icons.Must("moon")},
|
|
{ID: "zoom-in", Label: "Zoom in", Group: "View", Icon: icons.Must("zoom-in")},
|
|
{ID: "zoom-out", Label: "Zoom out", Group: "View", Icon: icons.Must("zoom-out")},
|
|
{ID: "settings", Label: "Open settings", Group: "Application", Keywords: []string{"preferences"}, Icon: icons.Must("settings")},
|
|
}, mujica.CommandPaletteOptions{})
|
|
if s.open != s.wasOpen {
|
|
log(fmt.Sprintf("Open: %v", s.open))
|
|
s.wasOpen = s.open
|
|
}
|
|
if id, ok := res.Chosen(); ok {
|
|
log("Run: " + id)
|
|
}
|
|
})
|
|
}
|