Documentation
¶
Overview ¶
Package examples (continued)
Package examples (continued)
Package examples (continued)
Package examples (continued)
Package examples (continued)
Package examples (continued)
Package examples (continued)
Package examples (continued)
Package examples (continued)
Package examples (continued)
Package examples (continued)
Package examples (continued)
Package examples (continued)
Package examples (continued)
Package examples (continued)
Package examples (continued)
Package examples (continued)
Package examples (continued)
Package examples (continued)
Package examples (continued)
Package examples (continued)
Package examples (continued)
Package examples (continued)
Package examples (continued)
Package examples (continued)
Package examples — Go-only nested Card demo (callout/code inside a card). Validates docs/GO_FIRST_UI.md: nesting is a Card layout concern, not JSON-only.
Package examples contains self-contained Gru demo scenes.
Package examples — development helpers (Air, local iteration).
Package examples — shared file-dialog helpers (all platforms).
Package examples — native file dialogs for reference apps (Windows, macOS, Linux).
Package examples (continued)
Package examples — FlexCopy helpers for flex-column body copy in demos.
Use FlexCopy / FlexCopyPair instead of NewLabel + form-* styles in scroll pages and panel bodies. Label is for fixed chrome only (see docs/HYGIENE_AUDIT.md §7).
Package examples (continued)
Package examples — docked ListTile list pane in SplitView (Open Notes / master-list pattern). Recipe: CP-SHELL-EDGE + CP-LIST-PANE-01 (see docs/COMPOSITION_PATTERNS.md §11).
Package examples — docked list-pane shell (master list in SplitView).
Package examples — shared Remix icon wiring for Go-first demos.
Package examples (continued)
Package examples provides self-contained Gru demo scenes.
Go is the engine; declarative pages compile to the same widgets via ui.BuildDocumentSpec (see docs/GO_FIRST_UI.md). Scenes here are the native reference for layout patterns that work.
Each demo implements the Scene interface. Register a factory function with Register(); main.go calls Build() on the active scene and Destroy() when switching away — ensuring textures and signals are cleaned up promptly.
To add a new demo:
- Create a new file in this package.
- Define a struct that embeds BaseScene (or implements Scene directly).
- Implement Title(), Build(*ui.Document), and Destroy().
- Call Register() in an init() function.
Prefer MountAppPage or MountPageGrid (page_shell.go) in Build so the tree follows Root (absolute) → page shell → Viewport → Panel → flex.
Package examples (continued)
Package examples — desktop settings under MenuBar (no AppBar). Reference for Notepad-style in-shell settings.
Package examples — desktop settings row helpers (panel + flat layouts).
Package examples (continued)
Package examples — shared helpers for SplitView / ResizablePanel demos (Phase A).
Package examples (continued)
Index ¶
- Constants
- Variables
- func AppBarBackButton(id string) *ui.IconButton
- func AppBarLeadingMenu(id string) *ui.IconButton
- func AppBarMenuButton(id string) *ui.IconButton
- func AppIconPNG() string
- func ConfigureTitleBar(tb *ui.TitleBar, scene Scene)
- func DefaultSaveName(path string) string
- func DevOpenFilePath() string
- func DevSceneTitle() string
- func FilterPublicFactories(all []func() Scene) []func() Scene
- func FinishShellMount(doc *ui.Document)
- func FlexCopy(id, style, text string) *ui.RichText
- func FlexCopyMirror(id, style string, src *ui.Signal[string], prefix string) *ui.RichText
- func FlexCopyPair(id, style, initial string) (*ui.RichText, *ui.Signal[string])
- func HandleDemoLink(link string, status *ui.RichText)
- func IndexOfPublicStart(factories []func() Scene) int
- func IsPublicDemoTitle(title string) bool
- func MountDesktopPageShell(doc *ui.Document, id string) (*ui.Container, *ui.Container)
- func MountEdgeToEdgeRoot(doc *ui.Document, id string, row bool) *ui.Container
- func MountFlexPageShell(doc *ui.Document, id string) (*ui.Container, *ui.Viewport)
- func MountPageGrid(doc *ui.Document, id string) *ui.Container
- func MountSceneHeader(vp *ui.Viewport, id, title, subtitle string) *ui.Header
- func NavigateFromDemoLink(link string) bool
- func NewAppShellScrollViewport(id string) *ui.Viewport
- func NewBatchEqualFillGrid(id string, gap float32) *ui.Container
- func NewBatchPageGrid(id string, gap float32) *ui.Container
- func PickHTMLReportSave(defaultName string) (string, error)
- func PickPNGSave(defaultName string) (string, error)
- func PickPlanJSONOpen() (string, error)
- func PickTextFileOpen() (string, error)
- func PickTextFileSave(defaultName string) (string, error)
- func PreloadSceneIcons(doc *ui.Document)
- func PreloadScenePhosphor(doc *ui.Document)deprecated
- func PublicDemoMode() bool
- func PublicSceneTitles() []string
- func Register(factory func() Scene)
- func RegisterFirst(factory func() Scene)
- func Registered() []func() Scene
- func RegisteredSceneCount() int
- func RegistryTitle(index int) string
- func ResolveStartupSceneIndex(factories []func() Scene, defaultIndex int) int
- func SetInstanceOpenFileHandler(func(string))
- func StartupInstance(forwardPath string) (exit bool, stop func())
- func StartupOpenFilePath() string
- func UpdateShellFooterAutoHide(footer ui.Node, doc *ui.Document)
- type AppPage
- type AppShellMount
- type BaseScene
- type GRUPageReloader
- type ListPane
- type ListPaneOptions
- type Scene
- type TitleBarChrome
Constants ¶
const DirectorySceneTitle = "Demo Directory"
DirectorySceneTitle is the launcher hub scene; main.go starts here when registered.
const NotepadSceneTitle = "Notepad (Go)"
NotepadSceneTitle is the Gru Notepad scene id (private product). Kept in a tiny shared file so non-Notepad builds (Studio / grudemo / public export) can reference the name without compiling notepad_demo.go.
const PublicDemoStartTitle = "Counter Demo"
PublicDemoStartTitle is the first scene when running with -tags grudemo.
const PublicDirectorySceneTitle = "Demo Index"
PublicDirectorySceneTitle is the grudemo scene picker (footer Scenes button).
Variables ¶
var ErrFileDialogCancelled = errors.New("file dialog cancelled")
ErrFileDialogCancelled is returned when the user dismisses a native dialog.
ErrFileDialogUnavailable is returned on platforms without native pickers yet (Android v1).
NavigateToScene is set by main.go to switch demo scenes by Title(). Returns true when the scene exists (even if already active).
Functions ¶
func AppBarBackButton ¶
func AppBarBackButton(id string) *ui.IconButton
AppBarBackButton returns a leading AppBar control (caret-left).
func AppBarLeadingMenu ¶
func AppBarLeadingMenu(id string) *ui.IconButton
AppBarLeadingMenu returns a leading navigation control (list / “hamburger”).
func AppBarMenuButton ¶
func AppBarMenuButton(id string) *ui.IconButton
AppBarMenuButton returns a trailing overflow control (dots-three).
func AppIconPNG ¶
func AppIconPNG() string
AppIconPNG returns the baked OS app icon PNG path, or "" if missing. Regenerate with: go run ./scripts/build/gen_app_icon.go
func ConfigureTitleBar ¶
ConfigureTitleBar applies scene chrome preferences to the borderless title bar.
func DefaultSaveName ¶
DefaultSaveName returns a filename hint from the current path or untitled.txt.
func DevOpenFilePath ¶
func DevOpenFilePath() string
DevOpenFilePath returns GRU_OPEN_FILE when set (GORY_OPEN_FILE alias; path passed to Notepad on Build).
func DevSceneTitle ¶
func DevSceneTitle() string
DevSceneTitle returns GRU_SCENE when set (GORY_SCENE alias; exact match to Scene.Title()).
func FilterPublicFactories ¶
FilterPublicFactories keeps only allowlisted scene factories, in allowlist order. Factories whose Title() is not on the list are dropped. Missing titles are skipped (so a not-yet-registered demo does not break the launcher).
func FinishShellMount ¶
FinishShellMount runs layout passes after scene Build + Document.Resize. main.go calls this once per loadScene (scenes should not call it from Build — that runs before Resize and freezes wrong AutoHeight measures until a nudge).
func FlexCopyMirror ¶
FlexCopyMirror keeps PlainText in sync with src, optionally with a string prefix.
func FlexCopyPair ¶
FlexCopyPair returns PlainText bound to a display signal you update.
func HandleDemoLink ¶
HandleDemoLink navigates when possible; otherwise writes a status message.
func IndexOfPublicStart ¶
IndexOfPublicStart returns the index of PublicDemoStartTitle in factories, or 0 if not found.
func IsPublicDemoTitle ¶
IsPublicDemoTitle reports whether title is on the frozen public allowlist.
func MountDesktopPageShell ¶
MountDesktopPageShell mounts the architecture page shell (sole direct child of Root, sized to doc, flex column) with a flex-row workspace for NavigationRail + content.
Root → shell (flex column) → [optional MenuBar] → workspace (flex row, flex-grow) → rail | main → [optional StatusBar]
Demos insert full-width MenuBar / StatusBar as direct shell children (not beside the rail). Same resize contract as MountFlexPageShell (Document.fitRootChildrenToContent + applyShellFlexAndSyncRootLayout). Add rail and main to workspace, viewport inside main.
func MountEdgeToEdgeRoot ¶
MountEdgeToEdgeRoot clears the document root and adds a full-content flex row/column shell (no page-shell inset). Prefer MountDesktopPageShell for rail + AppBar scenes.
func MountFlexPageShell ¶
MountFlexPageShell mounts a scrollable page without a title header.
func MountPageGrid ¶
MountPageGrid clears the document root and adds a single full-window responsive page grid (see ui.NewPageGrid). Add grid children with default ColSpan (full row) or SetColSpan for breakpoint-aware spans.
Root (absolute) → **page grid** → your Viewports / panels.
func MountSceneHeader ¶
MountSceneHeader adds a page Header inside a scroll viewport (first row of the document). Prefer MountAppPage title/subtitle args for new scenes.
func NavigateFromDemoLink ¶
NavigateFromDemoLink switches scenes for known demo:// page links.
func NewAppShellScrollViewport ¶
NewAppShellScrollViewport returns the page-scroll viewport for app-shell scenes. Add as a direct child of the shell (flex-grow 1) between pinned chrome rows.
func NewBatchEqualFillGrid ¶
NewBatchEqualFillGrid fills the viewport band with equal-height rows — use only when the demo intentionally fills one screen with no page scroll (e.g. a single full-viewport fixture). Split showcases with multiple sections should use NewBatchPageGrid + fixed section heights (see batch8_demo.go).
func NewBatchPageGrid ¶
NewBatchPageGrid returns the standard shrink-wrap 12-column grid for batch demos (docs/LAYOUT_CONTRACTS.md §7). Panels use intrinsic height; rows do not equal-fill the viewport unless you opt into NewBatchEqualFillGrid.
func PickHTMLReportSave ¶
PickHTMLReportSave shows the OS save-file dialog for an HTML plan report.
func PickPNGSave ¶
PickPNGSave shows the OS save-file dialog for a PNG image.
func PickPlanJSONOpen ¶
PickPlanJSONOpen shows the OS open-file dialog for terraform plan JSON.
func PickTextFileOpen ¶
PickTextFileOpen shows the OS open-file dialog for text documents.
func PickTextFileSave ¶
PickTextFileSave shows the OS save-file dialog. defaultName may be empty.
func PreloadSceneIcons ¶
PreloadSceneIcons warms Remix icon-font glyphs used by shell and form demos.
func PreloadScenePhosphor
deprecated
func PublicDemoMode ¶
func PublicDemoMode() bool
PublicDemoMode is false for Studio / Notepad / Prism builds.
func PublicSceneTitles ¶
func PublicSceneTitles() []string
PublicSceneTitles returns a copy of the frozen allowlist (stable order).
func Register ¶
func Register(factory func() Scene)
Register appends a scene factory to the global list. Call from init() in each demo file so main.go doesn't need to import individual scenes.
func RegisterFirst ¶
func RegisterFirst(factory func() Scene)
RegisterFirst prepends a scene so it appears first in Tab order (use for the demo directory).
func Registered ¶
func Registered() []func() Scene
Registered returns a snapshot of all registered factory functions. main.go calls this once after init() functions have run.
func RegisteredSceneCount ¶
func RegisteredSceneCount() int
RegisteredSceneCount returns the number of registered demo scenes.
func RegistryTitle ¶
RegistryTitle returns the title for a registered scene index.
func ResolveStartupSceneIndex ¶
ResolveStartupSceneIndex picks the scene index for main.go startup. When GRU_SCENE (or GORY_SCENE alias) is set, the first factory whose Title() matches wins. On Android, defaults to Notepad when unset.
func SetInstanceOpenFileHandler ¶
func SetInstanceOpenFileHandler(func(string))
func StartupInstance ¶
func StartupOpenFilePath ¶
func StartupOpenFilePath() string
StartupOpenFilePath returns a file to open on launch: first non-flag CLI arg, then GRU_OPEN_FILE / GORY_OPEN_FILE (Air/dev). Windows Explorer "Open with" passes the selected file as argv[1].
Types ¶
type AppPage ¶
type AppPage struct {
// Frame is a full-client flex wrapper (transparent, no padding). It exists
// only for Document.Resize — the scroll viewport is the real page surface.
Frame *ui.Container
Body *ui.Viewport
Header *ui.Header // nil when title is empty; lives inside Body (scrolls with the page)
// Shell aliases Frame for callers that still use page.Shell.
Shell *ui.Container
}
AppPage is the set-and-forget page chrome from MountAppPage.
func MountAppPage ¶
MountAppPage mounts the web-faithful scrollable page:
TitleBar (window chrome, outside doc tree)
Root → frame (full client, no inset) → page-scroll Viewport (1:1 with client area)
└── [Header] + your grids/panels — all page content scrolls inside the viewport
Pass empty title to omit the header. Add grids and panels to Body. Margins and the scrollbar gutter are owned by page-scroll inside the viewport.
type AppShellMount ¶
AppShellMount is a single flex-column shell filling the document content band. Add AppBar, page-scroll Viewport, and optional footer as direct shell children.
func MountAppShellRoot ¶
func MountAppShellRoot(doc *ui.Document, id string) AppShellMount
MountAppShellRoot clears Root and mounts one transparent flex-column shell. Window chrome (title bar, launcher nav) is handled by Document — do not add an extra appshell-content body wrapper around the scroll viewport.
type BaseScene ¶
type BaseScene struct{}
BaseScene is an embeddable struct that provides no-op implementations of Destroy and OnUpdate. Embed it in your scene struct to avoid boilerplate when you have nothing to clean up or update manually.
func (BaseScene) Destroy ¶
func (BaseScene) Destroy()
Destroy is a no-op. Override in your scene struct if you hold GPU resources.
func (BaseScene) HideDemoNav ¶
HideDemoNav is false by default; override on product-style scenes (e.g. Notepad).
type GRUPageReloader ¶
type GRUPageReloader struct {
LogicalPath string
VP *ui.Viewport
Ctx *ui.BuildContext
MutateSpec func(*ui.DocumentSpec)
AfterBuild func(ui.Node)
// PreserveControls keeps ControlSnapshot values and viewport ScrollY across reloads.
PreserveControls bool
// contains filtered or unexported fields
}
GRUPageReloader watches a .gru file and swaps the compiled page body when it changes. Go-owned shell (header, BuildContext actions) stays mounted; only the spec body rebuilds.
Reload detection uses fsnotify when available, with per-frame ModTime polling as backup. When PreserveControls is true (default), form values and page scroll position survive reload.
func (*GRUPageReloader) Close ¶
func (r *GRUPageReloader) Close()
Close stops the fsnotify watcher. Call from Scene.Destroy when leaving a .gru demo.
func (*GRUPageReloader) Compile ¶
func (r *GRUPageReloader) Compile() (ui.Node, error)
Compile reads and builds the current .gru file.
func (*GRUPageReloader) MountShell ¶
func (r *GRUPageReloader) MountShell(doc *ui.Document, shellID, hdrTitle, hdrSubtitle string, body ui.Node) *ui.Viewport
MountShell mounts the page viewport shell and records the file mod time.
func (*GRUPageReloader) Poll ¶
func (r *GRUPageReloader) Poll(doc *ui.Document)
Poll reloads the body when the .gru file changes on disk.
type ListPane ¶
type ListPane struct {
Root *ui.Container
Hdr *ui.Container
Title *ui.Label
Collapse *ui.IconButton
Scroll *ui.Viewport
List *ui.Container
PreferredWidth float32
MinWidth float32
}
ListPane is a flat grey sidebar: customizable header + flush scroll + row list.
func NewListPane ¶
func NewListPane(doc *ui.Document, opts ListPaneOptions) *ListPane
NewListPane builds a borderless list column. Add rows to List; scrollbar aligns with the split edge.
type ListPaneOptions ¶
type ListPaneOptions struct {
ID string
Title string
TitleStyle string // theme key; default list-pane-header-title
PreferredWidth float32
MinWidth float32
ShowCollapse bool
OnCollapse func()
}
ListPaneOptions configures a flat, borderless list sidebar.
type Scene ¶
type Scene interface {
Title() string
Build(doc *ui.Document)
Destroy()
OnUpdate(doc *ui.Document, dt float32)
// be hidden so the scene uses the full client area (reference apps, utilities).
HideDemoNav() bool
}
Scene is the lifecycle interface every demo scene must implement.
- Title — short name shown in the window title bar and nav strip.
- Build — construct the widget tree into doc; called once on activation.
- Destroy — release any GPU resources (textures, render targets) not managed by doc itself; called before the scene is replaced.
- OnUpdate — optional per-frame hook; called after doc.Root.Update(dt). Use it for tween ticks, focus management, key shortcuts, etc. Implementations that don't need per-frame work can embed BaseScene, which provides a no-op OnUpdate.
type TitleBarChrome ¶
type TitleBarChrome interface {
TitleBarShowTitle() bool
TitleBarShowAppIcon() bool
TitleBarCenterText() string
}
TitleBarChrome optionally overrides custom title bar content. OS window title (taskbar tooltip) may still be set separately via rl.SetWindowTitle.
Source Files
¶
- appshell_demo.go
- batch11_date_range_demo.go
- batch12_rating_demo.go
- batch13_pagination_demo.go
- batch14_segmented_demo.go
- batch15_combobox_demo.go
- batch16_spinbox_demo.go
- batch17_breadcrumbs_demo.go
- batch18_colorwell_demo.go
- batch19_dropdown_demo.go
- batch1_demo.go
- batch20_radiogroup_demo.go
- batch21_listtile_demo.go
- batch22_toggle_demo.go
- batch23_checkbox_demo.go
- batch24_slider_demo.go
- batch25_progressbar_demo.go
- batch26_colorpicker_demo.go
- batch2_demo.go
- batch3_datepicker_demo.go
- batch3_demo.go
- batch3b_demo.go
- batch4_demo.go
- batch6_demo.go
- batch7_demo.go
- batch_caption.go
- card_nest_demo.go
- counter_demo.go
- dev_env.go
- dev_env_startup_default.go
- document_gallery_demo.go
- filedialog_common.go
- filedialog_desktop.go
- filters_demo.go
- flex_copy.go
- form_demo.go
- gru_hot_reload.go
- gru_page.go
- list_pane_demo.go
- list_pane_shell.go
- notepad_instance_stub.go
- packaging_paths.go
- page_grid.go
- page_shell.go
- phosphor_chrome.go
- public_catalog.go
- public_demo_mode.go
- public_directory_demo.go
- responsive_demo.go
- scene.go
- scene_nav.go
- scene_product_titles.go
- settings_demo.go
- settings_desktop_demo.go
- settings_desktop_rows.go
- shell_chrome.go
- shell_desktop_demo.go
- split_demo_helpers.go
- theme_v2_demo.go
- timeline_demo.go
- titlebar_chrome.go
- webview_demo.go
- webview_focus_demo.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package appinstance forwards startup files to an already-running Gru Notepad.
|
Package appinstance forwards startup files to an already-running Gru Notepad. |
|
Package startuppath resolves optional file paths from argv and environment.
|
Package startuppath resolves optional file paths from argv and environment. |