Difference between revisions of "Dynamic Menu"

From Fire And Ice Grid
Jump to navigation Jump to search
 
(5 intermediate revisions by the same user not shown)
Line 1: Line 1:
 +
[[Category: Useful Scripts]]
 +
[[Category: Opensim Script Library]]
 +
 
This script will allow you to create dynamic menus for your items. This means that if you have more buttons than will fit on the dialogue menus (popup menus in the world) they will dynamically spread over multiple pages.  
 
This script will allow you to create dynamic menus for your items. This means that if you have more buttons than will fit on the dialogue menus (popup menus in the world) they will dynamically spread over multiple pages.  
 +
 +
This script is written in LSL (Linden Scripting Language) and compiles in both Opensim (using either X or Y engine) and Second Life.
  
 
<br>
 
<br>
Line 6: Line 11:
 
* Copy-paste the licence and script
 
* Copy-paste the licence and script
 
* Edit the two lists in the User Variables to change the fixed and dynamic button names
 
* Edit the two lists in the User Variables to change the fixed and dynamic button names
 +
 +
=== Script On Github ===
 +
[https://github.com/Fire-And-Ice-Grid/LSL-And-OSSL-Script-Library LSL And OSSL Script Library On GitHub]
  
 
==== Licence ====
 
==== Licence ====
<syntaxhighlight lang="" line>
+
<syntaxhighlight lang="ini" line>
 
BSD 3-Clause License
 
BSD 3-Clause License
 
Copyright (c) 2020, Sara Payne
 
Copyright (c) 2020, Sara Payne
Line 156: Line 164:
 
}// close state default
 
}// close state default
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
==Syntax Highlighting==
 +
 +
