Here's a version with a scrollbar. It also fixes a bug with the scrolling.
Code: #define MENU_WIDTH 180
#define TEXT_HEIGHT 18
#define MENU_Y_GAP 17
#define MAX_CHOICES_DISPLAYED (LCD_HEIGHT_PX - 2*MENU_Y_GAP)/(TEXT_HEIGHT+1)
int ShowMenuList(char** menuchoices, int numofitems, char* title, color_t fg, color_t bg, color_t titlecolor, int showscrollbar) //returns the choice picked by the user
{
int curchoice = 0;
int curchoicex = 0;
int startchoice = 0;
int update = 1;
int scrollbarheight = (LCD_HEIGHT_PX-2*MENU_Y_GAP-TEXT_HEIGHT)/(numofitems-MAX_CHOICES_DISPLAYED+1);
while (!(keydownlast(KEY_PRGM_RETURN) && !keydownhold(KEY_PRGM_RETURN)))
{
keyupdate();
if (update)
{
if (showscrollbar)
{
fillArea((LCD_WIDTH_PX-MENU_WIDTH)/2, MENU_Y_GAP, MENU_WIDTH+1, LCD_HEIGHT_PX-2*MENU_Y_GAP, bg);
drawLine((LCD_WIDTH_PX-MENU_WIDTH)/2,MENU_Y_GAP,(LCD_WIDTH_PX+MENU_WIDTH)/2+1,MENU_Y_GAP,fg); //draw a rectangle
drawLine((LCD_WIDTH_PX-MENU_WIDTH)/2,MENU_Y_GAP,(LCD_WIDTH_PX-MENU_WIDTH)/2,LCD_HEIGHT_PX-MENU_Y_GAP,fg);
drawLine((LCD_WIDTH_PX-MENU_WIDTH)/2,LCD_HEIGHT_PX-MENU_Y_GAP,(LCD_WIDTH_PX+MENU_WIDTH)/2+1,LCD_HEIGHT_PX-MENU_Y_GAP,fg);
drawLine((LCD_WIDTH_PX+MENU_WIDTH)/2+1,MENU_Y_GAP,(LCD_WIDTH_PX+MENU_WIDTH)/2+1,LCD_HEIGHT_PX-MENU_Y_GAP,fg);
drawLine((LCD_WIDTH_PX-MENU_WIDTH)/2,MENU_Y_GAP+TEXT_HEIGHT+1,(LCD_WIDTH_PX+MENU_WIDTH)/2+1,MENU_Y_GAP+TEXT_HEIGHT+1,fg);
if (startchoice < (numofitems-MAX_CHOICES_DISPLAYED))
drawLine((LCD_WIDTH_PX+MENU_WIDTH)/2,MENU_Y_GAP+TEXT_HEIGHT+1+(startchoice)*scrollbarheight+1,(LCD_WIDTH_PX+MENU_WIDTH)/2,MENU_Y_GAP+TEXT_HEIGHT+1+(startchoice+1)*scrollbarheight+1,titlecolor);
else
drawLine((LCD_WIDTH_PX+MENU_WIDTH)/2,LCD_HEIGHT_PX-MENU_Y_GAP-scrollbarheight,(LCD_WIDTH_PX+MENU_WIDTH)/2,LCD_HEIGHT_PX-MENU_Y_GAP-1,titlecolor);
}
else
{
fillArea((LCD_WIDTH_PX-MENU_WIDTH)/2, MENU_Y_GAP, MENU_WIDTH, LCD_HEIGHT_PX-2*MENU_Y_GAP, bg);
drawLine((LCD_WIDTH_PX-MENU_WIDTH)/2,MENU_Y_GAP,(LCD_WIDTH_PX+MENU_WIDTH)/2,MENU_Y_GAP,fg); //draw a rectangle
drawLine((LCD_WIDTH_PX-MENU_WIDTH)/2,MENU_Y_GAP,(LCD_WIDTH_PX-MENU_WIDTH)/2,LCD_HEIGHT_PX-MENU_Y_GAP,fg);
drawLine((LCD_WIDTH_PX-MENU_WIDTH)/2,LCD_HEIGHT_PX-MENU_Y_GAP,(LCD_WIDTH_PX+MENU_WIDTH)/2,LCD_HEIGHT_PX-MENU_Y_GAP,fg);
drawLine((LCD_WIDTH_PX+MENU_WIDTH)/2,MENU_Y_GAP,(LCD_WIDTH_PX+MENU_WIDTH)/2,LCD_HEIGHT_PX-MENU_Y_GAP,fg);
drawLine((LCD_WIDTH_PX-MENU_WIDTH)/2,MENU_Y_GAP+TEXT_HEIGHT+1,(LCD_WIDTH_PX+MENU_WIDTH)/2,MENU_Y_GAP+TEXT_HEIGHT+1,fg);
}
PrintMiniFix((LCD_WIDTH_PX-MENU_WIDTH)/2+1,MENU_Y_GAP+1,title,PMF_ALLOW_STATUSAREA,titlecolor,bg);
for (int x = 0; x < MAX_CHOICES_DISPLAYED && x < numofitems; x++)
{
PrintMiniFix((LCD_WIDTH_PX-MENU_WIDTH)/2+14,(x+1)*TEXT_HEIGHT+MENU_Y_GAP+2,menuchoices[startchoice+x],PMF_ALLOW_STATUSAREA,fg,bg);
if ((startchoice+x) == curchoice)
{
PrintMiniFix((LCD_WIDTH_PX-MENU_WIDTH)/2+2,(x+1)*TEXT_HEIGHT+MENU_Y_GAP+2,">",PMF_ALLOW_STATUSAREA,fg,bg);
}
}
Bdisp_PutDisp_DD();
update = 0;
}
if (keydownlast(KEY_PRGM_DOWN) && !keydownhold(KEY_PRGM_DOWN))
{
if (curchoice < numofitems-1)
{
curchoice++;
curchoicex++;
if (curchoicex >= MAX_CHOICES_DISPLAYED)
{
curchoicex = MAX_CHOICES_DISPLAYED;
if (startchoice < (numofitems-MAX_CHOICES_DISPLAYED)) startchoice++;
}
update = 1;
}
}
if (keydownlast(KEY_PRGM_UP) && !keydownhold(KEY_PRGM_UP))
{
if (curchoice > 0)
{
curchoice--;
curchoicex--;
if (curchoicex <= 0)
{
curchoicex = 0;
if (startchoice > 0) startchoice--;
}
update = 1;
}
}
}
return curchoice;
}