reworked menu rendering
[taskasaur.git] / taskasaur.c
1
2 #include "headers/parser.h"
3 #include "headers/render.h"
4 #include "headers/menu.h"
5 #include "headers/utils.h"
6 #include "config.h"
7
8 char* boardfile_name = "test_board.md"; 
9
10 void normal_handleinput(BoardMenu* boardmenu, int ch);
11 void popup_handleinput(BoardMenu* boardmenu, int ch);
12 void generic_handleinput(Menu* menu, int ch);
13
14 void normal_renderstep(BoardMenu* boardmenu);
15 void popup_renderstep(BoardMenu* boardmenu);
16 void save_to_file(char* filepath, BoardMenu* boardmenu);
17
18 void exit_step(BoardMenu* boardmenu);
19
20 int
21 main(int argc, char** argv)
22 {
23     printf("%c]0;%s - %s%c", '\033', "taskasaur", boardfile_name, '\007'); // need to reset after program exits
24
25     /* read from todo file */
26     Board* board;
27     board = begin_parse(boardfile_name);
28     /* log_todo(board); */
29
30     /* init curses */
31     init_tscurses();
32
33     BoardMenu* boardmenu;
34     boardmenu = create_board_menu(board);
35
36     /* need to render before user presses anything */
37     normal_renderstep(boardmenu);
38
39     int ch;
40     while (1) {
41         
42         ch = getch();
43
44         if (boardmenu->popup_open == 0) {
45             normal_handleinput(boardmenu, ch);
46             normal_renderstep(boardmenu);
47         } else {
48             popup_handleinput(boardmenu, ch);
49             popup_renderstep(boardmenu);
50         }
51
52     }
53     
54     /* save on exit - this causes weird stuff to happen, maybe it's not given enough time to write before program exits? */
55     /* save_to_file(boardfile_name, boardmenu); */
56
57     return 0;    
58 }
59
60 void
61 normal_handleinput(BoardMenu* boardmenu, int ch)
62 {
63
64     Menu* active_menu;
65     active_menu = boardmenu->menu_list[boardmenu->selected];
66
67     switch (ch) {
68
69         case BINDING_SCROLL_LEFT:
70             if (boardmenu->selected-1 < 0) break;
71             set_selected_menu(boardmenu, boardmenu->selected-1);
72             break;
73         case BINDING_SCROLL_RIGHT:
74             if (boardmenu->selected+1 > boardmenu->menu_count-1) break;
75             set_selected_menu(boardmenu, boardmenu->selected+1);
76             break;
77         case BINDING_MOVE_ITEM_LEFT:
78             if (boardmenu->selected-1 < 0) break;
79             if (get_menu_length(boardmenu->menu_list[boardmenu->selected]) == 0) break;
80             {
81                 Menu* from_menu;
82                 Menu* to_menu;
83
84                 from_menu = boardmenu->menu_list[boardmenu->selected];
85                 to_menu = boardmenu->menu_list[boardmenu->selected-1];
86
87                 insert_item(
88                     to_menu,
89                     get_menu_item(
90                         from_menu,
91                         get_selected_item(from_menu)
92                     ),
93                     min(
94                         get_selected_item(from_menu),
95                         get_menu_length(to_menu)
96                     )
97                 );
98                 delete_item(
99                     from_menu,
100                     get_selected_item(from_menu) 
101                 );
102                 set_selected_menu(boardmenu, boardmenu->selected-1);
103             }
104
105             break;
106         case BINDING_MOVE_ITEM_RIGHT:
107             if (boardmenu->selected >= boardmenu->menu_count-1) break;
108             if (get_menu_length(boardmenu->menu_list[boardmenu->selected]) == 0) break;
109             // this is legit cpy paste please fix this
110             {
111                 Menu* from_menu;
112                 Menu* to_menu;
113
114                 from_menu = boardmenu->menu_list[boardmenu->selected];
115                 to_menu = boardmenu->menu_list[boardmenu->selected+1];
116
117                 insert_item(
118                     to_menu,
119                     get_menu_item(
120                         from_menu,
121                         get_selected_item(from_menu)
122                     ),
123                     min(
124                         get_selected_item(from_menu),
125                         get_menu_length(to_menu)
126                     )
127                 );
128                 delete_item(
129                     from_menu,
130                     get_selected_item(from_menu) 
131                 );
132                 set_selected_menu(boardmenu, boardmenu->selected+1);
133             }
134
135             break;
136         /* case BINDING_MOVE_MENU_LEFT: */
137         /*     if (boardmenu->selected-1 < 0) break; */
138
139         /*     swap_menu(boardmenu, boardmenu->selected, boardmenu->selected-1); */
140             /* boardmenu->selected -= 1; */
141             /* set_selected_menu(boardmenu, boardmenu->selected); */
142
143             /* break; */
144         /* case BINDING_MOVE_MENU_RIGHT: */
145             /* if (boardmenu->selected >= boardmenu->menu_count-1) break; */
146             /* swap_menu(boardmenu, boardmenu->selected, boardmenu->selected+1); */
147             /* boardmenu->selected += 1; */
148             /* set_selected_menu(boardmenu, boardmenu->selected); */
149
150             /* break; */
151         case BINDING_SELECT:
152             {
153                 Menu* sel_menu;
154                 TodoItem* sel_itemdata;
155
156                 sel_menu = boardmenu->menu_list[boardmenu->selected];
157                 sel_itemdata = (TodoItem*)get_menuitem_userdata(
158                     get_menu_item(sel_menu, get_selected_item(sel_menu))
159                 );
160
161                 /* set mode to popup */
162                 boardmenu->popupmenu = make_popupmenu(sel_itemdata);
163                 boardmenu->popup_open = 1;
164             } 
165
166             break;
167         case BINDING_WRITE:
168             save_to_file(boardfile_name, boardmenu);
169             break;
170         case BINDING_QUIT:
171             exit_step(boardmenu);
172             break;
173         case KEY_RESIZE:
174             /* ; */
175             /* int y, x; */
176             /* char out[10]; */
177             /* getmaxyx(stdscr, y, x); */
178             /* sprintf(out, "%d,%d", y, x); */
179
180             /* mvprintw(20, 20, out); */
181             /* resize_term(y, x); */
182             break;
183
184         default:
185             generic_handleinput(active_menu, ch);
186
187     }
188 }
189
190 void
191 popup_handleinput(BoardMenu* boardmenu, int ch)
192 {
193     Menu* popupmenu_menu;
194
195     popupmenu_menu = boardmenu->popupmenu->menu;
196
197     switch (ch) {
198
199         case BINDING_QUIT:
200             boardmenu->popup_open = 0;
201             clear();
202             break;
203
204         case BINDING_TOGGLE_DONE:
205             {
206                 SubTask* curitem_data = (SubTask*)get_menuitem_userdata(get_menu_item(popupmenu_menu, get_selected_item(popupmenu_menu))); 
207                 curitem_data->done = (curitem_data->done == SubTaskState_todo) ? SubTaskState_done : SubTaskState_todo;
208             }
209
210             break;
211
212         default:
213             generic_handleinput(popupmenu_menu, ch);
214     }    
215 }
216
217 void
218 generic_handleinput(Menu* menu, int ch)
219 {
220     switch (ch) {
221
222         case BINDING_SCROLL_UP:
223             menu_driver(menu, MENU_UP);
224             break;
225         case BINDING_SCROLL_DOWN:
226             menu_driver(menu, MENU_DOWN);
227             break;
228         case BINDING_JUMP_TOP:
229             menu_driver(menu, MENU_TOP);
230             break;
231         case BINDING_JUMP_BOTTOM:
232             menu_driver(menu, MENU_BOTTOM);
233             break;
234         case BINDING_MOVE_ITEM_UP:
235             menu_driver(menu, MENU_MOVE_UP);
236             break;
237         case BINDING_MOVE_ITEM_DOWN:
238             menu_driver(menu, MENU_MOVE_DOWN);
239             break;
240         case BINDING_DELETE_ITEM:
241             menu_driver(menu, MENU_DELETE);
242             break;
243         case BINDING_APPEND_ITEM:
244             menu_driver(menu, MENU_APPEND);
245             break;
246         case BINDING_INSERT_ABOVE:
247             menu_driver(menu, MENU_INSERT_ABOVE);
248             break;
249         case BINDING_INSERT_BELOW:
250             menu_driver(menu, MENU_INSERT_BELOW);
251             break;
252         case BINDING_EDIT_ITEM:
253             menu_driver(menu, MENU_EDIT);
254             break;
255     }            
256 }
257
258 void
259 normal_renderstep(BoardMenu* boardmenu)
260 {
261     for (int i = 0; i < boardmenu->menu_count; i++) {
262
263         Menu* curmenu = boardmenu->menu_list[i];
264
265         /* update the descriptions - maybe not do this here */ 
266         for (int j = 0; j < get_menu_length(curmenu); j++) {
267             update_menuitem_descrip(get_menu_item(curmenu, j));
268         }
269
270         render_menu(curmenu);
271     }
272 }
273
274 void
275 popup_renderstep(BoardMenu* boardmenu)
276 {
277     if (boardmenu->popupmenu == NULL) return;
278
279     render_popupmenu(boardmenu->popupmenu); 
280 }
281
282 void
283 save_to_file(char* filepath, BoardMenu* boardmenu)
284 {
285     Board* writeboard;
286     writeboard = boardmenu_to_board(boardmenu);
287
288     begin_write(filepath, writeboard);
289     free_board(writeboard);
290 }
291
292 void
293 exit_step(BoardMenu* boardmenu)
294 {
295     exit_tscurses();
296     exit(0);
297 }