[https://www.mediawiki.org/wiki/Extension:SyntaxHighlight GeShi] syntax highlighting is enabled on this wiki. <be>
 +
 +
When using the tabs described in the link, change the language part to "lsl". Eg.<br>
 +
syntaxhighlight lang="lsl" line<br>
 +
inside angled brackets <>

Latest revision as of 23:17, 16 January 2021


This script will allow you to create dynamic menus for your items. This means that if you have more buttons than will fit on the dialogue menus (popup menus in the world) they will dynamically spread over multiple pages.

This script is written in LSL (Linden Scripting Language) and compiles in both Opensim (using either X or Y engine) and Second Life.


  • Create a prim in world
  • Add a new script to the prim
  • Copy-paste the licence and script
  • Edit the two lists in the User Variables to change the fixed and dynamic button names

Script On Github

LSL And OSSL Script Library On GitHub

Licence

 1 BSD 3-Clause License
 2 Copyright (c) 2020, Sara Payne
 3 All rights reserved.
 4 Redistribution and use in source and binary forms, with or without
 5 modification, are permitted provided that the following conditions are met:
 6 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
 7 2. Redistributions in binary form must reproduce the above copyright notice,
 8    this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
 9 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
10 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
11 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
12 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
13 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
14 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
15 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
16 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
17 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
18 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
19 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  1 //Start User Variables
  2 //Menu Lists, Dynamic Buttons, Reserved Buttons and a temp list used to display the menu
  3 list menuButtons = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24"]; //menu buttons list
  4 list reservedButtons = ["Next", "Back"]; // permanant buttons on the menu
  5 //End User Variables
  6 
  7 list tempMenuButtons; //used to store temp menu entries.This is the list which gets displayed in the dialog statement.
  8 //variables used in creating the dynaic menus
  9 integer numOfPages; //used to store the total number of pages in this menu
 10 integer dynamicButtonsPerPage; //the number of spaces left after the reserved buttons
 11 integer reservedButtonsPerPage; //number of reserved buttoons per page
 12 integer currentPageNumber; //used to store the current page number
 13 integer menuLength; //used to store the length of the menu being worked on
 14 //Listeners used for hearing menu button entries
 15 integer mainMenuChannel; //global integer for menu channel
 16 integer mainMenuChannelListen;//clobal control integer for turning menu listen on and off
 17 //Other Variables
 18 key user; //uuid of who ever is using the menu
 19 string menuMessage = "You are viewing page "; //message to display in the dialog menu
 20 
 21 
 22 SetUpListeners()
 23 {//sets the coms channel and the random menu channel then turns the listeners on.
 24 mainMenuChannel = (integer)(llFrand(-1000000000.0) - 1000000000.0); //generates random main menu channel
 25 mainMenuChannelListen = llListen(mainMenuChannel, "", NULL_KEY, "");//sets up main menu listen integer
 26 llListenControl (mainMenuChannelListen, TRUE); //turns on listeners for main menu channel
 27 }//close set up listeners
 28 
 29 integer CalcPagesInMenu(list inputList)
 30 { // works out the total number of pages needed allowing two buttons for forwards and backwards
 31     reservedButtonsPerPage = llGetListLength(reservedButtons); // how many button spaces per page we need to reserve
 32     dynamicButtonsPerPage = 12-reservedButtonsPerPage;  //subtract the reserve from the total availible of 12
 33     numOfPages = (integer)(menuLength /dynamicButtonsPerPage); // 2 buttons for next and back with 1p per page and an extra page for any remainders
 34     if (menuLength%dynamicButtonsPerPage > 0) ++numOfPages; //if there is any remainder after dividing the number of buttons by 10 addd on another page
 35     return numOfPages; //returns the number of pages
 36 }//close calculate pages in menu
 37 
 38 GenTempMenuList(list inputList)
 39 { // generates the temp menu buttons (the ones for the current page)
 40     tempMenuButtons = []; //makes sure the list is blank before we start
 41     integer firstIndex = currentPageNumber*dynamicButtonsPerPage; //uses the page number to work out the start index in the menu buttons list
 42     integer lastIndex = firstIndex + dynamicButtonsPerPage-1; // calculates the last index in the menu buttons list
 43     if (lastIndex >= llGetListLength(inputList)) lastIndex = llGetListLength(inputList) -1; //don't add extra blank buttons for no good reason
 44     integer i; 
 45     for ( i = firstIndex; i <= lastIndex; ++ i)
 46     {   // adds each of the index is the range calculated to the temp buttons list
 47         tempMenuButtons += llList2String(inputList,i); 
 48     }
 49     AddReservedButtonsToTempMenu(); //adds the reserved buttons to the temp buttons list
 50 } //close generate temp menu list
 51 
 52 AddReservedButtonsToTempMenu()
 53 { // loops through the reserved buttons and adds them to the temp list
 54     integer i;
 55     for (i = 0; i < llGetListLength(reservedButtons); ++i)
 56     {
 57         tempMenuButtons += llList2String (reservedButtons, i);
 58     }
 59 }//close add reserved buttons to temp list
 60 
 61 DialogueMenu(list inputList)
 62 { //displays a big list of buttons dynamially over many pages 
 63 menuLength = llGetListLength (inputList);
 64 if  (menuLength <= 12 - llGetListLength(reservedButtons)) 
 65     { // come here if the dynamic buttons and reserved buttons fit on one page
 66         tempMenuButtons = inputList; // make the temp list the same as the main list
 67         AddReservedButtonsToTempMenu(); //add the reserved buttons
 68     } // close if everything fits on one page
 69 else
 70     {   //work out the menu structure and display the requested page number
 71         numOfPages = CalcPagesInMenu(inputList); 
 72         if ( currentPageNumber >= numOfPages) currentPageNumber = 0; // these two lines make sure the page number never goes out of range;
 73         else if (currentPageNumber < 0) currentPageNumber = numOfPages-1; //counting starts from 0 so the last page is 1 less than the total number of pages 
 74         GenTempMenuList(inputList); //gen list and pass the menu to process from   
 75     }
 76 string pageMessage = menuMessage + " " + (string)(currentPageNumber+1) + " of " + (string) numOfPages;
 77 llDialog(user, pageMessage, tempMenuButtons, mainMenuChannel); //display the current page in the dialog
 78 //llOwnerSay("Debug: Current Page Buttons: \n" + llList2CSV(tempMenuButtons));
 79 }// close display dialogue menu
 80 
 81 ProcessMenuResponse(string message)
 82 { // processes responses to the listen event
 83     if (message == llList2String(reservedButtons, 0) )
 84     {
 85         ++ currentPageNumber; //button in this example is Next to add 1 to the page number and call the menu again
 86         DialogueMenu(menuButtons); //call the menu again
 87     }
 88     else if (message == llList2String(reservedButtons, 1))
 89     {
 90         -- currentPageNumber; // button in this example is back so subtract 1 from the page number 
 91         DialogueMenu(menuButtons); //call the menu again
 92     }
 93     else 
 94         {   // come here if pressed button is not in the reserved list
 95             if(~llListFindList(menuButtons, (list)message))
 96             {   //come her if the button pressed is in the dynamic buttons list
 97                 llRegionSayTo(user, PUBLIC_CHANNEL, "A dynamic button was pressed");
 98             }
 99             else llOwnerSay ("Debug: Unknown button pressed");
100         }
101 }// close process messages from the listen event
102 
103 default
104 {
105     state_entry()
106     {   //come here once when the scrip first runs
107         SetUpListeners(); // sets up the listeners
108         currentPageNumber = 0; //sets the page number to 0 when the script is frist run
109     } // close state entry
110     
111     touch_start(integer count)
112     { //someones touched the prim
113         user = llDetectedKey(0); //stores the uuid of the person who touched me
114         DialogueMenu(menuButtons); // to use a different list just change menu buttons to what ever list you wish to use for your menu
115     }// close touch start
116     
117     listen (integer channel, string name, key id, string message)
118     { // listens for inputs from the dialog menu
119         if (llGetOwnerKey(id) == llGetOwner() && channel == mainMenuChannel); 
120         {  //if the message heard is on the correct channel and the objects owner is the same as this objects owner process the message
121             ProcessMenuResponse(message); //sends the heard message to the process method
122         }// close if owner and channel number match
123     }//close listen
124 }// close state default

Syntax Highlighting

GeShi syntax highlighting is enabled on this wiki. <be>

When using the tabs described in the link, change the language part to "lsl". Eg.
syntaxhighlight lang="lsl" line
inside angled brackets <>