Difference between revisions of "SimpleDialogMenuSystem"

From Second Life Wiki
Jump to: navigation, search
(Removed second declaration of "firstChoice" and "lastChoice" as they have been declared already.)
(See Discussion Page for changes)
Line 21: Line 21:
 
string msg = "Please make a choice.";
 
string msg = "Please make a choice.";
 
string msgTimeout = "Sorry. You snooze; you lose.";
 
string msgTimeout = "Sorry. You snooze; you lose.";
float Timeout= 60;
+
float Timeout= 60.0;
 
list DIALOG_CHOICES = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","Y","Z"];
 
list DIALOG_CHOICES = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","Y","Z"];
  
Line 31: Line 31:
 
//MAX_DIALOG_CHOICES_PER_PG, and 2 code lines in the giveDialog function.
 
//MAX_DIALOG_CHOICES_PER_PG, and 2 code lines in the giveDialog function.
 
//It is noted in the function exactly where and how to change these.
 
//It is noted in the function exactly where and how to change these.
 
  
 
integer N_DIALOG_CHOICES;
 
integer N_DIALOG_CHOICES;
Line 41: Line 40:
 
integer pageNum;
 
integer pageNum;
  
giveDialog(key ID, integer pageNum) {
+
giveDialog(key ID) {
 
     list buttons;
 
     list buttons;
 
     integer firstChoice;
 
     integer firstChoice;
Line 99: Line 98:
 
           //omit DIALOG_BACK_BTN in line above if not offering
 
           //omit DIALOG_BACK_BTN in line above if not offering
 
         }
 
         }
         llDialog(ID, "Page "+(string)pageNum+"\nChoose one:", buttons, channel_dialog);
+
        llSetTimerEvent(Timeout);
 +
         llDialog(ID, "Page "+(string)pageNum+"\n" + msg, buttons, channel_dialog);
 
}
 
}
  
Line 105: Line 105:
 
CancelListen() {
 
CancelListen() {
 
     llListenRemove(listen_id);
 
     llListenRemove(listen_id);
     llSetTimerEvent(0);
+
     llSetTimerEvent(0.0);
 
}
 
}
  
 
default{
 
default{
  state_entry() {
+
    state_entry() {
    channel_dialog = ( -1 * (integer)("0x"+llGetSubString((string)llGetKey(),-5,-1)) );
+
        channel_dialog = ( -1 * (integer)("0x"+llGetSubString((string)llGetKey(),-5,-1)) );
  }
+
    }
 
    
 
    
  touch_start(integer total_number) {
+
    touch_start(integer total_number) {
    ToucherID = llDetectedKey(0);
+
        ToucherID = llDetectedKey(0);
    listen_id = llListen( channel_dialog, "", ToucherID, "");
+
        listen_id = llListen( channel_dialog, "", ToucherID, "");
    llSetTimerEvent(Timeout);
+
        pageNum = 1;
    pageNum = 1;
+
        giveDialog(ToucherID, pageNum);
    giveDialog(ToucherID, pageNum);
+
    }
  }
+
  
  
  listen(integer channel, string name, key id, string choice) {
+
    listen(integer channel, string name, key id, string choice) {
    //here, you need to only:
+
        //here, you need to only:
    //1. implement something that happens when the back button is pressed, or omit back button
+
        //1. implement something that happens when the back button is pressed, or omit back button
    //2. Go to the else event. That is where any actual choice is. Process that choice.
+
        //2. Go to the else event. That is where any actual choice is. Process that choice.
    if (choice == "-") {
+
        if (choice == "-") {
    giveDialog(ToucherID, pageNum);  
+
            giveDialog(ToucherID);
 +
        }
 +
        else if ( choice == DIALOG_DONE_BTN){
 +
            CancelListen();
 +
            return;
 +
        }
 +
        else if (choice == DIALOG_BACK_BTN) {
 +
            CancelListen();
 +
            //go back to where you want
 +
        }
 +
        else if (llSubStringIndex(choice, PREV_PG_DIALOG_PREFIX) == 0) {
 +
            pageNum = (integer)llGetSubString(choice, llStringLength(PREV_PG_DIALOG_PREFIX), -1);
 +
            giveDialog(ToucherID);
 +
        }
 +
        else if (llSubStringIndex(choice, NEXT_PG_DIALOG_PREFIX) == 0) {
 +
            pageNum = (integer)llGetSubString(choice, llStringLength(NEXT_PG_DIALOG_PREFIX), -1);
 +
            giveDialog(ToucherID);
 +
        }
 +
        else { //this is the section where you do stuff
 +
            llSay(0, "You chose " + choice);
 +
            //okay anything else left is an actual choice, so do something with it
 +
        }
 
     }
 
     }
     else if ( choice == DIALOG_DONE_BTN){
+
 
 +
     timer() {
 
         CancelListen();
 
         CancelListen();
         return;
+
         llWhisper(0, msgTimeout);
 
     }
 
     }
    else if (choice == DIALOG_BACK_BTN) {
 
        CancelListen();
 
        //go back to where you want
 
    }
 
    else if (llSubStringIndex(choice, PREV_PG_DIALOG_PREFIX) == 0){
 
        pageNum =
 
        (integer)llGetSubString(choice, llStringLength(PREV_PG_DIALOG_PREFIX), -1);
 
        giveDialog(ToucherID, pageNum);
 
    }
 
    else if (llSubStringIndex(choice, NEXT_PG_DIALOG_PREFIX) == 0) {
 
        pageNum =
 
        (integer)llGetSubString(choice, llStringLength(NEXT_PG_DIALOG_PREFIX), -1);
 
        giveDialog(ToucherID, pageNum);
 
    }
 
    else { //this is the section where you do stuff
 
        llSay(0, "You chose " + choice);
 
        //okay anything else left is an actual choice, so do something with it
 
 
    }
 
  }
 
 
  timer() {
 
    llListenRemove(listen_id);
 
    llWhisper(0, msgTimeout);
 
  }
 
 
}
 
}
 
