dialog

show a custom dialog on the interface

Syntax

dialog(json_form, callback_function_name)

Returns

the input json_form with the chosen unique names added with return value.

Parameters

json_form (string)
in json format
callback_function_name (string)
Optional; the name of the callback function to be called. If not given default is 'dialog_callback'.

Usage

Updated since core 0.5.0. the first 3 arguments title, message and icon arguments are now obsolete but backward compatible.

This function will display a dialog to the end-user. It can be used to display simple errors, questions and warnings.

Note that the dialog blocks the ongoing process. But it will stop blocking if the process is being cancelled (by closing the magnetron application window) to allow the process to exit gracefully. Your recipes should keep this edge case in mind. The dialog will return the same form but the returns dialog value will be null.

A simple legacy 'okay' dialog warning call looks like this:

dialog("FFPROBE Not Found", "FFPROBE Not Found.", "w");

User Interaction

With the json_form parameter you can create a form object with name and object pairs for dialog elements.

For example a simple text field will look like:

var form = {
  "field" : {
    "type" : "textedit",
    "default" : "enter your text here",
    "label" : "text input:"
    },
};		
        
// call the dialog function
var r = dialog(form);		

// the returned value
echo("textedit: " + r["field"]);

This will add 2 components to the dialog, a label with the text "enter your text here" and the text input component.

depending on the type the additional properties are;

timer
- ms (integer) miliseconds interval to the dialog_callback(props) function for lightweight realtime updates. expect a max resolution of 100 ms.
The callback value is the amount of ms since the dialog opened.

label / text
- label (string) the text
- just (string) either "r" "l" or "c" for right left or center justification of the text.
- bounds (object) containing 4 name value pairs "x" "y" "w" and "h" with (integer) values for top left x/y positon and width and height in pixels. (*)
- visible (boolean) optional (temporary) hide the component (default true)

combobox
- items (array) of (string)s.
- default (string) one of the items.
- label (string) optional text label


textedit
- default (string) prefilled edit text
- multiline (boolean) allow new lines in the text
- wordwrap (boolean) breakup long lines
- readonly (boolean) allow the text to be changed by the user (default true)

button
- returns (integer) the value copied to the returned object by the dialog function. Available under a property also called "returns''. Each button to close the dialog should have a unique "returns" number.
- menu (object) optional object with multiple (string) name and (interger) value pairs. The last selected menu value will be the returns values for the button. (useful for multiple dialog presets via dialog_callback()) the value can have 1 sub menu layer with its own menu (object) with multiple (string) name and (interger) value pairs.
The 'okay' and 'cancel' placement on dialogs are swapped on Windows and mac OS. add the following tags to auto swap the buttons.
- is_okay (boolean) optional set to true to indicate it is the "okay" button
- is_cancel (boolean) optional set to true to indicate it is the "cancel" button

togglebox
- label (string) text label
- toggle (boolean) wheter the default/initial status is toggled on or off
- bounds (object) containing 4 name value pairs "x" "y" "w" and "h" with (integer) values for top left x/y positon and width and height in pixels. (*)
- visible (boolean) optional (temporary) hide the component (default true)

fileselect
- path (string) a current valid path
- editable (boolean) make the path text editable
- dir (boolean) set true when targeting a folder instead of file
- saving (boolean) changes the dialog type: open or save
- wildcard (string) dialog wildcard ie. "*.txt",
- suffix (string) forced file suffix ie. "txt"
- label (string) text label

slider
- style (string) either: slider_h / slider_v / bar_h / bar_v / rotary / rotary_HD / rotary_VD / rotary_HVD / incdec
- range (object) with (string) name and (integer) value pairs "min" "max" "interval" and "decimals"
- textpos (string) text box placement for rotary knobs either "t", "b", "l" or "r" for top bottom left or right

Each component except the timer also has the following values:

- bounds (object) containing 4 name value pairs "x" "y" "w" and "h" with (integer) values for top left x/y positon and width and height in pixels. (*)
- visible (boolean) optional hide the component (default true)
- enabled (boolean) optional disable the component to indicate the relevance (default true)
- grabfocus (boolean) optional one component with this value as true will grab the keyboard focus to improve the user experience
- silent (boolean) optional for interactive components. to be used in dialog_callback() and prevent recursion

(*) the bounds are optional and partially optional. 
 Without bounds a list of components will be stacked by these rules:
 Without x the previous x will be used
 Without y the previous x plus height plus 10px margin will be used
 Without w the previous w will be used while keeping in mind the x and current maximum width of the dialog
 Without h currently 30px default
For y, -1 will use the same heigth as the previous component.
The width and height of the dialog will be derived from the components. Extra margin will be added to the bottom and right side, mirroring the margin on the opposite sides.

Since core 0.5.0 the dialog has the ability to make lightweight callbacks to the recipe when a value is changed or optionally called with a timer. The code here should not take long to block the process as this will happen on the message thread. And blocking the process here will freeze the interface. The props argument contains an object with only the changed value.

