The alternate and original way of creating Alias editors utilizes a scheme interface. This technique is described next.
If the plug-in requires an option box, the first scheme file is used to define it. All Alias option boxes are written in Scheme, which is described below. For many examples of option box files, examine the .o.scm files that reside in subdirectories in the Alias install area.
If the plug-in requires an option box and the option box requires default values for its variables, these default values are set in this file, which is invoked from plugin_init().
Creating symbols and strings in Scheme
To pass information around in scheme,we define symbols as place-holders for values, and strings as names for those values. This is done through two primitives, ui-symbol and ui-string. These functions add elements to symbol tables inside of Alias, unlike the define primitive which adds a symbol to Scheme’s symbol table. In places where the name of a symbol is desired (for example, the label for a menu item), a search is done of the string symbol table for a string with the same symbol name as the given symbol. If one is found, the associated string is used. If not, the actual symbol name is used instead. So, for example:
(ui-symbol ’my_symbol 16)
The default value of the symbol will be 16. No ui-string is associated with this symbol. Therefore, the text “my_symbol” will appear whenever the name of this symbol is displayed.
Example 2: (ui-string ’my_symbol “Number of Cows”) (ui-symbol ’my_symbol 16)
In this case a ui-string is defined with the same symbol name. When the name of the symbol “my_symbol” is required, a search is done for a ui-string with the same name. Here one is found, and the text “Number of Cows” will be used as the name of this symbol.
Creating an Option Box with Scheme
You create option boxes with a call to the ui-editor primitive. There are several arguments that apply to option boxes in general. The remaining arguments specify the widgets (editor tools) that make up the option box.
The following attributes describe the general behavior of an option box.
Example: (list 'title "View Frame Options")
Example: (list 'symbols 'nothing.intval 'nothing.doubval 'nothing.boolean )
Example: Scheme file: (ui-editor 'control.options (list 'symbols 'control.pos_x) (list 'init_option_function "control.init_func" ) (list 'title "Control Options") (ui-double-widget 'control.pos_x (list 'range -10.0 10.0) (list 'precision "%f4.6") ) ) ) Scheme init file: (ui-symbol 'control.pos_x 0.0) (ui-string 'control.pos_x "X") Plug-in: static void option_box_init_func( void ) { AlSetDouble( "control.pos_x", 45 ); } static AlMomentaryFunction function; static AlFunctionHandle handle; extern "C" int plugin_init( const char* dirName ) { AlUniverse::initialize(); function.create( "control.init_func", option_box_init_func ); // other code goes here }
Note: Allocating memory in the init_option_function will result in memory leaks if the Exit button is selected. There is no corresponding exit_option_function where allocated memory can be released. This function follows the same programming principles as the example in the previous bullet except that 3 functions will be needed.
An option box can specify any number of ui-widgets, a set of editor tools like sliders, ticks, and buttons that can be used to set ui-symbols.
Radio and popup widgets are collectively called selector widgets. The order of the elements of the widget is unimportant with the exceptions that the variable is the first item and the choices will appear in the order specified. The following apply to both popup widgets and radio widgets. The columns property only applies to ui-radio-widget. It is ignored if specified in a popup widget.
; Define the label strings. (ui-string ’title_symbol_1 “First Choice”) (ui-string ’title_symbol_2 “Second Choice”) (ui-string ’title_symbol_3 “Third Choice”) (ui-radio-widget ’variable (ui-choice ’title_symbol_1 ’VALUE1) (ui-choice ’title_symbol_2 ’VALUE2) (ui-choice ’title_symbol_3 ’VALUE3) )
(ui-popup-widget ’variable (ui-choice ’title_symbol_1 ’VALUE1) (ui-choice ’title_symbol_2 ’VALUE2) (ui-choice ’title_symbol_3 ’VALUE3) )
(ui-string 'ao_set_device_offset "Offset") (list 'symbols 'ao_set_device_offset ) (ui-double-widget 'ao_set_device_offset list 'precision "%f6.3") (list 'slider_range 1 10) )
(list 'symbols 'nothing.boolean ) (ui-tick-widget 'nothing.boolean)
Left: (list ’symbols ’mo_bevel_front_cap) (ui-tick-left-widget ’mo_bevel_front_cap) Right: (list ’symbols ’mo_bevel_front_cap) (ui-tick-right-widget ’mo_bevel_back_cap) If there is a whole group with a tick-left at the end,use the regular ui-tick-widget for the last one,otherwise there will be a hole on the right.
If a rebuild is desired when a change of value occurs we add the rebuild property.
(ui-radio-widget ’variable (list ’rebuild) (ui-choice ’title_symbol_1 ’VALUE1) (ui-choice ’title_symbol_2 ’VALUE2) (ui-choice ’title_symbol_3 ’VALUE3) )
Selectively Enabling Selectors
Sometimes the selector should be displayed only under certain conditions.
The enabled property is used to specify this condition. The expression is built from the relational primitives ui-eq (equal), ui-ne (not equal), ui-lt (less than), ui-le (less than or equal), ui-gt (greater than), ui-ge (greater than or equal). The relational primitives can be combined using the logical primitives ui-and, ui-or, and ui-not.
(ui-radio-widget ’variable (list ’enabled (ui-eq ’other_variable ’SOME_VALUE)) (list ’rebuild) (ui-choice ’title_symbol_1 ’VALUE1) (ui-choice ’title_symbol_2 ’VALUE2) (ui-choice ’title_symbol_3 ’VALUE3) )
The default for radio widgets is two columns. To specify the number of columns use the columns property. The value range is 1, 2 or 3.
(ui-radio-widget ’variable (list ’columns 3) (list ’enabled (ui-eq ’other_variable ’SOME_VALUE)) (list ’rebuild) (ui-choice ’title_symbol_1 ’VALUE1) (ui-choice ’title_symbol_2 ’VALUE2) (ui-choice ’title_symbol_3 ’VALUE3) )
Making Assignments to Variables
When a choice is selected you may assign a value to another variable. For example in the primitives option box the number of caps is set when cylinders or cones are specified.
(ui-radio-widget ’mo_prim_type (list ’rebuild #t) (ui-choice ’prim.type.cube ’MO_CUBE) (ui-choice ’prim.type.plane ’MO_PLANE) (ui-choice ’prim.type.circle ’MO_CIRCLE) (ui-choice ’prim.type.cylinder ’MO_CYLINDER (list ’assign ’mo_prim_caps 2) ) (ui-choice ’prim.type.cone ’MO_CONE (list ’assign ’mo_prim_caps 1) ) (ui-choice ’prim.type.sphere ’MO_SPHERE) )
These assignments may be made conditionally. If for example the number of caps for a cone should be set to one only if it was two then we could specify this as
(ui-choice ’prim.type.cone ’MO_CONE (list ’assign (ui-eq ’mo_prim_caps 2) ’mo_prim_caps 1) )
This way if it was set to zero then it wouldn’t change.
(ui-separator-widget)
Note that if the ui-radio-widget has an “enabled” bit to it, the separator widget has to have the same.