vshell.h Header

#include <vshell.h>

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.

Appearance
Theme
—