Reimplemented AddWindowCloseCB
[grace.git] / src / motifutils.c
blob79f32248d47891336cbb1134e9eb7d8d23e6f617
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 windowCloseCB(Widget w, XtPointer client_data, XtPointer call_data)
2911 Widget_CBData *cbdata = (Widget_CBData *) client_data;
2913 cbdata->cbproc(cbdata);
2916 * handle the close item on the WM menu
2918 void AddWindowCloseCB(Widget w, Widget_CBProc cbproc, void *anydata)
2920 X11Stuff *xstuff = gapp->gui->xstuff;
2921 Atom WM_DELETE_WINDOW;
2922 Widget_CBData *cbdata;
2924 cbdata = (Widget_CBData *) xmalloc(sizeof(Widget_CBData));
2925 cbdata->w = w;
2926 cbdata->cbproc = cbproc;
2927 cbdata->anydata = anydata;
2929 XtVaSetValues(w, XmNdeleteResponse, XmDO_NOTHING, NULL);
2931 WM_DELETE_WINDOW = XmInternAtom(xstuff->disp, "WM_DELETE_WINDOW", False);
2932 XmAddWMProtocolCallback(w, WM_DELETE_WINDOW, windowCloseCB, cbdata);
2934 savewidget(w);
2937 void DefineDialogCursor(Cursor c)
2939 X11Stuff *xstuff = gapp->gui->xstuff;
2940 int i;
2942 for (i = 0; i < nsavedwidgets; i++) {
2943 XDefineCursor(xstuff->disp, XtWindow(savewidgets[i]), c);
2945 XFlush(xstuff->disp);
2948 void UndefineDialogCursor(void)
2950 X11Stuff *xstuff = gapp->gui->xstuff;
2951 int i;
2953 for (i = 0; i < nsavedwidgets; i++) {
2954 XUndefineCursor(xstuff->disp, XtWindow(savewidgets[i]));
2956 XFlush(xstuff->disp);
2959 static void help_int_cb(Widget w, XtPointer client_data, XtPointer call_data)
2961 HelpCB(w, client_data);
2964 void AddHelpCB(Widget w, char *ha)
2966 if (XtHasCallbacks(w, XmNhelpCallback) == XtCallbackHasSome) {
2967 /* allow only one help callback */
2968 XtRemoveAllCallbacks(w, XmNhelpCallback);
2971 XtAddCallback(w, XmNhelpCallback, help_int_cb, (XtPointer) ha);
2974 void ContextHelpCB(Widget but, void *data)
2976 X11Stuff *xstuff = gapp->gui->xstuff;
2977 Widget whelp;
2978 Cursor cursor;
2979 int ok = FALSE;
2981 cursor = XCreateFontCursor(xstuff->disp, XC_question_arrow);
2982 whelp = XmTrackingLocate(app_shell, cursor, False);
2983 while (whelp != NULL) {
2984 if (XtHasCallbacks(whelp, XmNhelpCallback) == XtCallbackHasSome) {
2985 XtCallCallbacks(whelp, XmNhelpCallback, NULL);
2986 ok = TRUE;
2987 break;
2988 } else {
2989 whelp = XtParent(whelp);
2992 if (!ok) {
2993 HelpCB(but, NULL);
2995 XFreeCursor(xstuff->disp, cursor);
2999 static int yesno_retval = FALSE;
3000 static Boolean keep_grab = True;
3002 void yesnoCB(Widget w, XtPointer client_data, XtPointer call_data)
3004 XmAnyCallbackStruct *cbs = (XmAnyCallbackStruct *) call_data;
3005 int why = cbs->reason;
3007 keep_grab = False;
3009 XtRemoveGrab(XtParent(w));
3010 WidgetUnmanage(w);
3011 switch (why) {
3012 case XmCR_OK:
3013 yesno_retval = TRUE;
3014 /* process ok action */
3015 break;
3016 case XmCR_CANCEL:
3017 yesno_retval = FALSE;
3018 /* process cancel action */
3019 break;
3023 int yesnowin(char *msg, char *s1, char *s2, char *help_anchor)
3025 static Widget dialog = NULL;
3026 XEvent event;
3027 static char *ha = NULL;
3028 Widget but;
3029 XmString str;
3031 ha = help_anchor;
3033 keep_grab = True;
3035 if (dialog == NULL) {
3036 dialog = XmCreateErrorDialog(app_shell, "warningDialog", NULL, 0);
3038 str = XmStringCreateLocalized("Grace: Warning");
3039 XtVaSetValues(dialog, XmNdialogTitle, str, NULL);
3040 XmStringFree(str);
3042 XtAddCallback(dialog, XmNokCallback, yesnoCB, NULL);
3043 XtAddCallback(dialog, XmNcancelCallback, yesnoCB, NULL);
3045 but = XtNameToWidget(dialog, "Help");
3046 AddButtonCB(but, HelpCB, ha);
3049 if (msg != NULL) {
3050 str = XmStringCreateLocalized(msg);
3051 } else {
3052 str = XmStringCreateLocalized("Warning");
3054 XtVaSetValues(dialog, XmNmessageString, str, NULL);
3055 XmStringFree(str);
3057 but = XtNameToWidget(dialog, "OK");
3058 if (s1) {
3059 LabelSetString(but, s1);
3060 } else {
3061 LabelSetString(but, "OK");
3064 but = XtNameToWidget(dialog, "Cancel");
3065 if (s2) {
3066 LabelSetString(but, s2);
3067 } else {
3068 LabelSetString(but, "Cancel");
3071 but = XtNameToWidget(dialog, "Help");
3072 if (ha) {
3073 WidgetManage(but);
3074 } else {
3075 WidgetUnmanage(but);
3078 WidgetManage(dialog);
3079 XMapRaised(XtDisplay(dialog), XtWindow(dialog));
3081 XtAddGrab(XtParent(dialog), True, False);
3082 while (keep_grab || XtAppPending(app_con)) {
3083 XtAppNextEvent(app_con, &event);
3084 XtDispatchEvent(&event);
3086 return yesno_retval;
3089 void update_set_lists(Quark *gr)
3091 update_set_selectors(gr);
3093 snapshot_and_update(gapp->gp, FALSE);
3096 void update_all(void)
3098 if (!gapp->gui->inwin) {
3099 return;
3102 if (gui_is_page_free(gapp->gui)) {
3103 sync_canvas_size(gapp);
3106 update_ssd_selectors(gproject_get_top(gapp->gp));
3107 update_frame_selectors(gproject_get_top(gapp->gp));
3108 update_graph_selectors(gproject_get_top(gapp->gp));
3109 update_set_selectors(NULL);
3111 if (gapp->gui->need_colorsel_update == TRUE) {
3112 init_xvlibcolors();
3113 update_color_selectors();
3114 gapp->gui->need_colorsel_update = FALSE;
3117 if (gapp->gui->need_fontsel_update == TRUE) {
3118 update_font_selectors();
3119 gapp->gui->need_fontsel_update = FALSE;
3122 update_undo_buttons(gapp->gp);
3123 update_props_items();
3124 set_left_footer(NULL);
3125 update_app_title(gapp->gp);
3128 int clean_graph_selectors(Quark *pr, int etype, void *data)
3130 if (etype == QUARK_ETYPE_DELETE) {
3131 int i;
3132 for (i = 0; i < ngraph_selectors; i++) {
3133 SetStorageChoiceQuark(graph_selectors[i], NULL);
3135 for (i = 0; i < nssd_selectors; i++) {
3136 SetStorageChoiceQuark(ssd_selectors[i], NULL);
3138 } else
3139 if (etype == QUARK_ETYPE_MODIFY) {
3140 /* update_graph_selectors(pr); */
3143 return RETURN_SUCCESS;
3146 int clean_frame_selectors(Quark *pr, int etype, void *data)
3148 if (etype == QUARK_ETYPE_DELETE) {
3149 int i;
3150 for (i = 0; i < nframe_selectors; i++) {
3151 SetStorageChoiceQuark(frame_selectors[i], NULL);
3153 } else
3154 if (etype == QUARK_ETYPE_MODIFY) {
3155 /* update_frame_selectors(pr); */
3158 return RETURN_SUCCESS;
3161 int clean_set_selectors(Quark *gr, int etype, void *data)
3163 if (etype == QUARK_ETYPE_DELETE) {
3164 int i;
3165 for (i = 0; i < nset_selectors; i++) {
3166 Quark *cg;
3167 StorageStructure *ss = set_selectors[i];
3169 cg = get_set_choice_gr(ss);
3170 if (!gr || cg == gr) {
3171 SetStorageChoiceQuark(ss, NULL);
3176 return RETURN_SUCCESS;
3179 /* what a mess... */
3180 void unlink_ssd_ui(Quark *q)
3182 GUI *gui = gui_from_quark(q);
3183 if (gui && gui->eui && gui->eui->ssd_ui) {
3184 if (gui->eui->ssd_ui->q == q) {
3185 gui->eui->ssd_ui->q = NULL;
3187 if (gui->eui->ssd_ui->col_sel->anydata == q) {
3188 gui->eui->ssd_ui->col_sel->anydata = NULL;
3195 * action routines, to be used with translations
3198 /* This is for buggy Motif-2.1 that crashes with Ctrl+<Btn1Down> */
3199 static void do_nothing_action(Widget w, XEvent *e, String *par, Cardinal *npar)
3203 static void pageUp_action(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3205 Widget scrolledWindow, scrollBar;
3206 String al[1];
3208 al[0] = "Up";
3209 scrolledWindow = XtParent(w);
3210 scrollBar = XtNameToWidget (scrolledWindow, "VertScrollBar");
3211 if (scrollBar)
3212 XtCallActionProc(scrollBar, "PageUpOrLeft", event, al, 1) ;
3213 return;
3216 static void pageDown_action(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3218 Widget scrolledWindow, scrollBar;
3219 String al[1];
3221 al[0] = "Down";
3222 scrolledWindow = XtParent(w);
3223 scrollBar = XtNameToWidget (scrolledWindow, "VertScrollBar");
3224 if (scrollBar)
3225 XtCallActionProc(scrollBar, "PageDownOrRight", event, al, 1) ;
3226 return;
3229 static void scrollUp_action(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3231 Widget scrolledWindow, scrollBar;
3232 String al[1];
3233 int i, nLines;
3235 if (*nArgs == 0 || sscanf(args[0], "%d", &nLines) != 1)
3236 return;
3237 al[0] = "Up";
3238 scrolledWindow = XtParent(w);
3239 scrollBar = XtNameToWidget (scrolledWindow, "VertScrollBar");
3240 if (scrollBar)
3241 for (i=0; i<nLines; i++)
3242 XtCallActionProc(scrollBar, "IncrementUpOrLeft", event, al, 1) ;
3243 return;
3246 static void scrollDown_action(Widget w, XEvent *event, String *args, Cardinal *nArgs)
3248 Widget scrolledWindow, scrollBar;
3249 String al[1];
3250 int i, nLines;
3252 if (*nArgs == 0 || sscanf(args[0], "%d", &nLines) != 1)
3253 return;
3254 al[0] = "Down";
3255 scrolledWindow = XtParent(w);
3256 scrollBar = XtNameToWidget (scrolledWindow, "VertScrollBar");
3257 if (scrollBar)
3258 for (i=0; i<nLines; i++)
3259 XtCallActionProc(scrollBar, "IncrementDownOrRight", event, al, 1) ;
3260 return;
3263 static XtActionsRec dummy_actions[] = {
3264 {"do_nothing", do_nothing_action}
3267 static XtActionsRec list_select_actions[] = {
3268 {"list_activate_action", list_activate_action },
3269 {"list_selectall_action", list_selectall_action },
3270 {"list_unselectall_action", list_unselectall_action },
3271 {"list_invertselection_action", list_invertselection_action}
3274 static XtActionsRec sw_scroll_actions[] = {
3275 {"scrolled-window-scroll-up", scrollUp_action },
3276 {"scrolled-window-page-up", pageUp_action },
3277 {"scrolled-window-scroll-down", scrollDown_action},
3278 {"scrolled-window-page-down", pageDown_action }
3281 void InitWidgets(void)
3283 XtAppAddActions(app_con, dummy_actions, XtNumber(dummy_actions));
3284 XtAppAddActions(app_con, list_select_actions, XtNumber(list_select_actions));
3285 XtAppAddActions(app_con, sw_scroll_actions, XtNumber(sw_scroll_actions));
3288 void set_title(char *title, char *icon_name)
3290 XtVaSetValues(app_shell, XtNtitle, title, XtNiconName, icon_name, NULL);
3293 /* Tree Widget */
3294 typedef struct {
3295 Widget w;
3296 XtIntervalId timeout_id;
3297 } TreeRefresh_CBdata;
3299 Widget CreateTree(Widget parent)
3301 Widget w;
3302 TreeRefresh_CBdata *cbdata;
3304 w = XmCreateScrolledListTree(parent, "tree", NULL, 0);
3305 ListTreeRefreshOff(w);
3307 cbdata = (TreeRefresh_CBdata *) xmalloc(sizeof(TreeRefresh_CBdata));
3308 cbdata->w = w;
3309 cbdata->timeout_id = (XtIntervalId) 0;
3311 WidgetSetUserData(w, cbdata);
3313 return w;
3316 TreeItem *TreeInsertItem(Widget w, TreeItem *parent, Quark *q, int row)
3318 ListTreeItem *item;
3319 ListTreeItem *parent_item = parent;
3321 if (row < 0) {
3322 item = ListTreeInsert(w, parent, "", parent_item->count + row + 1);
3323 } else {
3324 item = ListTreeInsert(w, parent, "", row);
3326 item->user_data = q;
3328 return item;
3331 void TreeDeleteItem(Widget w, TreeItem *item)
3333 ListTreeItem *titem = item;
3335 if (!item) {
3336 titem = ListTreeFirstItem(w);
3339 ListTreeDelete(w, titem);
3342 void TreeSetItemOpen(Widget w, TreeItem *item, int open)
3344 ListTreeItem *titem = item;
3346 titem->open = open;
3349 void TreeSetItemText(Widget w, TreeItem *item, char *text)
3351 ListTreeRenameItem(w, item, text);
3354 void TreeSetItemPixmap(Widget w, TreeItem *item, Pixmap pixmap)
3356 ListTreeSetItemPixmaps(w, item, pixmap, pixmap);
3359 Quark *TreeGetQuark(TreeItem *item)
3361 ListTreeItem *titem = item;
3363 return titem->user_data;
3366 void TreeGetHighlighted(Widget w, TreeItemList *items)
3368 int i;
3369 ListTreeMultiReturnStruct ret;
3371 ListTreeGetHighlighted(w, &ret);
3372 items->count = ret.count;
3373 items->items = (TreeItem **) xmalloc(items->count*sizeof(TreeItem *));
3374 for (i = 0; i < items->count; i++) {
3375 items->items[i] = (TreeItem *) ret.items[i];
3379 void TreeHighlightItem(Widget w, TreeItem *item)
3381 ListTreeItem *titem = item;
3382 ListTreeMultiReturnStruct ret;
3384 if (!item) {
3385 titem = ListTreeFirstItem(w);
3388 ListTreeHighlightItemMultiple(w, titem);
3390 ListTreeGetHighlighted(w, &ret);
3391 XtCallCallbacks(w, XtNhighlightCallback, (XtPointer) &ret);
3394 void TreeClearSelection(Widget w)
3396 ListTreeClearHighlighted(w);
3399 void TreeScrollToItem(Widget w, TreeItem *item)
3401 ListTreeItem *titem = item;
3402 int top, visible;
3404 ListTreeRefreshOn(w);
3405 ListTreeRefresh(w);
3406 ListTreeRefreshOff(w);
3408 XtVaGetValues(w,
3409 XtNtopItemPosition, &top,
3410 XtNvisibleItemCount, &visible,
3411 NULL);
3413 if (titem->count < top) {
3414 ListTreeSetPos(w, titem);
3415 } else
3416 if (titem->count >= top + visible) {
3417 ListTreeSetBottomPos(w, titem);
3421 static void tree_refresh_timer_proc(XtPointer client_data, XtIntervalId *id)
3423 TreeRefresh_CBdata *cbdata = (TreeRefresh_CBdata *) client_data;
3425 ListTreeRefreshOn(cbdata->w);
3426 ListTreeRefresh(cbdata->w);
3427 ListTreeRefreshOff(cbdata->w);
3429 cbdata->timeout_id = (XtIntervalId) 0;
3432 void TreeRefresh(Widget w)
3434 TreeRefresh_CBdata *cbdata;
3436 cbdata = (TreeRefresh_CBdata *) WidgetGetUserData(w);
3438 if (cbdata->timeout_id) {
3439 XtRemoveTimeOut(cbdata->timeout_id);
3441 cbdata->timeout_id = XtAppAddTimeOut(app_con,
3442 100 /* 0.1 second */, tree_refresh_timer_proc, cbdata);
3445 static void tree_context_menu_cb_proc(Widget w, XtPointer client_data, XtPointer call_data)
3447 Tree_CBData *cbdata = (Tree_CBData *) client_data;
3448 ListTreeItemReturnStruct *ret = (ListTreeItemReturnStruct *) call_data;
3449 XButtonEvent *xbe = (XButtonEvent *) ret->event;
3451 TreeEvent event;
3452 event.w = cbdata->w;
3453 event.anydata = cbdata->anydata;
3454 event.udata = xbe;
3456 cbdata->cbproc(&event);
3459 void AddTreeContextMenuCB(Widget w, Tree_CBProc cbproc, void *anydata)
3461 Tree_CBData *cbdata;
3463 cbdata = (Tree_CBData *) xmalloc(sizeof(Tree_CBData));
3464 cbdata->w = w;
3465 cbdata->cbproc = cbproc;
3466 cbdata->anydata = anydata;
3468 XtAddCallback(w, XtNmenuCallback, tree_context_menu_cb_proc, cbdata);
3471 static void tree_highlight_cb_proc(Widget w, XtPointer client_data, XtPointer call_data)
3473 Tree_CBData *cbdata = (Tree_CBData *) client_data;
3475 TreeEvent event;
3476 event.w = cbdata->w;
3477 event.anydata = cbdata->anydata;
3479 cbdata->cbproc(&event);
3482 void AddTreeHighlightItemsCB(Widget w, Tree_CBProc cbproc, void *anydata)
3484 Tree_CBData *cbdata;
3486 cbdata = (Tree_CBData *) xmalloc(sizeof(Tree_CBData));
3487 cbdata->w = w;
3488 cbdata->cbproc = cbproc;
3489 cbdata->anydata = anydata;
3491 XtAddCallback(w, XtNhighlightCallback, tree_highlight_cb_proc, cbdata);
3494 static void tree_drop_items_cb_proc(Widget w, XtPointer client_data, XtPointer call_data)
3496 Tree_CBData *cbdata = (Tree_CBData *) client_data;
3497 ListTreeDropStruct *cbs = (ListTreeDropStruct *) call_data;
3499 TreeEvent event;
3500 event.w = cbdata->w;
3501 event.anydata = cbdata->anydata;
3502 event.udata = cbs->item;
3504 switch (cbs->operation) {
3505 case XmDROP_MOVE:
3506 event.drop_action = DROP_ACTION_MOVE;
3507 break;
3508 case XmDROP_COPY:
3509 event.drop_action = DROP_ACTION_COPY;
3510 break;
3511 default:
3512 cbs->ok = FALSE;
3513 return;
3516 if (cbdata->cbproc(&event)) {
3517 cbs->ok = TRUE;
3518 } else {
3519 cbs->ok = FALSE;
3523 void AddTreeDropItemsCB(Widget w, Tree_CBProc cbproc, void *anydata)
3525 Tree_CBData *cbdata;
3527 cbdata = (Tree_CBData *) xmalloc(sizeof(Tree_CBData));
3528 cbdata->w = w;
3529 cbdata->cbproc = cbproc;
3530 cbdata->anydata = anydata;
3532 XtAddCallback(w, XtNdropCallback, tree_drop_items_cb_proc, cbdata);
3535 /* Table Widget */
3536 typedef struct {
3537 int default_col_width;
3538 int default_col_label_alignment;
3539 int nrows_visible;
3540 int ncols_visible;
3541 } TableData;
3543 Widget CreateTable(char *name, Widget parent, int nrows, int ncols, int nrows_visible, int ncols_visible)
3545 Widget w;
3546 TableData *td;
3548 td = (TableData*) xmalloc(sizeof(TableData));
3549 td->default_col_width = 5;
3550 td->default_col_label_alignment = ALIGN_BEGINNING;
3551 td->nrows_visible = nrows_visible;
3552 td->ncols_visible = ncols_visible;
3554 w = XtVaCreateManagedWidget(name,
3555 xbaeMatrixWidgetClass, parent,
3556 XmNrows, nrows,
3557 XmNvisibleRows, nrows_visible,
3558 XmNcolumns, ncols,
3559 XmNvisibleColumns, ncols_visible,
3560 NULL);
3562 WidgetSetUserData(w, td);
3564 return w;
3567 static char tfield_translation_table[] = "\
3568 <Key>osfCancel : CancelEdit(True)\n\
3569 <Key>osfActivate : EditCell(Down)\n\
3570 <Key>osfUp : EditCell(Up)\n\
3571 <Key>osfDown : EditCell(Down)\n\
3572 ~Shift ~Meta ~Alt <Key>Return : EditCell(Down)";
3574 void TableSSDInit(Widget w)
3576 Widget tfield;
3578 XtVaSetValues(w,
3579 #if 0
3580 XmNhorizontalScrollBarDisplayPolicy, XmDISPLAY_NONE,
3581 XmNverticalScrollBarDisplayPolicy, XmDISPLAY_NONE,
3582 #endif
3583 XmNbuttonLabels, True,
3584 XmNallowColumnResize, True,
3585 XmNgridType, XmGRID_CELL_SHADOW,
3586 XmNcellShadowType, XmSHADOW_ETCHED_OUT,
3587 XmNcellShadowThickness, 1,
3588 XmNcellMarginHeight, 1,
3589 XmNcellMarginWidth, 1,
3590 XmNshadowThickness, 1,
3591 XmNaltRowCount, 0,
3592 XmNcalcCursorPosition, True,
3593 XmNtraverseFixedCells, True,
3594 NULL);
3596 tfield = XtNameToWidget(w, "textField");
3597 XtOverrideTranslations(tfield,
3598 XtParseTranslationTable(tfield_translation_table));
3601 void TableFontInit(Widget w)
3603 XtVaSetValues(w,
3604 XmNfill, True,
3605 XmNgridType, XmGRID_CELL_SHADOW,
3606 XmNcellShadowType, XmSHADOW_ETCHED_OUT,
3607 XmNcellShadowThickness, 2,
3608 XmNaltRowCount, 0,
3609 NULL);
3612 void TableDataSetPropInit(Widget w)
3614 XtVaSetValues(w,
3615 XmNshowArrows, True,
3616 XmNallowColumnResize, True,
3617 XmNgridType, XmGRID_COLUMN_SHADOW,
3618 XmNcellShadowType, XmSHADOW_OUT,
3619 XmNcellShadowThickness, 1,
3620 XmNaltRowCount, 1,
3621 XmNtraversalOn, False,
3622 NULL);
3625 void TableLevalInit(Widget w)
3627 XtVaSetValues(w,
3628 XmNgridType, XmGRID_CELL_SHADOW,
3629 XmNcellShadowType, XmSHADOW_ETCHED_OUT,
3630 XmNcellShadowThickness, 2,
3631 XmNaltRowCount, 0,
3632 XmNallowColumnResize, True,
3633 NULL);
3636 static int align_to_xmalign(int align)
3638 switch(align) {
3639 case ALIGN_BEGINNING:
3640 return XmALIGNMENT_BEGINNING;
3641 break;
3642 case ALIGN_CENTER:
3643 return XmALIGNMENT_CENTER;
3644 break;
3645 case ALIGN_END:
3646 return XmALIGNMENT_END;
3647 break;
3648 default:
3649 return XmALIGNMENT_BEGINNING;
3653 int TableGetNrows(Widget w)
3655 int nr;
3657 XtVaGetValues(w, XmNrows, &nr, NULL);
3659 return nr;
3662 int TableGetNcols(Widget w)
3664 int nc;
3666 XtVaGetValues(w, XmNcolumns, &nc, NULL);
3668 return nc;
3671 void TableAddRows(Widget w, int nrows)
3673 XbaeMatrixAddRows(w, TableGetNrows(w), NULL, NULL, NULL, nrows);
3676 void TableDeleteRows(Widget w, int nrows)
3678 XbaeMatrixDeleteRows(w, TableGetNrows(w) - nrows, nrows);
3681 void TableAddCols(Widget w, int ncols)
3683 TableData *td;
3684 short *widths;
3685 int i;
3686 unsigned char *alignment, xm_alignment;
3688 td = (TableData*) WidgetGetUserData(w);
3689 xm_alignment = align_to_xmalign(td->default_col_label_alignment);
3690 widths = xmalloc(ncols*SIZEOF_SHORT);
3691 alignment = xmalloc(ncols);
3693 for (i = 0; i < ncols; i++) {
3694 widths[i] = td->default_col_width;
3695 alignment[i] = xm_alignment;
3698 XbaeMatrixAddColumns(w, TableGetNcols(w), NULL, NULL, widths, NULL, NULL, alignment, NULL, ncols);
3700 xfree(alignment);
3701 xfree(widths);
3704 void TableDeleteCols(Widget w, int ncols)
3706 XbaeMatrixDeleteColumns(w, TableGetNcols(w) - ncols, ncols);
3709 void TableGetCellDimentions(Widget w, int *cwidth, int *cheight)
3711 int x0, x1, y0, y1;
3713 XbaeMatrixRowColToXY(w, 0, 0, &x0, &y0);
3714 XbaeMatrixRowColToXY(w, 1, 1, &x1, &y1);
3715 *cwidth = x1 - x0;
3716 *cheight = y1 - y0;
3719 void TableSetColWidths(Widget w, int *widths)
3721 int i, ncols;
3722 short *short_widths;
3724 ncols = TableGetNcols(w);
3726 short_widths = xmalloc(ncols*SIZEOF_SHORT);
3728 for (i = 0; i < ncols; i++) {
3729 short_widths[i] = (short) widths[i];
3732 XtVaSetValues(w, XmNcolumnWidths, short_widths, NULL);
3734 xfree(short_widths);
3737 void TableSetDefaultRowLabelWidth(Widget w, int width)
3739 XtVaSetValues(w, XmNrowLabelWidth, width, NULL);
3742 void TableSetDefaultRowLabelAlignment(Widget w, int align)
3744 unsigned char xm_alignment;
3746 xm_alignment = align_to_xmalign(align);
3748 XtVaSetValues(w, XmNrowLabelAlignment, xm_alignment, NULL);
3751 void TableSetDefaultColWidth(Widget w, int width)
3753 TableData *td;
3754 short *widths;
3755 int ncols, i;
3757 td = (TableData*) WidgetGetUserData(w);
3758 td->default_col_width = width;
3760 ncols = TableGetNcols(w);
3762 widths = xmalloc(ncols*SIZEOF_SHORT);
3764 for (i = 0; i < ncols; i++) {
3765 widths[i] = td->default_col_width;
3768 XtVaSetValues(w, XmNcolumnWidths, widths, NULL);
3770 xfree(widths);
3773 void TableSetDefaultColAlignment(Widget w, int align)
3775 unsigned char *alignment, xm_alignment;
3776 int ncols, i;
3778 xm_alignment = align_to_xmalign(align);
3779 ncols = TableGetNcols(w);
3781 alignment = xmalloc(ncols);
3783 for (i = 0; i < ncols; i++) {
3784 alignment[i] = xm_alignment;
3787 XtVaSetValues(w, XmNcolumnAlignments, alignment, NULL);
3789 xfree(alignment);
3792 void TableSetDefaultColLabelAlignment(Widget w, int align)
3794 TableData *td;
3795 unsigned char *alignment, xm_alignment;
3796 int ncols, i;
3798 td = (TableData*) WidgetGetUserData(w);
3799 td->default_col_label_alignment = align;
3801 xm_alignment = align_to_xmalign(align);
3802 ncols = TableGetNcols(w);
3804 alignment = xmalloc(ncols);
3806 for (i = 0; i < ncols; i++) {
3807 alignment[i] = xm_alignment;
3810 XtVaSetValues(w, XmNcolumnLabelAlignments, alignment, NULL);
3812 xfree(alignment);
3815 void TableSetColMaxlengths(Widget w, int *maxlengths)
3817 XtVaSetValues(w, XmNcolumnMaxLengths, maxlengths, NULL);
3820 void TableSetRowLabels(Widget w, char **labels)
3822 XtVaSetValues(w, XmNrowLabels, labels, NULL);
3824 XtVaSetValues(w, XmNrowLabelWidth, 0, NULL);
3827 void TableSetColLabels(Widget w, char **labels)
3829 XtVaSetValues(w, XmNcolumnLabels, labels, NULL);
3832 void TableSetFixedCols(Widget w, int nfixed_cols)
3834 XtVaSetValues(w, XmNfixedColumns, nfixed_cols, NULL);
3837 void TableUpdateVisibleRowsCols(Widget w)
3839 XtVaSetValues(w,
3840 XmNheight, 0,
3841 XmNwidth, 0,
3842 NULL);
3845 void TableCommitEdit(Widget w, int close)
3847 XbaeMatrixCommitEdit(w, close);
3850 void TableSetCells(Widget w, char ***cells)
3852 XtVaSetValues(w, XmNcells, cells, NULL);
3855 void TableSetCell(Widget w, int row, int col, char *value)
3857 XbaeMatrixSetCell(w, row, col, value);
3860 char *TableGetCell(Widget w, int row, int col)
3862 return XbaeMatrixGetCell(w, row, col);
3865 void TableSelectCell(Widget w, int row, int col)
3867 XbaeMatrixSelectCell(w, row, col);
3870 void TableDeselectCell(Widget w, int row, int col)
3872 XbaeMatrixDeselectCell(w, row, col);
3875 void TableSelectRow(Widget w, int row)
3877 XbaeMatrixSelectRow(w, row);
3880 void TableDeselectRow(Widget w, int row)
3882 XbaeMatrixDeselectRow(w, row);
3885 void TableSelectCol(Widget w, int col)
3887 XbaeMatrixSelectColumn(w, col);
3890 void TableDeselectCol(Widget w, int col)
3892 XbaeMatrixDeselectColumn(w, col);
3895 void TableDeselectAllCells(Widget w)
3897 XbaeMatrixDeselectAll(w);
3900 int TableIsRowSelected(Widget w, int row)
3902 return XbaeMatrixIsRowSelected(w, row);
3905 int TableIsColSelected(Widget w, int col)
3907 return XbaeMatrixIsColumnSelected(w, col);
3910 void TableUpdate(Widget w)
3912 XbaeMatrixRefresh(w);
3915 static void drawcellCB(Widget w, XtPointer client_data, XtPointer call_data)
3917 TableEvent event;
3918 Table_CBData *cbdata = (Table_CBData *) client_data;
3919 XbaeMatrixDrawCellCallbackStruct *cs =
3920 (XbaeMatrixDrawCellCallbackStruct *) call_data;
3922 event.w = cbdata->w;
3923 event.row = cs->row;
3924 event.col = cs->column;
3925 event.anydata = cbdata->anydata;
3926 event.value_type = TABLE_CELL_NONE;
3928 cbdata->cbproc(&event);
3930 if (event.value_type == TABLE_CELL_STRING) {
3931 cs->type = XbaeString;
3932 cs->string = event.value;
3933 } else if (event.value_type == TABLE_CELL_PIXMAP) {
3934 cs->type = XbaePixmap;
3935 cs->pixmap = event.pixmap;
3939 void AddTableDrawCellCB(Widget w, Table_CBProc cbproc, void *anydata)
3941 Table_CBData *cbdata;
3943 cbdata = (Table_CBData *) xmalloc(sizeof(Table_CBData));
3944 cbdata->w = w;
3945 cbdata->cbproc = cbproc;
3946 cbdata->anydata = anydata;
3948 XtAddCallback(w, XmNdrawCellCallback, drawcellCB, cbdata);
3951 static void enterCB(Widget w, XtPointer client_data, XtPointer call_data)
3953 TableEvent event;
3954 Table_CBData *cbdata = (Table_CBData *) client_data;
3955 XbaeMatrixEnterCellCallbackStruct *cs =
3956 (XbaeMatrixEnterCellCallbackStruct *) call_data;
3958 int ok;
3960 event.w = cbdata->w;
3961 event.row = cs->row;
3962 event.col = cs->column;
3963 event.anydata = cbdata->anydata;
3964 ok = cbdata->cbproc(&event);
3966 if (!ok) {
3967 cs->doit = False;
3968 cs->map = False;
3972 void AddTableEnterCellCB(Widget w, Table_CBProc cbproc, void *anydata)
3974 Table_CBData *cbdata;
3976 cbdata = (Table_CBData *) xmalloc(sizeof(Table_CBData));
3977 cbdata->w = w;
3978 cbdata->cbproc = cbproc;
3979 cbdata->anydata = anydata;
3981 XtAddCallback(w, XmNenterCellCallback, enterCB, cbdata);
3984 static void leaveCB(Widget w, XtPointer client_data, XtPointer call_data)
3986 TableEvent event;
3987 Table_CBData *cbdata = (Table_CBData *) client_data;
3988 XbaeMatrixLeaveCellCallbackStruct *cs =
3989 (XbaeMatrixLeaveCellCallbackStruct *) call_data;
3991 int ok;
3993 event.w = cbdata->w;
3994 event.row = cs->row;
3995 event.col = cs->column;
3996 event.value = cs->value;
3997 event.anydata = cbdata->anydata;
3998 ok = cbdata->cbproc(&event);
4000 if (!ok) {
4001 cs->doit = False;
4005 void AddTableLeaveCellCB(Widget w, Table_CBProc cbproc, void *anydata)
4007 Table_CBData *cbdata;
4009 cbdata = (Table_CBData *) xmalloc(sizeof(Table_CBData));
4010 cbdata->w = w;
4011 cbdata->cbproc = cbproc;
4012 cbdata->anydata = anydata;
4014 XtAddCallback(w, XmNleaveCellCallback, leaveCB, cbdata);
4017 static void labelCB(Widget w, XtPointer client_data, XtPointer call_data)
4019 XButtonEvent *xbe;
4021 TableEvent event;
4022 Table_CBData *cbdata = (Table_CBData *) client_data;
4023 XbaeMatrixLabelActivateCallbackStruct *cbs =
4024 (XbaeMatrixLabelActivateCallbackStruct *) call_data;
4026 event.button = NO_BUTTON;
4027 event.modifiers = NO_MODIFIER;
4028 event.anydata = cbdata->anydata;
4030 event.w = w;
4031 event.row = cbs->row;
4032 event.col = cbs->column;
4033 event.row_label = cbs->row_label;
4035 switch (cbs->event->type) {
4036 case ButtonPress:
4037 event.type = MOUSE_PRESS;
4038 xbe = (XButtonEvent *) cbs->event;
4039 event.udata = xbe;
4040 switch (cbs->event->xbutton.button) {
4041 case Button1:
4042 event.button = event.button ^ LEFT_BUTTON;
4043 break;
4044 case Button3:
4045 event.button = event.button ^ RIGHT_BUTTON;
4046 break;
4048 if (xbe->state & ControlMask) {
4049 event.modifiers = event.modifiers ^ CONTROL_MODIFIER;
4051 if (xbe->state & ShiftMask) {
4052 event.modifiers = event.modifiers ^ SHIFT_MODIFIER;
4054 break;
4055 default:
4056 break;
4059 cbdata->cbproc(&event);
4062 void AddTableLabelActivateCB(Widget w, Table_CBProc cbproc, void *anydata)
4064 Table_CBData *cbdata;
4066 cbdata = (Table_CBData *) xmalloc(sizeof(Table_CBData));
4067 cbdata->w = w;
4068 cbdata->cbproc = cbproc;
4069 cbdata->anydata = anydata;
4071 XtAddCallback(w, XmNlabelActivateCallback, labelCB, cbdata);
4074 /* ScrollBar */
4075 void GetScrollBarValues(Widget w, int *value, int *maxvalue, int *slider_size, int *increment)
4077 Arg args[4];
4078 int i = 0;
4080 if (value) {
4081 XtSetArg(args[i], XmNvalue, value); i++;
4084 if (maxvalue) {
4085 XtSetArg(args[i], XmNmaximum, maxvalue); i++;
4088 if (slider_size) {
4089 XtSetArg(args[i], XmNsliderSize, slider_size); i++;
4092 if (increment) {
4093 XtSetArg(args[i], XmNincrement, increment); i++;
4096 if (i != 0) {
4097 XtGetValues(w, args, i);
4101 void SetScrollBarValue(Widget w, int value)
4103 XmScrollBarSetValues(w, value, 0, 0, 0, True);
4106 void SetScrollBarIncrement(Widget w, int increment)
4108 XtVaSetValues(w, XmNincrement, increment, NULL);
4111 Widget GetHorizontalScrollBar(Widget w)
4113 return XtNameToWidget(w, "HorScrollBar");
4116 Widget GetVerticalScrollBar(Widget w)
4118 return XtNameToWidget(w, "VertScrollBar");
4122 ** Add mouse wheel support to a specific widget, which must be the scrollable
4123 ** widget of a ScrolledWindow.
4125 void AddMouseWheelSupport(Widget w)
4127 if (XmIsScrolledWindow(XtParent(w)))
4129 static const char scrollTranslations[] =
4130 "Shift<Btn4Down>: scrolled-window-scroll-up(1)\n"
4131 "Shift<Btn5Down>: scrolled-window-scroll-down(1)\n"
4132 "Ctrl<Btn4Down>: scrolled-window-page-up()\n"
4133 "Ctrl<Btn5Down>: scrolled-window-page-down()\n"
4134 "<Btn4Down>: scrolled-window-scroll-up(3)\n"
4135 "<Btn5Down>: scrolled-window-scroll-down(3)\n";
4136 static XtTranslations trans_table = NULL;
4138 if (trans_table == NULL)
4140 trans_table = XtParseTranslationTable(scrollTranslations);
4142 XtOverrideTranslations(w, trans_table);
4146 void SetFocus(Widget w)
4148 XmProcessTraversal(w, XmTRAVERSE_CURRENT);