Since core 0.6.3 an extra argument after the form argument can be given. A string with the name of a custom callback function. for example var r = dialog(form, "my_callback");
. Note the name is given as quoted string. It is than used to call my_callback(props) instead of the default dialog_callback(props)

// the dialog call back to match the example form at the end of this page. 
// this callback is only to be used for light processes. ie. to update the dialog data realtime
function dialog_callback(props)
{    
    if (props["name"] == "clock")
        var r = dialog({ "textEditor2" : { "default" : parseInt(props.ms / 1000) + " sec" } }); // print the amount of sec to textEditor2

    if (props["name"] == "menu")
        echo(objectToString(props)); // print the object with menu button selection to the console

    if (props["name"] == "cancel")
    {
        var test = { "quit" : { "type" : "return", "value" : 0 }, }; // "quit" is a special override to cancel the dialog with a chosen returns value
        var r = dialog(test);
    }
}

Example

var json_form = {
        "clock" : {
            "type" : "timer",
            "ms" : 1000
        },
        "menu" : {
            "type" : "button",
            "label" : "menu",
            "bounds" : { 
                "w" : 100, 
            }, 
            "menu" : {
                "option 1" : 1,
                "option 2" : 2,
                "option 3" : {
                    "option 4" : 4,
                    "option 5" : 5,
                },
            }
        },
        "header" : {
            "type" : "text",
            "label" : "instruction text",
            "just" : "r",
            "bounds" : { 
                "x": 120, 
                "y" : -1, 
                "w" : 200, 
            }, 
        },
        "combobox_1" : {
            "type" : "combobox",
            "default" : "item 3",
            "items" : "item 1,item 2,item 3",
            "label" : "items test:",
            "bounds" : { 
                "x": 320, 
                "y" : -1, 
                "w" : 300, 
            }
        },
        "textEditor1": { 
            "type": "texteditor", 
            "bounds" : { 
                "w" : 600, 
                "h" : 100 
            }, 
            "visible": true, 
            "multiline" : true, 
            "wordwrap" : true, 
            "default" : "Enter text here" 
        }, 
        "fileselect_1" : {
            "type" : "fileselect",
            "path" : "c:/test/test.txt",
            "editable" : true,
            "dir" : false,
            "saving" : false,
            "wildcard" : "*.txt",
            "suffix" : "txt",
            "label" : "empty",
        },
        "slider_1": { 
            "type": "slider", 
            "style": "slider_h",
            "visible": true, 
            "range" : { 
                "min": 20, 
                "max" : 80, 
                "interval" : 1, 
                "decimals" : 0 
            }, 
            "bounds" : {
                "w" : 400,
            }, 
            "value": 50 
        }, 
        "togglebox_1": { 
            "type": "togglebox", 
            "bounds" : {
                "y": -1,
                "x": 430, 
                "w" : 100,
            }, 
            "visible": true, 
            "label" : "Toggle Me" 
        }, 
        "slider_2": { 
            "type": "slider",
            "style": "rotary",
            "textpos" : "r",
            "range" : {
                "min": -1,
                "max" : 1,
                "interval" : 0.1,
                "decimals" : 1
            },
            "bounds" : {
                "h" : 100,
                "w" : 200,
            },
            "value": 0.
        }, 
        "slider_3": { 
            "type": "slider",
            "style": "bar_v",
            "range" : {
                "min": 0,
                "max" : 10,
                "interval" : 0.25,
                "decimals" : 2
            },
            "bounds" : {
                "x" : 250,
                "y" : -1,
                "h" : 100,
                "w" : 100,
            },
            "value": 0.2
        }, 
        "slider_4": { 
            "type": "slider",
            "range" : {
                "min": 0,
                "max" : 10,
                "interval" : 0.1,
                "decimals" : 1
            },
            "bounds" : {
                "x" : 360,
                "y" : -1,
                "w" : 100,
            },
            "value": 0.2
        }, 
        "okay" : {
            "type" : "button",
            "label" : "ok",
            "bounds" : { 
                "w" : 100, 
            }, 
            "returns" : 1,
            "grabfocus" : true
        },
        "cancel" : {
            "type" : "button",
            "label" : "cancel",
            "bounds" : { 
                "y": -1,
                "x": 130,
                "w" : 100
            }, 
            //"returns" : 0 // uncomment to make button close dialog. now done in dialog_callback
        },
        "textEditor2": { 
            "type": "texteditor", 
            "bounds" : { 
                "y": -1,
                "x": 500, 
                "w" : 80, 
                "h" : 25 
            },
            "readonly" : true,
            "default" : "read only text here" 
        },
    };	

var r = dialog("the title", "main message", "w", form);		
echo("combobox: " + r["unique_name_01"]);
echo("textedit: " + r.unique_name_03);

if (r.unique_name_04 == 1) // clicked okay
   echo("dialog okay");

else if (r.unique_name_05 == 1) // clicked cancel
   echo("dialog cancel");