4 #include "gui-windows.h"
6 #if defined(USE_NCURSES) && !defined(RENAMED_NCURSES)
18 #define INIT_ENTRIES 8
22 #define CUIX_FIELD_WIDTH 16
24 object *create_object (char *title, int type, void **entries)
30 obj = g_malloc (sizeof(object));
37 new_entries = g_new0 (void *, INIT_ENTRIES);
38 obj->entries = new_entries;
39 obj->alloced = INIT_ENTRIES;
42 for (i = 0; ((entry **)entries)[i]; i++);
45 obj->entries = entries;
51 object *create_menu (char *title)
53 return create_object (title, CUIX_MENU, NULL);
57 object *create_form (char *title)
59 return create_object (title, CUIX_FORM, NULL);
63 /* entries must be NULL terminated */
64 object *create_list (char *title, entry **entries)
66 return create_object (title, CUIX_LIST, (void **)entries);
69 entry *create_entry (char *label, int type, action_fn_type action)
73 entry = g_malloc (sizeof(object));
79 entry->action = action;
83 entry *create_menuentry (char *label, action_fn_type action)
85 return create_entry (label, CUIX_MENUENTRY, action);
88 entry *create_label (char *label)
90 return create_entry (label, CUIX_LABEL, NULL);
94 entry *create_field (char *label, action_fn_type action)
96 return create_entry (label, CUIX_FIELD, action);
101 /* Adds child at the last position of father->entries */
102 void attach_entry (object *father, void *child)
107 /* Check that we have enough space in father->entries, otherwise alloc
108 * twice more than previously */
109 if (father->last >= father->alloced) {
110 entries = g_new0 (void *,2 * father->alloced);
112 fprintf (stderr, "Problem with memory allocation, quitting now...\n");
115 for (i = 0; i < father->alloced; i++) {
116 entries[i] = father->entries[i];
118 g_free (father->entries);
119 father->entries = entries;
120 father->alloced *= 2;
122 father->entries[father->last++] = child;
126 /* Adds a submenu to father */
127 void attach_submenu (object *father, object *child)
130 /* Check that both are really menus */
131 if (father->type != CUIX_MENU || child->type != CUIX_MENU) {
132 fprintf (stderr, "Typing error, trying to add %p (%d) as child of"
133 "%p (%d)\n", father, father->type, child, child->type);
136 attach_entry (father, (void *)child);
140 /* Returns the maximum width occupied by labels */
141 int get_labels_width (object *obj)
148 for (i = 0; i < obj->last; i++) {
149 e = (entry *)obj->entries[i];
150 if (e->type == CUIX_LABEL || e->type == CUIX_MENUENTRY) {
151 w = (w > strlen (e->data)) ? w : strlen (e->data);
153 if (e->type == CUIX_MENU) {
154 o = (object *)obj->entries[i];
155 w = (w > strlen (o->title)) ? w : strlen (o->title);
164 /* Puts in x and y the coordinates to center an object of size objw and objh
165 * in the window win */
166 void get_center (WINDOW *win, int objh, int objw, int *y, int *x)
168 int begx, begy, maxx, maxy, w, h;
169 getbegyx (win, begy, begx);
170 getmaxyx (win, maxy, maxx);
173 *x = (w - objw) / 2 + begx;
174 *y = (h - objh) / 2 + begy;
183 void display_object (object *obj)
189 ITEM **items, *cur_item;
195 p_main = new_panel(root_window->win);
197 if (obj->type >= CUIX_LABEL) {
198 fprintf (stderr, "Trying to display an entry %p (%d), terminating...\n",
205 w = get_labels_width (obj);
206 h = Y_OFFSET * obj->last + 2 * Y0_OFFSET;
207 get_center (root_window->win, h, w, &y, &x);
208 cuix_win = newwin (h, w, y, x);
209 box (cuix_win, 0, 0);
210 p_cuix = new_panel(cuix_win);
214 for (i = 0; i < obj->last; i++) {
215 e = (entry *)obj->entries[i];
216 if (e->type != CUIX_LABEL) {
217 fprintf (stderr, "Non-label entry in a list.\n");
220 wmove (cuix_win,y,x);
221 waddstr (cuix_win,e->data);
230 /* wrefresh (cuix_win); */
234 w = get_labels_width (obj);
235 w = (w > CUIX_FIELD_WIDTH + 2 * X0_OFFSET) ?
236 w : CUIX_FIELD_WIDTH + 2 * X0_OFFSET;
237 h = Y_OFFSET * obj->last + 2 * Y0_OFFSET;
238 fields = g_new0 (FIELD *, obj->last + 1);
239 for (i = 0; i < obj->last; i++) {
240 e = (entry *)obj->entries[i];
241 fields[i] = new_field (1, w,
242 Y0_OFFSET + i * Y_OFFSET, X0_OFFSET, 0, 0);
243 if (e->type == CUIX_LABEL) {
244 field_opts_off (fields[i], O_ACTIVE);
245 field_opts_off (fields[i], O_EDIT);
246 set_field_back (fields[i], A_BOLD);
248 set_field_buffer (fields[i], 0, e->data);
250 fields[obj->last] = NULL;
251 form = new_form (fields);
252 scale_form (form, &h, &w);
255 get_center (root_window->win, h, w, &y, &x);
256 cuix_win = newwin (h, w, y, x);
257 keypad (cuix_win, TRUE);
259 set_form_win (form, cuix_win);
260 set_form_sub (form, derwin(cuix_win, w, h, X0_OFFSET, Y0_OFFSET));
262 box (cuix_win, 0, 0);
263 p_cuix = new_panel (cuix_win);
265 while((ch = wgetch(cuix_win)) != '\n' && ch != '\r' && ch != 27 /* ESC */) {
268 /* Go to next field */
269 form_driver(form, REQ_NEXT_FIELD);
270 /* Go to the end of the present buffer */
271 /* Leaves nicely at the last character */
272 form_driver(form, REQ_END_LINE);
275 /* Go to previous field */
276 form_driver(form, REQ_PREV_FIELD);
277 form_driver(form, REQ_END_LINE);
280 form_driver(form, REQ_PREV_CHAR);
281 form_driver(form, REQ_DEL_CHAR);
284 form_driver(form, REQ_PREV_CHAR);
287 form_driver(form, REQ_NEXT_CHAR);
290 /* If this is a normal character, it gets */
292 form_driver(form, ch);
296 form_driver (form, REQ_VALIDATION);
298 for (i = 0; i < obj->last; i++) {
299 e = (entry *)obj->entries[i];
300 if (e->type == CUIX_FIELD) {
301 result = field_buffer(fields[i],0);
306 for (i = 0; i < obj->last; i++) {
307 free_field (fields[i]);
315 w = get_labels_width (obj);
316 w = (w > CUIX_FIELD_WIDTH + 2 * X0_OFFSET) ?
317 w : CUIX_FIELD_WIDTH + 2 * X0_OFFSET;
318 h = Y_OFFSET * obj->last + 2 * Y0_OFFSET;
319 items = g_new0 (ITEM *, obj->last + 1);
320 for (i = 0; i < obj->last; i++) {
321 e = (entry *)obj->entries[i];
322 o = (object *)obj->entries[i];
323 if (e->type == CUIX_MENUENTRY) {
324 items[i] = new_item (e->data, "");
325 set_item_userptr (items[i], (void*)e);
327 if (e->type == CUIX_LABEL) {
328 items[i] = new_item (e->data, "");
329 item_opts_off (items[i], O_SELECTABLE);
331 items[i] = new_item (o->title, " (SUB) ");
332 set_item_userptr (items[i], (void*)o);
336 items[obj->last] = NULL;
337 menu = new_menu (items);
338 set_menu_mark (menu, " * ");
339 scale_menu (menu, &h, &w);
342 get_center (root_window->win, h, w, &y, &x);
343 cuix_win = newwin (h, w, y, x);
344 keypad (cuix_win, TRUE);
346 set_menu_win (menu, cuix_win);
347 subwin = derwin (cuix_win,
348 h - 2 * Y0_OFFSET, w - 2 * X0_OFFSET, Y0_OFFSET, X0_OFFSET);
349 set_menu_sub (menu, subwin);
350 box (cuix_win, 0, 0);
352 p_cuix = new_panel (cuix_win);
354 while((ch = wgetch(cuix_win)) != 27 /* ESC */) {
357 menu_driver(menu, REQ_DOWN_ITEM);
360 menu_driver(menu, REQ_UP_ITEM);
364 cur_item = current_item(menu);
365 e = (entry *)item_userptr(cur_item);
366 o = (object *)item_userptr(cur_item);
367 if (e->type == CUIX_MENUENTRY)
380 for (i = 0; i < obj->last; i++) {
381 free_item (items[i]);