MAXScript Tools and Interaction with 3ds Max > Creating MAXScript Tools > Scripted Utilities and Rollouts >

# Rollout Clauses

| Creating User Interfaces - Quick Navigation

Rollout clauses define the components of a rollout (utilities are considered a special case of rollouts) and can be one of four basic things:

- Local variables, functions, or structure definitions are variables, functions, and structures whose scope is the rollout. These locals will exist as long as the rollout value exists. The rollout value will exist until a new value is assigned to the rollout’s variable name. Local variables are particularly useful for storing working data associated with the rollout such as picked objects or arrays of generated objects. The visibility of locals, and accessing rollout locals from external code, are described in Visibility of Locals, Functions, Structures, and User-Interface Items in Rollout Code and Accessing Locals and Other Items in a Rollout from External Code.

- Mouse tools are used to perform a set of actions based on mouse clicks in the 3ds Max viewports, and are described in Scripted Mouse Tools.

- User-interface control items are elements displayed in the rollout, such as buttons, spinners, and list boxes.

- Event handlers are special kinds of functions associated with particular user-interface control items. Event handlers specify the processing you want to occur when a user interacts with a user-interface item. For example pressing a button or adjusting a spinner. These user actions generate named events and the optional event handler you supply for that event is called when the user action occurs. For example, if you press a button named DoIt, the on DoIt pressed event handler expression is executed.

Formally, the syntax of a <rollout_clause> is defined as follows:

    <rollout_clause> ::= <local_variable_decl> | <local_function_decl> | <local_struct_decl> | <global_variable_decl> | <mousetool> | <user_interface_item> | <item_group> | <event_handler>

Locals

A <local_variable_decl> , <global_variable_decl> , <local_function_decl> , and <local_struct_decl> are exactly the same as local and global variable, local function, and local structure definitions in MAXScript:

    <local_variable_decl> ::= local <decl> { , <decl> }
    <decl> ::= <name> [ = <expr> ] -- optional initial value

    <global_variable_decl> ::= global <decl> { , <decl> }
    <decl> ::= <name> [ = <expr> ] -- optional initial value

    <local_function_decl> ::= [ mapped ](function | fn) <name> { <argument> } = <expr>

    <local_struct_decl> ::= struct <name> ( <member> { , <member> } )
    <member> ::= ( <name> [ =<expr> ] | <local_function_decl> )

Examples of the previous (in order) are:

    local numSelected
    global foo
    local numSelected = 0
    fn onlyOneSelected = (selection.count == 1)
    struct parents (mother="", father="")

When writing scripts, it is good programming practice to explicitly declare your local and global variables. Implicit declaration is provided as a short-hand, typically used when working in the Listener interactively or developing short scripts. When developing extended scripts, explicitly declaring variables can reduce errors and improve readability of the code. It is also recommend that you declare as local all variables unless you really want them to be global variables. The reasons for this are described in Scope of Variables.

User-Interface Items

A <user_interface_item> defines an individual button, check box, spinner, or other user-interface control item that will appear in the rollout. These user-interface control items are described in Rollout User-Interface Controls.

An <item_group> is used to place a sequence of user-interface items in a labeled box in the rollout, so you can organize large rollouts into meaningful groups.

Its syntax is:

    group <group_label_string>
    (
    { <user_interface_item> }
    )

The use of group is shown in the following script:

EXAMPLE
    utility Infinity "Game Utilities"
    (
    group "Lighting"
    (
    label label1d "Number of Day lights:" across:2 offset:[10,0]
    label label2d "0" offset:[10,0]
    label label1n "Number of Night lights:" across:2 offset:[13,0]
    label label2n "0" offset:[10,0]
    label label3
    Radiobuttons WhichOn "Active Lights:" labels:#("Day","Night")
    )
    group "Scene Data Dump"
    (
    Button scenedump "Dump Scene Data"
    )
    group "Exclusions/Inclusions"
    (
    Button DispExcl "Unhide Exclusions&Inclusions"
    )
    group "Camera Mattes"
    (
    radiobuttons CamMatte labels:#("None","1","2","3","4") columns:3
    )
    Button resetb "Reset"
    )

The Utilities panel rollout which the previous script generates looks like the following figure.

Game Utilities rollout using group user-interface item

NoteA group is technically not an user-interface control. If you want to use a group that is an interface control, consider the GroupBox user-interface control.

Internally, a group is implemented as two controls, of GroupStartControl and GroupEndControl classes, enclosing the grouped user-interface controls like brackets.

In 3ds Max 8 and higher, you can access and change the .caption property of either controls if you access them via the .controls property of a rollout - this was not possible in previous versions.

EXAMPLE
    rollout test "Test"
    (
    group "Group"
    (
    button pressme "Press Me"
    )
    )
    createDialog test
    test.controls
    test.controls[1].caption = "XXX" --this is the GroupStartControl
    test.controls[3].caption = "Test me" --this is the GroupEndControl --Both change the group's caption!

In 3ds Max 2010 and higher, user Interface controls' event handlers can be included inside a Group's body. In previous versions of 3ds Max, including an even handler inside the group caused a Syntax Error.

EXAMPLE
    rollout test "Test"
    (
    group "Group"
    (
    button pressme "Press Me"
    --In versions prior to 3ds Max 2010, --this would have caused a Syntax Error:
    on pressme pressed do print "Pressed!"
    ) --because the handler is inside the group's body.Now allowed.
    )
    createDialog test

Event Handlers

An <event_handler> is a special function definition local to a utility or rollout that you provide to handle the processing you want to occur when a user performs an action on a user-interface item. For example, event handlers are called when the user presses a button or adjusts a spinner, opens or closes the utility or rollout, or resizes or moves a rollout floater window. These user actions generate named events and any event handler you supply for that event is called when the action occurs. The syntax for defining an event handler is as follows:

    on <item_name> <event_name> [ <argument> ] do <expr>

The <item_name> specifies the name of the item to which this handler is connected. The <event_name> specifies the type of event to be handled and the optional <argument> is used to pass various values to the handler. The possible events you can specify depend on the item type. These events include:

    pressed changed picked entered selected resized moved open close

The available events and the arguments passed are defined in the description for each user-interface item type, as listed in Rollout User-Interface Controls. The available events and the arguments passed for utilities and rollouts are described in Utility and Rollout Properties, Methods, and Event Handlers.

You can access and invoke the event handler functions in a scripted rollout by referring to the handlers as properties on the user-interface items. The event handler functions are accessed as sub-properties of the item, using the event name as the sub-property name. For example, if a scripted rollout had a check box item named foo , and an on foo changed event handler was defined, you could invoke the handler as follows:

    foo.changed true -- call foo's 'changed' handler function, passing argument of true

Or, if a scripted rollout had a button item named apply , and an on apply pressed event handler was defined, you could invoke the handler as follows:

FOR EXAMPLE
    apply.pressed() -- call apply’s 'pressed' handler function, no argument.

You can access an event handler function as a sub-property of the item.

FOR EXAMPLE
    ApplyPressedEH = apply.pressed
stores a copy of the on apply pressed event handler function value to variable ApplyPressedEH . The event handler functions can only be read. You cannot set the handler function to another user-defined function.