diff --git a/ui.c b/ui.c index 5d1bf67..02824d9 100644 --- a/ui.c +++ b/ui.c @@ -30,7 +30,10 @@ #include "recovery_ui.h" #define MAX_COLS 64 -#define MAX_ROWS 32 +#define MAX_ROWS 32 + +#define MENU_MAX_COLS 64 +#define MENU_MAX_ROWS 250 #define CHAR_WIDTH 10 #define CHAR_HEIGHT 18 @@ -89,9 +92,10 @@ static int text_cols = 0, text_rows = 0; static int text_col = 0, text_row = 0, text_top = 0; static int show_text = 0; -static char menu[MAX_ROWS][MAX_COLS]; +static char menu[MENU_MAX_ROWS][MENU_MAX_COLS]; static int show_menu = 0; static int menu_top = 0, menu_items = 0, menu_sel = 0; +static int menu_show_start = 0; // this is line which menu display is starting at // Key event input queue static pthread_mutex_t key_queue_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -180,35 +184,43 @@ static void draw_screen_locked(void) gr_fill(0, 0, gr_fb_width(), gr_fb_height()); int i = 0; + int j = 0; + int row = 0; // current row that we are drawing on if (show_menu) { gr_color(MENU_TEXT_COLOR); - gr_fill(0, (menu_top+menu_sel) * CHAR_HEIGHT, - gr_fb_width(), (menu_top+menu_sel+1)*CHAR_HEIGHT+1); + gr_fill(0, (menu_top + menu_sel - menu_show_start) * CHAR_HEIGHT, + gr_fb_width(), (menu_top + menu_sel - menu_show_start + 1)*CHAR_HEIGHT+1); gr_color(HEADER_TEXT_COLOR); - int is_drawing_header = 1; - for (; i < menu_top + menu_items; ++i) { - if (is_drawing_header && strcmp(menu[i], "") == 0) { - gr_color(MENU_TEXT_COLOR); - is_drawing_header = 0; - } + for (i = 0; i < menu_top; ++i) { + draw_text_line(i, menu[i]); + row++; + } + + if (menu_items - menu_show_start + menu_top >= MAX_ROWS) + j = MAX_ROWS - menu_top; + else + j = menu_items - menu_show_start; + + gr_color(MENU_TEXT_COLOR); + for (i = menu_show_start + menu_top; i < (menu_show_start + menu_top + j); ++i) { if (i == menu_top + menu_sel) { gr_color(255, 255, 255, 255); - draw_text_line(i, menu[i]); + draw_text_line(i - menu_show_start , menu[i]); gr_color(MENU_TEXT_COLOR); } else { - draw_text_line(i, menu[i]); + gr_color(MENU_TEXT_COLOR); + draw_text_line(i - menu_show_start, menu[i]); } + row++; } - gr_fill(0, i*CHAR_HEIGHT+CHAR_HEIGHT/2-1, - gr_fb_width(), i*CHAR_HEIGHT+CHAR_HEIGHT/2+1); - ++i; + gr_fill(0, row*CHAR_HEIGHT+CHAR_HEIGHT/2-1, + gr_fb_width(), row*CHAR_HEIGHT+CHAR_HEIGHT/2+1); } gr_color(NORMAL_TEXT_COLOR); - - for (; i < text_rows; ++i) { - draw_text_line(i, text[(i+text_top) % text_rows]); + for (; row < text_rows; ++row) { + draw_text_line(row, text[(row+text_top) % text_rows]); } } } @@ -481,15 +493,16 @@ void ui_start_menu(char** headers, char** items) { menu[i][text_cols-1] = '\0'; } menu_top = i; - for (; i < text_rows; ++i) { + for (; i < MENU_MAX_ROWS; ++i) { if (items[i-menu_top] == NULL) break; strcpy(menu[i], MENU_ITEM_HEADER); strncpy(menu[i] + MENU_ITEM_HEADER_LENGTH, items[i-menu_top], text_cols-1 - MENU_ITEM_HEADER_LENGTH); menu[i][text_cols-1] = '\0'; } + menu_items = i - menu_top; show_menu = 1; - menu_sel = 0; + menu_sel = menu_show_start = 0; update_screen_locked(); } pthread_mutex_unlock(&gUpdateMutex); @@ -501,9 +514,21 @@ int ui_menu_select(int sel) { if (show_menu > 0) { old_sel = menu_sel; menu_sel = sel; + if (menu_sel < 0) menu_sel = 0; if (menu_sel >= menu_items) menu_sel = menu_items-1; + + + if (menu_sel < menu_show_start && menu_show_start > 0) { + menu_show_start--; + } + + if (menu_sel - menu_show_start + menu_top >= text_rows) { + menu_show_start++; + } + sel = menu_sel; + if (menu_sel != old_sel) update_screen_locked(); } pthread_mutex_unlock(&gUpdateMutex);