Dialog Menus Control

From Second Life Wiki
Revision as of 09:57, 25 January 2015 by ObviousAltIsObvious Resident (talk | contribs) (<lsl> tag to <source>)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
KBcaution.png Important: This script is considered obsoleted. Latest version of Dialog Control has this functionality built-in! An obsoleted version of Nargus Dialog Control script is required to work with this script.

This is example of usage and function library needed in each scripts to use this dialog menus module.

IMPORTANT NOTE: This menus control REQUIRED Nargus Dialog Control script. You MUST have both Nargus Dialog Control and Nargus Dialog Menus in the same prim for it to work.

Menus Usage

  1. Initialize menus control using:
    • llMessageLinked(LINK_THIS, lnkMenuClear, "", NULL_KEY);
  1. Using "packDialogMessage" function to generate new menu, and add it to menus list:
    • llMessageLinked(LINK_THIS, lnkMenuAdd, packDialogMessage(....), "MenuName");
    • While "MenuName" is the same of this menu, ie: MainMenu
  1. To make a dialog button show a sub-menu, use following as return value of the button:
    • MENU_<name>
    • Replace "<name>" with the actual name of the added menu (without parenthesis).
  1. Repeat (2) and (3) for all menus you want
  1. To show a menu, use:
    • llMessageLinked(LINK_THIS, lnkMenuShow, "MenuName", llGetOwner());
    • Where "MenuName" is the name of menu to show. To show last-used menu, leave this field empty.
  1. Dialog will return value the same way as usual call to Nargus Dialog Module script.

Sample Scripts

If anyone uses this module, please IM Nargus Asturias, I'd love to hear what you think.

Scripts & Example

// READ ME:
// To see this sample in action;
// Put "Nargus Dialog Control" and "Nargus Dialog Menus" along with this script
// in a prim and touch.

// Dialog constants
integer lnkDialog = 14001;
integer lnkDialogNotify = 14004;
integer lnkDialogResponse = 14002;
integer lnkDialogTimeOut = 14003;

integer lnkDialogReshow = 14011;
integer lnkDialogCancel = 14012;

integer lnkMenuClear = 15001;
integer lnkMenuAdd = 15002;
integer lnkMenuShow = 15003;

string seperator = "||";
integer dialogTimeOut = 0;

// ********** DIALOG FUNCTIONS **********
string packDialogMessage(string message, list buttons, list returns){
    string packed_message = message + seperator + (string)dialogTimeOut;
    
    integer i;
    integer count = llGetListLength(buttons);
    for(i=0; i<count; i++) packed_message += seperator + llList2String(buttons, i) + seperator + llList2String(returns, i);

    return packed_message;
}

dialogReshow(){llMessageLinked(LINK_THIS, lnkDialogReshow, "", NULL_KEY);}
dialogCancel(){
    llMessageLinked(LINK_THIS, lnkDialogCancel, "", NULL_KEY);
    llSleep(1);
}

dialogNotify(key id, string message){
    list rows;
    
    llMessageLinked(LINK_THIS, lnkDialogNotify,
        message + seperator + (string)dialogTimeOut + seperator,
        id);
}
// ********** END DIALOG FUNCTIONS **********


default{
    state_entry(){
        llMessageLinked(LINK_THIS, lnkMenuClear, "", NULL_KEY);
        llMessageLinked(LINK_THIS, lnkMenuAdd, packDialogMessage(
            "[ Main Menu ]\n" +
            "Messages go here",
            [ "BUTTON_1", "BUTTON_2", "BUTTON_3", "BUTTON_X" ],
            [ "MENU_SubMenu1", "MENU_SubMenu2", "MENU_SubMenu3", "EXIT" ]
        ), "MainMenu");
        llMessageLinked(LINK_THIS, lnkMenuAdd, packDialogMessage(
            "[ Sub Menu 1 ]\n" +
            "Messages go here",
            [ "SUB_1_1", "SUB_1_2", "SUB_1_3", "MAIN MENU", "SUB_3", "BUTTON_X" ],
            [ "1.1", "1.2", "1.3", "MENU_MainMenu", "MENU_SubMenu3", "EXIT" ]
        ), "SubMenu1");
        llMessageLinked(LINK_THIS, lnkMenuAdd, packDialogMessage(
            "[ Sub Menu 2 ]\n" +
            "Messages go here",
            [ "SUB_2_1", "SUB_2_2", "SUB_2_3", "MAIN MENU", "SUB_1", "BUTTON_X" ],
            [ "2.1", "2.2", "2.3", "MENU_MainMenu", "MENU_SubMenu1", "EXIT" ]
        ), "SubMenu2");
        llMessageLinked(LINK_THIS, lnkMenuAdd, packDialogMessage(
            "[ Sub Menu 3 ]\n" +
            "Messages go here",
            [ "SUB_3_1", "SUB_3_2", "SUB_3_3", "MAIN MENU", "SUB_2", "BUTTON_X" ],
            [ "3.1", "3.2", "3.3", "MENU_MainMenu", "MENU_SubMenu2", "EXIT" ]
        ), "SubMenu3");
        
        llSetText("Touch me to show menu", <1,1,1>, 1);
    }

    link_message(integer sender_num, integer num, string str, key id){
        if(num == lnkDialogTimeOut){
            dialogNotify(llGetOwner(), "Menu time-out. Please try again.");
            state default;
        }else if(num == lnkDialogResponse){
            llWhisper(0, str);
        }
    }
    
    touch_start(integer num_detected){
        llMessageLinked(LINK_THIS, lnkMenuShow, "", llDetectedOwner(0));
    }
}

