Skip to main content
Coming soon — experimental API 0.3. Existing 0.2 declarations remain accepted. See availability and scope. You can create a nonmodal floating tool dialog parented to the main application window. You declare controls as values; Armorsmith creates and owns the widgets. Persistent Python callbacks and arbitrary Qt objects are not part of this contract.

ShowDialog

Requires ReadDocument, CreateUi, and a host with UI support. Buttons also require the permission for their declared action. DialogSpec contains std::string title, std::vector<DialogControl> controls, and Version version. The C++ version defaults to 0.3. Python’s helper defaults to 0.2; pass version=(0, 3) for new controls. Controls appear in declaration order. Provide 1 to 32 controls. The service permits at most eight dialog registrations per session. Titles, labels, and IDs are plain text, not HTML. They must pass the nonempty UTF-8 name validation: no control characters, no value made only of ASCII spaces, and at most 1,024 bytes. IDs must also be unique within the dialog and at most 64 bytes.

Controls

DialogControl.id and label are strings. kind defaults to Label. Numeric fields are doubles, defaulting to value = 1.5, minimum = 0.25, and maximum = 2.0. Every number control must use finite values with minimum <= value <= maximum. A 0.2 declaration is limited to 0.25..2.0; a 0.3 declaration allows -1000000..1000000. Each action still enforces its domain bounds. A mesh stretch remains limited to 0.25..2.0. action defaults to UiAction::None. Every button must declare a non-None action. Other control kinds must use None. The mesh picker offers parts with can_filter = true. It tries to preserve the choice on refresh and uses an eligible selected part or the first eligible part when it needs a default. An empty picker means no mesh in the current snapshot meets the command’s requirements for this session. The measurement picker offers entries with can_set = true. A linked measurement action initializes its number control from the selected entry’s current value and bounds. Choosing another measurement updates that control. Height action inputs also refresh from the current avatar. The tool picker offers entries with can_activate = true. Pickers preserve an eligible prior choice when refreshed.

Host actions

For a stretch button, mesh_control must name a MeshPicker and number_control must name a Number in the same dialog. The host validates these references before displaying the dialog. For a measurement button, measurement_control must name a MeasurementPicker and number_control must name a Number. A height button requires number_control. A tool button requires tool_control naming a ToolPicker. These added fields are strings. The Python ops builders supply them for you. Give each measurement or height input its own number control so refreshing one action cannot overwrite another action’s input. Buttons execute through the session and host command layer. They do not call back into Python. The host checks current handles, permissions, target eligibility, and the dialog’s stored revision before changing document state. After edits outside the dialog, click Refresh. A revision conflict requires a refresh and a new decision about the target. Replacing the costume requires closing the dialog and creating a new one.

CloseDialog

Requires CreateUi and a handle registered to this session. Success returns true, releases the registration, and asks the host to dispose its UI. Repeated calls with a retired handle return InvalidHandle. Closing a window visually does not itself release the C++ service’s registration in the current implementation. Use CloseDialog when retaining a C++ session and reusing its dialog capacity. Session destruction also disposes its registrations. Script-created dialogs retain their host session while they run and release it when they finish.

Other UI extensions

0.3 does not expose custom widget classes, dock panels, arbitrary layouts, HTML views, menu/tool registration, or general event callbacks. The test build’s Scripts menu is an application-provided launcher, not a public menu registration API. Normal release builds hide it until it is explicitly enabled. Use Python scripting to create a dialog declaration with the same controls and named actions.