Index: menuselect_curses.c =================================================================== --- menuselect_curses.c (revision 205) +++ menuselect_curses.c (working copy) @@ -45,6 +45,14 @@ #define PAGE_OFFSET 10 +#define SCROLL_NONE 0 +#define SCROLL_DOWN 1 + +#define SCROLL_DOWN_INDICATOR "... More ..." + +#define MIN(x,y) ((x)<(y)?(x):(y)) +#define MAX(x,y) ((x)<(y)?(y):(x)) + extern int changes_made; /*! Maximum number of characters horizontally */ @@ -223,7 +231,7 @@ } -static void draw_category_menu(WINDOW *menu, struct category *cat, int start, int end, int curopt, int changed) +static void draw_category_menu(WINDOW *menu, struct category *cat, int start, int end, int curopt, int changed, int flags) { int i = 0; int j = 0; @@ -269,16 +277,49 @@ if (curopt + 1 == i) display_mem_info(menu, mem, start, end); - if (i == end) + if (i == end - (flags & SCROLL_DOWN ? 1 : 0)) break; } + if (flags & SCROLL_DOWN) { + wmove(menu, j, max_x / 2 - sizeof(SCROLL_DOWN_INDICATOR) / 2); + waddstr(menu, SCROLL_DOWN_INDICATOR); + } + wmove(menu, curopt - start, max_x / 2 - 9); wrefresh(menu); } static void play_space(void); +static int move_up(int *current, int itemcount, int delta, int *start, int *end, int scroll) +{ + if (*current > 0) { + *current = MAX(*current - delta, 0); + if (*current < *start) { + int diff = *start - MAX(*start - delta, 0); + *start -= diff; + *end -= diff; + return 1; + } + } + return 0; +} + +static int move_down(int *current, int itemcount, int delta, int *start, int *end, int scroll) +{ + if (*current < itemcount) { + *current = MIN(*current + delta, itemcount); + if (*current > *end - 1 - (scroll & SCROLL_DOWN ? 1 : 0)) { + int diff = MIN(*end + delta - 1, itemcount) - *end + 1; + *start += diff; + *end += diff; + return 1; + } + } + return 0; +} + static int run_category_menu(WINDOW *menu, int cat_num) { struct category *cat; @@ -289,6 +330,7 @@ int curopt = 0; int maxopt; int changed = 1; + int scroll = SCROLL_NONE; AST_LIST_TRAVERSE(&categories, cat, list) { if (i++ == cat_num) @@ -299,37 +341,27 @@ maxopt = count_members(cat) - 1; - draw_category_menu(menu, cat, start, end, curopt, changed); + if (maxopt > end) { + scroll = SCROLL_DOWN; + } + draw_category_menu(menu, cat, start, end, curopt, changed, scroll); + while ((c = getch())) { changed = 0; switch (c) { case KEY_UP: - if (curopt > 0) { - curopt--; - if (curopt < start) { - start--; - end--; - changed = 1; - } - } + changed = move_up(&curopt, maxopt, 1, &start, &end, scroll); break; case KEY_DOWN: - if (curopt < maxopt) { - curopt++; - if (curopt > end - 1) { - start++; - end++; - changed = 1; - } - } + changed = move_down(&curopt, maxopt, 1, &start, &end, scroll); break; + case KEY_PPAGE: + changed = move_up(&curopt, maxopt, MIN(PAGE_OFFSET, max_y - TITLE_HEIGHT - 6 - (scroll & SCROLL_DOWN ? 1 : 0)), &start, &end, scroll); + break; case KEY_NPAGE: - /* XXX Move down the list by PAGE_OFFSET */ + changed = move_down(&curopt, maxopt, MIN(PAGE_OFFSET, max_y - TITLE_HEIGHT - 6 - (scroll & SCROLL_DOWN ? 1 : 0)), &start, &end, scroll); break; - case KEY_PPAGE: - /* XXX Move up the list by PAGE_OFFSET */ - break; case KEY_LEFT: case 27: /* Esc key */ return 0; @@ -366,8 +398,15 @@ break; } if (c == 'x' || c == 'X' || c == 'Q' || c == 'q') - break; - draw_category_menu(menu, cat, start, end, curopt, changed); + break; + + if (end <= maxopt) { + scroll |= SCROLL_DOWN; + } else { + scroll &= ~SCROLL_DOWN; + } + + draw_category_menu(menu, cat, start, end, curopt, changed, scroll); } wrefresh(menu);