From 53d20619ec206183cf45202d5f573a9aed46ffdf Mon Sep 17 00:00:00 2001 From: mintsuki Date: Fri, 7 Oct 2022 07:35:08 +0200 Subject: [PATCH] menu: Properly handly high number of entries --- common/menu.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/common/menu.c b/common/menu.c index 55958ae6..a87280fb 100644 --- a/common/menu.c +++ b/common/menu.c @@ -493,7 +493,7 @@ refresh: goto refresh; } -static size_t print_tree(const char *shift, size_t level, size_t base_index, size_t selected_entry, +static size_t print_tree(size_t offset, size_t window, const char *shift, size_t level, size_t base_index, size_t selected_entry, struct menu_entry *current_entry, struct menu_entry **selected_menu_entry) { size_t max_entries = 0; @@ -506,6 +506,12 @@ static size_t print_tree(const char *shift, size_t level, size_t base_index, siz for (;;) { if (current_entry == NULL) break; + if (!no_print && base_index + max_entries < offset) { + goto skip_line; + } + if (!no_print && base_index + max_entries >= offset + window) { + goto skip_line; + } if (!no_print) print("%s", shift); if (level) { for (size_t i = level - 1; i > 0; i--) { @@ -536,8 +542,9 @@ static size_t print_tree(const char *shift, size_t level, size_t base_index, siz if (!no_print) print("\e[7m"); } if (!no_print) print(" %s \e[27m\n", current_entry->name); +skip_line: if (current_entry->sub && current_entry->expanded) { - max_entries += print_tree(shift, level + 1, base_index + max_entries + 1, + max_entries += print_tree(offset, window, shift, level + 1, base_index + max_entries + 1, selected_entry, current_entry->sub, selected_menu_entry); @@ -699,7 +706,7 @@ noreturn void _menu(bool first_run) { if (!skip_timeout && !timeout) { // Use print tree to load up selected_menu_entry and determine if the // default entry is valid. - print_tree(NULL, 0, 0, selected_entry, menu_tree, &selected_menu_entry); + print_tree(0, 0, NULL, 0, 0, selected_entry, menu_tree, &selected_menu_entry); if (selected_menu_entry == NULL || selected_menu_entry->sub != NULL) { quiet = false; print("Default entry is not valid or directory, booting to menu.\n"); @@ -711,7 +718,16 @@ noreturn void _menu(bool first_run) { menu_init_term(); + size_t tree_offset = 0; + refresh: + if (selected_entry >= tree_offset + term->rows - 10) { + tree_offset = selected_entry - (term->rows - 11); + } + if (selected_entry < tree_offset) { + tree_offset = selected_entry; + } + term->autoflush = false; term->disable_cursor(term); @@ -770,7 +786,7 @@ refresh: set_cursor_pos_helper(x, y + 2); } - size_t max_entries = print_tree(serial ? "| " : "\xb3 ", 0, 0, selected_entry, menu_tree, + size_t max_entries = print_tree(tree_offset, term->rows - 10, serial ? "| " : "\xb3 ", 0, 0, selected_entry, menu_tree, &selected_menu_entry); { @@ -834,7 +850,7 @@ timeout_aborted: int ent = (c - '0') - 1; if (ent < (int)max_entries) { selected_entry = ent; - print_tree(NULL, 0, 0, selected_entry, menu_tree, + print_tree(0, 0, NULL, 0, 0, selected_entry, menu_tree, &selected_menu_entry); goto autoboot; }