1 #include "menu.h"
2 #include <stdarg.h>
3 #include "popup_items.h"
4 #include "creation.h"
5
6 #define MAX_POPUP_SIZE 12
7 #define MAX_POPUP_STRING 20
8
9 struct popup_item
10 {
11 item_t item;
12 char *display_text;
13 menu_t *menu_handle;
14 int choice;
15 int max_choice;
16 void (*save_hook)(void *, popup_entry_t *entry);
17 int (*load_hook)(void *, popup_entry_t *);
18 void *hook_user_data;
19 popup_entry_t *entries;
20 };
21
itemtype_popup_render(menu_t * menu,item_t * item,int state)22 void itemtype_popup_render(menu_t *menu, item_t *item, int state)
23 {
24 struct popup_item *it = (struct popup_item *)item;
25 int x,y;
26 x = menu->x + item->x;
27 y = menu->y + item->y;
28
29 video_draw_text(x,y, MENUATTR_NORMAL, it->display_text, item->w);
30 video_draw_text(x+item->front_width,y, MENUATTR_NORMAL, ":", -1);
31 video_draw_text(x+item->front_width+1,y,state,
32 it->choice >= 0 ? it->entries[it->choice].display_text : "<none>",
33 item->back_width);
34 }
35
itemtype_popup_invoke(menu_t * menu,item_t * item,int key)36 void itemtype_popup_invoke(menu_t *menu, item_t *item, int key)
37 {
38 struct popup_item
39 *it = (struct popup_item *)item;
40
41 switch(key)
42 {
43 case KEY_ACTIVATE:
44 menu_set_active_item(it->menu_handle, it->choice);
45 menu_set_position(it->menu_handle,
46 menu->y+item->y, menu->x+item->x+item->front_width+1);
47 menu_form_popup(menu->parent_form, it->menu_handle);
48 break;
49 case KEY_NEXT_OPTION:
50 if (it->choice < it->max_choice)
51 {
52 itemtype_popup_render(menu, item, MENUATTR_HILITE);
53 it->choice++;
54 itemtype_popup_render(menu, item, MENUATTR_HILITE);
55 }
56 break;
57 case KEY_PREV_OPTION:
58 if (it->choice > 0)
59 {
60 itemtype_popup_render(menu, item, MENUATTR_HILITE);
61 it->choice--;
62 itemtype_popup_render(menu, item, MENUATTR_HILITE);
63 }
64 break;
65 default:
66 return;
67 }
68 }
69
itemtype_popup_save(menu_t * menu,item_t * item)70 void itemtype_popup_save(menu_t *menu, item_t *item)
71 {
72 struct popup_item *it = (struct popup_item *)item;
73 if (it->save_hook)
74 it->save_hook(it->hook_user_data, &it->entries[it->choice]);
75 }
76
itemtype_popup_load(menu_t * menu,item_t * item)77 void itemtype_popup_load(menu_t *menu, item_t *item)
78 {
79 struct popup_item *it = (struct popup_item *)item;
80 if (it->load_hook)
81 {
82 int i = it->load_hook(it->hook_user_data, it->entries);
83 if (i != -1) it->choice = i;
84 }
85 item->f_save = itemtype_popup_save;
86 item->f_load = 0;
87 }
88
89
item_func(item_t * item,void * param1,int param2)90 static void item_func(item_t *item, void *param1, int param2)
91 {
92 *(int *)param1 = param2;
93 }
94
itemtype_popup_alloc(menu_t * menu,va_list args)95 item_t *itemtype_popup_alloc(menu_t *menu, va_list args)
96 {
97 menu_t
98 *popup;
99 item_t
100 *newitem;
101 popup_entry_t
102 *e;
103 int
104 i,
105 maximum_width = 0,
106 m;
107
108 struct popup_item
109 *item = (struct popup_item *)malloc(sizeof(struct popup_item) + MAX_POPUP_STRING * MAX_POPUP_SIZE );
110
111 if (!item) return NULL;
112 menu_item_init(&item->item);
113
114 item->display_text = va_arg(args, char *);
115 item->choice = va_arg(args, int);
116 item->hook_user_data = va_arg(args, void *);
117 item->save_hook = va_arg(args, void *);
118 item->load_hook = va_arg(args, void *);
119 item->entries = va_arg(args, popup_entry_t*);
120
121 popup = new_menu(MENUTYPE_POPUP, NULL, menu->parent_form, NULL);
122
123 i=0;
124 e = item->entries;
125 do
126 {
127 if (e->display_text == NULL) break;
128 m = strlen(e->display_text);
129 if (m > maximum_width) maximum_width = m;
130 newitem = menu_item_create(ITEMTYPE_FUNC, popup, e->display_text, item_func, &(item->choice),i);
131 i++;
132 e++;
133 } while (1);
134
135 item->max_choice = i-1;
136
137 item->menu_handle = popup;
138
139 item->item.f_render = itemtype_popup_render;
140 item->item.f_save = 0;
141 item->item.f_invoke = itemtype_popup_invoke;
142 item->item.f_load = itemtype_popup_load;
143
144 item->item.w = item->item.front_width = strlen(item->display_text);
145 item->item.back_width = maximum_width;
146 item->item.h = 1;
147 item->item.disabled = false;
148
149 return (item_t *)item;
150 }
151