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