1 #include "menu.h"
2 #include <stdarg.h>
3 #include <malloc.h>
4 #include "func_items.h"
5 #include "popup_items.h"
6 #include "string_items.h"
7 #include "label_items.h"
8 
9 #define SINGLE_BOX 0
10 #define DOUBLE_BOX 1
11 
12 /* -- Forms -- */
new_form(char * title)13 form_t *new_form(char *title)
14 {
15 	form_t *form = (form_t *)malloc(sizeof(form_t));
16 	if (form)
17 	{
18 		memset(form, 0, sizeof(form_t));
19 		form->form_title = title;
20 		list_init(& form->menu_list);
21 	}
22 	return form;
23 }
24 
menu_form_set_menu(form_t * form,menu_t * menu)25 void menu_form_set_menu(form_t *form, menu_t *menu)
26 {
27 	item_t *item = (item_t *)(menu->item_list.first);
28 	while (item)
29 	{
30 		if (item->f_load) item->f_load(menu, item);
31 		item = (item_t *)(item->link.next);
32 	}
33 
34 	form->current_menu = menu;
35 	menu_draw_form(form);
36 }
37 
menu_form_add_menu(form_t * form,menu_t * menu)38 void menu_form_add_menu(form_t *form, menu_t *menu)
39 {
40 	list_add(&(form->menu_list), (node_t *)menu);
41 }
42 
menu_form_find_menu(form_t * form,char * name)43 menu_t* menu_form_find_menu(form_t *form, char *name)
44 {
45 	node_t *n;
46 	n = form->menu_list.first;
47 	while (n)
48 	{
49 		if (strcmp(name, ((menu_t *)n)->menu_title) == 0)
50 			return (menu_t *)n;
51 		n = n->next;
52 	}
53 	return NULL;
54 }
55 
56 /* -- Menus -- */
new_menu(int type,char * title,form_t * parent,char * parent_menu)57 menu_t *new_menu(int type, char *title, form_t *parent, char *parent_menu)
58 {
59 	menu_t *menu = (menu_t *)malloc(sizeof(menu_t));
60 	if (menu)
61 	{
62 		menu->type         = type;
63 		menu->menu_title   = title;
64 		menu->parent_form  = parent;
65 		menu->x = menu->y  = 0;
66 		menu->w = menu->h  = 0;
67 		menu->needs_layout = true;
68 		menu->item_spacing = 1;
69 		menu->parent_menu  = parent_menu;
70 		menu->current_item = NULL;
71 		list_init(&(menu->item_list));
72 	}
73 	return menu;
74 }
75 
menu_set_position(menu_t * menu,int line,int col)76 void menu_set_position(menu_t *menu, int line, int col)
77 {
78 	if (menu)
79 	{
80 		menu->x = col;
81 		menu->y = line;
82 	}
83 }
84 
menu_add_item(menu_t * menu,item_t * item)85 void menu_add_item(menu_t *menu, item_t *item)
86 {
87 	list_add(&(menu->item_list), (node_t *)item);
88 	menu->needs_layout = true;
89 }
90 
91 /* Items */
92 
93 typedef struct
94 {
95 	int type;
96 	item_t * (*create)(menu_t *, va_list);
97 } itemtype_t;
98 
99 
100 itemtype_t item_types_templates[] =
101 {
102 	//{ ITEMTYPE_BOOL_CVAR, itemtype_bool_cvar_alloc },
103 	{ ITEMTYPE_FUNC, itemtype_func_alloc },
104 	{ ITEMTYPE_SUBMENU, itemtype_submenu_alloc },
105 	{ ITEMTYPE_POPUP, itemtype_popup_alloc },
106 	{ ITEMTYPE_STRING_CVAR, itemtype_string_cvar_alloc },
107 	{ ITEMTYPE_LABEL, itemtype_label_alloc },
108 	//{ ITEMTYPE_NUMERIC, itemtype_numeric_alloc },
109 	//{ ITEMTYPE_REGISTER, itemtype_register_alloc },
110 };
111 
112 itemtype_t item_types[10];
113 
114 
115 #define NUM_ITEMTYPES (sizeof(item_types) / sizeof(itemtype_t))
116 
menu_item_relocate(unsigned long offset)117 void menu_item_relocate(unsigned long offset)
118 {
119 	int i;
120 	for (i=0; i<NUM_ITEMTYPES; i++)
121 	{
122 		item_types[i].type = item_types_templates[i].type;
123 		item_types[i].create =
124 			(item_t * (*)(menu_t *, va_list)) ((unsigned char *)item_types_templates[i].create); // - offset);
125 	}
126 }
127 
menu_item_create(int type,menu_t * menu,...)128 item_t *menu_item_create(int type, menu_t *menu, ...)
129 {
130 	va_list args;
131 	int i;
132 	item_t *new_item;
133 
134 	for (i=0; i<NUM_ITEMTYPES; i++)
135 	{
136 		if (item_types[i].type == type)
137 		{
138 			va_start(args, menu);
139 			new_item = item_types[i].create(menu, args);
140 			va_end(args);
141 			if (menu)
142 			{
143 				menu_add_item(menu, new_item);
144 			}
145 			return new_item;
146 		}
147 	}
148 
149 	return NULL;
150 }
151 
menu_item_init(item_t * item)152 void menu_item_init(item_t *item)
153 {
154 	item->disabled = false;
155 	item->break_after = false;
156 	item->help_text = NULL;
157 }
158 
menu_item_break_after(item_t * item)159 void menu_item_break_after(item_t *item)
160 {
161 	if (item) item->break_after = true;
162 }
163 
menu_item_set_help(item_t * item,char * help_string)164 void menu_item_set_help(item_t *item, char *help_string)
165 {
166 	if (item)
167 		item->help_text = help_string;
168 }
169