7 #include "headers/menu.h"
8 #include "headers/render.h"
9 #include "headers/utils.h"
11 #define MENU_PAD_TOP 2
12 #define MENU_PAD_BOTTOM 1
13 #define MENU_PAD_LEFT 2
14 #define MENU_PAD_RIGHT 1
16 typedef struct MenuItem {
21 MenuItem** menu_items;
30 int swap_item(Menu* menu, int src_index, int dest_index);
31 int delete_item(Menu* menu, int index);
34 create_menuitem(char* contents)
36 MenuItem* new_menuitem;
38 new_menuitem = malloc(sizeof(MenuItem));
39 new_menuitem->contents = contents;
45 create_menu(MenuItem** item_list)
49 new_menu = malloc(sizeof(Menu));
50 new_menu->menu_items = item_list;
51 new_menu->menu_length = array_length(MenuItem*, item_list);
52 new_menu->selected_item = 0;
53 set_menu_win(new_menu, stdscr);
59 set_menu_win(Menu* menu, WINDOW* win)
64 getmaxyx(menu->menu_win, height, width);
66 /* create a subwin (also prob free old subwin?) */
67 menu->max_height = height-MENU_PAD_TOP-MENU_PAD_BOTTOM;
68 menu->max_width = width-MENU_PAD_LEFT-MENU_PAD_RIGHT;
69 menu->sub_win = derwin(
81 get_menu_items(Menu* menu)
87 swap_item(Menu* menu, int src_index, int dest_index)
91 temp = menu->menu_items[dest_index];
92 menu->menu_items[dest_index] = menu->menu_items[src_index];
93 menu->menu_items[src_index] = temp;
99 delete_item(Menu* menu, int index)
101 if (index < 0 || index > menu->menu_length-1) return -1;
103 int temp_size = (menu->menu_length-index-1)*sizeof(MenuItem*);
104 MenuItem* temp[temp_size];
106 /* might break if last item? */
107 memcpy(temp, menu->menu_items[index+1], temp_size);
108 memcpy(menu->menu_items[index], temp, temp_size);
110 menu->menu_items = realloc(menu->menu_items, menu->menu_length*sizeof(MenuItem*));
111 menu->menu_items[menu->menu_length-1] = 0; // preserve null at end
113 menu->menu_length -= 1;
115 /* also move the current selected position if it's last */
116 if (menu->selected_item > menu->menu_length-1) {
117 menu->selected_item = menu->menu_length-1;
124 menu_driver(Menu* menu, MenuAction action)
129 menu->selected_item = menu->selected_item-1 >= 0 ? menu->selected_item-1 : 0;
133 menu->selected_item = menu->selected_item+1 <= menu->menu_length-1 ? menu->selected_item+1 : menu->menu_length-1;
137 menu->selected_item = 0;
141 menu->selected_item = menu->menu_length-1;
145 if (menu->selected_item <= 0) break;
146 swap_item(menu, menu->selected_item, menu->selected_item-1);
147 menu->selected_item -= 1;
151 if (menu->selected_item >= menu->menu_length-1) break;
152 swap_item(menu, menu->selected_item, menu->selected_item+1);
153 menu->selected_item += 1;
157 delete_item(menu, menu->selected_item);
158 wclear(menu->menu_win);
161 default: // This is here for debug, disable later
162 fprintf(stderr, "Invalid menu action");
169 render_menu(Menu* menu)
171 /* draw outer menu (prob dont need this every render) */
172 mvwprintw(menu->menu_win, 0, MENU_PAD_LEFT, "TODO");
174 /* draw inner menu */
176 for (int i = 0; i < menu->menu_length; i++) {
182 /* wrap text by inserting newlines (maxwidth-1 for newline char)*/
183 wrapped_text = wrap_text(menu->menu_items[i]->contents, menu->max_width-1, &wrapped_lines);
185 /* color selected item */
186 text_color = (i == menu->selected_item) ? TS_SELECTED : TS_NONSELECTED;
188 wattron(menu->sub_win, COLOR_PAIR(text_color));
189 mvwprintw(menu->sub_win, cur_line, 0, wrapped_text);
190 wattroff(menu->sub_win, COLOR_PAIR(text_color));
192 cur_line += wrapped_lines;
198 wrefresh(menu->sub_win);
199 wrefresh(menu->menu_win);
205 free_menu(Menu* menu)