If the title means gibberish to you, here's what it does.
A: Dynamically returns a correct sized list to llDialog (12 or less items)
B: puts your llDialog buttons in english order(left to right Then TOP TO BOTTOM) instead of the default order(left to right, bottom to top)
C: automatically inserts a Back and Forward button on each page, with the page number encoded
D: remenu compatible (auto pop-the same page on item selection, if you want)
E: allows handling multiple users on the same chat channel (because all page changes are encoded into the fwd/bck buttons)
CODE
/*//-- Note:
This function replaces the list in llDialog.
Expected input is 1 (default) or greater
input outside the possible page range
will redirect to valid pages but the
other page buttons may be absent.
Requires the button text(s) to be
in a gloabal list named gLstMnu.
single button text length > 24
causes errors in llDialog.
Make sure you sanitize
button text lengths
BEFOREHAND!
//*/
list uDlgBtnLst( integer vIntPag ){
integer vIdxBeg = 10 * ~-vIntPag; //-- "~-x" == "x - 1"
integer vIdxMax = -~(~([] != gLstMnu) / 10); //-- integer math to get last valid page
list vLstRtn =
llListInsertList(
llList2List( gLstMnu, vIdxBeg, vIdxBeg + 9 ), //-- grab 10 dialog buttons
(list)(" <<---(" + (string)(vIntPag + (-(vIntPag > 1) | vIdxMax - vIntPag)) + ""
, //-- back button
-1 ) + //-- inserts back button before last item
(list)(" (" + (string)(-~((vIntPag < vIdxMax) * vIntPag)) + "--->>"
; //-- tack on the fwd button
return //-- fun trick to fix the order for L2R T2B
llList2List( vLstRtn, -3, -1 ) + llList2List( vLstRtn, -6, -4 ) +
llList2List( vLstRtn, -9, -7 ) + llList2List( vLstRtn, -12, -10 );
}
/*//-- Anti-License Text --//*/
/*// Contributed Freely to the Public Domain without limitation. //*/
/*// 2009 (CC0) [ http://creativecommons.org/publicdomain/zero/1.0 ] //*/
/*// Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ] //*/
/*//-- --//*/
Addendum:
===initial call example:
CODE
llDialog( Target_avatar_key, text_for_dialog_header, uDlgBtnLst( 1 ), chat_channel_to_use );
===to detect the next page button use the following format
CODE
listen( integer vIntChn, string vStrNom, key vKeySpk, string vStrMsg ){
if (!llSubStringIndex( vStrMsg, " " )){ //-- detects 2 leading spaces
llDialog( vKeySpk,
"dialog text",
//-- next line parse the next page request
uDlgBtnLst( (integer)llGetSubString( vStrMsg, -~llSubStringIndex( vStrMsg, "" ), -1 ) ),
vIntChn );
}else{
//-- button was not a page change button, act on vStrMsg as needed
}
}
===you can get the remenu page number with this formula (assuming a page change was not called)
CODE
integer vIntReMenuPage = -~(llListFindList( gLstMnu, (list)vStrMsg ) / 10);
===and a VERY simple example, that demonstrates it in use.
CODE
//--// Completely pointless example
integer gBooLIO = TRUE; //-- Listen is off
integer gIntChn = -42; //-- listen channel
float gFltTmt = 45.0; //-- seconds to wait since last dialog to clear listen
string gStrDlg = "This Dialog is Pointless, pick something anyway =P";
list gLstMnu = //-- build this anyway you want....
["00","01","02","03","04","05","06","07","08","09",
"10","11","12","13","14","15","16","17","18","19",
"20","21","22","23","24","25","26","27","28","29",
"30","31","32","33","34","35","36","37","38","39"
];
list uDlgBtnLst( integer vIntPag ){
integer vIdxBeg = 10 * ~-vIntPag; //-- "~-x" == "x - 1"
integer vIdxMax = -~(~([] != gLstMnu) / 10); //-- integer math to get last valid page
list vLstRtn =
llListInsertList(
llList2List( gLstMnu, vIdxBeg, vIdxBeg + 9 ), //-- grab 10 dialog buttons
(list)(" <<---(" + (string)(vIntPag + (-(vIntPag > 1) | vIdxMax - vIntPag)) + ""
, //-- back button
-1 ) + //-- inserts back button before last item
(list)(" (" + (string)(-~((vIntPag < vIdxMax) * vIntPag)) + "--->>"
; //-- tack on the fwd button
return //-- fun trick to fix the order for L2R T2B
llList2List( vLstRtn, -3, -1 ) + llList2List( vLstRtn, -6, -4 ) +
llList2List( vLstRtn, -9, -7 ) + llList2List( vLstRtn, -12, -10 );
}
default{
touch_end( integer vIntTch ){
if (gBooLIO){
llListen( gIntChn , "", "", "" );
gBooLIO = !gBooLIO;
}
llSetTimerEvent( gFltTmt );
do{
llDialog( llDetectedKey( --vIntTch ),
gStrDlg,
uDlgBtnLst( 1 ),
gIntChn );
}while (vIntTch);
}
listen( integer vIntChn, string vStrNom, key vKeySpk, string vStrMsg ){
if (!llSubStringIndex( vStrMsg, " " )){ //-- detects 2 leading spaces
llSetTimerEvent( gFltTmt );
llDialog( vKeySpk,
gStrDlg,
uDlgBtnLst( (integer)llGetSubString( vStrMsg, -~llSubStringIndex( vStrMsg, "" ), -1 ) ),
vIntChn );
}else{
integer vIdxFnd = llListFindList( gLstMnu, (list)vStrMsg );
if (~vIdxFnd){
llSetTimerEvent( gFltTmt );
llSay( 0, vStrNom + " picked " + vStrMsg );
//-- remenu on the next line
llDialog( vKeySpk, gStrDlg, uDlgBtnLst( -~(vIdxFnd / 10) ), vIntChn );
}
}
}
timer(){
gBooLIO = !gBooLIO;
llSetTimerEvent( 0.0 );
state sListenKiller;
}
}
state sListenKiller{
state_entry(){
//-- just here to turn off all active listen and go back
state default;
}
}