Simplified handle_close
[grace.git] / src / motifutils.c
blob46c51f330e1f12298f32a87bfe7de87ab4ad5de4
1 /*
2 * Grace - GRaphing, Advanced Computation and Exploration of data
3 *
4 * Home page: http://plasma-gate.weizmann.ac.il/Grace/
5 *
6 * Copyright (c) 1991-1995 Paul J Turner, Portland, OR
7 * Copyright (c) 1996-2006 Grace Development Team
8 *
9 * Maintained by Evgeny Stambulchik
12 * All Rights Reserved
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31 * utilities for Motif
35 #include <config.h>
37 #include <stdlib.h>
38 #include <ctype.h>
39 #include <stdarg.h>
41 #include <X11/X.h>
42 #include <X11/Xatom.h>
43 #include <X11/cursorfont.h>
45 #if defined(HAVE_XPM_H)
46 # include <xpm.h>
47 #else
48 # include <X11/xpm.h>
49 #endif
51 #include <Xm/Xm.h>
52 #include <Xm/Protocols.h>
53 #include <Xm/BulletinB.h>
54 #include <Xm/MessageB.h>
55 #include <Xm/Form.h>
56 #include <Xm/Label.h>
57 #include <Xm/List.h>
58 #include <Xm/PushB.h>
59 #include <Xm/CascadeBG.h>
60 #include <Xm/RowColumn.h>
61 #include <Xm/Text.h>
62 #include <Xm/ScrollBar.h>
64 #include <Xbae/Matrix.h>
65 #include "ListTree.h"
67 #if XmVersion < 2000
68 # define XmStringConcatAndFree(a, b) XmStringConcat(a, b); XmStringFree(a); XmStringFree(b)
69 #endif
71 #include "motifinc.h"
72 #include "explorer.h"
74 #include "defines.h"
75 #include "globals.h"
76 #include "grace/canvas.h"
77 #include "jbitmaps.h"
78 #include "core_utils.h"
79 #include "utils.h"
80 #include "xprotos.h"
81 #include "events.h"
83 #define canvas grace_get_canvas(gapp->grace)
85 extern XtAppContext app_con;
87 static unsigned long *xvlibcolors;
90 static OptionItem *color_option_items = NULL;
91 static unsigned int ncolor_option_items = 0;
92 static OptionStructure **color_selectors = NULL;
93 static unsigned int ncolor_selectors = 0;
95 static Widget color_choice_popup = NULL;
97 void Beep(void)
99 X11Stuff *xstuff = gapp->gui->xstuff;
101 XBell(xstuff->disp, 50);
104 OptionStructure *CreateBitmapOptionChoice(Widget parent, char *labelstr, int ncols,
105 int nchoices, int width, int height, BitmapOptionItem *items)
107 int i;
108 XmString str;
109 OptionStructure *retval;
111 retval = xcalloc(1, sizeof(OptionStructure));
112 if (!retval) {
113 return NULL;
115 retval->nchoices = nchoices;
116 retval->options = xmalloc(nchoices*sizeof(OptionWidgetItem));
117 if (retval->options == NULL) {
118 errmsg("Malloc error in CreateBitmapOptionChoice()");
119 XCFREE(retval);
120 return retval;
124 retval->pulldown = XmCreatePulldownMenu(parent, "pulldownMenu", NULL, 0);
125 XtVaSetValues(retval->pulldown,
126 XmNentryAlignment, XmALIGNMENT_CENTER,
127 NULL);
129 if (ncols > 0) {
130 XtVaSetValues(retval->pulldown,
131 XmNpacking, XmPACK_COLUMN,
132 XmNnumColumns, ncols,
133 NULL);
136 for (i = 0; i < nchoices; i++) {
137 retval->options[i].value = items[i].value;
138 if (items[i].bitmap != NULL) {
140 retval->options[i].widget =
141 CreateBitmapButton(retval->pulldown, width, height, items[i].bitmap);
142 } else {
143 retval->options[i].widget =
144 CreateButton(retval->pulldown, "None");
149 retval->menu = XmCreateOptionMenu(parent, "optionMenu", NULL, 0);
150 str = XmStringCreateLocalized(labelstr);
151 XtVaSetValues(retval->menu,
152 XmNlabelString, str,
153 XmNsubMenuId, retval->pulldown,
154 NULL);
155 XmStringFree(str);
156 WidgetManage(retval->menu);
158 return retval;
161 void UpdateCharOptionChoice(OptionStructure *opt, int font)
163 int *old_font;
164 old_font = (int *) WidgetGetUserData(opt->menu);
165 if (*old_font != font) {
166 int i, csize = 24;
167 for (i = 0; i < opt->nchoices; i++) {
168 Widget w = opt->options[i].widget;
169 Pixmap ptmp = char_to_pixmap(opt->pulldown, font, (char) i, csize);
170 XtVaSetValues(w, XmNlabelPixmap, ptmp, NULL);
171 WidgetSetSensitive(w, ptmp ? TRUE:FALSE);
173 *old_font = font;
177 static unsigned char dummy_bits[] = {
178 0x00, 0x00, 0x00, 0x00, 0xec, 0x2e, 0x04, 0x20, 0x00, 0x20, 0x04, 0x00,
179 0x04, 0x20, 0x04, 0x20, 0x00, 0x20, 0x04, 0x00, 0x04, 0x20, 0x04, 0x20,
180 0x00, 0x20, 0xdc, 0x1d, 0x00, 0x00, 0x00, 0x00};
182 OptionStructure *CreateCharOptionChoice(Widget parent, char *s)
184 int i;
185 int ncols = 16, nchoices = 256;
186 XmString str;
187 OptionStructure *retval;
188 int *fontid;
190 retval = xcalloc(1, sizeof(OptionStructure));
191 if (retval == NULL) {
192 errmsg("Malloc error in CreateBitmapOptionChoice()");
194 retval->nchoices = nchoices;
195 retval->options = xmalloc(nchoices*sizeof(OptionWidgetItem));
196 if (retval->options == NULL) {
197 errmsg("Malloc error in CreateBitmapOptionChoice()");
198 XCFREE(retval);
199 return retval;
202 retval->pulldown = XmCreatePulldownMenu(parent, "pulldownMenu", NULL, 0);
203 XtVaSetValues(retval->pulldown,
204 XmNentryAlignment, XmALIGNMENT_CENTER,
205 XmNpacking, XmPACK_COLUMN,
206 XmNorientation, XmHORIZONTAL,
207 XmNnumColumns, ncols,
208 NULL);
210 for (i = 0; i < nchoices; i++) {
211 retval->options[i].value = (char) i;
212 retval->options[i].widget = CreateBitmapButton(retval->pulldown, 16, 16, dummy_bits);
215 retval->menu = XmCreateOptionMenu(parent, "optionMenu", NULL, 0);
216 str = XmStringCreateLocalized(s);
217 XtVaSetValues(retval->menu,
218 XmNlabelString, str,
219 XmNsubMenuId, retval->pulldown,
220 NULL);
221 XmStringFree(str);
222 WidgetManage(retval->menu);
224 fontid = xmalloc(SIZEOF_INT);
225 *fontid = -1;
226 WidgetSetUserData(retval->menu, fontid);
228 return retval;
231 void SetOptionChoice(OptionStructure *opt, int value)
233 int i;
234 Arg a;
236 if (opt->options == NULL || opt->nchoices <= 0) {
237 return;
240 for (i = 0; i < opt->nchoices; i++) {
241 if (opt->options[i].value == value) {
242 XtSetArg(a, XmNmenuHistory, opt->options[i].widget);
243 XtSetValues(opt->menu, &a, 1);
244 return;
248 errmsg("Value not found in SetOptionChoice()");
251 int GetOptionChoice(OptionStructure *opt)
253 Arg a;
254 Widget warg;
255 int i;
257 if (opt->options == NULL || opt->nchoices <= 0) {
258 errmsg("Internal error in GetOptionChoice()");
259 return 0;
262 XtSetArg(a, XmNmenuHistory, &warg);
263 XtGetValues(opt->menu, &a, 1);
265 for (i = 0; i < opt->nchoices; i++) {
266 if (opt->options[i].widget == warg) {
267 return(opt->options[i].value);
270 errmsg("Internal error in GetOptionChoice()");
271 return 0;
274 static char list_translation_table[] = "\
275 Ctrl<Key>E: list_activate_action()\n\
276 Ctrl<Key>A: list_selectall_action()\n\
277 Ctrl<Key>U: list_unselectall_action()\n\
278 Ctrl<Key>I: list_invertselection_action()";
280 static void list_selectall(Widget list)
282 XtCallActionProc(list, "ListKbdSelectAll", NULL, NULL, 0);
285 static void list_unselectall(Widget list)
287 XmListDeselectAllItems(list);
290 static void list_invertselection(Widget list)
292 X11Stuff *xstuff = gapp->gui->xstuff;
293 int i, n;
294 unsigned char selection_type_save;
296 XtVaGetValues(list,
297 XmNselectionPolicy, &selection_type_save,
298 XmNitemCount, &n,
299 NULL);
300 if (selection_type_save == XmSINGLE_SELECT) {
301 XBell(xstuff->disp, 50);
302 return;
305 XtVaSetValues(list, XmNselectionPolicy, XmMULTIPLE_SELECT, NULL);
306 for (i = 0; i < n; i++) {
307 XmListSelectPos(list, i, False);
309 XtVaSetValues(list, XmNselectionPolicy, selection_type_save, NULL);
312 static int list_get_selected_count(Widget list)
314 int n;
315 #if XmVersion < 2000
316 int *selected;
317 if (XmListGetSelectedPos(list, &selected, &n) != True) {
318 n = 0;
319 } else {
320 XFree(selected);
322 #else
323 XtVaGetValues(list, XmNselectedPositionCount, &n, NULL);
324 #endif
325 return n;
328 static void list_activate_action(Widget w, XEvent *e, String *par, Cardinal *npar)
330 XtCallActionProc(w, "ListKbdActivate", NULL, NULL, 0);
333 static void list_selectall_action(Widget w, XEvent *e, String *par, Cardinal *npar)
335 list_selectall(w);
338 static void list_unselectall_action(Widget w, XEvent *e, String *par, Cardinal *npar)
340 list_unselectall(w);
343 static void list_invertselection_action(Widget w, XEvent *e, String *par,
344 Cardinal *npar)
346 list_invertselection(w);
349 ListStructure *CreateListChoice(Widget parent, char *labelstr, int type,
350 int nvisible, int nchoices, OptionItem *items)
352 Arg args[4];
353 Widget lab;
354 ListStructure *retval;
356 retval = xmalloc(sizeof(ListStructure));
357 retval->rc = XmCreateRowColumn(parent, "rcList", NULL, 0);
358 AddHelpCB(retval->rc, "doc/UsersGuide.html#list-selector");
360 lab = XmCreateLabel(retval->rc, labelstr, NULL, 0);
361 WidgetManage(lab);
363 XtSetArg(args[0], XmNlistSizePolicy, XmCONSTANT);
364 XtSetArg(args[1], XmNscrollBarDisplayPolicy, XmSTATIC);
365 if (type == LIST_TYPE_SINGLE) {
366 XtSetArg(args[2], XmNselectionPolicy, XmSINGLE_SELECT);
367 } else {
368 XtSetArg(args[2], XmNselectionPolicy, XmEXTENDED_SELECT);
370 XtSetArg(args[3], XmNvisibleItemCount, nvisible);
371 retval->list = XmCreateScrolledList(retval->rc, "listList", args, 4);
372 retval->values = NULL;
374 AddMouseWheelSupport(retval->list);
376 XtOverrideTranslations(retval->list,
377 XtParseTranslationTable(list_translation_table));
379 UpdateListChoice(retval, nchoices, items);
381 WidgetManage(retval->list);
383 WidgetManage(retval->rc);
385 return retval;
388 void UpdateListChoice(ListStructure *listp, int nchoices, OptionItem *items)
390 int i, nsel;
391 int *selvalues;
392 XmString str;
394 if (listp == NULL) {
395 return;
398 nsel = GetListChoices(listp, &selvalues);
400 listp->nchoices = nchoices;
401 listp->values = xrealloc(listp->values, nchoices*SIZEOF_INT);
402 for (i = 0; i < nchoices; i++) {
403 listp->values[i] = items[i].value;
406 XmListDeleteAllItems(listp->list);
407 for (i = 0; i < nchoices; i++) {
408 str = XmStringCreateLocalized(items[i].label);
409 XmListAddItemUnselected(listp->list, str, 0);
410 XmStringFree(str);
412 SelectListChoices(listp, nsel, selvalues);
413 if (nsel > 0) {
414 xfree(selvalues);
418 int SelectListChoice(ListStructure *listp, int choice)
420 int top, visible;
421 int i = 0;
423 while (i < listp->nchoices && listp->values[i] != choice) {
424 i++;
426 if (i < listp->nchoices) {
427 i++;
428 XmListDeselectAllItems(listp->list);
429 XmListSelectPos(listp->list, i, True);
430 XtVaGetValues(listp->list, XmNtopItemPosition, &top,
431 XmNvisibleItemCount, &visible,
432 NULL);
433 if (i < top) {
434 XmListSetPos(listp->list, i);
435 } else if (i >= top + visible) {
436 XmListSetBottomPos(listp->list, i);
439 return RETURN_SUCCESS;
440 } else {
441 return RETURN_FAILURE;
445 void SelectListChoices(ListStructure *listp, int nchoices, int *choices)
447 int i = 0, j;
448 unsigned char selection_type_save;
449 int bottom, visible;
451 XtVaGetValues(listp->list, XmNselectionPolicy, &selection_type_save, NULL);
452 XtVaSetValues(listp->list, XmNselectionPolicy, XmMULTIPLE_SELECT, NULL);
454 XmListDeselectAllItems(listp->list);
455 for (j = 0; j < nchoices; j++) {
456 i = 0;
457 while (i < listp->nchoices && listp->values[i] != choices[j]) {
458 i++;
460 if (i < listp->nchoices) {
461 i++;
462 XmListSelectPos(listp->list, i, True);
466 if (nchoices > 0) {
467 /* Rewind list so the last choice is always visible */
468 XtVaGetValues(listp->list, XmNtopItemPosition, &bottom,
469 XmNvisibleItemCount, &visible,
470 NULL);
471 if (i > bottom) {
472 XmListSetBottomPos(listp->list, i);
473 } else if (i <= bottom - visible) {
474 XmListSetPos(listp->list, i);
478 XtVaSetValues(listp->list, XmNselectionPolicy, selection_type_save, NULL);
481 int GetListChoices(ListStructure *listp, int **values)
483 int i, n;
485 if (XmListGetSelectedPos(listp->list, values, &n) != True) {
486 return 0;
489 for (i = 0; i < n; i++) {
490 (*values)[i] = listp->values[(*values)[i] - 1];
493 return n;
496 int GetSingleListChoice(ListStructure *listp, int *value)
498 int n, *values, retval;
500 n = GetListChoices(listp, &values);
501 if (n == 1) {
502 *value = values[0];
503 retval = RETURN_SUCCESS;
504 } else {
505 retval = RETURN_FAILURE;
507 if (n > 0) {
508 xfree(values);
510 return retval;
513 int GetListSelectedCount(ListStructure *listp)
515 int count;
516 XtVaGetValues(listp->list, XmNselectedItemCount, &count, NULL);
517 return count;
521 typedef struct {
522 ListStructure *listp;
523 List_CBProc cbproc;
524 void *anydata;
525 } List_CBdata;
527 static void list_int_cb_proc(Widget w, XtPointer client_data, XtPointer call_data)
529 int n, *values;
530 List_CBdata *cbdata = (List_CBdata *) client_data;
532 n = GetListChoices(cbdata->listp, &values);
534 cbdata->cbproc(cbdata->listp, n, values, cbdata->anydata);
536 if (n > 0) {
537 xfree(values);
541 void AddListChoiceCB(ListStructure *listp, List_CBProc cbproc, void *anydata)
543 List_CBdata *cbdata;
545 cbdata = xmalloc(sizeof(List_CBdata));
546 cbdata->listp = listp;
547 cbdata->cbproc = (List_CBProc) cbproc;
548 cbdata->anydata = anydata;
549 XtAddCallback(listp->list,
550 XmNsingleSelectionCallback, list_int_cb_proc, (XtPointer) cbdata);
551 XtAddCallback(listp->list,
552 XmNmultipleSelectionCallback, list_int_cb_proc, (XtPointer) cbdata);
553 XtAddCallback(listp->list,
554 XmNextendedSelectionCallback, list_int_cb_proc, (XtPointer) cbdata);
559 #define SS_HIDE_CB 0
560 #define SS_SHOW_CB 1
561 #define SS_DELETE_CB 2
562 #define SS_DUPLICATE_CB 3
563 #define SS_BRING_TO_FRONT_CB 4
564 #define SS_SEND_TO_BACK_CB 5
565 #define SS_MOVE_UP_CB 6
566 #define SS_MOVE_DOWN_CB 7
568 static char *default_storage_labeling_proc(Quark *q, unsigned int *rid)
570 char *buf;
572 if (!q) {
573 return NULL;
576 buf = (char *) xmalloc(strlen(QIDSTR(q)) + 128);
577 if (!buf) {
578 return NULL;
581 sprintf(buf, "Quark \"%s\"", QIDSTR(q));
583 (*rid)++;
585 return buf;
588 typedef struct {
589 StorageStructure *ss;
590 unsigned int rid;
591 } storage_traverse_data;
593 static int traverse_hook(Quark *q, void *udata, QTraverseClosure *closure)
595 char *s;
596 storage_traverse_data *stdata = (storage_traverse_data *) udata;
597 StorageStructure *ss = stdata->ss;
599 s = ss->labeling_proc(q, &stdata->rid);
600 if (s) {
601 char buf[16], *sbuf;
602 XmString str;
604 ss->values = xrealloc(ss->values, SIZEOF_VOID_P*(ss->nchoices + 1));
605 ss->values[ss->nchoices++] = q;
607 sprintf(buf, "(%c) ", quark_is_active(q) ? '+':'-');
608 sbuf = copy_string(NULL, buf);
609 sbuf = concat_strings(sbuf, s);
610 xfree(s);
612 str = XmStringCreateLocalized(sbuf);
613 xfree(sbuf);
615 XmListAddItemUnselected(ss->list, str, 0);
616 XmStringFree(str);
619 return TRUE;
622 static void storage_popup(Widget parent,
623 XtPointer closure, XEvent *event, Boolean *cont)
625 XButtonPressedEvent *e = (XButtonPressedEvent *) event;
626 StorageStructure *ss = (StorageStructure *) closure;
627 Widget popup = ss->popup;
628 int n, selected;
630 if (e->button != 3) {
631 return;
634 /* don't post menu if governor selection isn't single */
635 if (ss->governor && list_get_selected_count(ss->governor->list) != 1) {
636 return;
639 n = list_get_selected_count(ss->list);
641 if (n != 0) {
642 selected = TRUE;
643 } else {
644 selected = FALSE;
647 WidgetSetSensitive(ss->popup_hide_bt, selected);
648 WidgetSetSensitive(ss->popup_show_bt, selected);
649 WidgetSetSensitive(ss->popup_delete_bt, selected);
650 WidgetSetSensitive(ss->popup_duplicate_bt, selected);
651 WidgetSetSensitive(ss->popup_bring_to_front_bt, selected);
652 WidgetSetSensitive(ss->popup_send_to_back_bt, selected);
653 WidgetSetSensitive(ss->popup_move_up_bt, selected);
654 WidgetSetSensitive(ss->popup_move_down_bt, selected);
656 WidgetSetSensitive(ss->popup_properties_bt, n == 1);
658 if (ss->popup_cb) {
659 ss->popup_cb(ss, n);
662 XmMenuPosition(popup, e);
663 WidgetManage(popup);
666 static void ss_any_cb(StorageStructure *ss, int type)
668 int i, n;
669 Quark **values;
671 n = GetStorageChoices(ss, &values);
673 for (i = 0; i < n; i ++) {
674 Quark *q;
676 switch (type) {
677 case SS_SEND_TO_BACK_CB:
678 case SS_MOVE_UP_CB:
679 q = values[n - i - 1];
680 break;
681 default:
682 q = values[i];
683 break;
686 switch (type) {
687 case SS_HIDE_CB:
688 quark_set_active(q, FALSE);
689 break;
690 case SS_SHOW_CB:
691 quark_set_active(q, TRUE);
692 break;
693 case SS_DELETE_CB:
694 quark_free(q);
695 break;
696 case SS_BRING_TO_FRONT_CB:
697 quark_push(q, TRUE);
698 break;
699 case SS_SEND_TO_BACK_CB:
700 quark_push(q, FALSE);
701 break;
702 case SS_MOVE_UP_CB:
703 quark_move(q, TRUE);
704 break;
705 case SS_MOVE_DOWN_CB:
706 quark_move(q, FALSE);
707 break;
708 case SS_DUPLICATE_CB:
709 quark_copy(q);
710 break;
714 if (n > 0) {
715 xfree(values);
716 snapshot_and_update(gapp->gp, TRUE);
720 static void ss_hide_cb(Widget but, void *udata)
722 ss_any_cb((StorageStructure *) udata, SS_HIDE_CB);
725 static void ss_show_cb(Widget but, void *udata)
727 ss_any_cb((StorageStructure *) udata, SS_SHOW_CB);
730 static void ss_delete_cb(Widget but, void *udata)
732 if (yesno("Really delete selected item(s)?", NULL, NULL, NULL)) {
733 ss_any_cb((StorageStructure *) udata, SS_DELETE_CB);
737 static void ss_duplicate_cb(Widget but, void *udata)
739 ss_any_cb((StorageStructure *) udata, SS_DUPLICATE_CB);
742 static void ss_bring_to_front_cb(Widget but, void *udata)
744 ss_any_cb((StorageStructure *) udata, SS_BRING_TO_FRONT_CB);
747 static void ss_send_to_back_cb(Widget but, void *udata)
749 ss_any_cb((StorageStructure *) udata, SS_SEND_TO_BACK_CB);
752 static void ss_move_up_cb(Widget but, void *udata)
754 ss_any_cb((StorageStructure *) udata, SS_MOVE_UP_CB);
757 static void ss_move_down_cb(Widget but, void *udata)
759 ss_any_cb((StorageStructure *) udata, SS_MOVE_DOWN_CB);
762 static void ss_properties_cb(Widget but, void *udata)
764 StorageStructure *ss = (StorageStructure *) udata;
765 Quark *q;
767 if (GetSingleStorageChoice(ss, &q) == RETURN_SUCCESS) {
768 raise_explorer(gapp->gui, q);
772 static void ss_select_all_cb(Widget but, void *udata)
774 list_selectall(((StorageStructure *) udata)->list);
777 static void ss_unselect_all_cb(Widget but, void *udata)
779 list_unselectall(((StorageStructure *) udata)->list);
782 static void ss_invert_selection_cb(Widget but, void *udata)
784 list_invertselection(((StorageStructure *) udata)->list);
787 static void ss_update_cb(Widget but, void *udata)
789 StorageStructure *ss = (StorageStructure *) udata;
791 UpdateStorageChoice(ss);
794 static void s_dc_cb(StorageStructure *ss, Quark *q, void *data)
796 raise_explorer(gapp->gui, q);
799 static void CreateStorageChoicePopup(StorageStructure *ss)
801 Widget popup, submenupane;
803 popup = XmCreatePopupMenu(ss->list, "popupMenu", NULL, 0);
804 ss->popup = popup;
805 #if XmVersion >= 2000
806 XtVaSetValues(popup, XmNpopupEnabled, XmPOPUP_DISABLED, NULL);
807 #else
808 XtVaSetValues(popup, XmNpopupEnabled, False, NULL);
809 #endif
811 ss->popup_properties_bt =
812 CreateMenuButton(popup, "Properties...", '\0', ss_properties_cb, ss);
814 CreateMenuSeparator(popup);
816 ss->popup_hide_bt = CreateMenuButton(popup, "Hide", '\0', ss_hide_cb, ss);
817 ss->popup_show_bt = CreateMenuButton(popup, "Show", '\0', ss_show_cb, ss);
818 CreateMenuSeparator(popup);
820 ss->popup_delete_bt =
821 CreateMenuButton(popup, "Delete", '\0', ss_delete_cb, ss);
822 ss->popup_duplicate_bt =
823 CreateMenuButton(popup, "Duplicate", '\0', ss_duplicate_cb, ss);
825 CreateMenuSeparator(popup);
827 ss->popup_bring_to_front_bt = CreateMenuButton(popup,
828 "Bring to front", '\0', ss_bring_to_front_cb, ss);
829 ss->popup_move_up_bt =
830 CreateMenuButton(popup, "Move up", '\0', ss_move_up_cb, ss);
831 ss->popup_move_down_bt =
832 CreateMenuButton(popup, "Move down", '\0', ss_move_down_cb, ss);
833 ss->popup_send_to_back_bt =
834 CreateMenuButton(popup, "Send to back", '\0', ss_send_to_back_cb, ss);
836 CreateMenuSeparator(popup);
838 submenupane = CreateMenu(popup, "Selector operations", 'o', FALSE);
839 ss->selpopup = submenupane;
841 ss->popup_select_all_bt =
842 CreateMenuButton(submenupane, "Select all", '\0', ss_select_all_cb, ss);
843 ss->popup_unselect_all_bt =
844 CreateMenuButton(submenupane, "Unselect all", '\0', ss_unselect_all_cb, ss);
845 ss->popup_invert_selection_bt = CreateMenuButton(submenupane,
846 "Invert selection", '\0', ss_invert_selection_cb, ss);
848 CreateMenuSeparator(submenupane);
850 CreateMenuButton(submenupane, "Update list", '\0', ss_update_cb, ss);
852 AddStorageChoiceDblClickCB(ss, s_dc_cb, NULL);
855 StorageStructure *CreateStorageChoice(Widget parent,
856 char *labelstr, int type, int nvisible)
858 Arg args[4];
859 Widget lab;
860 StorageStructure *retval;
862 retval = xmalloc(sizeof(StorageStructure));
863 memset(retval, 0, sizeof(StorageStructure));
865 retval->labeling_proc = default_storage_labeling_proc;
866 retval->rc = XmCreateRowColumn(parent, "rc", NULL, 0);
867 AddHelpCB(retval->rc, "doc/UsersGuide.html#list-selector");
869 lab = XmCreateLabel(retval->rc, labelstr, NULL, 0);
870 WidgetManage(lab);
872 XtSetArg(args[0], XmNlistSizePolicy, XmCONSTANT);
873 XtSetArg(args[1], XmNscrollBarDisplayPolicy, XmSTATIC);
874 if (type == LIST_TYPE_SINGLE) {
875 XtSetArg(args[2], XmNselectionPolicy, XmSINGLE_SELECT);
876 } else {
877 XtSetArg(args[2], XmNselectionPolicy, XmEXTENDED_SELECT);
879 XtSetArg(args[3], XmNvisibleItemCount, nvisible);
880 retval->list = XmCreateScrolledList(retval->rc, "list", args, 4);
881 retval->values = NULL;
883 AddMouseWheelSupport(retval->list);
885 CreateStorageChoicePopup(retval);
886 XtAddEventHandler(retval->list,
887 ButtonPressMask, False, storage_popup, retval);
889 XtOverrideTranslations(retval->list,
890 XtParseTranslationTable(list_translation_table));
892 WidgetManage(retval->list);
894 WidgetManage(retval->rc);
896 return retval;
899 void SetStorageChoiceLabeling(StorageStructure *ss, Storage_LabelingProc proc)
901 ss->labeling_proc = proc;
904 int GetStorageSelectedCount(StorageStructure *ss)
906 int count;
907 XtVaGetValues(ss->list, XmNselectedItemCount, &count, NULL);
908 return count;
911 int GetStorageChoices(StorageStructure *ss, Quark ***values)
913 int i, n;
914 int *selected;
916 if (XmListGetSelectedPos(ss->list, &selected, &n) != True) {
917 return 0;
920 *values = xmalloc(n*SIZEOF_VOID_P);
921 for (i = 0; i < n; i++) {
922 (*values)[i] = ss->values[selected[i] - 1];
925 if (n) {
926 XtFree((char *) selected);
929 return n;
932 int GetSingleStorageChoice(StorageStructure *ss, Quark **value)
934 int n, retval;
935 Quark **values;
937 n = GetStorageChoices(ss, &values);
938 if (n == 1) {
939 *value = values[0];
940 retval = RETURN_SUCCESS;
941 } else {
942 retval = RETURN_FAILURE;
945 if (n) {
946 xfree(values);
949 return retval;
953 int SelectStorageChoices(StorageStructure *ss, int nchoices, Quark **choices)
955 int i = 0, j;
956 unsigned char selection_type_save;
957 int bottom, visible;
959 XtVaGetValues(ss->list, XmNselectionPolicy, &selection_type_save, NULL);
960 XtVaSetValues(ss->list, XmNselectionPolicy, XmMULTIPLE_SELECT, NULL);
962 XmListDeselectAllItems(ss->list);
963 for (j = 0; j < nchoices; j++) {
964 i = 0;
965 while (i < ss->nchoices && ss->values[i] != choices[j]) {
966 i++;
968 if (i < ss->nchoices) {
969 i++;
970 XmListSelectPos(ss->list, i, True);
974 if (nchoices > 0) {
975 /* Rewind list so the last choice is always visible */
976 XtVaGetValues(ss->list, XmNtopItemPosition, &bottom,
977 XmNvisibleItemCount, &visible,
978 NULL);
979 if (i > bottom) {
980 XmListSetBottomPos(ss->list, i);
981 } else if (i <= bottom - visible) {
982 XmListSetPos(ss->list, i);
986 XtVaSetValues(ss->list, XmNselectionPolicy, selection_type_save, NULL);
988 return RETURN_SUCCESS;
991 int SelectStorageChoice(StorageStructure *ss, Quark *choice)
993 return SelectStorageChoices(ss, 1, &choice);
996 void UpdateStorageChoice(StorageStructure *ss)
998 Quark **selvalues;
999 storage_traverse_data stdata;
1000 int nsel;
1002 nsel = GetStorageChoices(ss, &selvalues);
1004 XmListDeleteAllItems(ss->list);
1006 ss->nchoices = 0;
1007 stdata.rid = 0;
1008 stdata.ss = ss;
1009 if (ss->q) {
1010 quark_traverse(ss->q, traverse_hook, &stdata);
1012 SelectStorageChoices(ss, nsel, selvalues);
1015 if (nsel > 0) {
1016 xfree(selvalues);
1019 nsel = GetStorageSelectedCount(ss);
1020 if (!nsel && XtHasCallbacks(ss->list, XmNsingleSelectionCallback) ==
1021 XtCallbackHasSome) {
1022 /* invoke callbacks to make any dependent GUI control to sync */
1023 XtCallCallbacks(ss->list, XmNsingleSelectionCallback, NULL);
1027 void SetStorageChoiceQuark(StorageStructure *ss, Quark *q)
1029 ss->q = q;
1030 UpdateStorageChoice(ss);
1034 typedef struct {
1035 StorageStructure *ss;
1036 Storage_CBProc cbproc;
1037 void *anydata;
1038 } Storage_CBdata;
1040 typedef struct {
1041 StorageStructure *ss;
1042 Storage_DCCBProc cbproc;
1043 void *anydata;
1044 } Storage_DCCBdata;
1046 static void storage_int_cb_proc(Widget w,
1047 XtPointer client_data, XtPointer call_data)
1049 int n;
1050 Quark **values;
1051 Storage_CBdata *cbdata = (Storage_CBdata *) client_data;
1053 n = GetStorageChoices(cbdata->ss, &values);
1055 cbdata->cbproc(cbdata->ss, n, values, cbdata->anydata);
1057 if (n > 0) {
1058 xfree(values);
1062 void AddStorageChoiceCB(StorageStructure *ss,
1063 Storage_CBProc cbproc, void *anydata)
1065 Storage_CBdata *cbdata;
1067 cbdata = xmalloc(sizeof(Storage_CBdata));
1068 cbdata->ss = ss;
1069 cbdata->cbproc = cbproc;
1070 cbdata->anydata = anydata;
1071 XtAddCallback(ss->list,
1072 XmNsingleSelectionCallback, storage_int_cb_proc, (XtPointer) cbdata);
1073 XtAddCallback(ss->list,
1074 XmNmultipleSelectionCallback, storage_int_cb_proc, (XtPointer) cbdata);
1075 XtAddCallback(ss->list,
1076 XmNextendedSelectionCallback, storage_int_cb_proc, (XtPointer) cbdata);
1079 static void storage_int_dc_cb_proc(Widget w,
1080 XtPointer client_data, XtPointer call_data)
1082 void *value;
1083 XmListCallbackStruct *cbs = (XmListCallbackStruct *) call_data;
1084 Storage_DCCBdata *cbdata = (Storage_DCCBdata *) client_data;
1086 value = cbdata->ss->values[cbs->item_position - 1];
1088 cbdata->cbproc(cbdata->ss, value, cbdata->anydata);
1091 void AddStorageChoiceDblClickCB(StorageStructure *ss,
1092 Storage_DCCBProc cbproc, void *anydata)
1094 Storage_DCCBdata *cbdata;
1096 cbdata = xmalloc(sizeof(Storage_DCCBdata));
1097 cbdata->ss = ss;
1098 cbdata->cbproc = cbproc;
1099 cbdata->anydata = anydata;
1100 XtAddCallback(ss->list,
1101 XmNdefaultActionCallback, storage_int_dc_cb_proc, (XtPointer) cbdata);
1107 * same for AddButtonCB
1109 void destroy_dialog_cb(Widget but, void *data)
1111 DialogClose(data);
1114 static OptionItem *settype_option_items;
1115 static OptionItem *fmt_option_items;
1116 static OptionItem *frametype_option_items;
1117 static BitmapOptionItem *pattern_option_items;
1118 static BitmapOptionItem *lines_option_items;
1120 #define LINES_BM_HEIGHT 15
1121 #define LINES_BM_WIDTH 64
1123 static void init_xvlibcolors(void)
1125 X11Stuff *xstuff = gapp->gui->xstuff;
1126 Project *pr = project_get_data(gproject_get_top(gapp->gp));
1127 unsigned int i;
1129 if (!pr) {
1130 return;
1133 xvlibcolors = xrealloc(xvlibcolors, pr->ncolors*sizeof(unsigned long));
1134 if (!xvlibcolors) {
1135 return;
1138 for (i = 0; i < pr->ncolors; i++) {
1139 long pixel;
1140 Colordef *c = &pr->colormap[i];
1142 pixel = x11_allocate_color(gapp->gui, &c->rgb);
1144 if (pixel >= 0) {
1145 xvlibcolors[c->id] = pixel;
1146 } else {
1147 xvlibcolors[c->id] = BlackPixel(xstuff->disp, xstuff->screennumber);
1152 int init_option_menus(void) {
1153 unsigned int i, j, k, l, n;
1155 init_xvlibcolors();
1157 n = number_of_patterns(canvas);
1158 if (n) {
1159 pattern_option_items = xmalloc(n*sizeof(BitmapOptionItem));
1160 if (pattern_option_items == NULL) {
1161 errmsg("Malloc error in init_option_menus()");
1162 return RETURN_FAILURE;
1164 for (i = 0; i < n; i++) {
1165 pattern_option_items[i].value = i;
1166 if (i == 0) {
1167 pattern_option_items[i].bitmap = NULL;
1168 } else {
1169 Pattern *pat = canvas_get_pattern(canvas, i);
1170 pattern_option_items[i].bitmap = pat->bits;
1175 n = number_of_linestyles(canvas);
1176 if (n) {
1177 lines_option_items = xmalloc(n*sizeof(BitmapOptionItem));
1178 if (lines_option_items == NULL) {
1179 errmsg("Malloc error in init_option_menus()");
1180 xfree(pattern_option_items);
1181 return RETURN_FAILURE;
1183 for (i = 0; i < n; i++) {
1184 LineStyle *linestyle = canvas_get_linestyle(canvas, i);
1185 lines_option_items[i].value = i;
1186 if (i == 0) {
1187 lines_option_items[i].bitmap = NULL;
1188 continue;
1191 lines_option_items[i].bitmap =
1192 xcalloc(LINES_BM_HEIGHT*LINES_BM_WIDTH/8/SIZEOF_CHAR, SIZEOF_CHAR);
1194 k = LINES_BM_WIDTH*(LINES_BM_HEIGHT/2);
1195 while (k < LINES_BM_WIDTH*(LINES_BM_HEIGHT/2 + 1)) {
1196 for (j = 0; j < linestyle->length; j++) {
1197 for (l = 0; l < linestyle->array[j]; l++) {
1198 if (k < LINES_BM_WIDTH*(LINES_BM_HEIGHT/2 + 1)) {
1199 if (j % 2 == 0) {
1200 /* black */
1201 lines_option_items[i].bitmap[k/8] |= 1 << k % 8;
1203 k++;
1211 settype_option_items = xmalloc(NUMBER_OF_SETTYPES*sizeof(OptionItem));
1212 if (settype_option_items == NULL) {
1213 errmsg("Malloc error in init_option_menus()");
1214 return RETURN_FAILURE;
1216 for (i = 0; i < NUMBER_OF_SETTYPES; i++) {
1217 settype_option_items[i].value = i;
1218 settype_option_items[i].label = copy_string(NULL,
1219 set_type_descr(gapp->grace, i));
1222 fmt_option_items = xmalloc(NUMBER_OF_FORMATTYPES*sizeof(OptionItem));
1223 if (fmt_option_items == NULL) {
1224 errmsg("Malloc error in init_option_menus()");
1225 return RETURN_FAILURE;
1227 for (i = 0; i < NUMBER_OF_FORMATTYPES; i++) {
1228 fmt_option_items[i].value = i;
1229 fmt_option_items[i].label = copy_string(NULL,
1230 format_type_descr(gapp->grace, i));
1233 frametype_option_items = xmalloc(NUMBER_OF_FRAMETYPES*sizeof(OptionItem));
1234 if (frametype_option_items == NULL) {
1235 errmsg("Malloc error in init_option_menus()");
1236 return RETURN_FAILURE;
1238 for (i = 0; i < NUMBER_OF_FRAMETYPES; i++) {
1239 frametype_option_items[i].value = i;
1240 frametype_option_items[i].label = copy_string(NULL,
1241 frame_type_descr(gapp->grace, i));
1244 return RETURN_SUCCESS;
1247 static OptionItem *font_option_items = NULL;
1248 static unsigned int nfont_option_items = 0;
1249 static OptionStructure **font_selectors = NULL;
1250 static unsigned int nfont_selectors = 0;
1252 void update_font_selectors(void)
1254 unsigned int i;
1255 Project *pr = project_get_data(gproject_get_top(gapp->gp));
1257 nfont_option_items = pr->nfonts;
1258 font_option_items =
1259 xrealloc(font_option_items, nfont_option_items*sizeof(OptionItem));
1261 for (i = 0; i < nfont_option_items; i++) {
1262 Fontdef *f = &pr->fontmap[i];
1263 font_option_items[i].value = f->id;
1264 font_option_items[i].label = f->fontname;
1267 for (i = 0; i < nfont_selectors; i++) {
1268 UpdateOptionChoice(font_selectors[i],
1269 nfont_option_items, font_option_items);
1273 OptionStructure *CreateFontChoice(Widget parent, char *s)
1275 OptionStructure *retvalp = NULL;
1277 nfont_selectors++;
1278 font_selectors = xrealloc(font_selectors,
1279 nfont_selectors*sizeof(OptionStructure *));
1280 if (font_selectors == NULL) {
1281 errmsg("Malloc failed in CreateFontChoice()");
1282 return retvalp;
1285 retvalp = CreateOptionChoice(parent, s, 0,
1286 nfont_option_items, font_option_items);
1288 font_selectors[nfont_selectors - 1] = retvalp;
1290 return retvalp;
1293 OptionStructure *CreatePatternChoice(Widget parent, char *s)
1295 return (CreateBitmapOptionChoice(parent, s, 4, number_of_patterns(canvas),
1296 16, 16, pattern_option_items));
1299 OptionStructure *CreateLineStyleChoice(Widget parent, char *s)
1301 return (CreateBitmapOptionChoice(parent, s, 0, number_of_linestyles(canvas),
1302 LINES_BM_WIDTH, LINES_BM_HEIGHT, lines_option_items));
1305 OptionStructure *CreateSetTypeChoice(Widget parent, char *s)
1307 return (CreateOptionChoice(parent,
1308 s, 0, NUMBER_OF_SETTYPES, settype_option_items));
1311 OptionStructure *CreateFrameTypeChoice(Widget parent, char *s)
1313 return (CreateOptionChoice(parent,
1314 s, 0, NUMBER_OF_FRAMETYPES, frametype_option_items));
1317 static BitmapOptionItem text_just_option_items[12] =
1319 {JUST_LEFT |JUST_BLINE , j_lm_o_bits},
1320 {JUST_CENTER|JUST_BLINE , j_cm_o_bits},
1321 {JUST_RIGHT |JUST_BLINE , j_rm_o_bits},
1322 {JUST_LEFT |JUST_BOTTOM, j_lb_b_bits},
1323 {JUST_CENTER|JUST_BOTTOM, j_cb_b_bits},
1324 {JUST_RIGHT |JUST_BOTTOM, j_rb_b_bits},
1325 {JUST_LEFT |JUST_MIDDLE, j_lm_b_bits},
1326 {JUST_CENTER|JUST_MIDDLE, j_cm_b_bits},
1327 {JUST_RIGHT |JUST_MIDDLE, j_rm_b_bits},
1328 {JUST_LEFT |JUST_TOP , j_lt_b_bits},
1329 {JUST_CENTER|JUST_TOP , j_ct_b_bits},
1330 {JUST_RIGHT |JUST_TOP , j_rt_b_bits}
1333 OptionStructure *CreateTextJustChoice(Widget parent, char *s)
1335 return (CreateBitmapOptionChoice(parent, s, 4,
1336 12, JBITMAP_WIDTH, JBITMAP_HEIGHT, text_just_option_items));
1339 static BitmapOptionItem just_option_items[9] =
1341 {JUST_LEFT |JUST_BOTTOM, j_lb_b_bits},
1342 {JUST_CENTER|JUST_BOTTOM, j_cb_b_bits},
1343 {JUST_RIGHT |JUST_BOTTOM, j_rb_b_bits},
1344 {JUST_LEFT |JUST_MIDDLE, j_lm_b_bits},
1345 {JUST_CENTER|JUST_MIDDLE, j_cm_b_bits},
1346 {JUST_RIGHT |JUST_MIDDLE, j_rm_b_bits},
1347 {JUST_LEFT |JUST_TOP , j_lt_b_bits},
1348 {JUST_CENTER|JUST_TOP , j_ct_b_bits},
1349 {JUST_RIGHT |JUST_TOP , j_rt_b_bits}
1352 OptionStructure *CreateJustChoice(Widget parent, char *s)
1354 return (CreateBitmapOptionChoice(parent, s, 3,
1355 9, JBITMAP_WIDTH, JBITMAP_HEIGHT, just_option_items));
1358 RestrictionStructure *CreateRestrictionChoice(Widget parent, char *s)
1360 RestrictionStructure *retval;
1361 Widget rc;
1362 OptionItem restr_items[7];
1364 restr_items[0].value = RESTRICT_NONE;
1365 restr_items[0].label = "None";
1366 restr_items[1].value = RESTRICT_REG0;
1367 restr_items[1].label = "Region 0";
1368 restr_items[2].value = RESTRICT_REG1;
1369 restr_items[2].label = "Region 1";
1370 restr_items[3].value = RESTRICT_REG2;
1371 restr_items[3].label = "Region 2";
1372 restr_items[4].value = RESTRICT_REG3;
1373 restr_items[4].label = "Region 3";
1374 restr_items[5].value = RESTRICT_REG4;
1375 restr_items[5].label = "Region 4";
1376 restr_items[6].value = RESTRICT_WORLD;
1377 restr_items[6].label = "Inside graph";
1379 retval = xmalloc(sizeof(RestrictionStructure));
1381 retval->frame = CreateFrame(parent, s);
1382 rc = XtVaCreateWidget("rc",
1383 xmRowColumnWidgetClass, retval->frame,
1384 XmNorientation, XmHORIZONTAL,
1385 NULL);
1387 retval->r_sel = CreateOptionChoice(rc,
1388 "Restriction:", 1, 7, restr_items);
1389 retval->negate = CreateToggleButton(rc, "Negated");
1390 WidgetManage(rc);
1392 return retval;
1395 #define PEN_CHOICE_WIDTH 64
1396 #define PEN_CHOICE_HEIGHT 16
1398 typedef struct {
1399 Pen pen;
1400 Widget color_popup;
1401 Widget pattern_popup;
1403 Pen_CBProc cb_proc;
1404 void *cb_data;
1405 } Button_PData;
1407 static GC gc_pen;
1409 static void SetPenChoice_int(Widget button, Pen *pen, int call_cb)
1411 X11Stuff *xstuff = gapp->gui->xstuff;
1412 Pixel bg, fg;
1413 Pixmap pixtile, pixmap;
1414 Button_PData *pdata;
1415 Pattern *pat;
1417 /* Safety checks */
1418 if (!button || !pen ||
1419 (pen->pattern < 0 || pen->pattern >= number_of_patterns(canvas)) ||
1420 (pen->color < 0 || pen->color >= number_of_colors(canvas))) {
1421 return;
1424 pdata = WidgetGetUserData(button);
1425 pdata->pen = *pen;
1427 if (!gc_pen) {
1428 gc_pen = XCreateGC(xstuff->disp, xstuff->root, 0, NULL);
1429 XSetFillStyle(xstuff->disp, gc_pen, FillTiled);
1432 fg = xvlibcolors[pen->color];
1433 bg = xvlibcolors[getbgcolor(canvas)];
1435 pat = canvas_get_pattern(canvas, pen->pattern);
1436 pixtile = XCreatePixmapFromBitmapData(xstuff->disp, xstuff->root,
1437 (char *) pat->bits, pat->width, pat->height, fg, bg, xstuff->depth);
1439 XSetTile(xstuff->disp, gc_pen, pixtile);
1441 pixmap = XCreatePixmap(xstuff->disp, xstuff->root, PEN_CHOICE_WIDTH, PEN_CHOICE_HEIGHT, xstuff->depth);
1442 XFillRectangle(xstuff->disp, pixmap, gc_pen, 0, 0, PEN_CHOICE_WIDTH, PEN_CHOICE_HEIGHT);
1444 XtVaSetValues(button, XmNlabelPixmap, pixmap, NULL);
1446 XFreePixmap(xstuff->disp, pixtile);
1448 if (call_cb && pdata->cb_proc) {
1449 pdata->cb_proc(button, pen, pdata->cb_data);
1453 void SetPenChoice(Widget button, Pen *pen)
1455 SetPenChoice_int(button, pen, FALSE);
1458 static void pen_popup(Widget parent,
1459 XtPointer closure, XEvent *event, Boolean *cont)
1461 XButtonPressedEvent *e = (XButtonPressedEvent *) event;
1462 Button_PData *pdata;
1463 Widget popup;
1465 if (e->button != 3) {
1466 return;
1469 pdata = WidgetGetUserData(parent);
1471 if (e->state & ShiftMask) {
1472 popup = pdata->pattern_popup;
1473 } else {
1474 popup = pdata->color_popup;
1477 WidgetSetUserData(popup, parent);
1479 XmMenuPosition(popup, e);
1480 WidgetManage(popup);
1483 static void cc_cb(Widget w, XtPointer client_data, XtPointer call_data)
1485 Pen pen;
1486 Widget button = WidgetGetUserData(XtParent(w));
1487 Button_PData *pdata;
1489 pdata = WidgetGetUserData(button);
1490 pen = pdata->pen;
1491 pen.color = (long) client_data;
1493 SetPenChoice_int(button, &pen, TRUE);
1495 #define MAX_PULLDOWN_LENGTH 30
1496 void update_color_choice_popup(void)
1498 X11Stuff *xstuff = gapp->gui->xstuff;
1499 Project *pr = project_get_data(gproject_get_top(gapp->gp));
1500 unsigned int ci;
1502 if (pr && color_choice_popup) {
1503 int ncols = 4;
1504 Widget *ws = NULL;
1505 Cardinal nw_old = 0, nw_new = pr->ncolors;
1507 XtVaGetValues(color_choice_popup,
1508 XtNnumChildren, &nw_old,
1509 XtNchildren, &ws,
1510 NULL);
1512 /* Delete extra button widgets, if any */
1513 if (nw_new < nw_old) {
1514 XtUnmanageChildren(ws + nw_new, nw_old - nw_new);
1516 for (ci = nw_new; ci < nw_old; ci++) {
1517 XtDestroyWidget(ws[ci]);
1521 /* Don't create too tall pulldowns */
1522 if (nw_new > MAX_PULLDOWN_LENGTH*ncols) {
1523 ncols = (nw_new + MAX_PULLDOWN_LENGTH - 1)/MAX_PULLDOWN_LENGTH;
1526 XtVaSetValues(color_choice_popup,
1527 XmNnumColumns, ncols,
1528 XmNpacking, XmPACK_COLUMN,
1529 NULL);
1531 /* Create new buttons, if needed */
1532 for (ci = nw_old; ci < nw_new; ci++) {
1533 Widget cb;
1534 cb = XmCreatePushButton(color_choice_popup, "cb", NULL, 0);
1537 XtVaGetValues(color_choice_popup,
1538 XtNchildren, &ws,
1539 NULL);
1541 /* Manage newly added widgets */
1542 if (nw_new > nw_old) {
1543 XtManageChildren(ws + nw_old, nw_new - nw_old);
1546 /* Paint/label new buttons */
1547 for (ci = 0; ci < pr->ncolors; ci++) {
1548 Colordef *c = &pr->colormap[ci];
1549 long bg, fg;
1550 long color = c->id;
1551 Widget cb = ws[ci];
1552 XmString str;
1554 bg = xvlibcolors[color];
1555 if (get_rgb_intensity(&c->rgb) < 0.5) {
1556 fg = WhitePixel(xstuff->disp, xstuff->screennumber);
1557 } else {
1558 fg = BlackPixel(xstuff->disp, xstuff->screennumber);
1561 XtRemoveAllCallbacks(cb, XmNactivateCallback);
1562 XtAddCallback(cb, XmNactivateCallback, cc_cb, (XtPointer) color);
1564 str = XmStringCreateLocalized(c->cname);
1565 XtVaSetValues(cb,
1566 XmNlabelString, str,
1567 XmNbackground, bg,
1568 XmNforeground, fg,
1569 NULL);
1570 XmStringFree(str);
1575 static Widget CreateColorChoicePopup(Widget button)
1577 if (!color_choice_popup) {
1578 color_choice_popup =
1579 XmCreatePopupMenu(button, "colorPopupMenu", NULL, 0);
1580 update_color_choice_popup();
1581 } else {
1582 XmAddToPostFromList(color_choice_popup, button);
1585 return color_choice_popup;
1588 static Widget CreatePatternChoicePopup(Widget button)
1590 Widget popup;
1592 popup = XmCreatePopupMenu(button, "patternPopupMenu", NULL, 0);
1593 CreateLabel(popup, "Pattern:");
1594 CreateMenuSeparator(popup);
1596 return popup;
1599 typedef struct {
1600 Widget top;
1601 OptionStructure *color;
1602 OptionStructure *pattern;
1604 Widget pen_button;
1605 } PenChoiceDialog;
1607 static int pen_choice_aac(void *data)
1609 PenChoiceDialog *ui = (PenChoiceDialog *) data;
1611 if (ui->pen_button) {
1612 Pen pen;
1613 pen.color = GetOptionChoice(ui->color);
1614 pen.pattern = GetOptionChoice(ui->pattern);
1616 SetPenChoice_int(ui->pen_button, &pen, TRUE);
1619 return RETURN_SUCCESS;
1622 static void define_pen_choice_dialog(Widget but, void *data)
1624 static PenChoiceDialog *ui = NULL;
1626 set_wait_cursor();
1628 if (!ui) {
1629 Widget fr, rc;
1631 ui = xmalloc(sizeof(PenChoiceDialog));
1633 ui->top = CreateDialog(app_shell, "Pen properties");
1635 fr = CreateFrame(ui->top, "Pen");
1636 rc = CreateVContainer(fr);
1637 ui->color = CreateColorChoice(rc, "Color");
1638 ui->pattern = CreatePatternChoice(rc, "Pattern");
1640 CreateAACDialog(ui->top, fr, pen_choice_aac, ui);
1643 ui->pen_button = (Widget) data;
1645 if (ui->pen_button) {
1646 Button_PData *pdata;
1647 Pen pen;
1649 pdata = WidgetGetUserData(ui->pen_button);
1651 pen = pdata->pen;
1653 SetOptionChoice(ui->color, pen.color);
1654 SetOptionChoice(ui->pattern, pen.pattern);
1657 DialogRaise(ui->top);
1658 unset_wait_cursor();
1661 Widget CreatePenChoice(Widget parent, char *s)
1663 Widget rc, button;
1664 Button_PData *pdata;
1665 Pen pen;
1667 pdata = xmalloc(sizeof(Button_PData));
1668 memset(pdata, 0, sizeof(Button_PData));
1670 rc = CreateHContainer(parent);
1671 CreateLabel(rc, s);
1672 button = XtVaCreateWidget("penButton",
1673 xmPushButtonWidgetClass, rc,
1674 XmNlabelType, XmPIXMAP,
1675 XmNuserData, pdata,
1676 NULL);
1678 AddHelpCB(button, "doc/UsersGuide.html#pen-chooser");
1680 AddButtonCB(button, define_pen_choice_dialog, button);
1682 pdata->color_popup = CreateColorChoicePopup(button);
1683 pdata->pattern_popup = CreatePatternChoicePopup(button);
1685 XtAddEventHandler(button, ButtonPressMask, False, pen_popup, NULL);
1687 pen.color = 0;
1688 pen.pattern = 0;
1689 SetPenChoice_int(button, &pen, FALSE);
1691 WidgetManage(button);
1693 return button;
1696 int GetPenChoice(Widget pen_button, Pen *pen)
1698 Button_PData *pdata = WidgetGetUserData(pen_button);
1699 if (pdata) {
1700 *pen = pdata->pen;
1701 return RETURN_SUCCESS;
1702 } else {
1703 return RETURN_FAILURE;
1707 void AddPenChoiceCB(Widget button, Pen_CBProc cbproc, void *anydata)
1709 Button_PData *pdata = WidgetGetUserData(button);
1711 if (pdata->cb_proc) {
1712 errmsg("AddPenChoiceCB: only one callback is supported");
1713 } else {
1714 pdata->cb_proc = cbproc;
1715 pdata->cb_data = anydata;
1719 SpinStructure *CreateViewCoordInput(Widget parent, char *s)
1721 return CreateSpinChoice(parent, s, 6, SPIN_TYPE_FLOAT, -10.0, 10.0, 0.05);
1724 static StorageStructure **ssd_selectors = NULL;
1725 static int nssd_selectors = 0;
1727 static char *ssd_labeling(Quark *q, unsigned int *rid)
1729 char *buf;
1731 if (!q) {
1732 return NULL;
1735 buf = (char *) xmalloc(strlen(QIDSTR(q)) + 128);
1736 if (!buf) {
1737 return NULL;
1740 if (quark_fid_get(q) == QFlavorSSD) {
1741 sprintf(buf, "SSD \"%s\" (%d x %d)", QIDSTR(q),
1742 ssd_get_ncols(q), ssd_get_nrows(q));
1744 (*rid)++;
1746 return buf;
1747 } else {
1748 return NULL;
1752 StorageStructure *CreateSSDChoice(Widget parent, char *labelstr, int type)
1754 StorageStructure *ss;
1755 int nvisible;
1757 nvisible = (type == LIST_TYPE_SINGLE) ? 4 : 6;
1759 ss = CreateStorageChoice(parent, labelstr, type, nvisible);
1760 SetStorageChoiceLabeling(ss, ssd_labeling);
1761 SetStorageChoiceQuark(ss, gproject_get_top(gapp->gp));
1763 nssd_selectors++;
1764 ssd_selectors =
1765 xrealloc(ssd_selectors, nssd_selectors*sizeof(StorageStructure *));
1766 ssd_selectors[nssd_selectors - 1] = ss;
1768 AddHelpCB(ss->rc, "doc/UsersGuide.html#ssd-selector");
1770 return ss;
1773 int GetSSDColChoices(SSDColStructure *sc, Quark **ssd, int **cols)
1775 if (GetSingleStorageChoice(sc->ssd_sel, ssd) != RETURN_SUCCESS) {
1776 return -1;
1777 } else {
1778 return GetListChoices(sc->col_sel, cols);
1782 void update_ssd_selectors(Quark *pr)
1784 int i;
1785 for (i = 0; i < nssd_selectors; i++) {
1786 StorageStructure *ss = ssd_selectors[i];
1787 if (!ss->q && pr) {
1788 ss->q = pr;
1789 } else
1790 if (!pr) {
1791 ss->q = NULL;
1793 UpdateStorageChoice(ss);
1798 static StorageStructure **graph_selectors = NULL;
1799 static int ngraph_selectors = 0;
1801 #define GSS_FOCUS_CB 0
1803 typedef struct {
1804 Widget focus_bt;
1805 } GSSData;
1807 static void gss_any_cb(void *udata, int cbtype)
1809 StorageStructure *ss = (StorageStructure *) udata;
1810 int i, n;
1811 Quark **values;
1813 n = GetStorageChoices(ss, &values);
1815 for (i = 0; i < n; i ++) {
1816 Quark *gr = values[i];
1818 switch (cbtype) {
1819 case GSS_FOCUS_CB:
1820 switch_current_graph(gr);
1821 break;
1825 if (n > 0) {
1826 xfree(values);
1827 update_all();
1828 xdrawgraph(gapp->gp);
1832 static void g_focus_cb(Widget but, void *udata)
1834 gss_any_cb(udata, GSS_FOCUS_CB);
1837 static void g_popup_cb(StorageStructure *ss, int nselected)
1839 GSSData *gssdata = (GSSData *) ss->data;
1841 WidgetSetSensitive(gssdata->focus_bt, (nselected == 1));
1844 static void g_new_cb(Widget but, void *udata)
1846 graph_next(gproject_get_top(gapp->gp));
1847 snapshot_and_update(gapp->gp, TRUE);
1850 static char *graph_labeling(Quark *q, unsigned int *rid)
1852 char *buf;
1854 if (!q) {
1855 return NULL;
1858 buf = (char *) xmalloc(strlen(QIDSTR(q)) + 128);
1859 if (!buf) {
1860 return NULL;
1863 if (quark_fid_get(q) == QFlavorGraph) {
1864 sprintf(buf, "Graph \"%s\" (type: %s, sets: %d)",
1865 QIDSTR(q),
1866 graph_types(gapp->grace, graph_get_type(q)), quark_get_number_of_descendant_sets(q));
1868 (*rid)++;
1870 return buf;
1871 } else {
1872 return NULL;
1876 StorageStructure *CreateGraphChoice(Widget parent, char *labelstr, int type)
1878 StorageStructure *ss;
1879 GSSData *gssdata;
1880 Widget popup;
1881 int nvisible;
1883 nvisible = (type == LIST_TYPE_SINGLE) ? 2 : 4;
1884 ss = CreateStorageChoice(parent, labelstr, type, nvisible);
1885 SetStorageChoiceLabeling(ss, graph_labeling);
1886 SetStorageChoiceQuark(ss, gproject_get_top(gapp->gp));
1887 AddHelpCB(ss->rc, "doc/UsersGuide.html#graph-selector");
1889 ngraph_selectors++;
1890 graph_selectors =
1891 xrealloc(graph_selectors, ngraph_selectors*sizeof(StorageStructure *));
1892 graph_selectors[ngraph_selectors - 1] = ss;
1894 gssdata = xmalloc(sizeof(GSSData));
1895 ss->data = gssdata;
1896 ss->popup_cb = g_popup_cb;
1898 popup = ss->popup;
1900 CreateMenuSeparator(popup);
1902 CreateMenuButton(popup, "Create new", '\0', g_new_cb, ss);
1904 CreateMenuSeparator(popup);
1906 gssdata->focus_bt =
1907 CreateMenuButton(popup, "Focus to selected", '\0', g_focus_cb, ss);
1909 return ss;
1912 void update_graph_selectors(Quark *pr)
1914 int i;
1915 for (i = 0; i < ngraph_selectors; i++) {
1916 StorageStructure *ss = graph_selectors[i];
1917 if (!ss->q && pr) {
1918 ss->q = pr;
1919 } else
1920 if (!pr) {
1921 ss->q = NULL;
1923 UpdateStorageChoice(ss);
1927 void graph_set_selectors(Quark *gr)
1929 int i;
1931 for (i = 0; i < ngraph_selectors; i++) {
1932 SelectStorageChoice(graph_selectors[i], gr);
1936 static StorageStructure **frame_selectors = NULL;
1937 static int nframe_selectors = 0;
1939 static char *frame_labeling(Quark *q, unsigned int *rid)
1941 char *buf;
1943 if (!q) {
1944 return NULL;
1947 buf = (char *) xmalloc(strlen(QIDSTR(q)) + 128);
1948 if (!buf) {
1949 return NULL;
1952 if (quark_fid_get(q) == QFlavorFrame) {
1953 sprintf(buf, "Frame \"%s\"", QIDSTR(q));
1955 (*rid)++;
1957 return buf;
1958 } else {
1959 return NULL;
1963 StorageStructure *CreateFrameChoice(Widget parent, char *labelstr, int type)
1965 StorageStructure *ss;
1966 Widget popup;
1967 int nvisible;
1969 nvisible = (type == LIST_TYPE_SINGLE) ? 2 : 4;
1970 ss = CreateStorageChoice(parent, labelstr, type, nvisible);
1971 SetStorageChoiceLabeling(ss, frame_labeling);
1972 SetStorageChoiceQuark(ss, gproject_get_top(gapp->gp));
1973 AddHelpCB(ss->rc, "doc/UsersGuide.html#frame-selector");
1975 nframe_selectors++;
1976 frame_selectors =
1977 xrealloc(frame_selectors, nframe_selectors*sizeof(StorageStructure *));
1978 frame_selectors[nframe_selectors - 1] = ss;
1980 popup = ss->popup;
1982 CreateMenuSeparator(popup);
1984 CreateMenuButton(popup, "Create new", '\0', g_new_cb, ss);
1986 CreateMenuSeparator(popup);
1988 return ss;
1991 void update_frame_selectors(Quark *pr)
1993 int i;
1994 for (i = 0; i < nframe_selectors; i++) {
1995 StorageStructure *ss = frame_selectors[i];
1996 if (!ss->q && pr) {
1997 ss->q = pr;
1998 } else
1999 if (!pr) {
2000 ss->q = NULL;
2002 UpdateStorageChoice(ss);
2006 /* Set selectors */
2007 static StorageStructure **set_selectors = NULL;
2008 static int nset_selectors = 0;
2011 #define SSS_NEWF_CB 1
2013 typedef struct {
2014 StorageStructure *graphss;
2015 } SSSData;
2017 Quark *get_set_choice_gr(StorageStructure *ss)
2019 Quark *gr;
2020 SSSData *sdata = (SSSData *) ss->data;
2022 if (sdata->graphss) {
2023 if (GetSingleStorageChoice(sdata->graphss, &gr) != RETURN_SUCCESS) {
2024 gr = NULL;
2026 } else {
2027 gr = NULL;
2030 return gr;
2033 static void sss_any_cb(void *udata, int cbtype)
2035 StorageStructure *ss = (StorageStructure *) udata;
2036 Quark *gr = get_set_choice_gr(ss);
2038 switch (cbtype) {
2039 case SSS_NEWF_CB:
2040 create_leval_frame(NULL, gr);
2041 break;
2044 snapshot_and_update(gapp->gp, TRUE);
2047 static void s_newF_cb(Widget but, void *udata)
2049 sss_any_cb(udata, SSS_NEWF_CB);
2052 static char *set_labeling(Quark *q, unsigned int *rid)
2054 char *buf;
2056 if (!q) {
2057 return NULL;
2060 buf = (char *) xmalloc(strlen(QIDSTR(q)) + 128);
2061 if (!buf) {
2062 return NULL;
2065 if (quark_fid_get(q) == QFlavorSet) {
2066 set *p = set_get_data(q);
2068 sprintf(buf, "Set \"%s\" (type: %s, length: %d)",
2069 QIDSTR(q), set_type_descr(gapp->grace, p->type),
2070 set_get_length(q));
2072 (*rid)++;
2074 return buf;
2075 } else {
2076 return NULL;
2080 StorageStructure *CreateSetChoice(Widget parent,
2081 char *labelstr, int type, StorageStructure *graphss)
2083 StorageStructure *ss;
2084 SSSData *sssdata;
2085 Widget popup, submenupane;
2086 int nvisible;
2088 nvisible = (type == LIST_TYPE_SINGLE) ? 4 : 8;
2089 ss = CreateStorageChoice(parent, labelstr, type, nvisible);
2090 SetStorageChoiceLabeling(ss, set_labeling);
2091 AddHelpCB(ss->rc, "doc/UsersGuide.html#set-selector");
2093 nset_selectors++;
2094 set_selectors =
2095 xrealloc(set_selectors, nset_selectors*sizeof(StorageStructure *));
2096 set_selectors[nset_selectors - 1] = ss;
2098 sssdata = xmalloc(sizeof(SSSData));
2099 ss->data = sssdata;
2100 sssdata->graphss = graphss;
2102 popup = ss->popup;
2104 CreateMenuSeparator(popup);
2106 submenupane = CreateMenu(popup, "Create new", '\0', FALSE);
2107 CreateMenuButton(submenupane, "By formula", '\0', s_newF_cb, ss);
2109 UpdateSetChoice(ss);
2111 return ss;
2114 void UpdateSetChoice(StorageStructure *ss)
2116 Quark *gr;
2118 gr = get_set_choice_gr(ss);
2120 SetStorageChoiceQuark(ss, gr);
2124 void update_set_selectors(Quark *gr)
2126 int i;
2128 if (gr) {
2129 update_graph_selectors(get_parent_project(gr));
2132 for (i = 0; i < nset_selectors; i++) {
2133 Quark *cg;
2135 cg = get_set_choice_gr(set_selectors[i]);
2136 if (!gr || cg == gr) {
2137 UpdateSetChoice(set_selectors[i]);
2142 static void update_sets_cb(StorageStructure *ss, int n, Quark **values, void *data)
2144 GraphSetStructure *gs = (GraphSetStructure *) data;
2146 UpdateSetChoice(gs->set_sel);
2149 GraphSetStructure *CreateGraphSetSelector(Widget parent, char *s, int sel_type)
2151 GraphSetStructure *retval;
2152 Widget rc;
2154 retval = xmalloc(sizeof(GraphSetStructure));
2155 retval->frame = CreateFrame(parent, s);
2156 rc = XtVaCreateWidget("rc", xmRowColumnWidgetClass, retval->frame, NULL);
2157 retval->graph_sel = CreateGraphChoice(rc, "Graph:", LIST_TYPE_SINGLE);
2158 retval->set_sel = CreateSetChoice(rc, "Set:", sel_type, retval->graph_sel);
2159 AddStorageChoiceCB(retval->graph_sel, update_sets_cb, (void *) retval);
2160 UpdateSetChoice(retval->set_sel);
2161 retval->set_sel->governor = retval->graph_sel;
2162 WidgetManage(rc);
2164 return retval;
2168 SSDSetStructure *CreateSSDSetSelector(Widget parent, char *s, int sel_type)
2170 SSDSetStructure *retval;
2171 Widget rc;
2173 retval = xmalloc(sizeof(SSDSetStructure));
2174 retval->frame = CreateFrame(parent, s);
2175 rc = XtVaCreateWidget("rc", xmRowColumnWidgetClass, retval->frame, NULL);
2176 retval->ssd_sel = CreateSSDChoice(rc, "SSD:", LIST_TYPE_SINGLE);
2177 retval->set_sel = CreateSetChoice(rc, "Set:", sel_type, retval->ssd_sel);
2178 AddStorageChoiceCB(retval->ssd_sel, update_sets_cb, (void *) retval);
2179 UpdateSetChoice(retval->set_sel);
2180 retval->set_sel->governor = retval->ssd_sel;
2181 WidgetManage(rc);
2183 return retval;
2188 ListStructure *CreateColChoice(Widget parent, char *labelstr, int type)
2190 int nvisible;
2191 ListStructure *retval;
2193 nvisible = 6;
2195 retval = CreateListChoice(parent, labelstr, type, nvisible, 0, NULL);
2197 return retval;
2200 void UpdateColChoice(ListStructure *sel, const Quark *ssd)
2202 unsigned int i, ncols;
2203 OptionItem *items;
2205 if (ssd) {
2206 ncols = ssd_get_ncols(ssd);
2207 items = xmalloc(ncols*sizeof(OptionItem));
2208 for (i = 0; i < ncols; i++) {
2209 char *label, *s, buf[32];
2210 items[i].value = i;
2211 label = ssd_get_col_label(ssd, i);
2212 if (string_is_empty(label)) {
2213 sprintf(buf, "#%d", i + 1);
2214 s = copy_string(NULL, buf);
2215 } else {
2216 s = copy_string(NULL, label);
2218 items[i].label = s;
2220 } else {
2221 ncols = 0;
2222 items = NULL;
2224 UpdateListChoice(sel, ncols, items);
2226 for (i = 0; i < ncols; i++) {
2227 xfree(items[i].label);
2229 xfree(items);
2231 sel->anydata = (void *) ssd;
2234 static void update_ssd_cb(StorageStructure *ss, int n, Quark **values, void *data)
2236 SSDColStructure *gs = (SSDColStructure *) data;
2237 Quark *ssd;
2239 if (n == 1) {
2240 ssd = values[0];
2241 } else {
2242 ssd = NULL;
2245 UpdateColChoice(gs->col_sel, ssd);
2248 SSDColStructure *CreateSSDColSelector(Widget parent, char *s, int sel_type)
2250 SSDColStructure *retval;
2251 Widget rc;
2253 retval = xmalloc(sizeof(SSDColStructure));
2254 retval->frame = CreateFrame(parent, s);
2255 rc = XtVaCreateWidget("rc", xmRowColumnWidgetClass, retval->frame, NULL);
2256 retval->ssd_sel = CreateSSDChoice(rc, "SSData:", LIST_TYPE_SINGLE);
2257 retval->col_sel = CreateColChoice(rc,
2258 sel_type == LIST_TYPE_SINGLE ? "Column:" : "Column(s):", sel_type);
2259 AddStorageChoiceCB(retval->ssd_sel, update_ssd_cb, (void *) retval);
2261 WidgetManage(rc);
2263 return retval;
2268 SrcDestStructure *CreateSrcDestSelector(Widget parent, int sel_type)
2270 SrcDestStructure *retval;
2272 retval = xmalloc(sizeof(SrcDestStructure));
2274 retval->form = XtVaCreateWidget("form",
2275 xmFormWidgetClass, parent,
2276 XmNfractionBase, 2,
2277 NULL);
2278 retval->src = CreateSSDSetSelector(retval->form, "Source", sel_type);
2279 retval->dest = CreateSSDSetSelector(retval->form, "Destination", sel_type);
2280 XtVaSetValues(retval->src->frame,
2281 XmNtopAttachment, XmATTACH_FORM,
2282 XmNbottomAttachment, XmATTACH_FORM,
2283 XmNleftAttachment, XmATTACH_FORM,
2284 XmNrightAttachment, XmATTACH_POSITION,
2285 XmNrightPosition, 1,
2286 NULL);
2288 XtVaSetValues(retval->dest->frame,
2289 XmNtopAttachment, XmATTACH_FORM,
2290 XmNbottomAttachment, XmATTACH_FORM,
2291 XmNleftAttachment, XmATTACH_POSITION,
2292 XmNleftPosition, 1,
2293 XmNrightAttachment, XmATTACH_FORM,
2294 NULL);
2296 WidgetManage(retval->form);
2298 return retval;
2301 void paint_color_selector(OptionStructure *optp)
2303 X11Stuff *xstuff = gapp->gui->xstuff;
2304 unsigned int i;
2305 long bg, fg;
2306 Project *pr = project_get_data(gproject_get_top(gapp->gp));
2308 if (!pr) {
2309 return;
2312 for (i = 0; i < pr->ncolors; i++) {
2313 Colordef *c = &pr->colormap[i];
2314 bg = xvlibcolors[c->id];
2315 if (get_rgb_intensity(&c->rgb) < 0.5) {
2316 fg = WhitePixel(xstuff->disp, xstuff->screennumber);
2317 } else {
2318 fg = BlackPixel(xstuff->disp, xstuff->screennumber);
2320 XtVaSetValues(optp->options[i].widget,
2321 XmNbackground, bg,
2322 XmNforeground, fg,
2323 NULL);
2328 void update_color_selectors(void)
2330 unsigned int i;
2331 Project *pr = project_get_data(gproject_get_top(gapp->gp));
2333 ncolor_option_items = pr->ncolors;
2335 color_option_items = xrealloc(color_option_items,
2336 ncolor_option_items*sizeof(OptionItem));
2337 for (i = 0; i < pr->ncolors; i++) {
2338 Colordef *c = &pr->colormap[i];
2339 color_option_items[i].value = c->id;
2340 color_option_items[i].label = c->cname;
2343 for (i = 0; i < ncolor_selectors; i++) {
2344 UpdateOptionChoice(color_selectors[i],
2345 ncolor_option_items, color_option_items);
2346 paint_color_selector(color_selectors[i]);
2349 update_color_choice_popup();
2352 OptionStructure *CreateColorChoice(Widget parent, char *s)
2354 OptionStructure *retvalp = NULL;
2356 ncolor_selectors++;
2357 color_selectors = xrealloc(color_selectors,
2358 ncolor_selectors*sizeof(OptionStructure *));
2359 if (color_selectors == NULL) {
2360 errmsg("Malloc failed in CreateColorChoice()");
2361 return retvalp;
2364 retvalp = CreateOptionChoice(parent, s, 4,
2365 ncolor_option_items, color_option_items);
2367 color_selectors[ncolor_selectors - 1] = retvalp;
2369 paint_color_selector(retvalp);
2371 return retvalp;
2374 SpinStructure *CreateLineWidthChoice(Widget parent, char *s)
2376 return CreateSpinChoice(parent, s, 3, SPIN_TYPE_FLOAT, 0.0, MAX_LINEWIDTH, 0.5);
2380 OptionStructure *CreatePanelChoice(Widget parent, char *labelstr, ...)
2382 OptionStructure *retval;
2383 int nchoices = 0;
2384 OptionItem *oi = NULL;
2385 va_list var;
2386 char *s;
2388 va_start(var, labelstr);
2389 while ((s = va_arg(var, char *)) != NULL) {
2390 nchoices++;
2391 oi = xrealloc(oi, nchoices*sizeof(OptionItem));
2392 oi[nchoices - 1].value = nchoices - 1;
2393 oi[nchoices - 1].label = copy_string(NULL, s);
2395 va_end(var);
2397 retval = CreateOptionChoice(parent, labelstr, 1, nchoices, oi);
2399 while (nchoices) {
2400 nchoices--;
2401 xfree(oi[nchoices].label);
2403 xfree(oi);
2405 return retval;
2408 static void format_call_cb(FormatStructure *fstr)
2410 if (fstr->cb_proc) {
2411 Format format;
2412 format.type = GetOptionChoice(fstr->type);
2413 format.prec = GetOptionChoice(fstr->prec);
2414 format.fstring = TextGetString(fstr->fstring);
2416 fstr->cb_proc(fstr, &format, fstr->cb_data);
2418 xfree(format.fstring);
2422 static void format_oc_cb(OptionStructure *opt, int a, void *data)
2424 FormatStructure *fstr = (FormatStructure *) data;
2425 if (!fstr) {
2426 return;
2429 if (opt == fstr->type) {
2430 WidgetSetSensitive(fstr->fstring->form,
2431 a == FORMAT_DATETIME || a == FORMAT_GEOGRAPHIC);
2434 format_call_cb(fstr);
2437 static void format_text_cb(TextStructure *cst, char *s, void *data)
2439 FormatStructure *fstr = (FormatStructure *) data;
2440 if (!fstr) {
2441 return;
2444 format_call_cb(fstr);
2447 FormatStructure *CreateFormatChoice(Widget parent)
2449 FormatStructure *retval;
2450 Widget rc, rc1;
2452 retval = xmalloc(sizeof(FormatStructure));
2454 rc = CreateVContainer(parent);
2455 rc1 = CreateHContainer(rc);
2456 retval->type = CreateOptionChoice(rc1, "Type:",
2457 1, NUMBER_OF_FORMATTYPES, fmt_option_items);
2458 AddOptionChoiceCB(retval->type, format_oc_cb, retval);
2459 retval->prec = CreatePrecisionChoice(rc1, "Precision:");
2460 AddOptionChoiceCB(retval->prec, format_oc_cb, retval);
2461 retval->fstring = CreateText(rc, "Format string:");
2462 AddTextActivateCB(retval->fstring, format_text_cb, retval);
2464 return retval;
2467 void SetFormatChoice(FormatStructure *fstr, const Format *format)
2469 SetOptionChoice(fstr->type, format->type);
2470 SetOptionChoice(fstr->prec, format->prec);
2471 TextSetString(fstr->fstring, format->fstring);
2472 WidgetSetSensitive(fstr->fstring->form,
2473 format->type == FORMAT_DATETIME || format->type == FORMAT_GEOGRAPHIC);
2476 Format *GetFormatChoice(FormatStructure *fstr)
2478 Format *format = format_new();
2479 if (format) {
2480 format->type = GetOptionChoice(fstr->type);
2481 format->prec = GetOptionChoice(fstr->prec);
2482 format->fstring = TextGetString(fstr->fstring);
2485 return format;
2488 void AddFormatChoiceCB(FormatStructure *fstr, Format_CBProc cbproc, void *data)
2490 fstr->cb_proc = cbproc;
2491 fstr->cb_data = data;
2495 static OptionItem as_option_items[4] =
2497 {AUTOSCALE_NONE, "None"},
2498 {AUTOSCALE_X, "X"},
2499 {AUTOSCALE_Y, "Y"},
2500 {AUTOSCALE_XY, "XY"}
2503 OptionStructure *CreateASChoice(Widget parent, char *s)
2505 OptionStructure *retval;
2507 retval = CreateOptionChoice(parent, s, 1, 4, as_option_items);
2508 /* As init value, use this */
2509 SetOptionChoice(retval, gapp->rt->autoscale_onread);
2511 return(retval);
2514 OptionStructure *CreatePrecisionChoice(Widget parent, char *s)
2516 return CreateOptionChoiceVA(parent, s,
2517 "0", 0,
2518 "1", 1,
2519 "2", 2,
2520 "3", 3,
2521 "4", 4,
2522 "5", 5,
2523 "6", 6,
2524 "7", 7,
2525 "8", 8,
2526 "9", 9,
2527 NULL);
2530 OptionStructure *CreatePaperOrientationChoice(Widget parent, char *s)
2532 return CreateOptionChoiceVA(parent, s,
2533 "Landscape", PAGE_ORIENT_LANDSCAPE,
2534 "Portrait", PAGE_ORIENT_PORTRAIT,
2535 NULL);
2538 OptionStructure *CreatePaperFormatChoice(Widget parent, char *s)
2540 return CreateOptionChoiceVA(parent, s,
2541 "Custom", PAGE_FORMAT_CUSTOM,
2542 "Letter", PAGE_FORMAT_USLETTER,
2543 "A4", PAGE_FORMAT_A4,
2544 NULL);
2548 SpinStructure *CreateAngleChoice(Widget parent, char *s)
2550 return CreateSpinChoice(parent, s, 5, SPIN_TYPE_FLOAT, -360.0, 360.0, 10.0);
2553 double GetAngleChoice(SpinStructure *sp)
2555 return GetSpinChoice(sp);
2558 void SetAngleChoice(SpinStructure *sp, double angle)
2560 if (angle < -360.0 || angle > 360.0) {
2561 angle = fmod(angle, 360.0);
2563 SetSpinChoice(sp, angle);
2566 SpinStructure *CreateCharSizeChoice(Widget parent, char *s)
2568 return CreateSpinChoice(parent, s, 4, SPIN_TYPE_FLOAT, 0.0, 100.0, 0.25);
2571 Pixmap XpmToPixmap(char **xpm)
2573 X11Stuff *xstuff = gapp->gui->xstuff;
2574 Pixel bg;
2575 XpmColorSymbol transparent;
2576 XpmAttributes attrib;
2577 Pixmap pixmap;
2579 XtVaGetValues(app_shell, XtNbackground, &bg, NULL);
2580 transparent.name = NULL;
2581 transparent.value = "None";
2582 transparent.pixel = bg;
2583 attrib.colorsymbols = &transparent;
2584 attrib.valuemask = XpmColorSymbols;
2585 attrib.numsymbols = 1;
2587 XpmCreatePixmapFromData(xstuff->disp, xstuff->root,
2588 xpm, &pixmap, NULL, &attrib);
2590 return pixmap;
2593 static Widget CreateCommandButtons(Widget parent, int n, Widget * buts, char **l)
2595 int i;
2596 Widget form;
2597 Dimension h;
2599 form = XtVaCreateWidget("form", xmFormWidgetClass, parent,
2600 XmNfractionBase, n,
2601 NULL);
2603 for (i = 0; i < n; i++) {
2604 buts[i] = XtVaCreateManagedWidget(l[i],
2605 xmPushButtonWidgetClass, form,
2606 XmNtopAttachment, XmATTACH_FORM,
2607 XmNbottomAttachment, XmATTACH_FORM,
2608 XmNleftAttachment, XmATTACH_POSITION,
2609 XmNleftPosition, i,
2610 XmNrightAttachment, XmATTACH_POSITION,
2611 XmNrightPosition, i + 1,
2612 XmNdefaultButtonShadowThickness, 1,
2613 XmNshowAsDefault, (i == 0) ? True : False,
2614 NULL);
2616 WidgetManage(form);
2617 XtVaGetValues(buts[0], XmNheight, &h, NULL);
2618 XtVaSetValues(form, XmNpaneMaximum, h, XmNpaneMinimum, h, NULL);
2620 return form;
2623 typedef struct {
2624 Widget form;
2625 int close;
2626 AACDialog_CBProc cbproc;
2627 void *anydata;
2628 } AACDialog_CBdata;
2630 void aacdialog_int_cb_proc(Widget but, void *data)
2632 AACDialog_CBdata *cbdata;
2633 int retval;
2635 set_wait_cursor();
2637 cbdata = (AACDialog_CBdata *) data;
2639 retval = cbdata->cbproc(cbdata->anydata);
2641 if (cbdata->close && retval == RETURN_SUCCESS) {
2642 WidgetUnmanage(XtParent(cbdata->form));
2645 unset_wait_cursor();
2648 WidgetList CreateAACDialog(Widget form,
2649 Widget container, AACDialog_CBProc cbproc, void *data)
2651 Widget fr;
2652 WidgetList aacbut;
2653 AACDialog_CBdata *cbdata_accept, *cbdata_apply;
2654 char *aaclab[3] = {"Apply", "Accept", "Close"};
2656 aacbut = (WidgetList) XtMalloc(3*sizeof(Widget));
2658 fr = CreateFrame(form, NULL);
2659 XtVaSetValues(fr,
2660 XmNtopAttachment, XmATTACH_NONE,
2661 XmNleftAttachment, XmATTACH_FORM,
2662 XmNrightAttachment, XmATTACH_FORM,
2663 XmNbottomAttachment, XmATTACH_FORM,
2664 NULL);
2665 CreateCommandButtons(fr, 3, aacbut, aaclab);
2667 FormAddVChild(form, container);
2668 XtVaSetValues(container,
2669 XmNbottomAttachment, XmATTACH_WIDGET,
2670 XmNbottomWidget, fr,
2671 NULL);
2673 XtVaSetValues(form, XmNcancelButton, aacbut[2], NULL);
2675 cbdata_accept = xmalloc(sizeof(AACDialog_CBdata));
2676 cbdata_accept->form = form;
2677 cbdata_accept->anydata = data;
2678 cbdata_accept->cbproc = cbproc;
2679 cbdata_accept->close = TRUE;
2681 cbdata_apply = xmalloc(sizeof(AACDialog_CBdata));
2682 cbdata_apply->form = form;
2683 cbdata_apply->anydata = data;
2684 cbdata_apply->cbproc = cbproc;
2685 cbdata_apply->close = FALSE;
2687 AddButtonCB(aacbut[0], aacdialog_int_cb_proc, cbdata_apply);
2688 AddButtonCB(aacbut[1], aacdialog_int_cb_proc, cbdata_accept);
2689 AddButtonCB(aacbut[2], destroy_dialog_cb, form);
2691 WidgetManage(container);
2692 WidgetManage(form);
2694 return aacbut;
2697 int td_cb(void *data)
2699 int res, i, nssrc, error;
2700 Quark **srcsets, **destsets;
2701 TransformStructure *tdialog = (TransformStructure *) data;
2702 void *tddata;
2704 res = GetTransformDialogSettings(tdialog, &nssrc, &srcsets, &destsets);
2706 if (res != RETURN_SUCCESS) {
2707 return RETURN_FAILURE;
2710 error = FALSE;
2712 tddata = tdialog->get_cb(tdialog->gui);
2713 if (!tddata) {
2714 error = TRUE;
2717 if (!error) {
2718 for (i = 0; i < nssrc; i++) {
2719 Quark *psrc, *pdest;
2720 psrc = srcsets[i];
2721 pdest = destsets[i];
2723 res = tdialog->run_cb(psrc, pdest, tddata);
2724 if (res != RETURN_SUCCESS) {
2725 error = TRUE;
2726 break;
2731 if (nssrc > 0) {
2732 xfree(srcsets);
2733 xfree(destsets);
2736 if (tddata) {
2737 tdialog->free_cb(tddata);
2740 snapshot_and_update(gapp->gp, TRUE);
2742 if (error == FALSE) {
2743 return RETURN_SUCCESS;
2744 } else {
2745 return RETURN_FAILURE;
2750 TransformStructure *CreateTransformDialogForm(Widget parent,
2751 const char *s, int sel_type, int exclusive, const TD_CBProcs *cbs)
2753 TransformStructure *retval;
2755 set_wait_cursor();
2757 retval = xmalloc(sizeof(TransformStructure));
2758 memset(retval, 0, sizeof(TransformStructure));
2760 retval->exclusive = exclusive;
2762 retval->build_cb = cbs->build_cb;
2763 retval->get_cb = cbs->get_cb;
2764 retval->run_cb = cbs->run_cb;
2765 retval->free_cb = cbs->free_cb;
2767 retval->form = CreateDialog(parent, s);
2769 retval->menubar = CreateMenuBar(retval->form);
2770 FormAddVChild(retval->form, retval->menubar);
2772 retval->srcdest = CreateSrcDestSelector(retval->form, sel_type);
2773 FormAddVChild(retval->form, retval->srcdest->form);
2775 retval->frame = CreateFrame(retval->form, NULL);
2776 retval->gui = retval->build_cb(retval);
2779 * retval->restr = CreateRestrictionChoice(retval->form, "Source data filtering");
2780 * AddDialogFormChild(retval->form, retval->restr->frame);
2783 CreateAACDialog(retval->form, retval->frame, td_cb, retval);
2785 /* FixateDialogFormChild(retval->frame); */
2787 unset_wait_cursor();
2789 return retval;
2792 int GetTransformDialogSettings(TransformStructure *tdialog,
2793 int *nssrc, Quark ***srcsets, Quark ***destsets)
2795 int i, nsdest;
2796 Quark *srcssd, *destssd;
2798 if (GetSingleStorageChoice(tdialog->srcdest->src->ssd_sel, &srcssd)
2799 != RETURN_SUCCESS) {
2800 errmsg("No source SSD selected");
2801 return RETURN_FAILURE;
2804 *nssrc = GetStorageChoices(tdialog->srcdest->src->set_sel, srcsets);
2805 if (*nssrc == 0) {
2806 errmsg("No source sets selected");
2807 return RETURN_FAILURE;
2810 nsdest = GetStorageChoices(tdialog->srcdest->dest->set_sel, destsets);
2811 if (nsdest != 0 && *nssrc != nsdest) {
2812 errmsg("Different number of source and destination sets");
2813 xfree(*srcsets);
2814 xfree(*destsets);
2815 return RETURN_FAILURE;
2818 if (GetSingleStorageChoice(tdialog->srcdest->dest->ssd_sel, &destssd)
2819 != RETURN_SUCCESS) {
2820 destssd = gapp_ssd_new(quark_parent_get(srcssd));
2821 if (!destssd) {
2822 xfree(*srcsets);
2823 errmsg("Cannot create new SSD");
2824 return RETURN_FAILURE;
2826 } else {
2827 /* check for mutually exclusive selections */
2828 if (tdialog->exclusive && destssd == srcssd) {
2829 xfree(*srcsets);
2830 if (nsdest) {
2831 xfree(*destsets);
2833 errmsg("Source and destination SSD's are the same");
2834 return RETURN_FAILURE;
2838 if (nsdest == 0) {
2839 ssd_set_indexed(destssd, TRUE);
2840 if (!ssd_is_indexed(destssd)) {
2841 if (!ssd_add_col(destssd, FFORMAT_NUMBER)) {
2842 return RETURN_FAILURE;
2846 *destsets = xmalloc((*nssrc)*sizeof(Quark *));
2847 for (i = 0; i < *nssrc; i++) {
2848 if (ssd_add_col(destssd, FFORMAT_NUMBER)) {
2849 Dataset *dsp;
2850 (*destsets)[i] = gapp_set_new(destssd);
2851 dsp = set_get_dataset((*destsets)[i]);
2852 dsp->cols[0] = 0;
2853 dsp->cols[1] = ssd_get_ncols(destssd) - 1;
2857 update_ssd_selectors(gproject_get_top(gapp->gp));
2859 SelectStorageChoice(tdialog->srcdest->dest->ssd_sel, destssd);
2860 SelectStorageChoices(tdialog->srcdest->dest->set_sel, *nssrc, *destsets);
2863 return RETURN_SUCCESS;
2866 void RaiseTransformationDialog(TransformStructure *tdialog)
2868 DialogRaise(tdialog->form);
2871 static Widget *savewidgets = NULL;
2872 static int nsavedwidgets = 0;
2874 static void savewidget(Widget w)
2876 int i;
2878 for (i = 0; i < nsavedwidgets; i++) {
2879 if (w == savewidgets[i]) {
2880 return;
2884 savewidgets = xrealloc(savewidgets, (nsavedwidgets + 1)*sizeof(Widget));
2885 savewidgets[nsavedwidgets] = w;
2886 nsavedwidgets++;
2889 #if 0
2890 static void deletewidget(Widget w)
2892 int i;
2894 for (i = 0; i < nsavedwidgets; i++) {
2895 if (w == savewidgets[i]) {
2896 nsavedwidgets--;
2897 for (; i < nsavedwidgets; i++) {
2898 savewidgets[i] = savewidgets[i + 1];
2900 savewidgets = xrealloc(savewidgets, nsavedwidgets*sizeof(Widget));
2901 XtDestroyWidget(w);
2902 return;
2907 #endif
2909 static void destroy_dialog(Widget w, XtPointer client_data, XtPointer call_data)
2911 if (w == app_shell) {
2912 bailout(gapp);
2913 } else {
2914 WidgetUnmanage((Widget) client_data);
2919 * handle the close item on the WM menu
2921 void handle_close(Widget w)
2923 X11Stuff *xstuff = gapp->gui->xstuff;
2924 Atom WM_DELETE_WINDOW;
2926 XtVaSetValues(w, XmNdeleteResponse, XmDO_NOTHING, NULL);
2928 WM_DELETE_WINDOW = XmInternAtom(xstuff->disp, "WM_DELETE_WINDOW", False);
2929 XmAddWMProtocolCallback(w, WM_DELETE_WINDOW, destroy_dialog, w);
2931 savewidget(w);
2934 void DefineDialogCursor(Cursor c)
2936 X11Stuff *xstuff = gapp->gui->xstuff;
2937 int i;
2939 for (i = 0; i < nsavedwidgets; i++) {
2940 XDefineCursor(xstuff->disp, XtWindow(savewidgets[i]), c);
2942 XFlush(xstuff->disp);
2945 void UndefineDialogCursor(void)
2947 X11Stuff *xstuff = gapp->gui->xstuff;
2948 int i;
2950 for (i = 0; i < nsavedwidgets; i++) {
2951 XUndefineCursor(xstuff->disp, XtWindow(savewidgets[i]));
2953 XFlush(xstuff->disp);
2956 static void help_int_cb(Widget w, XtPointer client_data, XtPointer call_data)
2958 HelpCB(w, client_data);
2961 void AddHelpCB(Widget w, char *ha)
2963 if (XtHasCallbacks(w, XmNhelpCallback) == XtCallbackHasSome) {
2964 /* allow only one help callback */
2965 XtRemoveAllCallbacks(w, XmNhelpCallback);
2968 XtAddCallback(w, XmNhelpCallback, help_int_cb, (XtPointer) ha);
2971 void ContextHelpCB(Widget but, void *data)
2973 X11Stuff *xstuff = gapp->gui->xstuff;
2974 Widget whelp;
2975 Cursor cursor;
2976 int ok = FALSE;
2978 cursor = XCreateFontCursor(xstuff->disp, XC_question_arrow);
2979 whelp = XmTrackingLocate(app_shell, cursor, False);
2980 while (whelp != NULL) {
2981 if (XtHasCallbacks(whelp, XmNhelpCallback) == XtCallbackHasSome) {
2982 XtCallCallbacks(whelp, XmNhelpCallback, NULL);
2983 ok = TRUE;
2984 break;
2985 } else {
2986 whelp = XtParent(whelp);
2989 if (!ok) {
2990 HelpCB(but, NULL);
2992 XFreeCursor(xstuff->disp, cursor);
2996 static int yesno_retval = FALSE;
2997 static Boolean keep_grab = True;
2999 void yesnoCB(Widget w, XtPointer client_data, XtPointer call_data)
3001 XmAnyCallbackStruct *cbs = (XmAnyCallbackStruct *) call_data;
3002 int why = cbs->reason;
3004 keep_grab = False;
3006 XtRemoveGrab(XtParent(w));
3007 WidgetUnmanage(w);
3008 switch (why) {
3009 case XmCR_OK:
3010 yesno_retval = TRUE;
3011 /* process ok action */
3012 break;
3013 case XmCR_CANCEL:
3014 yesno_retval = FALSE;
3015 /* process cancel action */
3016 break;
3020 int yesnowin(char *msg, char *s1, char *s2, char *help_anchor)
3022 static Widget dialog = NULL;
3023 XEvent event;
3024 static char *ha = NULL;
3025 Widget but;
3026 XmString str;
3028 ha = help_anchor;
3030 keep_grab = True;
3032 if (dialog == NULL) {
3033 dialog = XmCreateErrorDialog(app_shell, "warningDialog", NULL, 0);
3035 str = XmStringCreateLocalized("Grace: Warning");
3036 XtVaSetValues(dialog, XmNdialogTitle, str, NULL);
3037 XmStringFree(str);
3039 XtAddCallback(dialog, XmNokCallback, yesnoCB, NULL);
3040 XtAddCallback(dialog, XmNcancelCallback, yesnoCB, NULL);
3042 but = XtNameToWidget(dialog, "Help");
3043 AddButtonCB(but, HelpCB, ha);
3046 if (msg != NULL) {
3047 str = XmStringCreateLocalized(msg);
3048 } else {
3049 str = XmStringCreateLocalized("Warning");
3051 XtVaSetValues(dialog, XmNmessageString, str, NULL);
3052 XmStringFree(str);
3054 but = XtNameToWidget(dialog, "OK");
3055 if (s1) {
3056 LabelSetString(but, s1);
3057 } else {
3058 LabelSetString(but, "OK");
3061 but = XtNameToWidget(dialog, "Cancel");
3062 if (s2) {
3063 LabelSetString(but, s2);
3064 } else {
3065 LabelSetString(but, "Cancel");
3068 but = XtNameToWidget(dialog, "Help");
3069 if (ha) {
3070 WidgetManage(but);
3071 } else {
3072 WidgetUnmanage(but);
3075 WidgetManage(dialog);
3076 XMapRaised(XtDisplay(dialog), XtWindow(dialog));
3078 XtAddGrab(XtParent(dialog), True, False);
3079 while (keep_grab || XtAppPending(app_con)) {
3080 XtAppNextEvent(app_con, &event);
3081 XtDispatchEvent(&event);
3083 return yesno_retval;
3086 void update_set_lists(Quark *gr)
3088 update_set_selectors(gr);
3090 snapshot_and_update(gapp->gp, FALSE);
3093 void update_all(void)
3095 if (!gapp->gui->inwin) {
3096 return;
3099 if (gui_is_page_free(gapp->gui)) {
3100 sync_canvas_size(gapp);
3103 update_ssd_selectors(gproject_get_top(gapp->gp));
3104 update_frame_selectors(gproject_get_top(gapp->gp));
3105 update_graph_selectors(gproject_get_top(gapp->gp));
3106 update_set_selectors(NULL);
3108 if (gapp->gui->need_colorsel_update == TRUE) {
3109 init_xvlibcolors();
3110 update_color_selectors();
3111 gapp->gui->need_colorsel_update = FALSE;
3114 if (gapp->gui->need_fontsel_update == TRUE) {
3115 update_font_selectors();
3116 gapp->gui->need_fontsel_update = FALSE;
3119 update_undo_buttons(gapp->gp);
3120 update_props_items();
3121 set_left_footer(NULL);
3122 update_app_title(gapp->gp);
3125 int clean_graph_selectors(Quark *pr, int etype, void *data)
3127 if (etype == QUARK_ETYPE_DELETE) {
3128 int i;
3129 for (i = 0; i < ngraph_selectors; i++) {
3130 SetStorageChoiceQuark(graph_selectors[i], NULL);
3132 for (i = 0; i < nssd_selectors; i++) {
3133 SetStorageChoiceQuark(ssd_selectors[i], NULL);
3135 } else
3136 if (etype == QUARK_ETYPE_MODIFY) {
3137 /* update_graph_selectors(pr); */
3140 return RETURN_SUCCESS;
3143 int clean_frame_selectors(Quark *pr, int etype, void *data)
3145 if (etype == QUARK_ETYPE_DELETE) {
3146 int i;
3147 for (i = 0; i < nframe_selectors; i++) {
3148 SetStorageChoiceQuark(frame_selectors[i], NULL);
3150 } else
3151 if (etype == QUARK_ETYPE_MODIFY) {
3152 /* update_frame_selectors(pr); */
3155 return RETURN_SUCCESS;
3158 int clean_set_selectors(Quark *gr, int etype, void *data)
3160 if (etype == QUARK_ETYPE_DELETE) {
3161 int i;
3162 for (i = 0; i < nset_selectors; i++) {
3163 Quark *cg;
3164 StorageStructure *ss = set_selectors[i];
3166 cg = get_set_choice_gr(ss);
3167 if (!gr || cg == gr) {
3168 SetStorageChoiceQuark(ss, NULL);
3173 return RETURN_SUCCESS;
3176 /* what a mess... */
3177 void unlink_ssd_ui(Quark *q)
3179 GUI *gui = gui_from_quark(q);
3180 if (gui && gui->eui && gui->eui->ssd_ui) {
3181 if (gui->eui->ssd_ui->q == q) {
3182 gui->eui->ssd_ui->q = NULL;
3184 if (gui->eui->ssd_ui->col_sel->anydata == q) {
3185 gui->eui->ssd_ui->col_sel->anydata = NULL;
3192 * action routines, to be used with translations
3195 /* This is for buggy Motif-2.1 that crashes with Ctrl+<Btn1Down> */
3196 static void do_nothing_action(Widget w, XEvent *e, String *par, Cardinal *npar)
3200 static void pageUp_action(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3202 Widget scrolledWindow, scrollBar;
3203 String al[1];
3205 al[0] = "Up";
3206 scrolledWindow = XtParent(w);
3207 scrollBar = XtNameToWidget (scrolledWindow, "VertScrollBar");
3208 if (scrollBar)
3209 XtCallActionProc(scrollBar, "PageUpOrLeft", event, al, 1) ;
3210 return;
3213 static void pageDown_action(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3215 Widget scrolledWindow, scrollBar;
3216 String al[1];
3218 al[0] = "Down";
3219 scrolledWindow = XtParent(w);
3220 scrollBar = XtNameToWidget (scrolledWindow, "VertScrollBar");
3221 if (scrollBar)
3222 XtCallActionProc(scrollBar, "PageDownOrRight", event, al, 1) ;
3223 return;
3226 static void scrollUp_action(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3228 Widget scrolledWindow, scrollBar;
3229 String al[1];
3230 int i, nLines;
3232 if (*nArgs == 0 || sscanf(args[0], "%d", &nLines) != 1)
3233 return;
3234 al[0] = "Up";
3235 scrolledWindow = XtParent(w);
3236 scrollBar = XtNameToWidget (scrolledWindow, "VertScrollBar");
3237 if (scrollBar)
3238 for (i=0; i<nLines; i++)
3239 XtCallActionProc(scrollBar, "IncrementUpOrLeft", event, al, 1) ;
3240 return;
3243 static void scrollDown_action(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3245 Widget scrolledWindow, scrollBar;
3246 String al[1];
3247 int i, nLines;
3249 if (*nArgs == 0 || sscanf(args[0], "%d", &nLines) != 1)
3250 return;
3251 al[0] = "Down";
3252 scrolledWindow = XtParent(w);
3253 scrollBar = XtNameToWidget (scrolledWindow, "VertScrollBar");
3254 if (scrollBar)
3255 for (i=0; i<nLines; i++)
3256 XtCallActionProc(scrollBar, "IncrementDownOrRight", event, al, 1) ;
3257 return;
3260 static XtActionsRec dummy_actions[] = {
3261 {"do_nothing", do_nothing_action}
3264 static XtActionsRec list_select_actions[] = {
3265 {"list_activate_action", list_activate_action },
3266 {"list_selectall_action", list_selectall_action },
3267 {"list_unselectall_action", list_unselectall_action },
3268 {"list_invertselection_action", list_invertselection_action}
3271 static XtActionsRec sw_scroll_actions[] = {
3272 {"scrolled-window-scroll-up", scrollUp_action },
3273 {"scrolled-window-page-up", pageUp_action },
3274 {"scrolled-window-scroll-down", scrollDown_action},
3275 {"scrolled-window-page-down", pageDown_action }
3278 void InitWidgets(void)
3280 XtAppAddActions(app_con, dummy_actions, XtNumber(dummy_actions));
3281 XtAppAddActions(app_con, list_select_actions, XtNumber(list_select_actions));
3282 XtAppAddActions(app_con, sw_scroll_actions, XtNumber(sw_scroll_actions));
3285 void set_title(char *title, char *icon_name)
3287 XtVaSetValues(app_shell, XtNtitle, title, XtNiconName, icon_name, NULL);
3290 /* Tree Widget */
3291 typedef struct {
3292 Widget w;
3293 XtIntervalId timeout_id;
3294 } TreeRefresh_CBdata;
3296 Widget CreateTree(Widget parent)
3298 Widget w;
3299 TreeRefresh_CBdata *cbdata;
3301 w = XmCreateScrolledListTree(parent, "tree", NULL, 0);
3302 ListTreeRefreshOff(w);
3304 cbdata = (TreeRefresh_CBdata *) xmalloc(sizeof(TreeRefresh_CBdata));
3305 cbdata->w = w;
3306 cbdata->timeout_id = (XtIntervalId) 0;
3308 WidgetSetUserData(w, cbdata);
3310 return w;
3313 TreeItem *TreeInsertItem(Widget w, TreeItem *parent, Quark *q, int row)
3315 ListTreeItem *item;
3316 ListTreeItem *parent_item = parent;
3318 if (row < 0) {
3319 item = ListTreeInsert(w, parent, "", parent_item->count + row + 1);
3320 } else {
3321 item = ListTreeInsert(w, parent, "", row);
3323 item->user_data = q;
3325 return item;
3328 void TreeDeleteItem(Widget w, TreeItem *item)
3330 ListTreeItem *titem = item;
3332 if (!item) {
3333 titem = ListTreeFirstItem(w);
3336 ListTreeDelete(w, titem);
3339 void TreeSetItemOpen(Widget w, TreeItem *item, int open)
3341 ListTreeItem *titem = item;
3343 titem->open = open;
3346 void TreeSetItemText(Widget w, TreeItem *item, char *text)
3348 ListTreeRenameItem(w, item, text);
3351 void TreeSetItemPixmap(Widget w, TreeItem *item, Pixmap pixmap)
3353 ListTreeSetItemPixmaps(w, item, pixmap, pixmap);
3356 Quark *TreeGetQuark(TreeItem *item)
3358 ListTreeItem *titem = item;
3360 return titem->user_data;
3363 void TreeGetHighlighted(Widget w, TreeItemList *items)
3365 int i;
3366 ListTreeMultiReturnStruct ret;
3368 ListTreeGetHighlighted(w, &ret);
3369 items->count = ret.count;
3370 items->items = (TreeItem **) xmalloc(items->count*sizeof(TreeItem *));
3371 for (i = 0; i < items->count; i++) {
3372 items->items[i] = (TreeItem *) ret.items[i];
3376 void TreeHighlightItem(Widget w, TreeItem *item)
3378 ListTreeItem *titem = item;
3379 ListTreeMultiReturnStruct ret;
3381 if (!item) {
3382 titem = ListTreeFirstItem(w);
3385 ListTreeHighlightItemMultiple(w, titem);
3387 ListTreeGetHighlighted(w, &ret);
3388 XtCallCallbacks(w, XtNhighlightCallback, (XtPointer) &ret);
3391 void TreeClearSelection(Widget w)
3393 ListTreeClearHighlighted(w);
3396 void TreeScrollToItem(Widget w, TreeItem *item)
3398 ListTreeItem *titem = item;
3399 int top, visible;
3401 ListTreeRefreshOn(w);
3402 ListTreeRefresh(w);
3403 ListTreeRefreshOff(w);
3405 XtVaGetValues(w,
3406 XtNtopItemPosition, &top,
3407 XtNvisibleItemCount, &visible,
3408 NULL);
3410 if (titem->count < top) {
3411 ListTreeSetPos(w, titem);
3412 } else
3413 if (titem->count >= top + visible) {
3414 ListTreeSetBottomPos(w, titem);
3418 static void tree_refresh_timer_proc(XtPointer client_data, XtIntervalId *id)
3420 TreeRefresh_CBdata *cbdata = (TreeRefresh_CBdata *) client_data;
3422 ListTreeRefreshOn(cbdata->w);
3423 ListTreeRefresh(cbdata->w);
3424 ListTreeRefreshOff(cbdata->w);
3426 cbdata->timeout_id = (XtIntervalId) 0;
3429 void TreeRefresh(Widget w)
3431 TreeRefresh_CBdata *cbdata;
3433 cbdata = (TreeRefresh_CBdata *) WidgetGetUserData(w);
3435 if (cbdata->timeout_id) {
3436 XtRemoveTimeOut(cbdata->timeout_id);
3438 cbdata->timeout_id = XtAppAddTimeOut(app_con,
3439 100 /* 0.1 second */, tree_refresh_timer_proc, cbdata);
3442 static void tree_context_menu_cb_proc(Widget w, XtPointer client_data, XtPointer call_data)
3444 Tree_CBData *cbdata = (Tree_CBData *) client_data;
3445 ListTreeItemReturnStruct *ret = (ListTreeItemReturnStruct *) call_data;
3446 XButtonEvent *xbe = (XButtonEvent *) ret->event;
3448 TreeEvent event;
3449 event.w = cbdata->w;
3450 event.anydata = cbdata->anydata;
3451 event.udata = xbe;
3453 cbdata->cbproc(&event);
3456 void AddTreeContextMenuCB(Widget w, Tree_CBProc cbproc, void *anydata)
3458 Tree_CBData *cbdata;
3460 cbdata = (Tree_CBData *) xmalloc(sizeof(Tree_CBData));
3461 cbdata->w = w;
3462 cbdata->cbproc = cbproc;
3463 cbdata->anydata = anydata;
3465 XtAddCallback(w, XtNmenuCallback, tree_context_menu_cb_proc, cbdata);
3468 static void tree_highlight_cb_proc(Widget w, XtPointer client_data, XtPointer call_data)
3470 Tree_CBData *cbdata = (Tree_CBData *) client_data;
3472 TreeEvent event;
3473 event.w = cbdata->w;
3474 event.anydata = cbdata->anydata;
3476 cbdata->cbproc(&event);
3479 void AddTreeHighlightItemsCB(Widget w, Tree_CBProc cbproc, void *anydata)
3481 Tree_CBData *cbdata;
3483 cbdata = (Tree_CBData *) xmalloc(sizeof(Tree_CBData));
3484 cbdata->w = w;
3485 cbdata->cbproc = cbproc;
3486 cbdata->anydata = anydata;
3488 XtAddCallback(w, XtNhighlightCallback, tree_highlight_cb_proc, cbdata);
3491 static void tree_drop_items_cb_proc(Widget w, XtPointer client_data, XtPointer call_data)
3493 Tree_CBData *cbdata = (Tree_CBData *) client_data;
3494 ListTreeDropStruct *cbs = (ListTreeDropStruct *) call_data;
3496 TreeEvent event;
3497 event.w = cbdata->w;
3498 event.anydata = cbdata->anydata;
3499 event.udata = cbs->item;
3501 switch (cbs->operation) {
3502 case XmDROP_MOVE:
3503 event.drop_action = DROP_ACTION_MOVE;
3504 break;
3505 case XmDROP_COPY:
3506 event.drop_action = DROP_ACTION_COPY;
3507 break;
3508 default:
3509 cbs->ok = FALSE;
3510 return;
3513 if (cbdata->cbproc(&event)) {
3514 cbs->ok = TRUE;
3515 } else {
3516 cbs->ok = FALSE;
3520 void AddTreeDropItemsCB(Widget w, Tree_CBProc cbproc, void *anydata)
3522 Tree_CBData *cbdata;
3524 cbdata = (Tree_CBData *) xmalloc(sizeof(Tree_CBData));
3525 cbdata->w = w;
3526 cbdata->cbproc = cbproc;
3527 cbdata->anydata = anydata;
3529 XtAddCallback(w, XtNdropCallback, tree_drop_items_cb_proc, cbdata);
3532 /* Table Widget */
3533 typedef struct {
3534 int default_col_width;
3535 int default_col_label_alignment;
3536 int nrows_visible;
3537 int ncols_visible;
3538 } TableData;
3540 Widget CreateTable(char *name, Widget parent, int nrows, int ncols, int nrows_visible, int ncols_visible)
3542 Widget w;
3543 TableData *td;
3545 td = (TableData*) xmalloc(sizeof(TableData));
3546 td->default_col_width = 5;
3547 td->default_col_label_alignment = ALIGN_BEGINNING;
3548 td->nrows_visible = nrows_visible;
3549 td->ncols_visible = ncols_visible;
3551 w = XtVaCreateManagedWidget(name,
3552 xbaeMatrixWidgetClass, parent,
3553 XmNrows, nrows,
3554 XmNvisibleRows, nrows_visible,
3555 XmNcolumns, ncols,
3556 XmNvisibleColumns, ncols_visible,
3557 NULL);
3559 WidgetSetUserData(w, td);
3561 return w;
3564 static char tfield_translation_table[] = "\
3565 <Key>osfCancel : CancelEdit(True)\n\
3566 <Key>osfActivate : EditCell(Down)\n\
3567 <Key>osfUp : EditCell(Up)\n\
3568 <Key>osfDown : EditCell(Down)\n\
3569 ~Shift ~Meta ~Alt <Key>Return : EditCell(Down)";
3571 void TableSSDInit(Widget w)
3573 Widget tfield;
3575 XtVaSetValues(w,
3576 #if 0
3577 XmNhorizontalScrollBarDisplayPolicy, XmDISPLAY_NONE,
3578 XmNverticalScrollBarDisplayPolicy, XmDISPLAY_NONE,
3579 #endif
3580 XmNbuttonLabels, True,
3581 XmNallowColumnResize, True,
3582 XmNgridType, XmGRID_CELL_SHADOW,
3583 XmNcellShadowType, XmSHADOW_ETCHED_OUT,
3584 XmNcellShadowThickness, 1,
3585 XmNcellMarginHeight, 1,
3586 XmNcellMarginWidth, 1,
3587 XmNshadowThickness, 1,
3588 XmNaltRowCount, 0,
3589 XmNcalcCursorPosition, True,
3590 XmNtraverseFixedCells, True,
3591 NULL);
3593 tfield = XtNameToWidget(w, "textField");
3594 XtOverrideTranslations(tfield,
3595 XtParseTranslationTable(tfield_translation_table));
3598 void TableFontInit(Widget w)
3600 XtVaSetValues(w,
3601 XmNfill, True,
3602 XmNgridType, XmGRID_CELL_SHADOW,
3603 XmNcellShadowType, XmSHADOW_ETCHED_OUT,
3604 XmNcellShadowThickness, 2,
3605 XmNaltRowCount, 0,
3606 NULL);
3609 void TableDataSetPropInit(Widget w)
3611 XtVaSetValues(w,
3612 XmNshowArrows, True,
3613 XmNallowColumnResize, True,
3614 XmNgridType, XmGRID_COLUMN_SHADOW,
3615 XmNcellShadowType, XmSHADOW_OUT,
3616 XmNcellShadowThickness, 1,
3617 XmNaltRowCount, 1,
3618 XmNtraversalOn, False,
3619 NULL);
3622 void TableLevalInit(Widget w)
3624 XtVaSetValues(w,
3625 XmNgridType, XmGRID_CELL_SHADOW,
3626 XmNcellShadowType, XmSHADOW_ETCHED_OUT,
3627 XmNcellShadowThickness, 2,
3628 XmNaltRowCount, 0,
3629 XmNallowColumnResize, True,
3630 NULL);
3633 static int align_to_xmalign(int align)
3635 switch(align) {
3636 case ALIGN_BEGINNING:
3637 return XmALIGNMENT_BEGINNING;
3638 break;
3639 case ALIGN_CENTER:
3640 return XmALIGNMENT_CENTER;
3641 break;
3642 case ALIGN_END:
3643 return XmALIGNMENT_END;
3644 break;
3645 default:
3646 return XmALIGNMENT_BEGINNING;
3650 int TableGetNrows(Widget w)
3652 int nr;
3654 XtVaGetValues(w, XmNrows, &nr, NULL);
3656 return nr;
3659 int TableGetNcols(Widget w)
3661 int nc;
3663 XtVaGetValues(w, XmNcolumns, &nc, NULL);
3665 return nc;
3668 void TableAddRows(Widget w, int nrows)
3670 XbaeMatrixAddRows(w, TableGetNrows(w), NULL, NULL, NULL, nrows);
3673 void TableDeleteRows(Widget w, int nrows)
3675 XbaeMatrixDeleteRows(w, TableGetNrows(w) - nrows, nrows);
3678 void TableAddCols(Widget w, int ncols)
3680 TableData *td;
3681 short *widths;
3682 int i;
3683 unsigned char *alignment, xm_alignment;
3685 td = (TableData*) WidgetGetUserData(w);
3686 xm_alignment = align_to_xmalign(td->default_col_label_alignment);
3687 widths = xmalloc(ncols*SIZEOF_SHORT);
3688 alignment = xmalloc(ncols);
3690 for (i = 0; i < ncols; i++) {
3691 widths[i] = td->default_col_width;
3692 alignment[i] = xm_alignment;
3695 XbaeMatrixAddColumns(w, TableGetNcols(w), NULL, NULL, widths, NULL, NULL, alignment, NULL, ncols);
3697 xfree(alignment);
3698 xfree(widths);
3701 void TableDeleteCols(Widget w, int ncols)
3703 XbaeMatrixDeleteColumns(w, TableGetNcols(w) - ncols, ncols);
3706 void TableGetCellDimentions(Widget w, int *cwidth, int *cheight)
3708 int x0, x1, y0, y1;
3710 XbaeMatrixRowColToXY(w, 0, 0, &x0, &y0);
3711 XbaeMatrixRowColToXY(w, 1, 1, &x1, &y1);
3712 *cwidth = x1 - x0;
3713 *cheight = y1 - y0;
3716 void TableSetColWidths(Widget w, int *widths)
3718 int i, ncols;
3719 short *short_widths;
3721 ncols = TableGetNcols(w);
3723 short_widths = xmalloc(ncols*SIZEOF_SHORT);
3725 for (i = 0; i < ncols; i++) {
3726 short_widths[i] = (short) widths[i];
3729 XtVaSetValues(w, XmNcolumnWidths, short_widths, NULL);
3731 xfree(short_widths);
3734 void TableSetDefaultRowLabelWidth(Widget w, int width)
3736 XtVaSetValues(w, XmNrowLabelWidth, width, NULL);
3739 void TableSetDefaultRowLabelAlignment(Widget w, int align)
3741 unsigned char xm_alignment;
3743 xm_alignment = align_to_xmalign(align);
3745 XtVaSetValues(w, XmNrowLabelAlignment, xm_alignment, NULL);
3748 void TableSetDefaultColWidth(Widget w, int width)
3750 TableData *td;
3751 short *widths;
3752 int ncols, i;
3754 td = (TableData*) WidgetGetUserData(w);
3755 td->default_col_width = width;
3757 ncols = TableGetNcols(w);
3759 widths = xmalloc(ncols*SIZEOF_SHORT);
3761 for (i = 0; i < ncols; i++) {
3762 widths[i] = td->default_col_width;
3765 XtVaSetValues(w, XmNcolumnWidths, widths, NULL);
3767 xfree(widths);
3770 void TableSetDefaultColAlignment(Widget w, int align)
3772 unsigned char *alignment, xm_alignment;
3773 int ncols, i;
3775 xm_alignment = align_to_xmalign(align);
3776 ncols = TableGetNcols(w);
3778 alignment = xmalloc(ncols);
3780 for (i = 0; i < ncols; i++) {
3781 alignment[i] = xm_alignment;
3784 XtVaSetValues(w, XmNcolumnAlignments, alignment, NULL);
3786 xfree(alignment);
3789 void TableSetDefaultColLabelAlignment(Widget w, int align)
3791 TableData *td;
3792 unsigned char *alignment, xm_alignment;
3793 int ncols, i;
3795 td = (TableData*) WidgetGetUserData(w);
3796 td->default_col_label_alignment = align;
3798 xm_alignment = align_to_xmalign(align);
3799 ncols = TableGetNcols(w);
3801 alignment = xmalloc(ncols);
3803 for (i = 0; i < ncols; i++) {
3804 alignment[i] = xm_alignment;
3807 XtVaSetValues(w, XmNcolumnLabelAlignments, alignment, NULL);
3809 xfree(alignment);
3812 void TableSetColMaxlengths(Widget w, int *maxlengths)
3814 XtVaSetValues(w, XmNcolumnMaxLengths, maxlengths, NULL);
3817 void TableSetRowLabels(Widget w, char **labels)
3819 XtVaSetValues(w, XmNrowLabels, labels, NULL);
3821 XtVaSetValues(w, XmNrowLabelWidth, 0, NULL);
3824 void TableSetColLabels(Widget w, char **labels)
3826 XtVaSetValues(w, XmNcolumnLabels, labels, NULL);
3829 void TableSetFixedCols(Widget w, int nfixed_cols)
3831 XtVaSetValues(w, XmNfixedColumns, nfixed_cols, NULL);
3834 void TableUpdateVisibleRowsCols(Widget w)
3836 XtVaSetValues(w,
3837 XmNheight, 0,
3838 XmNwidth, 0,
3839 NULL);
3842 void TableCommitEdit(Widget w, int close)
3844 XbaeMatrixCommitEdit(w, close);
3847 void TableSetCells(Widget w, char ***cells)
3849 XtVaSetValues(w, XmNcells, cells, NULL);
3852 void TableSetCell(Widget w, int row, int col, char *value)
3854 XbaeMatrixSetCell(w, row, col, value);
3857 char *TableGetCell(Widget w, int row, int col)
3859 return XbaeMatrixGetCell(w, row, col);
3862 void TableSelectCell(Widget w, int row, int col)
3864 XbaeMatrixSelectCell(w, row, col);
3867 void TableDeselectCell(Widget w, int row, int col)
3869 XbaeMatrixDeselectCell(w, row, col);
3872 void TableSelectRow(Widget w, int row)
3874 XbaeMatrixSelectRow(w, row);
3877 void TableDeselectRow(Widget w, int row)
3879 XbaeMatrixDeselectRow(w, row);
3882 void TableSelectCol(Widget w, int col)
3884 XbaeMatrixSelectColumn(w, col);
3887 void TableDeselectCol(Widget w, int col)
3889 XbaeMatrixDeselectColumn(w, col);
3892 void TableDeselectAllCells(Widget w)
3894 XbaeMatrixDeselectAll(w);
3897 int TableIsRowSelected(Widget w, int row)
3899 return XbaeMatrixIsRowSelected(w, row);
3902 int TableIsColSelected(Widget w, int col)
3904 return XbaeMatrixIsColumnSelected(w, col);
3907 void TableUpdate(Widget w)
3909 XbaeMatrixRefresh(w);
3912 static void drawcellCB(Widget w, XtPointer client_data, XtPointer call_data)
3914 TableEvent event;
3915 Table_CBData *cbdata = (Table_CBData *) client_data;
3916 XbaeMatrixDrawCellCallbackStruct *cs =
3917 (XbaeMatrixDrawCellCallbackStruct *) call_data;
3919 event.w = cbdata->w;
3920 event.row = cs->row;
3921 event.col = cs->column;
3922 event.anydata = cbdata->anydata;
3923 event.value_type = TABLE_CELL_NONE;
3925 cbdata->cbproc(&event);
3927 if (event.value_type == TABLE_CELL_STRING) {
3928 cs->type = XbaeString;
3929 cs->string = event.value;
3930 } else if (event.value_type == TABLE_CELL_PIXMAP) {
3931 cs->type = XbaePixmap;
3932 cs->pixmap = event.pixmap;
3936 void AddTableDrawCellCB(Widget w, Table_CBProc cbproc, void *anydata)
3938 Table_CBData *cbdata;
3940 cbdata = (Table_CBData *) xmalloc(sizeof(Table_CBData));
3941 cbdata->w = w;
3942 cbdata->cbproc = cbproc;
3943 cbdata->anydata = anydata;
3945 XtAddCallback(w, XmNdrawCellCallback, drawcellCB, cbdata);
3948 static void enterCB(Widget w, XtPointer client_data, XtPointer call_data)
3950 TableEvent event;
3951 Table_CBData *cbdata = (Table_CBData *) client_data;
3952 XbaeMatrixEnterCellCallbackStruct *cs =
3953 (XbaeMatrixEnterCellCallbackStruct *) call_data;
3955 int ok;
3957 event.w = cbdata->w;
3958 event.row = cs->row;
3959 event.col = cs->column;
3960 event.anydata = cbdata->anydata;
3961 ok = cbdata->cbproc(&event);
3963 if (!ok) {
3964 cs->doit = False;
3965 cs->map = False;
3969 void AddTableEnterCellCB(Widget w, Table_CBProc cbproc, void *anydata)
3971 Table_CBData *cbdata;
3973 cbdata = (Table_CBData *) xmalloc(sizeof(Table_CBData));
3974 cbdata->w = w;
3975 cbdata->cbproc = cbproc;
3976 cbdata->anydata = anydata;
3978 XtAddCallback(w, XmNenterCellCallback, enterCB, cbdata);
3981 static void leaveCB(Widget w, XtPointer client_data, XtPointer call_data)
3983 TableEvent event;
3984 Table_CBData *cbdata = (Table_CBData *) client_data;
3985 XbaeMatrixLeaveCellCallbackStruct *cs =
3986 (XbaeMatrixLeaveCellCallbackStruct *) call_data;
3988 int ok;
3990 event.w = cbdata->w;
3991 event.row = cs->row;
3992 event.col = cs->column;
3993 event.value = cs->value;
3994 event.anydata = cbdata->anydata;
3995 ok = cbdata->cbproc(&event);
3997 if (!ok) {
3998 cs->doit = False;
4002 void AddTableLeaveCellCB(Widget w, Table_CBProc cbproc, void *anydata)
4004 Table_CBData *cbdata;
4006 cbdata = (Table_CBData *) xmalloc(sizeof(Table_CBData));
4007 cbdata->w = w;
4008 cbdata->cbproc = cbproc;
4009 cbdata->anydata = anydata;
4011 XtAddCallback(w, XmNleaveCellCallback, leaveCB, cbdata);
4014 static void labelCB(Widget w, XtPointer client_data, XtPointer call_data)
4016 XButtonEvent *xbe;
4018 TableEvent event;
4019 Table_CBData *cbdata = (Table_CBData *) client_data;
4020 XbaeMatrixLabelActivateCallbackStruct *cbs =
4021 (XbaeMatrixLabelActivateCallbackStruct *) call_data;
4023 event.button = NO_BUTTON;
4024 event.modifiers = NO_MODIFIER;
4025 event.anydata = cbdata->anydata;
4027 event.w = w;
4028 event.row = cbs->row;
4029 event.col = cbs->column;
4030 event.row_label = cbs->row_label;
4032 switch (cbs->event->type) {
4033 case ButtonPress:
4034 event.type = MOUSE_PRESS;
4035 xbe = (XButtonEvent *) cbs->event;
4036 event.udata = xbe;
4037 switch (cbs->event->xbutton.button) {
4038 case Button1:
4039 event.button = event.button ^ LEFT_BUTTON;
4040 break;
4041 case Button3:
4042 event.button = event.button ^ RIGHT_BUTTON;
4043 break;
4045 if (xbe->state & ControlMask) {
4046 event.modifiers = event.modifiers ^ CONTROL_MODIFIER;
4048 if (xbe->state & ShiftMask) {
4049 event.modifiers = event.modifiers ^ SHIFT_MODIFIER;
4051 break;
4052 default:
4053 break;
4056 cbdata->cbproc(&event);
4059 void AddTableLabelActivateCB(Widget w, Table_CBProc cbproc, void *anydata)
4061 Table_CBData *cbdata;
4063 cbdata = (Table_CBData *) xmalloc(sizeof(Table_CBData));
4064 cbdata->w = w;
4065 cbdata->cbproc = cbproc;
4066 cbdata->anydata = anydata;
4068 XtAddCallback(w, XmNlabelActivateCallback, labelCB, cbdata);
4071 /* ScrollBar */
4072 void GetScrollBarValues(Widget w, int *value, int *maxvalue, int *slider_size, int *increment)
4074 Arg args[4];
4075 int i = 0;
4077 if (value) {
4078 XtSetArg(args[i], XmNvalue, value); i++;
4081 if (maxvalue) {
4082 XtSetArg(args[i], XmNmaximum, maxvalue); i++;
4085 if (slider_size) {
4086 XtSetArg(args[i], XmNsliderSize, slider_size); i++;
4089 if (increment) {
4090 XtSetArg(args[i], XmNincrement, increment); i++;
4093 if (i != 0) {
4094 XtGetValues(w, args, i);
4098 void SetScrollBarValue(Widget w, int value)
4100 XmScrollBarSetValues(w, value, 0, 0, 0, True);
4103 void SetScrollBarIncrement(Widget w, int increment)
4105 XtVaSetValues(w, XmNincrement, increment, NULL);
4108 Widget GetHorizontalScrollBar(Widget w)
4110 return XtNameToWidget(w, "HorScrollBar");
4113 Widget GetVerticalScrollBar(Widget w)
4115 return XtNameToWidget(w, "VertScrollBar");
4119 ** Add mouse wheel support to a specific widget, which must be the scrollable
4120 ** widget of a ScrolledWindow.
4122 void AddMouseWheelSupport(Widget w)
4124 if (XmIsScrolledWindow(XtParent(w)))
4126 static const char scrollTranslations[] =
4127 "Shift<Btn4Down>: scrolled-window-scroll-up(1)\n"
4128 "Shift<Btn5Down>: scrolled-window-scroll-down(1)\n"
4129 "Ctrl<Btn4Down>: scrolled-window-page-up()\n"
4130 "Ctrl<Btn5Down>: scrolled-window-page-down()\n"
4131 "<Btn4Down>: scrolled-window-scroll-up(3)\n"
4132 "<Btn5Down>: scrolled-window-scroll-down(3)\n";
4133 static XtTranslations trans_table = NULL;
4135 if (trans_table == NULL)
4137 trans_table = XtParseTranslationTable(scrollTranslations);
4139 XtOverrideTranslations(w, trans_table);
4143 void SetFocus(Widget w)
4145 XmProcessTraversal(w, XmTRAVERSE_CURRENT);