X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=menu.c;h=4f9ee5e41cbed9ac543b251cddfd9ed01c669e27;hb=66d3a8f071cbf459f6799581146d4a34ca6e2c7b;hp=a7fbbecb9994adf74de10743749855f1b8d6d121;hpb=6eb3a028f4d79ee91e9d94e9c02932f280cd0ac8;p=taskasaur.git diff --git a/menu.c b/menu.c index a7fbbec..4f9ee5e 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) @@ -273,13 +274,20 @@ menu_insert_mode(Menu* menu, int insert_index) { char temp[MAX_CONTENTS_LENGTH+1]; // remember null char* new_contents; + int insert_pos; curs_on(); + // account for multiline items + insert_pos = menu->scroll_offset; + for (int i = 0; i < insert_index; i++) { + insert_pos += item_height(menu->menu_items[i]); + } + /* move cursor to right spot */ ungetstr(menu->menu_items[insert_index]->title); mvwgetnstr(menu->sub_win, - insert_index, // account for wrap later too + insert_pos, 0, temp, MAX_CONTENTS_LENGTH @@ -337,16 +345,19 @@ menu_driver(Menu* menu, MenuAction action) case MENU_APPEND: insert_item(menu, create_blank_menuitem(), menu->menu_length); + render_menu(menu); // refresh after inserting menu_insert_mode(menu, menu->selected_item); break; case MENU_INSERT_ABOVE: insert_item(menu, create_blank_menuitem(), menu->selected_item); + render_menu(menu); menu_insert_mode(menu, menu->selected_item); break; case MENU_INSERT_BELOW: insert_item(menu, create_blank_menuitem(), menu->selected_item+1); + render_menu(menu); menu_insert_mode(menu, menu->selected_item); // inserted item is cur now break; @@ -366,31 +377,41 @@ render_menu(Menu* menu) { /* draw outer menu (prob dont need this every render) */ /* wclear(menu->menu_win); */ - wattron(menu->menu_win, COLOR_PAIR( - (menu->focused == true) ? - TS_MENU_SELECTED: TS_MENU_NONSELECTED - )); + int titlecolor; + titlecolor = COLOR_PAIR((menu->focused == true) ? TS_MENU_SELECTED: TS_MENU_NONSELECTED); + wattron(menu->menu_win, titlecolor); mvwprintw(menu->menu_win, 0, MENU_PAD_LEFT, menu->menu_name); - wattroff(menu->menu_win, COLOR_PAIR(0)); + wattroff(menu->menu_win, titlecolor); - /* 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 -= 1; + 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++) { @@ -407,15 +428,14 @@ int render_item(Menu* menu, int item_index, int start_y) { MenuItem* curitem; + int hlcolor; curitem = menu->menu_items[item_index]; /* color selected item */ - wattron(menu->sub_win, COLOR_PAIR( - (item_index == menu->selected_item && menu->focused == true) ? - TS_SELECTED : TS_NONSELECTED - )); + hlcolor = COLOR_PAIR((item_index == menu->selected_item && menu->focused == true) ? TS_SELECTED : TS_NONSELECTED); + wattron(menu->sub_win, hlcolor); mvwprintw(menu->sub_win, start_y, 0, curitem->title); - wattroff(menu->sub_win, COLOR_PAIR(0)); + wattroff(menu->sub_win, hlcolor); /* display number of items */ if (strlen(curitem->description) > 0) { @@ -439,24 +459,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; + + } + + return vis; +} - if (lines >= maxheight) break; +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