Custom dialogs are built with `window()` and GUI component objects such as `label()`, `textinput()`, `numinput()`, `combobox()`, and `textbutton()`.
Use a custom dialog when the built-in message and file dialogs are not enough, or when a script needs several related inputs before it continues.
Start with a `window()`, set its title and size, add controls, then call `show()`.
w = window() .title('Tool Setup') .size(320, 160) .buttons(false, true, true); w.add(label().position(20, 20).size(120, 24).text('Tool name')); w.add(textinput().position(120, 20).size(160, 24).text('T1')); w.show();
`show()` is asynchronous. It shows the dialog and returns immediately.
Keep the window object in a variable or object field while the dialog is open.
Keep references to input controls that you need to read later.
name_input = textinput() .position(120, 20) .size(160, 24) .text('T1'); feed_input = numinput() .position(120, 52) .size(100, 24) .minmax(1, 5000, 0) .value(1000); w = window() .title('Tool Setup') .size(320, 150) .buttons(false, true, true); w.add(label().position(20, 20).size(90, 24).text('Tool')); w.add(name_input); w.add(label().position(20, 52).size(90, 24).text('Feed')); w.add(feed_input); w.show();
Object properties are read-only. Read values with properties such as `name_input.text` and `feed_input.value`. Change values with methods such as `text(…)` and `value(…)`.
`window.buttons(apply, ok, close)` enables the built-in buttons.
w = window() .title('Parameters') .size(320, 180) .buttons(false, true, true);
Result codes used by window request and close callbacks are:
| Code | Meaning |
|---|---|
| `0` | Close |
| `1` | OK |
| `2` | Apply |
Use `on_request(callback)` to validate before the window closes. Return `false` to keep the window open for OK or Close requests.
function CheckDialog(code) { if (code == 1 && feed_input.value <= 0) { print('Feed must be greater than zero'); return false; } return true; } w.on_request(CheckDialog);
For real dialogs, use a class. It keeps the window, controls, result values, and callbacks together.
class ToolDialog() { wnd = none(); name_input = none(); feed_input = none(); accepted = false; tool_name = ''; feed = 0; function Show() { name_input = textinput() .position(120, 20) .size(160, 24) .text('T1'); feed_input = numinput() .position(120, 52) .size(100, 24) .minmax(1, 5000, 0) .value(1000); wnd = window() .title('Tool Setup') .size(320, 150) .buttons(false, true, true) .on_request(this.OnRequest) .on_closed(this.OnClosed); wnd.add(label().position(20, 20).size(90, 24).text('Tool')); wnd.add(name_input); wnd.add(label().position(20, 52).size(90, 24).text('Feed')); wnd.add(feed_input); wnd.show(); } function OnRequest(code) { if (code == 1 && name_input.text.length() == 0) { print('Tool name is required'); return false; } return true; } function OnClosed(code) { accepted = code == 1; if (accepted) { tool_name = name_input.text; feed = feed_input.value; print('tool ', tool_name, ', feed ', feed); } } } dlg = ToolDialog(); dlg.Show();
Only `dlg` is stored as a root variable. The window, controls, and result values are fields of the object.
You can use `textbutton()` when you want buttons inside the dialog content area.
class RunDialog() { wnd = none(); value_input = none(); function Show() { value_input = numinput() .position(100, 20) .size(90, 24) .minmax(0, 100, 0) .value(10); run_button = textbutton() .position(100, 60) .size(90, 28) .text('Run') .on_click(this.RunClicked); wnd = window() .title('Run') .size(240, 130) .buttons(false, false, true); wnd.add(label().position(20, 20).size(70, 24).text('Value')); wnd.add(value_input); wnd.add(run_button); wnd.show(); } function RunClicked() { print('run value ', value_input.value); wnd.close(); } } dlg = RunDialog(); dlg.Show();
Button callbacks receive no arguments. Read needed values from object fields.
Use `combobox()` when the user should choose from known values.
mode_input = combobox() .position(120, 20) .size(150, 24) .add('Roughing') .add('Finishing') .item(1); print(mode_input.item); // selected index print(mode_input.item_text); // selected text
Item indexes start at `1`. Index `0` means no selection.
Most custom dialogs work well with fixed positions and sizes.
Use a consistent layout:
For larger dialogs, use `panel()`, `group()`, or `splitpanel()` to organize controls.
main = panel().position(10, 10).size(360, 140).border(1); main.add(label().position(10, 10).size(120, 24).text('Safe Z')); main.add(numinput().position(140, 10).size(90, 24).value(5)); w = window().title('Probe').size(400, 200).add(main).show();
A custom window is shown asynchronously. If you want callbacks and result values to remain available, keep the dialog object or window object in the session while it is open.
Good:
dlg = ToolDialog(); dlg.Show();
Avoid creating a dialog object that you immediately lose:
ToolDialog().Show(); // hard to inspect or close later
For dialogs created from include files, it is usually best to store one root object in the caller session.
For simple dialogs:
For reusable dialogs: