From 62ca4f5c30c0518812acd4515259c36329b28d78 Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 26 Feb 2021 19:35:52 -0500 Subject: [PATCH] fixed scrolling --- headers/utils.h | 2 ++ menu.c | 68 ++++++++++++++++++++++++++++++++++++------------- utils.c | 15 +++++++++++ 3 files changed, 67 insertions(+), 18 deletions(-) diff --git a/headers/utils.h b/headers/utils.h index 9783172..9e93b61 100644 --- a/headers/utils.h +++ b/headers/utils.h @@ -19,6 +19,8 @@ array_length(type, array) \ }) extern int min(int a, int b); +extern int clamp(int v, int min, int max); +extern int floorzero(int v); extern char* wrap_text(char* str, int max_width, int* lines); diff --git a/menu.c b/menu.c index 621607b..ab1aa17 100644 --- a/menu.c +++ b/menu.c @@ -10,7 +10,7 @@ #include "headers/utils.h" #define MENU_PAD_TOP 2 -#define MENU_PAD_BOTTOM 1 +#define MENU_PAD_BOTTOM 2 #define MENU_PAD_LEFT 2 #define MENU_PAD_RIGHT 1 @@ -47,7 +47,8 @@ MenuItem* create_blank_menuitem(void); /* rendering stuff */ int render_item(Menu* menu, int item_index, int start_y); int item_height(MenuItem* menuitem); -int items_visible(Menu* menu); +int items_visible(Menu* menu, int offset); +int items_visible_rev(Menu* menu, int offset); MenuItem* create_menuitem(char* title) @@ -383,25 +384,35 @@ render_menu(Menu* menu) mvwprintw(menu->menu_win, 0, MENU_PAD_LEFT, menu->menu_name); wattroff(menu->menu_win, COLOR_PAIR(0)); - /* char buf[20]; */ - /* sprintf(buf, "%d", items_visible(menu)); */ - /* mvprintw(20, 20, buf); */ + /* draw inner menu */ + wclear(menu->sub_win); /* calculate scroll */ int visible; - visible = items_visible(menu); + visible = items_visible(menu, menu->scroll_offset); + + if (menu->selected_item >= menu->scroll_offset+visible) { + menu->scroll_offset = clamp( + menu->selected_item-items_visible_rev(menu, menu->selected_item)+1, + 0, + floorzero(menu->menu_length-1) + ); - if (menu->selected_item > menu->scroll_offset+visible) { - // may be dangerous, assumes render after every action - menu->scroll_offset += 1; } else if (menu->selected_item < menu->scroll_offset) { - menu->scroll_offset = menu->scroll_offset-1; - if (menu->scroll_offset < 0) menu->scroll_offset = 0; + menu->scroll_offset = clamp( + menu->selected_item, + 0, + floorzero(menu->menu_length-1) + ); } - /* draw inner menu */ - wclear(menu->sub_win); + /* char abuf[20]; */ + /* int y; */ + /* int x; */ + /* getmaxyx(menu->sub_win, y, x); */ + /* sprintf(abuf, "%d,%d,%d max:%d,%d", menu->selected_item, visible, menu->scroll_offset,y,x); */ + /* mvprintw(19, 27, abuf); */ int curline = 0; for (int i = menu->scroll_offset; i < menu->menu_length; i++) { @@ -450,24 +461,45 @@ item_height(MenuItem* menuitem) } int -items_visible(Menu* menu) +items_visible(Menu* menu, int offset) { int maxheight; int maxwidth; // unused getmaxyx(menu->sub_win, maxheight, maxwidth); - int i = menu->scroll_offset; + int vis = 0; int lines = 0; - for (; i < menu->menu_length; i++) { + for (int i = offset ; i < menu->menu_length; i++) { lines += item_height(menu->menu_items[i]); + if (lines > maxheight) break; + vis += 1; - if (lines >= maxheight) break; + } + + return vis; +} + +int +items_visible_rev(Menu* menu, int offset) +{ + int maxheight; + int maxwidth; // unused + + getmaxyx(menu->sub_win, maxheight, maxwidth); + + int vis = 0; + int lines = 0; + for (int i = offset; i > 0; i--) { + + lines += item_height(menu->menu_items[i]); + if (lines > maxheight) break; + vis +=1; } - return i; + return vis; } int diff --git a/utils.c b/utils.c index f6f719a..9b37404 100644 --- a/utils.c +++ b/utils.c @@ -12,6 +12,21 @@ min(int a, int b) return (a < b) ? a : b; } +int +clamp(int v, int min, int max) +{ + if (v > max) return max; + if (v < min) return min; + return v; +} + +int +floorzero(int v) +{ + return (v >= 0) ? v : 0; +} + + char* wrap_text(char* str, int max_width, int* lines) { -- 2.20.1