Difference between revisions of "Dialog Menus Control"

From Second Life Wiki
Jump to navigation Jump to search
m (lsl code tagging)
Line 28: Line 28:


<lsl>
<lsl>
// READ ME:
// READ ME:
// To see this sample in action;
// To see this sample in action;
// Put "Nargus Dialog Control" and "Nargus Dialog Menus" along with this script
// Put "Nargus Dialog Control" and "Nargus Dialog Menus" along with this script
// in a prim and touch.
// in a prim and touch.
 
// Dialog constants
// Dialog constants
integer lnkDialog = 14001;
integer lnkDialog = 14001;
integer lnkDialogNotify = 14004;
integer lnkDialogNotify = 14004;
integer lnkDialogResponse = 14002;
integer lnkDialogResponse = 14002;
integer lnkDialogTimeOut = 14003;
integer lnkDialogTimeOut = 14003;
 
integer lnkDialogReshow = 14011;
integer lnkDialogReshow = 14011;
integer lnkDialogCancel = 14012;
integer lnkDialogCancel = 14012;
 
integer lnkMenuClear = 15001;
integer lnkMenuClear = 15001;
integer lnkMenuAdd = 15002;
integer lnkMenuAdd = 15002;
integer lnkMenuShow = 15003;
integer lnkMenuShow = 15003;
 
string seperator = "||";
string seperator = "||";
integer dialogTimeOut = 0;
integer dialogTimeOut = 0;
 
// ********** DIALOG FUNCTIONS **********
// ********** DIALOG FUNCTIONS **********
string packDialogMessage(string message, list buttons, list returns){
string packDialogMessage(string message, list buttons, list returns){
    string packed_message = message + seperator + (string)dialogTimeOut;
    string packed_message = message + seperator + (string)dialogTimeOut;
   
   
    integer i;
    integer i;
    integer count = llGetListLength(buttons);
    integer count = llGetListLength(buttons);
    for(i=0; i<count; i++) packed_message += seperator + llList2String(buttons, i) + seperator + llList2String(returns, i);
    for(i=0; i<count; i++) packed_message += seperator + llList2String(buttons, i) + seperator + llList2String(returns, i);
 
    return packed_message;
    return packed_message;
}
}
 
dialogReshow(){llMessageLinked(LINK_THIS, lnkDialogReshow, "", NULL_KEY);}
dialogReshow(){llMessageLinked(LINK_THIS, lnkDialogReshow, "", NULL_KEY);}
dialogCancel(){
dialogCancel(){
    llMessageLinked(LINK_THIS, lnkDialogCancel, "", NULL_KEY);
    llMessageLinked(LINK_THIS, lnkDialogCancel, "", NULL_KEY);
    llSleep(1);
    llSleep(1);
}
}
 
dialogNotify(key id, string message){
dialogNotify(key id, string message){
    list rows;
    list rows;
   
   
    llMessageLinked(LINK_THIS, lnkDialogNotify,
    llMessageLinked(LINK_THIS, lnkDialogNotify,
        message + seperator + (string)dialogTimeOut + seperator,
        message + seperator + (string)dialogTimeOut + seperator,
        id);
        id);
}
}
// ********** END DIALOG FUNCTIONS **********
// ********** END DIALOG FUNCTIONS **********
 
 
default{
default{
    state_entry(){
    state_entry(){
        llMessageLinked(LINK_THIS, lnkMenuClear, "", NULL_KEY);
        llMessageLinked(LINK_THIS, lnkMenuClear, "", NULL_KEY);
        llMessageLinked(LINK_THIS, lnkMenuAdd, packDialogMessage(
        llMessageLinked(LINK_THIS, lnkMenuAdd, packDialogMessage(
            "[ Main Menu ]\n" +
            "[ Main Menu ]\n" +
            "Messages go here",
            "Messages go here",
            [ "BUTTON_1", "BUTTON_2", "BUTTON_3", "BUTTON_X" ],
            [ "BUTTON_1", "BUTTON_2", "BUTTON_3", "BUTTON_X" ],
            [ "MENU_SubMenu1", "MENU_SubMenu2", "MENU_SubMenu3", "EXIT" ]
            [ "MENU_SubMenu1", "MENU_SubMenu2", "MENU_SubMenu3", "EXIT" ]
        ), "MainMenu");
        ), "MainMenu");
        llMessageLinked(LINK_THIS, lnkMenuAdd, packDialogMessage(
        llMessageLinked(LINK_THIS, lnkMenuAdd, packDialogMessage(
            "[ Sub Menu 1 ]\n" +
            "[ Sub Menu 1 ]\n" +
            "Messages go here",
            "Messages go here",
            [ "SUB_1_1", "SUB_1_2", "SUB_1_3", "MAIN MENU", "SUB_3", "BUTTON_X" ],
            [ "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" ]
            [ "1.1", "1.2", "1.3", "MENU_MainMenu", "MENU_SubMenu3", "EXIT" ]
        ), "SubMenu1");
        ), "SubMenu1");
        llMessageLinked(LINK_THIS, lnkMenuAdd, packDialogMessage(
        llMessageLinked(LINK_THIS, lnkMenuAdd, packDialogMessage(
            "[ Sub Menu 2 ]\n" +
            "[ Sub Menu 2 ]\n" +
            "Messages go here",
            "Messages go here",
            [ "SUB_2_1", "SUB_2_2", "SUB_2_3", "MAIN MENU", "SUB_1", "BUTTON_X" ],
            [ "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" ]
            [ "2.1", "2.2", "2.3", "MENU_MainMenu", "MENU_SubMenu1", "EXIT" ]
        ), "SubMenu2");
        ), "SubMenu2");
        llMessageLinked(LINK_THIS, lnkMenuAdd, packDialogMessage(
        llMessageLinked(LINK_THIS, lnkMenuAdd, packDialogMessage(
            "[ Sub Menu 3 ]\n" +
            "[ Sub Menu 3 ]\n" +
            "Messages go here",
            "Messages go here",
            [ "SUB_3_1", "SUB_3_2", "SUB_3_3", "MAIN MENU", "SUB_2", "BUTTON_X" ],
            [ "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" ]
            [ "3.1", "3.2", "3.3", "MENU_MainMenu", "MENU_SubMenu2", "EXIT" ]
        ), "SubMenu3");
        ), "SubMenu3");
       
       
        llSetText("Touch me to show menu", <1,1,1>, 1);
        llSetText("Touch me to show menu", <1,1,1>, 1);
    }
    }
 
    link_message(integer sender_num, integer num, string str, key id){
    link_message(integer sender_num, integer num, string str, key id){
        if(num == lnkDialogTimeOut){
        if(num == lnkDialogTimeOut){
            dialogNotify(llGetOwner(), "Menu time-out. Please try again.");
            dialogNotify(llGetOwner(), "Menu time-out. Please try again.");
            state default;
            state default;
        }else if(num == lnkDialogResponse){
        }else if(num == lnkDialogResponse){
            llWhisper(0, str);
            llWhisper(0, str);
        }
        }
    }
    }
   
   
    touch_start(integer num_detected){
    touch_start(integer num_detected){
        llMessageLinked(LINK_THIS, lnkMenuShow, "", llDetectedOwner(0));
        llMessageLinked(LINK_THIS, lnkMenuShow, "", llDetectedOwner(0));
    }
    }
}
}
</lsl>
</lsl>


