X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=render.c;h=3779273f55ad6436ddc76ea5c121ad14bceff1cb;hb=2239977d543e94803e2b0ecb07021152498350c8;hp=657b8c6ddd4127a28860628c28c647e76f7e1988;hpb=bcb6f1950bfd2867df61d5c93aa73b73e093edbc;p=taskasaur.git diff --git a/render.c b/render.c index 657b8c6..3779273 100644 --- a/render.c +++ b/render.c @@ -3,9 +3,22 @@ #include #include "config.h" +#define POPUP_MENU_PAD_TOP 4 +#define POPUP_MENU_PAD_BOTTOM 2 +#define POPUP_MENU_PAD_LEFT 2 +#define POPUP_MENU_PAD_RIGHT 1 + int init_tscolors(void); int create_todowin(void); +/* menu render callbacks */ +void render_menuitem(Menu* menu, int item_index, int start_y); +int menuitem_height(MenuItem* menuitem); + +void render_popup_menuitem(Menu* menu, int item_index, int start_y); +int popup_menuitem_height(MenuItem* menuitem); + + /* init stuff */ int init_tscurses(void) @@ -45,6 +58,7 @@ init_tscolors(void) init_pair(TS_NONSELECTED, non_selected_color, COLOR_BLACK); init_pair(TS_MENU_SELECTED, menu_selected_color, COLOR_BLACK); init_pair(TS_MENU_NONSELECTED, menu_non_selected_color, COLOR_BLACK); + init_pair(TS_ITEMCOUNT, item_count_color, COLOR_BLACK); return 0; } @@ -84,6 +98,8 @@ create_board_menu(Board* board) new_boardmenu->menu_list = make_menus(board, board->todolist_count); new_boardmenu->menu_count = board->todolist_count; new_boardmenu->selected = 0; + new_boardmenu->popupmenu = NULL; + new_boardmenu->popup_open = 0; return new_boardmenu; } @@ -112,6 +128,10 @@ make_menus(Board* board, int todolist_length) set_menu_win(new_menu, win); set_menu_focus(new_menu, i == 0); // make first win focused + /* set menu render callbacks */ + set_menu_renderitem(new_menu, *render_menuitem); + set_menu_itemheight(new_menu, *menuitem_height); + /* refresh */ refresh(); wrefresh(win); @@ -122,6 +142,44 @@ make_menus(Board* board, int todolist_length) return menu_list; } +void +render_menuitem(Menu* menu, int item_index, int start_y) +{ + MenuItem* curitem; + WINDOW* menu_win; + int hlcolor; + + curitem = get_menu_item(menu, item_index); + menu_win = get_menu_win(menu); + + /* color selected item */ + hlcolor = COLOR_PAIR((item_index == get_selected_item(menu) && get_menu_focused(menu) == true) ? TS_SELECTED : TS_NONSELECTED); + wattron(menu_win, hlcolor); + mvwprintw(menu_win, start_y, 0, get_menuitem_title(curitem)); + wattroff(menu_win, hlcolor); + + /* display number of items */ + if (strlen(get_menuitem_descrip(curitem)) > 0) { + wattron(menu_win, COLOR_PAIR(TS_ITEMCOUNT)); + mvwprintw(menu_win, start_y+1, 0, get_menuitem_descrip(curitem)); + wattroff(menu_win, COLOR_PAIR(TS_ITEMCOUNT)); + } + +} + +int +menuitem_height(MenuItem* menuitem) +{ + int lines; + + lines = 1; + if (strlen(get_menuitem_descrip(menuitem)) > 0) { + lines += 1; + } + + return lines; +} + MenuItem** todolist_to_menuitem(TodoItem** item_list, int list_length) { @@ -129,7 +187,12 @@ todolist_to_menuitem(TodoItem** item_list, int list_length) items = malloc((list_length+1)*sizeof(MenuItem*)); for (int i = 0; i < list_length; i++) { - items[i] = create_menuitem(item_list[i]->item_name); + MenuItem* new_menuitem; + new_menuitem = create_menuitem(item_list[i]->item_name); + /* using same struct, careful if it gets freed */ + set_menuitem_userdata(new_menuitem, item_list[i]); + + items[i] = new_menuitem; } items[list_length] = 0; //null terminate @@ -155,14 +218,25 @@ boardmenu_to_board(BoardMenu* boardmenu) for (int j = 0; j < get_menu_length(curmenu); j++) { MenuItem* curmenuitem = get_menu_item(curmenu, j); + TodoItem* itemdata = get_menuitem_userdata(curmenuitem); TodoItem* new_todoitem = malloc(sizeof(TodoItem)); + SubTask** new_subtask_list = malloc(itemdata->subtask_count*sizeof(SubTask*)); new_todoitem->item_name = strdup(get_menuitem_title(curmenuitem)); - new_todoitem->description = strdup(get_menuitem_descrip(curmenuitem)); - new_todoitem->due = strdup(""); //TEMP! - new_todoitem->subtask_list = malloc(0); //TEMP! - new_todoitem->subtask_count = 0; //TEMP! + new_todoitem->description = strdup(itemdata->description); + new_todoitem->due = strdup(itemdata->due); + new_todoitem->subtask_count = itemdata->subtask_count; + for (int k = 0; k < itemdata->subtask_count; k++) { + SubTask* new_subtask = malloc(sizeof(SubTask)); + + new_subtask->subtask_name = itemdata->subtask_list[k]->subtask_name; + new_subtask->done = itemdata->subtask_list[k]->done; + + new_subtask_list[k] = new_subtask; + } + + new_todoitem->subtask_list = new_subtask_list; new_item_list[j] = new_todoitem; } @@ -179,6 +253,13 @@ boardmenu_to_board(BoardMenu* boardmenu) return newboard; } +int +render_board(Board* board) +{ + + return 0; +} + int set_selected_menu(BoardMenu* boardmenu, int index) { @@ -195,6 +276,7 @@ set_selected_menu(BoardMenu* boardmenu, int index) /* also try to jump to a similar position if possible */ /* rn theres a bug if old menu is empty */ new_pos = min(get_selected_item(old_menu), get_menu_length(new_menu)-1); + if (new_pos < 0) new_pos = 0; set_selected_item(new_menu, new_pos); boardmenu->selected = index; @@ -227,14 +309,166 @@ swap_menu(BoardMenu* boardmenu, int src_index, int dest_index) return 0; } +/* menuitem */ +int +update_menuitem_descrip(MenuItem* menuitem) +{ /* need to do something about colored text */ + + TodoItem* item_data; + char* new_descrip; + + item_data = (TodoItem*)get_menuitem_userdata(menuitem); + new_descrip = strdup(""); + + if (strlen(item_data->description) > 0) { + /* strcat(new_descrip, "☰ "); */ + strcat(new_descrip, "# "); + } + if (strlen(item_data->due) > 0) { + strcat(new_descrip, item_data->due); + strcat(new_descrip, " "); + } + if (item_data->subtask_count > 0) { + + int tasks_complete = 0; + for (int i = 0; i < item_data->subtask_count; i++) { + if (item_data->subtask_list[i]->done == SubTaskState_done) { + tasks_complete += 1; + } + } + + /* [, # done, /, # total, ], null */ + char subtask_done[4]; // assume there wont be more than 999 subtasks (possibly danger?) + snprintf(subtask_done, 4, "%d", tasks_complete); + int substask_len = 1+item_data->subtask_count+1+strlen(subtask_done)+1+1; + char subtask_text[substask_len]; + sprintf(subtask_text, "[%s/%d]", subtask_done, item_data->subtask_count); + strcat(new_descrip, subtask_text); + } + + /* free old string */ + if (strlen(new_descrip) > 0) { + free(get_menuitem_descrip(menuitem)); + set_menuitem_descrip(menuitem, new_descrip); + } + + return 0; +} + /* popup */ -WINDOW* -create_popup_win() +PopupMenu* +make_popupmenu(TodoItem* itemdata) { - return NULL; + PopupMenu* new_popupmenu; + MenuItem** subtask_menuitems; + Menu* popupmenu_menu; + WINDOW* popupmenu_win; + WINDOW* popupmenu_menu_win; + + new_popupmenu = malloc(sizeof(PopupMenu)); + + subtask_menuitems = subtasklist_to_menuitem(itemdata->subtask_list, itemdata->subtask_count); + popupmenu_menu = create_menu(strdup(""), subtask_menuitems); + + /* popup win */ + int maxheight, maxwidth; + getmaxyx(stdscr, maxheight, maxwidth); + popupmenu_win = newwin( + maxheight-2*POPUP_BORDER, + maxwidth-2*2*POPUP_BORDER, + POPUP_BORDER, + POPUP_BORDER*2 + ); + + int popup_maxheight, popup_maxwidth; + getmaxyx(popupmenu_win, popup_maxheight, popup_maxwidth); + popupmenu_menu_win = derwin( + popupmenu_win, + popup_maxheight-POPUP_MENU_PAD_TOP-POPUP_MENU_PAD_BOTTOM, + popup_maxwidth-POPUP_MENU_PAD_LEFT-POPUP_MENU_PAD_RIGHT, + POPUP_MENU_PAD_TOP, + POPUP_MENU_PAD_LEFT + ); + + set_menu_win(popupmenu_menu, popupmenu_menu_win); + set_menu_focus(popupmenu_menu, 1); + set_menu_renderitem(popupmenu_menu, render_popup_menuitem); + set_menu_itemheight(popupmenu_menu, popup_menuitem_height); + box(popupmenu_win, 0, 0); + + /* move this stuff to render phase later? */ + mvwprintw(popupmenu_win, 1, 2, itemdata->item_name); + mvwprintw(popupmenu_win, 2, 2, (strlen(itemdata->description) > 0) ? itemdata->description : "no description"); + + /* don't forget to free popupmenu after */ + new_popupmenu->win = popupmenu_win; + new_popupmenu->menu = popupmenu_menu; + + return new_popupmenu; } +void +render_popup_menuitem(Menu* menu, int item_index, int start_y) +{ + MenuItem* curitem; + WINDOW* menu_win; + int hlcolor; + + curitem = get_menu_item(menu, item_index); + menu_win = get_menu_win(menu); + + /* color selected item */ + hlcolor = COLOR_PAIR((item_index == get_selected_item(menu) && get_menu_focused(menu) == true) ? TS_SELECTED : TS_NONSELECTED); + wattron(menu_win, hlcolor); + + wmove(menu_win, start_y, 0); + /* print subtask done indicator */ + if (strlen(get_menuitem_title(curitem)) > 0) + wprintw( + menu_win, + (((SubTask*)get_menuitem_userdata(curitem))->done == SubTaskState_done) ? "[X] " : "[ ] " + ); + wprintw(menu_win, get_menuitem_title(curitem)); + + wattroff(menu_win, hlcolor); +} + +int +popup_menuitem_height(MenuItem* menuitem) +{ + return 1; // account for wrap later +} + +int +render_popupmenu(PopupMenu* popupmenu) +{ + render_menu(popupmenu->menu); + wrefresh(popupmenu->win); + + return 0; +} + +/* this is copy paste of other, prob abstract */ +MenuItem** +subtasklist_to_menuitem(SubTask** subtask_list, int list_length) +{ + MenuItem** items; + + items = malloc((list_length+1)*sizeof(MenuItem*)); + for (int i = 0; i < list_length; i++) { + MenuItem* new_menuitem; + new_menuitem = create_menuitem(subtask_list[i]->subtask_name); + /* using same struct, careful if it gets freed */ + set_menuitem_userdata(new_menuitem, subtask_list[i]); + + items[i] = new_menuitem; + } + + items[list_length] = 0; //null terminate + return items; +} +/* helpers */ int ungetstr(char* str) {