vshell.h Header
Types
| struct | TabPane | A titlebar tab paired with the body pane it reveals. The tab lives under <window>/Titlebar/Right Tabs/<tab>; the pane is a sibling node <window>/<pane>. Clicking the tab shows its pane (and the @Selected highlight) and hides every other tab's pane — so each tab owns its own content, hidden until activated. |
| class | WindowTabs | Single-select controller for a window's tabs. At most one registered tab is active: its pane is shown, every other registered pane is hidden, and the active highlight is moved to it. It unifies STATIC titlebar tabs (registered once at wire time — App, Settings) with DYNAMIC tabs spawned at runtime (the left tabs: a node session and, later, the profiles opened within it), so they share ONE selection — activating a left tab deselects App/Settings and vice-versa. The framework's right tabs highlight with the Selected state; left tabs use Active (their template's highlight) — hence the per-tab state name. Created and pre-populated by wire_main_window_shell(), which returns it so app code can register/close its own dynamic tabs. |
Functions
| std::shared_ptr<WindowTabs> | wire_main_window_shell(VApp & app, const std::string & root = "App", const std::string & mainWindow = "Main Window", const std::vector<TabPane> & extraTabs = {}, const std::vector<TabPane> & extraSettingsTabs = {}) |
| void | wire_update_prompt(VApp & app, const std::string & root = "App", const std::string & mainWindow = "Main Window") |
| void | build_app(VApp & app) |
Function Documentation
std::shared_ptr<WindowTabs> wire_main_window_shell(VApp & app, const std::string & root = "App", const std::string & mainWindow = "Main Window", const std::vector<TabPane> & extraTabs = {}, const std::vector<TabPane> & extraSettingsTabs = {})
Install the standard Main Window shell behavior on app, rooted under the
app's top-level root style (the "App" style that lists the app's top-level
widgets — see the App-root convention). Wires: single-select titlebar tabs to
their body panes (App Tab -> "App Pane", Settings Tab -> "Settings Menu"), the
appearance/theme tab selected states, and the theme-directories dialog
open/close (when the app's root includes a "Theme Directories Dialog"
top-level widget). Safe to call when the dialog isn't present — its handlers
simply never fire.
mainWindow is the NAME of the window node under root. It defaults to the
shell's "Main Window", but an app that adds a window which inherits Main
Window under a different name (e.g. "nodeyou Window") passes that name so the
wiring targets the right node — the shell structure is inherited regardless.
extraTabs are app-added tab/pane pairs appended to the two framework
built-ins: add the tab to the titlebar's Right Tabs and a sibling pane under
the window in your styles, then pass {tab, pane} here to wire its swap. The
first tab overall (App Tab) is the one shown at startup.
The Settings Menu's own sidebar is a second single-select of the same shape:
the framework provides the App tab (the "App Settings" pane, opening with
the Version section — see wire_update_prompt) and the Appearance tab (the
theme pane), App selected at startup. extraSettingsTabs are app-added
sidebar entries: add the tab under the Settings Menu's Sidebar and a
sibling pane under the Settings Menu in your styles (both merge AFTER the
framework's — sidebar order is App, Appearance, then yours), then pass
{tab, pane} here to wire its swap.
Returns the WindowTabs controller, pre-populated with the framework + extra tabs and with the first one active. App code can register its own DYNAMIC tabs on it (e.g. node-session left tabs) so they share the same single selection; callers that only need the static tabs may ignore the return.
void wire_update_prompt(VApp & app, const std::string & root = "App", const std::string & mainWindow = "Main Window")
Install the standard update prompt (plans/08): the "Update Dialog" top-level
widget (add Update Dialog << Vortex/Update Dialog beside the window in
your App root, like the theme-directories dialog) plus the App settings
pane's Version section — its version line (the running app_version(), or
"Development Build" when none is set) and its "Check for Updates" button.
Called by wire_main_window_shell, so apps get it for free; exposed for an
app that skips the stock shell.
Reads the update channel's options off env() (the desktop runner publishes them from DesktopAppConfig — see vupdate.h). Unconfigured — web/Android, dev runs, apps that never opted in — the check button is hidden (the version line stays) and nothing is scheduled or fetched. Configured: a QUIET check fires a few seconds after launch and every checkHours thereafter, prompting only for a fresh release the user hasn't skipped; the check button runs the same check LOUDLY, reporting checking / up-to-date / failure states in the dialog too (and showing a skipped release again — asking is the un-skip). Dialog actions: Download (open_url, then close), Release Notes (open_url), Skip This Version (persists kUpdateSkipVersionKey), Later/Close (dismiss).
void build_app(VApp & app)
The application entry point, DEFINED BY EACH APP (the demo, nodeyou, ...) and called once at startup by every platform shell (desktop run_desktop(), the web/Android bridges). Apply the root style, reuse the shell via wire_main_window_shell(), bind content, and wire app-specific interaction.