Line 125: Line 125:


<lsl>
<lsl>
// ********** DIALOG MENUS MODULE ********** //
// ********** DIALOG MENUS MODULE ********** //
// By Nargus Asturias
// By Nargus Asturias
// Version 1.00
// Version 1.01
//
//
// Multi-layer menus management module for Nargus Dialog Control.
// Multi-layer menus management module for Nargus Dialog Control.
// Use same packing method as Nargus Dialog Control
// Use same packing method as Nargus Dialog Control
//
//
// HOW TO USE:
// HOW TO USE:
// 1) Initialize menu by sending "lnkMenuClear" signal:
// 1) Initialize menu by sending "lnkMenuClear" signal:
//          llMessageLinked(LINK_THIS, lnkMenuClear, "", NULL_KEY);
//          llMessageLinked(LINK_THIS, lnkMenuClear, "", NULL_KEY);
//
//
// 2) Add menu dialog using provided function (or manually, please referr to Nargus Dialog Control  
// 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;
//    manual). Make sure signal is sent with "lnkMenuAdd" and key field is menu's name;
//          llMessageLinked(LINK_THIS, lnkMenuAdd, ......, "MainMenu");
//          llMessageLinked(LINK_THIS, lnkMenuAdd, ......, "MainMenu");
//
//
//    To make a button show submenu, use following as return value of the button:
//    To make a button show submenu, use following as return value of the button:
//          MENU_<name>
//          MENU_<name>
//    Replace "<name>" with the actual name of the added menu (without parenthesis).
//    Replace "<name>" with the actual name of the added menu (without parenthesis).
//
//
// 3) Repeat (2) for as much menus as needed
// 3) Repeat (2) for as much menus as needed
//
//
// 4) To show a menu, use:
// 4) To show a menu, use:
//          llMessageLinked(LINK_THIS, lnkMenuShow, name, llGetOwner());
//          llMessageLinked(LINK_THIS, lnkMenuShow, name, llGetOwner());
//    When "name" is name of the menu to show. To show last-used menu, leave this field empty.
//    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.
// 5) Dialog will return value the same way as usual call to Nargus Dialog Module script.
// ******************************************* //
// ******************************************* //
 
// Dialog constants
// Dialog constants
integer lnkDialog = 14001;
integer lnkDialog = 14001;
integer lnkDialogNotify = 14004;
integer lnkDialogNotify = 14004;
integer lnkDialogResponse = 14002;
integer lnkDialogResponse = 14002;
integer lnkDialogTimeOut = 14003;
integer lnkDialogTimeOut = 14003;
 
integer lnkDialogReshow = 14011;
integer lnkDialogReshow = 14011;
integer lnkDialogCancel = 14012;
integer lnkDialogCancel = 14012;
 
string seperator = "||";
string seperator = "||";
integer dialogTimeOut = 0;
integer dialogTimeOut = 0;
 
