Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Dialog Buttons Prev Main Next and Paginating?

Bloodsong Termagant
Manic Artist
Join date: 22 Jan 2007
Posts: 615
05-23-2007 09:26
heyas;

does anybody have a routine for this that they are willing to share?

i want to create or generate a list for lldialog buttons. and if the list has more than 12 items, i would like the script to clip it off at 9 items per "page", and then add a 'previous', 'main', and 'next' button across the top 3.
and then when the prev/next buttons are pressed, it goes to the appropriate 'page' segment of the list. you know what i mean?

i know it requires some kind of pointer to keep track of the 'page' of the list parts, but every time i go to tackle this setup, my brain turns to mush, and im not sure what the best way to handle it is.

thanks!
_____________________
Why Johnny Can't Rotate:
http://forums.secondlife.com/showthread.php?t=94705
Talarus Luan
Ancient Archaean Dragon
Join date: 18 Mar 2006
Posts: 4,831
05-23-2007 09:38
It's not as straightforward as it would seem on first glance, because there are several edge cases that you have to handle. The one I use is about 25 lines, I think (can't check until grid comes back up, though). It doesn't do "up-level" or "Main", though, as I haven't had a need to make any menus hierarchical.

Everybody has a different way of solving it. Some folks just put ["<< Prev","Main","Next >>"] as the first three elements of their list, regardless of whether or not there are any more pages previous, next, or both. The rest is using some kind of page number parameter or global variable to track what multiple of the displayable item count to show.
Pale Spectre
Registered User
Join date: 2 Sep 2005
Posts: 586
05-23-2007 11:24
The 'edge cases' can be avoided by allowing the menu system to wrap. So, Previous can take you to the last page, and Next can take you to the first page.

The biggest pain with llDialog is keeping the buttons in a sensible order given the perverse way it transforms its list into the buttons.

This thread touched on the question of parsing a smaller list (or page if you like) out of a larger list: /54/a3/178561/1.html
Bloodsong Termagant
Manic Artist
Join date: 22 Jan 2007
Posts: 615
06-07-2007 08:24
aright....

let's try to hash something out, shall we?


doDialogue(integer channel, string text, list buttons, key id, integer page)
{
//--first, if page is 0, we've never done this before
if (0 == page)
{
if(llGetListLength(buttons) <= 12)
{
llDialog(channel, text, buttons, id); //--or whatever order, im tossing this off at work
return;
}
//--else, we need pages... i suppose then drop down to main bit, too
page = 1;
}
//--okay so page = 1 or more... we have to chop the button list into a smaller list. um...
list pagebuttons = [];
//--okay, so get 9 items, then add our < ^ > bits.
//-- um? pagebuttons = llGetListSegment from page-1 to um.. page*8? help? math??
pagebuttons += [ "<<", "^^", ">>"]; //--thats back, next and top, y'know.

llDialog(channel, text, pagebuttons, id);
}


okay, now we listen for the pagination buttons.

