User:ANSI Soderstrom/Extended Dialog Example: Difference between revisions
mNo edit summary |
|||
| (7 intermediate revisions by the same user not shown) | |||
| Line 4: | Line 4: | ||
== Extended Dialog Example == | == Extended Dialog Example == | ||
Some People in SL are asking me, how | Some People in SL are asking me, how would myself realize a extended dialog menu (with timeout, dynamic content, sort-option, ...) | ||
Before i invent the wheel every week new, i will post my "best" code here, so | |||
Before i invent the wheel every week new, i will post my "best" code here, so in future i can simply refer to this page. | |||
<lsl> | <lsl> | ||
| Line 11: | Line 12: | ||
// (C) 09/2010 ANSI Soderstrom | // (C) 09/2010 ANSI Soderstrom | ||
// First, let us define some example choices... | |||
list TEST_DIALOG_CHOICES = ["A","B","C","1","2","3","a","b","c","test1","test3","test2"]; | list TEST_DIALOG_CHOICES = ["A","B","C","1","2","3","a","b","c","test1","test3","test2"]; | ||
float TimeOut = 30; // | float TimeOut = 30; // (in Seconds) We need a Timeout for the Listener, not least because laaaaag. | ||
float maxButtons = 12; // How many Buttons | float maxButtons = 12; // How many Buttons shall we have per Page ? (12 is the maximum) | ||
integer Sort = TRUE; // Should i Sort the List ? (Logically) 0..9 --> a...b --> A...B | |||
integer | integer Sort_Ascending = TRUE; // (TRUE = Ascending, FALSE = Descending) permute the list vertically. Have only Effect if Sort == TRUE; | ||
integer CHANNEL; | integer CHANNEL; // We need a global channel... | ||
integer PAGE; | integer PAGE; // ...and a global memory for the actual Pagenumber | ||
key LastMenuUser; | key LastMenuUser; // ...and don´t forget who is the actual controluser. | ||
list CreateNavigation(integer PAGES) { | list CreateNavigation(integer PAGES) { | ||
| Line 55: | Line 55: | ||
CreateMenu(key id, list menu) { | CreateMenu(key id, list menu) { | ||
if(Sort) { | |||
menu = llListSort(menu,1,Sort_Ascending); | |||
} | |||
integer PAGES = llCeil(llGetListLength(menu)/(maxButtons-3)); | integer PAGES = llCeil(llGetListLength(menu)/(maxButtons-3)); | ||
list NAVIGATION = CreateNavigation(PAGES); | list NAVIGATION = CreateNavigation(PAGES); | ||
| Line 64: | Line 67: | ||
default { | default { | ||
state_entry() { | state_entry() { | ||
// prevent errormessages | |||
if(maxButtons > 12) { | |||
maxButtons = 12; | |||
} | |||
// Let us scramble the List... (...as example) | |||
TEST_DIALOG_CHOICES = llListRandomize(TEST_DIALOG_CHOICES,1); | |||
// and clear the timerview | |||
llSetText("",<1,1,1>,1); | llSetText("",<1,1,1>,1); | ||
} | } | ||
touch_start(integer i) { | touch_start(integer i) { | ||
// If we touch in this state, iam sure we are on the first Page | |||
PAGE = 1; | PAGE = 1; | ||
// Let us find a random channel | |||
CHANNEL = -llRound(llFrand(1000000)); | CHANNEL = -llRound(llFrand(1000000)); | ||
// remember for the user | |||
LastMenuUser = llDetectedKey(0); | LastMenuUser = llDetectedKey(0); | ||
// All done, we have the point to create our first menupage | |||
CreateMenu(LastMenuUser,TEST_DIALOG_CHOICES); | CreateMenu(LastMenuUser,TEST_DIALOG_CHOICES); | ||
// and for better code reading, we use a new state ! | |||
state Dialog; | state Dialog; | ||
} | } | ||
| Line 79: | Line 93: | ||
state Dialog { | state Dialog { | ||
state_entry() { | state_entry() { | ||
// Listen to the opened channel | |||
llListen(CHANNEL,"",NULL_KEY,""); | llListen(CHANNEL,"",NULL_KEY,""); | ||
// and count the time down to our timeout | |||
llSetTimerEvent(1); | llSetTimerEvent(1); | ||
// Reset the timer... | |||
llResetTime(); | |||
} | } | ||
listen(integer channel, string name, key id, string message) { | listen(integer channel, string name, key id, string message) { | ||
// if we have clicked a menuchoice, we can find the answer from the dialog here | |||
if(~llListFindList(TEST_DIALOG_CHOICES,[message])) { | if(~llListFindList(TEST_DIALOG_CHOICES,[message])) { | ||
// for debugging, tell us our choice | |||
llSay(0, "Your Choice : " + message); | llSay(0, "Your Choice : " + message); | ||
// and back to standby | |||
state default; | state default; | ||
} else { | } else { | ||
// we have clicked a Navigation button, find out which button ... | |||
if(message == "<<<" || message == "BACK") { | if(message == "<<<" || message == "BACK") { | ||
--PAGE; | --PAGE; | ||
| Line 97: | Line 119: | ||
PAGE = llCeil(llGetListLength(TEST_DIALOG_CHOICES)/(maxButtons-3)); | PAGE = llCeil(llGetListLength(TEST_DIALOG_CHOICES)/(maxButtons-3)); | ||
} else { | } else { | ||
// ... or for confusing, abort all :) (will reached with the "No Clue"-Button) | |||
state default; | state default; | ||
} | } | ||
// if we click a button, be sure we reset the timercount and start a new timeout-counter | |||
llResetTime(); | llResetTime(); | ||
// We are still in the listen event, so we can draw a new menu | |||
CreateMenu(id,TEST_DIALOG_CHOICES); | CreateMenu(id,TEST_DIALOG_CHOICES); | ||
} | } | ||
| Line 105: | Line 130: | ||
touch_start(integer i) { | touch_start(integer i) { | ||
// listen only to the control-user and give him the chance to draw a new menu if one page is not appearing... | |||
if(llDetectedKey(0) == LastMenuUser) { | if(llDetectedKey(0) == LastMenuUser) { | ||
CreateMenu(llDetectedKey(0),TEST_DIALOG_CHOICES); | CreateMenu(llDetectedKey(0),TEST_DIALOG_CHOICES); | ||
| Line 111: | Line 137: | ||
timer() { | timer() { | ||
// draw the timeout-counter on the prim | |||
llSetText((string)(llRound(TimeOut - llGetTime())) + " seconds left",<1,1,1>,1); | llSetText((string)(llRound(TimeOut - llGetTime())) + " seconds left",<1,1,1>,1); | ||
// and tell us if we run out of time... | |||
if(llGetTime() > TimeOut) { | if(llGetTime() > TimeOut) { | ||
llSay(0,"Dialog expired"); | llSay(0,"Dialog expired"); | ||
// back to standby | |||
state default; | state default; | ||
} | } | ||
Latest revision as of 23:21, 28 September 2010
Leave a comment
Extended Dialog Example
Some People in SL are asking me, how would myself realize a extended dialog menu (with timeout, dynamic content, sort-option, ...)
Before i invent the wheel every week new, i will post my "best" code here, so in future i can simply refer to this page.
<lsl> // Extended Dialog Example for your Items // (C) 09/2010 ANSI Soderstrom
// First, let us define some example choices... list TEST_DIALOG_CHOICES = ["A","B","C","1","2","3","a","b","c","test1","test3","test2"];
float TimeOut = 30; // (in Seconds) We need a Timeout for the Listener, not least because laaaaag. float maxButtons = 12; // How many Buttons shall we have per Page ? (12 is the maximum)
integer Sort = TRUE; // Should i Sort the List ? (Logically) 0..9 --> a...b --> A...B integer Sort_Ascending = TRUE; // (TRUE = Ascending, FALSE = Descending) permute the list vertically. Have only Effect if Sort == TRUE;
integer CHANNEL; // We need a global channel... integer PAGE; // ...and a global memory for the actual Pagenumber
key LastMenuUser; // ...and don´t forget who is the actual controluser.
list CreateNavigation(integer PAGES) {
list navi = ["No Clue"];
if((PAGE < 1 || PAGE == PAGES) && PAGES != 1) {
PAGE = PAGES;
navi += ["<<<","FIRST"];
} else if((PAGE > PAGES || PAGE == 1) && PAGES != 1) {
PAGE = 1;
navi += ["LAST",">>>"];
} else if (PAGES != 1) {
navi += ["<<<",">>>"];
}
if(PAGES==1) {
navi += [" "," "];
}
return navi;
}
list Padding(integer FillUp) {
list PlaceHolder;
if(FillUp<0) {
do {
PlaceHolder += ["~"]; // Nr# 126 in ASCII Table (Highest one, will be ever the last Letter in List?)
++FillUp;
} while(FillUp!=0);
}
return PlaceHolder;
}
CreateMenu(key id, list menu) {
if(Sort) {
menu = llListSort(menu,1,Sort_Ascending);
}
integer PAGES = llCeil(llGetListLength(menu)/(maxButtons-3));
list NAVIGATION = CreateNavigation(PAGES);
integer length = (integer)maxButtons-llGetListLength(NAVIGATION);
list NEW_MENU = llList2List(menu,(PAGE*length-length),(PAGE*length-1)) + Padding(llGetListLength(menu)-(PAGE*length));
llDialog(id, "(Page " + (string)PAGE + "/" + (string)PAGES + ")\n \nSelect your Height",NAVIGATION + NEW_MENU, CHANNEL);
}
default {
state_entry() {
// prevent errormessages
if(maxButtons > 12) {
maxButtons = 12;
}
// Let us scramble the List... (...as example)
TEST_DIALOG_CHOICES = llListRandomize(TEST_DIALOG_CHOICES,1);
// and clear the timerview
llSetText("",<1,1,1>,1);
}
touch_start(integer i) {
// If we touch in this state, iam sure we are on the first Page
PAGE = 1;
// Let us find a random channel
CHANNEL = -llRound(llFrand(1000000));
// remember for the user
LastMenuUser = llDetectedKey(0);
// All done, we have the point to create our first menupage
CreateMenu(LastMenuUser,TEST_DIALOG_CHOICES);
// and for better code reading, we use a new state !
state Dialog;
}
}
state Dialog {
state_entry() {
// Listen to the opened channel
llListen(CHANNEL,"",NULL_KEY,"");
// and count the time down to our timeout
llSetTimerEvent(1);
// Reset the timer...
llResetTime();
}
listen(integer channel, string name, key id, string message) {
// if we have clicked a menuchoice, we can find the answer from the dialog here
if(~llListFindList(TEST_DIALOG_CHOICES,[message])) {
// for debugging, tell us our choice
llSay(0, "Your Choice : " + message);
// and back to standby
state default;
} else {
// we have clicked a Navigation button, find out which button ...
if(message == "<<<" || message == "BACK") {
--PAGE;
} else if(message == ">>>") {
++PAGE;
} else if(message == "FIRST") {
PAGE = 1;
} else if(message == "LAST") {
PAGE = llCeil(llGetListLength(TEST_DIALOG_CHOICES)/(maxButtons-3));
} else {
// ... or for confusing, abort all :) (will reached with the "No Clue"-Button)
state default;
}
// if we click a button, be sure we reset the timercount and start a new timeout-counter
llResetTime();
// We are still in the listen event, so we can draw a new menu
CreateMenu(id,TEST_DIALOG_CHOICES);
}
}
touch_start(integer i) {
// listen only to the control-user and give him the chance to draw a new menu if one page is not appearing...
if(llDetectedKey(0) == LastMenuUser) {
CreateMenu(llDetectedKey(0),TEST_DIALOG_CHOICES);
}
}
timer() {
// draw the timeout-counter on the prim
llSetText((string)(llRound(TimeOut - llGetTime())) + " seconds left",<1,1,1>,1);
// and tell us if we run out of time...
if(llGetTime() > TimeOut) {
llSay(0,"Dialog expired");
// back to standby
state default;
}
}
} </lsl>