Nargus Dialog Menus v1.01 (by Nargus Asturias)

// ********** DIALOG MENUS MODULE ********** //
// By Nargus Asturias
// Version 1.01
//
// Multi-layer menus management module for Nargus Dialog Control.
// Use same packing method as Nargus Dialog Control
//
// HOW TO USE:
// 1) Initialize menu by sending "lnkMenuClear" signal:
//          llMessageLinked(LINK_THIS, lnkMenuClear, "", NULL_KEY);
//
// 2) Add menu dialog using provided function (or manually, please referr to Nargus Dialog Control 
//    manual). Make sure signal is sent with "lnkMenuAdd" and key field is menu's name;
//          llMessageLinked(LINK_THIS, lnkMenuAdd, ......, "MainMenu");
//
//    To make a button show submenu, use following as return value of the button:
//          MENU_<name>
//    Replace "<name>" with the actual name of the added menu (without parenthesis).
//
// 3) Repeat (2) for as much menus as needed
//
// 4) To show a menu, use:
//          llMessageLinked(LINK_THIS, lnkMenuShow, name, llGetOwner());
//    When "name" is name of the menu to show. To show last-used menu, leave this field empty.
//
// 5) Dialog will return value the same way as usual call to Nargus Dialog Module script.
// ******************************************* //

// Dialog constants
integer lnkDialog = 14001;
integer lnkDialogNotify = 14004;
integer lnkDialogResponse = 14002;
integer lnkDialogTimeOut = 14003;

integer lnkDialogReshow = 14011;
integer lnkDialogCancel = 14012;

string seperator = "||";
integer dialogTimeOut = 0;

// ********** DIALOG FUNCTIONS **********
dialogReshow(){llMessageLinked(LINK_THIS, lnkDialogReshow, "", NULL_KEY);}
dialogCancel(){
    llSleep(1);
    llMessageLinked(LINK_THIS, lnkDialogCancel, "", NULL_KEY);
}
// ********** END DIALOG FUNCTIONS **********

// Constants
integer lnkMenuClear = 15001;
integer lnkMenuAdd = 15002;
integer lnkMenuShow = 15003;

// Menus variables
list menuNames;             // List of names of all menus
list menus;                 // List of packed menus command, in order of menuNames

// Variables
integer lastMenuIndex;      // Latest called menu's index

// ********** Menu Functions **********
clearMenusList(){
    menuNames = [];
    menus = [];

    lastMenuIndex = 0;
}

addMenu(string name, string message, list buttons, list returns){
    // Reduced menu request time by packing request commands
    string packed_message = message + seperator + (string)dialogTimeOut;
    
    integer i;
    integer count = llGetListLength(buttons);
    for(i=0; i<count; i++) packed_message += seperator + llList2String(buttons, i) + seperator + llList2String(returns, i);

    // Add menu to the menus list
    menuNames += [name];
    menus += [packed_message];
}

showMenu(string name, key id){
    if(llGetListLength(menuNames) <= 0) return;
   
    integer index;
    if(name != ""){
        index = llListFindList(menuNames, [name]);
        if(index < 0) index = lastMenuIndex;
    }else index = lastMenuIndex;
    
    lastMenuIndex = index;
    
    // Load menu command and execute
    string packed_message = llList2String(menus, index);    
    llMessageLinked(LINK_THIS, lnkDialog, packed_message, id);
}

// ********** States **********
default{
    state_entry(){
        clearMenusList();
    }

    link_message(integer sender_num, integer num, string str, key id){
        // Menu response commands
        if(num == lnkDialogResponse){
            if(llGetSubString(str, 0, 4) == "MENU_"){
                str = llDeleteSubString(str, 0, 4);
                showMenu(str, id);
            }
        }
        
        // Menu management commands
        else if(num == lnkMenuClear)
            clearMenusList();
        else if(num == lnkMenuAdd){
            list data = llParseString2List(str, [seperator], []);

            string message = llList2String(data, 0);
            list buttons = [];
            list returns = [];

            integer i;
            integer count = llGetListLength(data);
            for(i=2; i<count;){
                buttons += [llList2String(data, i++)];
                returns += [llList2String(data, i++)];
            }

            addMenu((string)id, message, buttons, returns);

        }else if(num == lnkMenuShow){
            dialogCancel();
            showMenu(str, id);
        }
    }
}