Previous section < Non-preloading standard clients
- Chapter: Using themes -
Next section > Direct interface
The T-O-M-SC FullMenu script is a new (as of v3.0) client script that enables a full menu system, with submenus, to be defined to allow applying themes by the Theme-O-Matic and possibly other operations. This was suggested by a customer who wanted to organize her themes in a coherent way.
With this client script, the menu definitions go into a notecard with a syntax highly and shamelessly inspired by AVsitter's avPos notecard.
All menus have a name, and a number of buttons. They are automatically arranged in pages of 10 buttons as the need arises, but no automatic "way back" is added. This means that you have to define navigational buttons yourself, as you decide. The button pages are arranged according to the following structure.
As this table shows, the bottom left and bottom right buttons are reserved for navigational buttons : previous page or next page if any. On the first menu page, the Nav 1 page is a button that closes the menu. Then the first button is the bottom middle, and then upwards from left to right.
Menus can also have, optionally, a prompt, which by default equals the menu name. The first menu is defined as "Main menu", but this can be overriden by defining another menu name as the first directive in the notecard.
An example screengrab of a menu and the corresponding notecard is given at the end of the this page. It is the menu for the demo object.
On a technical note, the menus defined by this script are stored in the LSD of the object, and therefore count against the global LSD memory. Memory usage should however be rather small and a good compromise regarding the potential complexity of the menus managed by the script.
The notecard defining the menus is, by default, named ".menu" (but this can be changed inside the script). It is read when the script boots, and a number of checks will be performed while doing so. The script will notify you if it finds anything wrong (like a menu with no buttons, or a TOMENU redirecting to a non-existing menu).
As usual, lines starting with // (two slashes) are treated as comments and ignored by the script.
Buttons have a type and are introduced by a corresponding keyword on their lines. Here is the list of known keywords and their meaning. In the following descriptions, the <angle brackets> denote a mandatory argument and the [square brackets] denote an optional part.
MENU <menu name>
This directive registers the current menu with its button definitions and starts a new menu with the given name. If the <name> is the name of an already defined menu, then an error is reported.
PROMPT <text>
The prompt is the text displayed in the dialog in the viewer, above the buttons. By default the prompt is just the menu name, but this directive replaces it by a custom text.
The prompt text supports substitution (see below), a way to specify newlines and variable parts related to the users identity.
The following directives all create a button in the current menu (or the "Main menu" if no previous MENU directive was used). An SL viewer limitation says that all button labels are limited to 12 characters and must not be empty. The script enforces these rules by truncating the button labels if required, and replacing empty strings by a single space. In that case, a warning is issued.
TOMENU <label>[|menu name]
This directive creates a button that will redirect to the named menu. If no explicit menu name is given then it is assumed that the label both acts as a button label and the menu name.
While analyzing the notecard, the script ensures that all TOMENU destinations have a corresponding MENU definition.
APPLY_NC <label>[|notecard name or UUID]
This directive creates a button that results in a theme being applied from a notecard. If the notecard name is skipped, then it is assumed to be the same as the button label. If it is not found as a notecard in the prim's inventory, or as an UUID (consider the caveat here), then a warning is issued.
APPLY_LSD <label>[|LSD theme name]
The button created by this directive will apply a theme from LSD storage. Again if the theme name is skipped, it is expected to be the same as the button label. A warning is issued if the required theme is not found in the LSD storage of the object.
APPLY_PL <label>|<preloader number>
Again this directive will create a button that applies a preloaded theme, this time directly from the designated preloader. Both arguments (button label and preloader number) are mandatory. An error will be reported if preloader number is not a positive integer number.
For now only three other directives are understood by the script. The first two and are mainly meant to interface with other, third-party, scripts. The link_messages sent by BUTTON are appropriate for scripts inside the same object, while those sent by CHAT may only be "heard" by scripts inside other objects.
BUTTON <label>|<number>[|message[|key[|destination]]]
This new button will result in a link_message being sent across the object, for another script to catch and do something if it understands it. What really happens then entirely depends on this third party script: you can use this facility to trigger an AVSitter pose, for example, or start a motion with MvtPlayer, or whatever.
All arguments are optional except the button label and the number (which are mandatory). If the message is omitted then the button label is used. If the key is omitted too, it is replaced by the menu user's key. If destination is omitted then the message spreads across the whole linkset.
For more details about link_messages, please refer to the LSL portal (including special destination values).
Note that the message and key arguments support substitution (see below).
CHAT <label>|<message>[|channel[|range]]
The button created by this directive will cause the message to be said over a communication channel.
The default channel is 0, which is the public channel (local chat in the viewer). If you plan to interface with another script inside another object, make sure you use the correct channel number as it probably expects a number different from 0.
The default range is SAY (20 meters), and other possibilities are: WHISPER (10 meters), SHOUT (100 meters), REGIONSAY (the whole sim), OWNERSAY (appears in the viewer's local chat window but only visible to the owner), or USERSAY (hearable only by the menu user and their attachments. Visible in the viewer's local chat window if the channel is 0).
Note that a limitation (on purpose) is that you cannot use REGIONSAY on channel 0.
GIVE <label>[|inventory item]
The button created by this directive will give the corresponding inventory item to the menu user when it is clicked. Useful to provide landmarks, explanation notecards etc. to your customers. You will get a warning if the inventory item does not exist at the time the notecard is read.
In the context of the notecard, string substitution means to replace parts of the string with other, probably variable, sub strings. Currently this is supported inside:
the menu PROMPTs
the message and key parts of the BUTTON directive
the message part of the SAY directive.
To perform substitution, you just have to understand these simple rules:
\n is replaced by a new line control character, useful for splitting a long text across several lines
{{user}} is replaced by the current menu user's UUID (key), useful for certain commands,
{{user name}} is replaced by the current menu user's (legacy) name,
{{user dname}} is replaced by the current menu user's display name.
This gives a few interesting usage scenarios, as shown below.
The following examples show how you can control other script systems (MvtPlayer and AVSitter) FROM the T-O-M-SC FullMenu. Do not confuse with the next page where we'll show how these third-party system can tell the Theme-O-Matic to apply themes.
with AVSitter (reference: AVSitter messages to send):
BUTTON Cuddle|90000|Cuddle|{{user}}
When received by AVsitter, the pose "Cuddle" will be triggered on the menu user (provided that this pose is correctly defined for the sitter the user is using, of course).
BUTTON Poses|90005|My submenu|{{user}}
When received by AVsitter, this will cause the menu named "My submenu" to be opened for the user.
Note that these examples both use the substitution mechanism (described below) to replace {{user}} by the actual identifier of the menu user.
with MvtPlayer (reference: MvtPlayer's website):
BUTTON Start motion|200010||MVTPLAYER
The resulting message will cause MvtPlayer to start playing back the motion sequence. Please refer to the dedicated website for more information.
a simple greeter:
CHAT Hello|Hello {{user dname}}, thank you for using our product.\nHow are you today?|0|WHISPER
an RLV command! (only makes sense when the object is an attachment, and of course with a viewer that supports RestrainedLove):
CHAT Wear our group|@setgroup:<group_name>=force|0|OWNERSAY
A small number of settings are available inside the script itself. Depending on user requests, I might move them to the notecard in a future version.
string config_name=".menu";
This setting defines the name of the configuration notecard itself. If it's a name it must be inside the prim's inventory. If you use an UUID, it can be anywhere, including your own inventory.
string separator="|";
This is the separator to use when a configuration directive requires several arguments. Usage of the vertical bar is generally very fine, unless you need it for other purpose, like a notecard name (yikes) or a custom message sent by a BUTTON or CHAT directive. In that case, you can change it to something less common inside this setting, like "°~°" or maybe more simply a double vertical bar "||". Just make sure you modify your whole notecard accordingly.
integer allowed_users=0;
This setting defines who can use the menu by touching. Possible values are 0 (everyone), 1 (group members), 2 (the owner and their friends), 3 (owner only).
float menu_timeout=300.0;
The menu expires (stops responding) after this number of seconds of inactivity. This anti-lag measure can be disables by setting the value to 0.0.
string label_next="Next >";
string label_prev="< Previous";
string label_close="- Close -";
string label_placeholder=" - ";
These are special button labels, their meaning should be rather obvious. Remember that button labels cannot exceed 12 characters.
integer reload_on_inventory_change=TRUE;
If this setting is set to TRUE, the script will reboot (read the notecard again) as soon as the prim's inventory changes, as it may indicate that the configuration was altered. However this may not be the case and this behavior could be a problem. In that case just disable it by setting this switch to FALSE.
The Main menu and the notecard for the demo object for T-O-M-SC FullMenu
It is rather easy to add more button types supported by more directives, you just have to have a clear idea of what they are supposed to do.
Feel free to ask me about it!