fixed scrolling
authorDaniel <mr.picklepinosaur@gmail.com>
Sat, 27 Feb 2021 00:35:52 +0000 (19:35 -0500)
committerDaniel <mr.picklepinosaur@gmail.com>
Sat, 27 Feb 2021 00:35:52 +0000 (19:35 -0500)
headers/utils.h
menu.c
utils.c

index 9783172..9e93b61 100644 (file)
@@ -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 (file)
--- 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 (file)
--- 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)
 {