Skip to content

UI Editor

apps/ui_editor is a visual editor for retained-UI .ui documents. It frames a live canvas — the document rendered by the same runtime the game uses, so what you see is what you get — with an element tree, an inspector, and a selection gizmo. It is the reference consumer of the editor-authoring API, the transparent Gui.beginOverlay, and the --tool CLI mode.

  • WYSIWYG canvas — the center renders the document with Ui.renderEdit (edit mode: a click selects an element rather than firing its button). It is the identical renderer, letterboxed, so the preview matches the game exactly.
  • Authoring — the left panel adds panels/text/buttons under the selection, deletes, and saves; the right panel is an inspector over the selected element’s fields (id, offsets, anchors, color, text, font size, on_click). All backed by Ui.newDocument/createElement/deleteElement/reparent/ save and the UiElement field accessors.
  • Picking + gizmo — a canvas click is inverse-letterboxed to design space and Ui.hitTest selects the topmost element; an orange selection gizmo is drawn over the canvas through a transparent Gui.beginOverlay.

Selection is tracked by element id, because every structural edit invalidates live element handles — the editor re-fetches by id each frame.

The editor is an ordinary app, so you can run it standalone (it edits its own ui/main.ui):

plume3d apps/ui_editor

To edit another app’s document, launch it in --tool mode with the target project as the data dir:

plume3d --tool apps/ui_editor <target-app-dir>

In --tool mode the engine runs the tool’s main.wren/game.toml from the tool directory, but mounts the target project (and points the write dir there). So Ui.load("ui/main.ui") and Ui.save("ui/main.ui") transparently read and write the target’s ui/main.ui. This data/script-root split is the whole of --tool — the tool is invisible to the script, which just uses ordinary relative paths. --tool is mutually exclusive with --server and --test.

See the Ui API (runtime + authoring tier) and Gui (the Nuklear chrome + beginOverlay) for the building blocks.