</lsl>
 
</lsl>

Revision as of 11:43, 9 November 2013

Function: list giveDialog(Key ID, integer pageNum);

Multi-paging, next and previous pages. There are fancier dialog menu routines; this is a bit more accessible, perhaps, to beginners.

Even so, learners may find this script challenging enough. Tip! If it's just utility you are after -- getting a menu system in so you can get back to the rest of the script you are learning to write, then don't worry about how the main function, giveDialog(), actually works.

Instead, ignore it, as it's fairly complex for a learner, and just focus on these things that you do need to change, and on getting them right, and then focus on processing the answers your menu gets from the user. The changes you need to make are relatively easy. And though the script looks long, the part you need to be in control of is actually very short!

  1. Change any of the constant values at the top as per your needs at the time;
    For the list of DIALOG_CHOICES, you can hard code them in, as they are here, or as you get fancier, you can read them in -- from a notecard, from a list of inventory in the prim this script is in, from choices communicated to this script somehow, etc.
  2. If you are not offering a back button, follow directions in the code
  3. In the listen event:
    Add some way to process the back buttton, if offering;
    The final else in the listen event is an actual choice that made it through all the other evaluation. Do something with the choice.

See also: Building a dialog menu step by step

<lsl> string msg = "Please make a choice."; string msgTimeout = "Sorry. You snooze; you lose."; float Timeout= 60.0; list DIALOG_CHOICES = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","Y","Z"];

integer channel_dialog; integer listen_id; key ToucherID;

//if not offering a back button, there are 3 things to change: //MAX_DIALOG_CHOICES_PER_PG, and 2 code lines in the giveDialog function. //It is noted in the function exactly where and how to change these.

integer N_DIALOG_CHOICES; integer MAX_DIALOG_CHOICES_PER_PG = 8; // if not offering back button, increase this to 9 string PREV_PG_DIALOG_PREFIX = "< Page "; string NEXT_PG_DIALOG_PREFIX = "> Page "; string DIALOG_DONE_BTN = "Done"; string DIALOG_BACK_BTN = "<< Back"; integer pageNum;