// ********** DIALOG FUNCTIONS **********
// ********** DIALOG FUNCTIONS **********
dialogReshow(){llMessageLinked(LINK_THIS, lnkDialogReshow, "", NULL_KEY);}
dialogReshow(){llMessageLinked(LINK_THIS, lnkDialogReshow, "", NULL_KEY);}
dialogCancel(){
dialogCancel(){
    llSleep(1);
    llSleep(1);
    llMessageLinked(LINK_THIS, lnkDialogCancel, "", NULL_KEY);
    llMessageLinked(LINK_THIS, lnkDialogCancel, "", NULL_KEY);
}
}
// ********** END DIALOG FUNCTIONS **********
// ********** END DIALOG FUNCTIONS **********
 
// Constants
// Constants
integer lnkMenuClear = 15001;
integer lnkMenuClear = 15001;
integer lnkMenuAdd = 15002;
integer lnkMenuAdd = 15002;
integer lnkMenuShow = 15003;
integer lnkMenuShow = 15003;
 
// Menus variables
// Menus variables
list menuNames;            // List of names of all menus
list menuNames;            // List of names of all menus
list menus;                // List of packed menus command, in order of menuNames
list menus;                // List of packed menus command, in order of menuNames
 
// Variables
// Variables
integer lastMenuIndex;      // Latest called menu's index
integer lastMenuIndex;      // Latest called menu's index
 
// ********** Menu Functions **********
// ********** Menu Functions **********
clearMenusList(){
clearMenusList(){
    menuNames = [];
    menuNames = [];
    menus = [];
    menus = [];
 
    lastMenuIndex = 0;
    lastMenuIndex = 0;
}
}
 
addMenu(string name, string message, list buttons, list returns){
addMenu(string name, string message, list buttons, list returns){
    // Reduced menu request time by packing request commands
    // Reduced menu request time by packing request commands
    string packed_message = message + seperator + (string)dialogTimeOut;
    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;
    integer i;
    if(name != ""){
    integer count = llGetListLength(buttons);
        index = llListFindList(menuNames, [name]);
    for(i=0; i<count; i++) packed_message += seperator + llList2String(buttons, i) + seperator + llList2String(returns, i);
        if(index < 0) index = lastMenuIndex;
 
    }else index = lastMenuIndex;
    // Add menu to the menus list
   
    menuNames += [name];
    lastMenuIndex = index;
    menus += [packed_message];
   
}
    // Load menu command and execute
 
    string packed_message = llList2String(menus, index);     
showMenu(string name, key id){
    llMessageLinked(LINK_THIS, lnkDialog, packed_message, id);
    if(llGetListLength(menuNames) <= 0) return;
}
 
    integer index;
// ********** States **********
    if(name != ""){
default{
        index = llListFindList(menuNames, [name]);
    state_entry(){
        if(index < 0) index = lastMenuIndex;
        clearMenusList();
    }else index = lastMenuIndex;
    }
   
    lastMenuIndex = index;
    link_message(integer sender_num, integer num, string str, key id){
   
        // Menu response commands
    // Load menu command and execute
        if(num == lnkDialogResponse){
    string packed_message = llList2String(menus, index);     
            if(llGetSubString(str, 0, 4) == "MENU_"){
    llMessageLinked(LINK_THIS, lnkDialog, packed_message, id);
                str = llDeleteSubString(str, 0, 4);
}
                showMenu(str, id);
 
            }
// ********** States **********
        }
default{
       
    state_entry(){
        // Menu management commands
        clearMenusList();
        else if(num == lnkMenuClear)
    }
            clearMenusList();
 
        else if(num == lnkMenuAdd){
    link_message(integer sender_num, integer num, string str, key id){
            list data = llParseString2List(str, [seperator], []);
        // Menu response commands
        if(num == lnkDialogResponse){
            string message = llList2String(data, 0);
            if(llGetSubString(str, 0, 4) == "MENU_"){
            list buttons = [];
                str = llDeleteSubString(str, 0, 4);
            list returns = [];
                showMenu(str, id);
            }
            integer i;
        }
            integer count = llGetListLength(data);
       
            for(i=2; i<count;){
        // Menu management commands
                buttons += [llList2String(data, i++)];
        else if(num == lnkMenuClear)
                returns += [llList2String(data, i++)];
            clearMenusList();
            }
        else if(num == lnkMenuAdd){
            list data = llParseString2List(str, [seperator], []);
            addMenu((string)id, message, buttons, returns);
 
            string message = llList2String(data, 0);
        }else if(num == lnkMenuShow){
            list buttons = [];
            dialogCancel();
            list returns = [];
            showMenu(str, id);
 
        }
            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);
        }
    }
}
</lsl>
</lsl>


{{LSLC|Library|Dialog Menus Control}}
{{LSLC|Library|Dialog Menus Control}}

Revision as of 19:57, 25 May 2008

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.

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


<lsl> // 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));
   }

} </lsl>

Nargus Dialog Menus v1.01 (by Nargus Asturias)

<lsl> // ********** 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);
       }
   }

} </lsl>