Windows, widgets and the VLTONE workspace

Custom design: palettes, cards and buttons

SDK · API · User guide · Русский

A window or dock

ui.window accepts a native widget tree. Omit dock for a floating window; left/right/top/bottom creates a movable QDockWidget. Preview always floats. The title identifies the pinned project. Reopening a tool raises its existing window. Closing the last window ends a normal command; background=true in the manifest opts into background lifetime.

vlt.ui.window{id="tool", title="My tool", dock="right", children={
  {type="row", children={
    {type="field", id="name", label="Name", value="Intro"},
    {type="button", text="Read", onClick=function()
      local state = vlt.ui.get{id="name"}
      vlt.ui.set{id="status", text=state.value}
    end}
  }},
  {type="table", id="files", columns={"Name", "Size"}, rows={{"kick.wav", "2048"}}},
  {type="label", id="status", text="Ready"}
}}

Layouts and controls

TypesProperties
column, row, groupchildren, spacing, margin; group.text is a title. Child stretch controls growth.
grid, scroll, splittergrid.columns: 1..32, row-major. scroll wraps its children. splitter.orientation: horizontal/vertical; panes resize by dragging.
tabschildren with title; one-based value and onChange.
button, menu, toggletext, onClick; menu.items={text,onClick}; toggle.value and onChange.
field, textEditvalue string, text placeholder, readOnly. field emits onChange after editing; textEdit coalesces text changes.
list, choiceitems strings, one-based value (zero: no selection), onChange. ui.set can replace items.
tablecolumns headings, rows string arrays, editable. onClick.value={row,column}; onChange.value={row,column,text}. ui.get returns rows and selected row value. Indices are one-based.
knob, number, slidermin/max/value/onChange, or bind={track,device,parameter,identity}. number supports step/decimals/unit. Bound controls synchronize with DAW parameters and use one Undo per gesture.
canvas, waveformdrawing shapes, or peak array 0..1. Interactive callbacks below.
image, label, progressimage.path: package-relative or granted path (files.read). label.text: plain text. progress.value: 0..1.
separator, spacerHorizontal/vertical line; expanding or fixed-size empty space.

Common properties: id, label, tooltip, enabled, visible. width/height fix dimensions; minWidth/minHeight set minimums. Sizes are logical pixels with Qt DPI scaling. Limit: 512 nodes, 16 levels per tree; 16 windows per instance. Tables support 32 columns, 1024 rows and 16384 cells; page larger data.

State and replacement

ui.get{id} reads state. ui.set{id,...} changes value/text/visible/enabled/tooltip, items, rows/columns or drawing without firing onChange. ui.focus{id} raises the window and focuses a control. IDs are instance-local; other tools are inaccessible.

ui.replace{id,children} validates the entire tree before replacing existing controls. Failure leaves them working. Ordinary value updates should use ui.set to preserve focus and text entry. Replacement does not automatically retain old control state.

Custom drawing and input

drawing supports line (x,y,x2,y2), rect/ellipse (x,y,w,h,fill), text (x,y,text), color and pen width. Omitted color uses the theme text color. Callbacks receive {id,value}.

Callbackvalue
onPointerphase down/move/up/doubleClick; x,y,nx,ny,width,height,button,buttons,modifiers. Moves coalesce inside one gesture; gesture boundaries remain distinct.
onWheelx,y,dx,dy,modifiers; normally ±120 per notch. Without this handler, scrolling remains available to the parent.
onKeyKey presses: key (Left, Right, A…), text, code, repeat, modifiers. The focused canvas owns typing keys instead of the computer MIDI keyboard.
onResizewidth,height, coalesced. Read initial dimensions with ui.get after window creation.

Button and modifier masks use Qt values: 1=left, 2=right, 4=middle button. Keep handlers short; update only changed controls. Use host jobs or bounded timer steps for long calculations.

Native workspace

local workspace = vlt.workspace.get()
vlt.workspace.open{view="mixer",visible=true}
vlt.workspace.select{tracks={trackId},clips={{track=trackId,clip=clipId}}}
vlt.workspace.open{view="sample",track=trackId,clip=clipId}
vlt.workspace.open{view="plugin",track=trackId,device=deviceId,identity=identity}

Views: arrangement, mixer, inspector, browser, master, assistant, notebook, trackOverview, context, pianoRoll, pattern, sample, automation, plugin. Panels support visibility; editors require compatible clip kinds; plugin identity comes from parameters.list. get returns active/project/panels/selection; inactive projects have empty panels. open/select require the active pinned project and cannot navigate outside preview. Selection validates all targets first. Local workspace operations do not edit the document and remain available in collaboration.

Other actions use commands.list/run and project/parameter APIs. callable indicates host exposure; available indicates current QAction availability. Execution also checks permission, AI mode, collaboration and project binding. Raw QWidgets, synthetic coordinate clicks and third-party plugin UI internals are not exposed; use host-visible plugin parameters.

Runnable example

Package examples/interactive-workbench with the CLI to install it, or load it as a Creator project. It includes a project-media table, native workspace buttons and an interactive XY pad. Source · Manifest.