giveDialog(key ID) {

   list buttons;
   integer firstChoice;
   integer lastChoice;
   integer prevPage;
   integer nextPage;
   string OnePage;
   N_DIALOG_CHOICES = llGetListLength(DIALOG_CHOICES);
   if (N_DIALOG_CHOICES <= 10) {
       buttons = DIALOG_CHOICES;
       OnePage = "Yes";
   }
   else {
       integer nPages = (N_DIALOG_CHOICES+MAX_DIALOG_CHOICES_PER_PG-1)/MAX_DIALOG_CHOICES_PER_PG;
       if (pageNum < 1 || pageNum > nPages) {
           pageNum = 1;
       }
       firstChoice = (pageNum-1)*MAX_DIALOG_CHOICES_PER_PG;
       lastChoice = firstChoice+MAX_DIALOG_CHOICES_PER_PG-1;
       if (lastChoice >= N_DIALOG_CHOICES) {
           lastChoice = N_DIALOG_CHOICES;
       }
       if (pageNum <= 1) {
           prevPage = nPages;
           nextPage = 2;
       }
       else if (pageNum >= nPages) {
           prevPage = nPages-1;
           nextPage = 1;
       }
       else {
           prevPage = pageNum-1;
           nextPage = pageNum+1;
       }
       buttons = llList2List(DIALOG_CHOICES, firstChoice, lastChoice);
   }
   // FYI, this puts the navigation button row first, so it is always at the bottom of the dialog
       list buttons01 = llList2List(buttons, 0, 2);
       list buttons02 = llList2List(buttons, 3, 5);
       list buttons03 = llList2List(buttons, 6, 8);
       list buttons04;
       if (OnePage == "Yes") {
           buttons04 = llList2List(buttons, 9, 11);
       }
       buttons = buttons04 + buttons03 + buttons02 + buttons01;
       if (OnePage == "Yes") {
            buttons = [ DIALOG_DONE_BTN, DIALOG_BACK_BTN ]+ buttons;
           //omit DIALOG_BACK_BTN in line above  if not offering
           
       }
       else {
           buttons =
           (buttons=[])+
           [ PREV_PG_DIALOG_PREFIX+(string)prevPage,
           DIALOG_BACK_BTN, NEXT_PG_DIALOG_PREFIX+(string)nextPage, DIALOG_DONE_BTN
           ]+buttons;
          //omit DIALOG_BACK_BTN in line above if not offering
       }
       llSetTimerEvent(Timeout);
       llDialog(ID, "Page "+(string)pageNum+"\n" + msg, buttons, channel_dialog);

}


CancelListen() {

   llListenRemove(listen_id);
   llSetTimerEvent(0.0);

}

default{

   state_entry() {
       channel_dialog = ( -1 * (integer)("0x"+llGetSubString((string)llGetKey(),-5,-1)) );
   }
 
   touch_start(integer total_number) {
       ToucherID = llDetectedKey(0);
       listen_id = llListen( channel_dialog, "", ToucherID, "");
       pageNum = 1;
       giveDialog(ToucherID, pageNum);
   }


   listen(integer channel, string name, key id, string choice) {
       //here, you need to only:
       //1. implement something that happens when the back button is pressed, or omit back button
       //2. Go to the else event. That is where any actual choice is. Process that choice.
       if (choice == "-") {
           giveDialog(ToucherID);
       }
       else if ( choice == DIALOG_DONE_BTN){
           CancelListen();
           return;
       }
       else if (choice == DIALOG_BACK_BTN) {
           CancelListen();
           //go back to where you want
       }
       else if (llSubStringIndex(choice, PREV_PG_DIALOG_PREFIX) == 0) {
           pageNum = (integer)llGetSubString(choice, llStringLength(PREV_PG_DIALOG_PREFIX), -1);
           giveDialog(ToucherID);
       }
       else if (llSubStringIndex(choice, NEXT_PG_DIALOG_PREFIX) == 0) {
           pageNum = (integer)llGetSubString(choice, llStringLength(NEXT_PG_DIALOG_PREFIX), -1);
           giveDialog(ToucherID);
       }
       else { //this is the section where you do stuff
           llSay(0, "You chose " + choice);
           //okay anything else left is an actual choice, so do something with it
       }
   }
   timer() {
       CancelListen();
       llWhisper(0, msgTimeout);
   }

} </lsl>