Forms: Including SPL Code in a Dialog Box

 

A dialog box often relies on SPL code for processing and calculations. A form combines the normal syntax of a dialog box menu file with the normal syntax of an SPL function. For example:

 

// form1.pan - form based dialog

@dialog

 

// include SPL

@form

 

// default initial func, length and deltax if not defined

{defvar("_form_func", 0)}

{defvar("_form_dlen", 1000)}

{defvar("_form_dx",   0.01)}

 

Generate Data

 

// data, horizontal radio buttons

Series Type   <r h n w=20>~_form_func = <{_form_func}>~<Uniform Noise><Normal Noise><Sinusoid>

 

// get integer value, "%" sets value immediately

Length: <% w=20>~_form_dlen = <{_form_dlen}>~input(2)

 

// get real value, "%" sets value immediately

DeltaX: <% w=20>~_form_dx = <{_form_dx}>  ~input(1)

<L>

{_dwinstrS("w=20")}

<L>

 

// generate data when OK pressed

~form_gendata(_form_func, _form_dlen, _form_dx, _dwin)

 

@endform

 

// SPL code

form_gendata(type, len, dx, win)

{

    local func;

 

    // get generator function

    switch (type)

    {

        case 0:

        default:

            func = "Grandom";

            break;

        case 1:

            func = "Gnormal";

            break;

        case 2:

            func = "Gsin";

            break;

    }

 

    // format and set the current window formula

    eval(sprintf("%s := %s(%d, %g)", win, func, len, dx));

}

 

 

Statements that proceed the @endform declaration are standard menu file expressions. Statements that follow the @endform declaration are any valid SPL expressions. In this example, the type of series to generate is specified by an integer value ranging from 1 to 3. The SPL function form_gendata() uses a switch statement to map the integer value to a specific generation function. The appropriate formula is then created and evaluated.

 

Once the dialog box is dismissed, SPL functions declared in the form are removed from memory.

 

Variable Name Convention

 

Notice this form uses variables that begin with an _ underscore, such as _form_func. In this example, the variables referenced in the SPL portion of the form (between the @form and @endform options) are global variables. Variables that begin with an _ underscore are not saved with a worksheet, insuring that a newly loaded worksheet does alter previously selected dialog box options. In addition, _ variables do not appear in the standard variable display list and are much less likely to conflict with user defined names.

 

However, unless declared with the extern or global keyword, variables within an SPL function are local to that function and do not conflict with user defined or other SPL variables.  Variables can also be made private to an SPL routine with the static keyword. Thus, a form can avoid using global variables if it is invoked from an SPL routine.

 

The above form can be modified to use static variables from a calling function.

 

// form2.spl - invoking routine

 

// default initial func, length and deltax if not defined

static form_func = 0;

static form_dlen = 1000;

static form_dx   = 0.01;

 

form2()

{

    menufile(which("form2.pan", 0));

}

 

// form2.pan - form based dialog

@dialog

 

// include SPL

@form

 

Generate Data

 

// data, horizontal radio buttons

Series Type   <r h n w=20>~form_func = <{form_func}>~<Uniform Noise><Normal Noise><Sinusoid>

 

// get integer value, "%" sets value immediately

Length: <% w=20>~form_dlen = <{form_dlen}>~input(2)

 

// get real value, "%" sets value immediately

DeltaX: <% w=20>~form_dx = <{form_dx}>  ~input(1)

<L>

{_dwinstrS("w=20")}

<L>

 

// generate data when OK pressed

~form_gendata(form_func, form_dlen, form_dx, _dwin)

 

@endform

 

// SPL code

form_gendata(type, len, dx, win)

{

    local func;

 

    // get generator function

    switch (type)

    {

        case 0:

        default:

            func = "Grandom";

            break;

        case 1:

            func = "Gnormal";

            break;

        case 2:

            func = "Gsin";

            break;

    }

 

    // format and set the current window formula

    eval(sprintf("%s := %s(%d, %g)", win, func, len, dx));

}

 

 

Now the command form2() invokes the dialog box. Because form2.pan is invoked from form2.spl, the dialog box has access to the static variables form_func, form_dlen and form_dx of form2.spl. Even though these variables are private to form2.spl, they are still accessible to the form but cannot conflict with global variables of the same name,  resulting in more robust dialog box operation.

 

Variables from a calling SPL can also be made available to SPL routines in an invoked form with the nonlocal keyword. See Nonlocal Variables for further details.