listen(blahblahwhatever)
{
if ("<<" == msg)
{
page --;
if(page <= 0)
{//--do whatever you like, pop up to top page, or make it 'stick' at page 1
page = 1;
}
doDialogue(channel, text, buttons, page);
}
else if ("^^" == msg)
{//--um.... go to page 1? or go to a different dialogue part? this is multi-level menus, ugh
}
else if (">>" == msg)
{
page++;
if(page >= //--need more math to figure out list length divided by page length? divided by 9? something to get max page number. im an artist, not a mathematician!
{//--go to 1 or stick at max
//...?
}
doDialogue(channel, text, buttons, page);
}



something like that? is a wrapper for the lldialog like this possible? so you just make your button list however long you want, and it automatically pages for you via the wrapper?
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
06-07-2007 15:04
Bloodsong, take a peek here
_____________________
I'm back......
RJ Source
Green Sky Labs
Join date: 10 Jan 2007
Posts: 272
06-08-2007 07:20
Here's a version I've been messing with. Some notes:

- Given large list of buttons, and page number, returns a list ready to be fed to llDialog.
- Allows specifying buttons per page other than 12 (in case less buttons is better for your need).
- Allows specifying repeatable buttons (if for example, no matter what page, you want a RESET button on every page).
- Puts a "Page n" button on the list if needed to go to next page (when you call llDialog with this, look for a response of "Page ", parse the number, and call this routine again with the new number for the next page.
- Reorders the list so it displays in order top to bottom, instead of the button-row first stuff.

It only has the next page page number, not previous. For my applications, the thought was that if I needed to send so many buttons that the user couldn't wrap around after a reasonable amount of paging, I was overwhelming the user with buttons and should take a different approach anyways (more hierarchical perhaps).

Hopefully I've tested all the reasonable boundary conditions - but ymmv (and gigo).
The code is pretty tight, but could be made tighter with the removal of temporary list variables and using all pointers. But that's pretty hard to debug without lots of caffeine. So I prefer temp list vars.

Also it would be more efficient to make some of these vars global. I kept them local here for ease of porting.

Rj


CODE

// MakeMenu - Create the menu, return as list ready to be fed to llDialog
//
// llDialog has some limits. It doesn't allow easy paging thru all buttons in a list, if they don't
// all fit on one page. It orders the buttons in weird ways (button to top). This function tries
// to alleviate some of this. It will select a given range of numbers from a list (based on how
// many you want per page, and what page number you want). It will add any repeatable buttons
// that should be on all pages to the buttons. And it will add a Page number button appended with
// the next page number (or 1 if at the end) if needed.
//
// buttons - List of buttons to display. These will be reorded in a more sensible top/down order.
// page - Integer page number. Page number buttons to extract from list.
// perpage - Integer number of given buttons to display per page. Does not count repeat buttons.
// Use 0 for max that will fit. If number given won't fit, it will be shrunk.
// repeatbuttons- List of buttons to include on every page (at bottom).
// pageprefix - String that will be used to create a page number button, if needed.
//
// The list returned is ready to be fed to llDialog.
//
// Example:
//
// MakeMenu(["1","2","3","4","5","6","7","8","9","10"], 1, 9, ["Hello"], "Page ")
// returns: [9, Hello, Page 2, 6, 7, 8, 3, 4, 5, 1, 2]
//
// MakeMenu(["1","2","3","4","5","6","7","8","9","10"], 2, 9, [], "Page ")
// returns: [11, 12, Page 1, 10]

// 20070601 Rj Source Initial Coding


list MakeMenu(list buttons, integer page, integer perpage, list repeatbuttons, string pageprefix)
{
integer maxbuttons = 12; // Max buttons allowed by llDialog per page
integer perline = 3; // Max buttons allowed by llDialog per line
integer buttonlen = llGetListLength(buttons); // Number of buttons in given list
integer repeatlen = llGetListLength(repeatbuttons); // Number of repeatable buttons in given list
integer pageneeded = FALSE; // Becomes TRUE if buttons dont fit on one page
integer hunkstartptr; // Ptr to beginning of given page hunk of buttons
integer hunkendptr; // Ptr to end of given page hunk of buttons
integer startptr; // Ptr to current buttons (perline) in hunk
integer endptr; // Ptr to end of buttons (perlin) in hunk
list menu1 = []; // Hunk of buttons from original list
list menu2 = []; // Reordered hunk fro top to bottom
integer pagex; // Next page number button

if (perpage <= 0) perpage = maxbuttons - repeatlen; // Max out per page if 0 or less
if (buttonlen + repeatlen > perpage) // Pagination needed
{
pageneeded = TRUE;
}
if (perpage + repeatlen + pageneeded > maxbuttons) // Cap perpage if its too big
perpage = maxbuttons - repeatlen - pageneeded;

if (page <= 0) page = 1;
hunkstartptr = perpage * (page - 1); // Extract pagehunk of buttons from list
hunkendptr = hunkstartptr + perpage - 1;
if (pageneeded)
{
if (hunkendptr >= buttonlen - 1) // Next page loops back to beginning
{
pagex = 1;
hunkendptr = buttonlen - 1;
}
else pagex = page + 1; // Next page is next page
repeatbuttons += [(pageprefix + (string)pagex)];
}

menu1 = llList2List(buttons, hunkstartptr, hunkendptr) + repeatbuttons;
menu2 = [];

endptr = llGetListLength(menu1) - 1;

do // Reorder buttons top to bottom
{
startptr = endptr - perline + 1;
if (startptr < 0) startptr = 0;
menu2 = (menu2 = []) + menu2 + llList2List(menu1, startptr, endptr);
endptr = startptr - 1;
} while (endptr >= 0);

return menu2;
}