Table of Contents

How To Create Custom Dialogs

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.


Create A Simple Window

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.


Add Input Controls

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(…)`.


Use Built-In OK And Close Buttons

`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);

Store Dialog State In A Class

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.


Add Your Own Buttons

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 Combo Boxes For Choices

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.


Keep Layout Simple

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();

Keep Dialog Objects Alive

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:


See Also


How-To index: How-To Guides