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
// 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;
}