Tryst::UI::Session
Inherits Tryst::UI::WidgetDSL < Reference < Object
The object yielded to (and returned by) Tryst::UI.app - owns the build-phase Document and the realize/run lifecycle, and (via WidgetDSL) the ui.<widget> build surface itself.
Building is Tk-free: Tryst::UI.app never constructs a Tryst::App, so the block runs (and #document is buildable/inspectable) with no interpreter at all. Nothing talks to Tk until #realize (called by #run and #run_async, or directly) actually creates one and walks the tree into it via Realizer.
Vars and images are both realized ahead of the widget tree, so a widget's bind: or image: is already backed by the time it's created - in #realize, in #add for anything declared inside the block, and dropped again by #add's rollback.
Constants
How long a #toast stays up when no duration: is given.
Constructors
Instance methods
Build and immediately realize a subtree into the already-running app, as a child of an already-realized widget named parent_name - for UIs that grow at runtime (adding cards, rows, menu entries), not just the initial build. The block uses the same widget DSL as everywhere else, and new widgets show up immediately, routed through the same App#command/leak-cleanup path the initial realize uses - so destroying an added widget reclaims its callbacks the normal way.
Unlike ruby-tryst's #add, this DOES validate: the addition is walked by Validator.validate_subtree! rooted at parent_name before anything is realized, so a missing grid cell or a cell colliding with an already-placed sibling is a ValidationError naming both widgets rather than a mid-realize Tcl error.
Raises NotRealizedError if the session (or the named parent) isn't realized, ArgumentError if no widget is declared under parent_name.
parent_name resolves at the top level, since no #component is open at runtime - a container declared INSIDE a component has no top-level name to give here. Pass its Handle to the overload below instead.
The same, with the parent given as the Handle its own declaration returned rather than by name - the way to grow a container that lives inside a #component, whose name isn't visible from out here.
The block builds in the parent's OWN scope, as if it had been part of the parent's original declaration: #[] inside it sees the parent's component's names, a new name collides with that component's, and none of it becomes visible at the top level. (For a top-level parent that's the top level, so the Symbol form above behaves exactly as it always has.)
Raises NotRealizedError if the session or the parent isn't realized, ArgumentError for a Handle from some other Session's build.
Run a block once, ms milliseconds from now. Queues before realize exactly like #every does.
As above, with a handler instead of a policy.
The underlying app - the DSL's escape hatch. Anything the DSL doesn't wrap yet is one call away: ui.app.command(...). Raises NotRealizedError if called before #realize.
Show a busy cursor over window for the duration of the block. App#busy already restores it even if the block raises, so there's nothing extra to do for that here. Raises NotRealizedError before realize.
Show the native color picker dialog. Raises NotRealizedError before realize.
Show the native "choose directory" dialog. Raises NotRealizedError before realize.
.set(text)/.get/.clear. Text widgets don't need this for their own copy/cut/paste (Tk wires that to the platform's expected keys already) - this is for reading/writing the clipboard directly from app code. Raises NotRealizedError before realize.
A live snapshot of currently-registered callbacks, grouped by what registered them - "is my app leaking callbacks, and where." A kind absent from the result means nothing of that kind is currently registered, rather than a zero entry. Safe to call any time after realize; see #run/#run_async's debug: for printing it automatically instead of calling it yourself. Raises NotRealizedError before realize.
The build-phase tree - constructible and traversable with no interpreter, before or after realize.
Run a block every ms milliseconds, and keep doing it until the returned handle is cancelled.
Same queue-then-wire shape as an on_* event binding: called inside the build block it queues, and registers once the tree realizes; called after, it registers immediately. Same method, correct either way, so a tick loop can be declared right alongside the UI it drives instead of being pushed out into a separate post-run_async step. See TimerHandle for why cancelling works in both phases too.
As above, but hands each tick's exception to on_error - the only form that keeps the timer running after an error.
Reverse lookup: given a real Tk path (from an error message, a winfo query, or poking around at runtime), find which widget it belongs to - the counterpart to the name-based ui[:name]. See Document#find_by_path for exactly what counts as a match. Raises NotRealizedError before realize.
Show a message box with one or more buttons. Returns the pressed button as a Symbol. message is positional here, matching App#message_box - the message is the one thing every call has. Raises NotRealizedError before realize.
Show the native "choose file to open" dialog. Raises NotRealizedError before realize.
Validate the build tree, then create the underlying Tryst::App and realize the tree into it, if that hasn't happened yet. Idempotent
- calling it again after the first time just returns the same app (strict is ignored on that later call - the tree was already validated the first time).
Atomic in two senses: a validation failure means no interpreter is ever constructed at all, and even once realizing starts, the app's root window stays withdrawn until the whole tree is realized (Realizer's own guarantee), so a mid-realize error never leaves a half-built window visible either way. On failure the session is left exactly as if #realize had never been called - it isn't left half-realized (or half-validated).
Realize, show the window, and enter the Tk event loop. Blocks until the app exits.
debug: prints #debug_info's summary to stderr twice - once right before entering the event loop and once after it returns - so whether the app leaked callbacks over its run is a flag, not diagnostic code you have to write. Realize, bring the window to the front, and enter the event loop.
#bring_to_front rather than a bare #show, so an app started from a terminal actually appears in front with the focus - and, just as importantly, does NOT stay pinned above later windows, which is what makes native dialogs open behind the window that asked for them. See App#bring_to_front. #run_async keeps the plain #show: its caller drives the event loop and may not want the focus taken.
Realize and show the window without entering the event loop. Returns immediately - the caller is responsible for servicing the event loop from then on. debug: prints #debug_info's summary to stderr right after realize.
Show the native "choose file to save" dialog. Raises NotRealizedError before realize.
Briefly flash a message near the bottom of the window - "Saved" after a save, that kind of transient feedback, not a persistent status bar.
Reuses one widget across every call rather than building a new one each time, so calling this again while a toast is already up replaces it (new text, restarted timer) instead of stacking a second one. The earlier toast's pending auto-dismiss is cancelled too, so it can't fire late and hide its own replacement. Raises NotRealizedError before realize.