2 * Grace - GRaphing, Advanced Computation and Exploration of data
4 * Home page: http://plasma-gate.weizmann.ac.il/Grace/
6 * Copyright (c) 2012 Grace Development Team
8 * Maintained by Evgeny Stambulchik
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
38 #include <Xm/ArrowBG.h>
39 #include <Xm/CascadeBG.h>
40 #include <Xm/DialogS.h>
41 #include <Xm/FileSB.h>
45 #include <Xm/LabelG.h>
49 # include <Xm/PanedW.h>
55 #include <Xm/RowColumn.h>
56 #include <Xm/Separator.h>
58 #include <Xm/ScrolledW.h>
60 #include <Xm/ToggleB.h>
67 void WidgetManage(Widget w
)
72 void WidgetUnmanage(Widget w
)
77 int WidgetIsManaged(Widget w
)
79 return (XtIsManaged(w
) == True
) ? TRUE
:FALSE
;
82 void *WidgetGetUserData(Widget w
)
85 XtVaGetValues(w
, XmNuserData
, &udata
, NULL
);
90 void WidgetSetUserData(Widget w
, void *udata
)
92 XtVaSetValues(w
, XmNuserData
, udata
, NULL
);
95 void WidgetSetSensitive(Widget w
, int onoff
)
97 XtSetSensitive(w
, onoff
? True
: False
);
100 void WidgetSetFocus(Widget w
)
102 XmProcessTraversal(w
, XmTRAVERSE_CURRENT
);
105 void WidgetSetWidth(Widget w
, unsigned int width
)
107 XtVaSetValues(w
, XmNwidth
, (Dimension
) width
, NULL
);
110 void WidgetSetHeight(Widget w
, unsigned int height
)
112 XtVaSetValues(w
, XmNheight
, (Dimension
) height
, NULL
);
115 void WidgetSetSize(Widget w
, unsigned int width
, unsigned int height
)
118 XmNwidth
, (Dimension
) width
,
119 XmNheight
, (Dimension
) height
,
123 void WidgetGetSize(Widget w
, unsigned int *width
, unsigned int *height
)
132 *width
= (unsigned int) ww
;
133 *height
= (unsigned int) wh
;
136 static int toolkit_modifiers_to_grace_modifiers(void *event
)
138 XEvent
*e
= (XEvent
*) event
;
140 int modifiers
= NO_MODIFIER
;
145 state
= e
->xbutton
.state
;
149 state
= e
->xkey
.state
;
155 if (state
& ControlMask
) {
156 modifiers
= modifiers
^ CONTROL_MODIFIER
;
159 if (state
& ShiftMask
) {
160 modifiers
= modifiers
^ SHIFT_MODIFIER
;
166 static int toolkit_key_to_grace_key(void *event
)
168 XKeyEvent
*xke
= (XKeyEvent
*) event
;
171 keybuf
= XLookupKeysym(xke
, 0);
178 case XK_Down
: /* Down */
185 static int toolkit_button_to_grace_button(void *event
)
187 XButtonEvent
*xbe
= (XButtonEvent
*) event
;
189 switch (xbe
->button
) {
191 return WHEEL_UP_BUTTON
;
193 return WHEEL_DOWN_BUTTON
;
199 static int toolkit_to_grace(void *event
)
201 XEvent
*e
= (XEvent
*) event
;
206 return toolkit_button_to_grace_button(event
);
209 return toolkit_key_to_grace_key(event
);
215 static void action(Widget w
, XEvent
*event
, String
*par
, Cardinal
*npar
)
219 static void keyHook(Widget w
, XtPointer client_data
, String action_name
,
220 XEvent
*event
, String
*params
, Cardinal
*num_params
)
222 Key_CBData
*cbdata
= (Key_CBData
*) client_data
;
224 if (strcmp(action_name
, "action")) return;
226 /* In case if we have the same widget */
227 if (cbdata
->key
!= toolkit_to_grace(event
)) return;
228 if (cbdata
->modifiers
!= toolkit_modifiers_to_grace_modifiers(event
)) return;
230 if (w
!= cbdata
->w
) return;
232 cbdata
->cbproc(cbdata
->anydata
);
235 extern XtAppContext app_con
;
237 void AddWidgetKeyPressCB(Widget w
, int key
, Key_CBProc cbproc
, void *anydata
)
239 AddWidgetKeyPressCB2(w
, NO_MODIFIER
, key
, cbproc
, anydata
);
242 void AddWidgetKeyPressCB2(Widget w
, int modifiers
, int key
, Key_CBProc cbproc
, void *anydata
)
245 XtActionsRec actions
[1];
248 cbdata
= (Key_CBData
*) xmalloc(sizeof(Key_CBData
));
250 cbdata
->modifiers
= modifiers
;
252 cbdata
->cbproc
= cbproc
;
253 cbdata
->anydata
= anydata
;
255 modifiers
= modifiers
^ NO_MODIFIER
;
257 if (modifiers
& CONTROL_MODIFIER
) {
258 table
= copy_string(table
, "Ctrl");
263 table
= concat_strings(table
, "<Key>E: action()");
266 table
= concat_strings(table
, "<Key>osfUp: action()");
269 table
= concat_strings(table
, "<Key>osfDown: action()");
275 actions
[0].string
= "action";
276 actions
[0].proc
= action
;
278 XtOverrideTranslations(w
, XtParseTranslationTable(table
));
279 XtAppAddActions(app_con
, actions
, XtNumber(actions
));
280 XtAppAddActionHook(app_con
, keyHook
, cbdata
);
285 void AddWidgetButtonPressCB(Widget w
, int button
, Key_CBProc cbproc
, void *anydata
)
288 XtActionsRec actions
[1];
291 cbdata
= (Key_CBData
*) xmalloc(sizeof(Key_CBData
));
293 cbdata
->modifiers
= NO_MODIFIER
;
294 cbdata
->key
= button
;
295 cbdata
->cbproc
= cbproc
;
296 cbdata
->anydata
= anydata
;
299 case WHEEL_UP_BUTTON
:
300 table
= concat_strings(table
, "<Btn4Down>: action()");
302 case WHEEL_DOWN_BUTTON
:
303 table
= concat_strings(table
, "<Btn5Down>: action()");
309 actions
[0].string
= "action";
310 actions
[0].proc
= action
;
312 XtOverrideTranslations(w
, XtParseTranslationTable(table
));
313 XtAppAddActions(app_con
, actions
, XtNumber(actions
));
314 XtAppAddActionHook(app_con
, keyHook
, cbdata
);
319 static void widgetCB(Widget w
, XtPointer client_data
, XtPointer call_data
)
321 Widget_CBData
*cbdata
= (Widget_CBData
*) client_data
;
323 cbdata
->calldata
= call_data
;
325 cbdata
->cbproc(cbdata
);
328 void AddWidgetCB(Widget w
, const char *callback
, Widget_CBProc cbproc
, void *anydata
)
331 Widget_CBData
*cbdata
;
333 cbdata
= (Widget_CBData
*) xmalloc(sizeof(Widget_CBData
));
335 cbdata
->cbproc
= cbproc
;
336 cbdata
->anydata
= anydata
;
338 cb
= copy_string(NULL
, callback
);
339 cb
= concat_strings(cb
, "Callback");
341 XtAddCallback(w
, cb
, widgetCB
, (XtPointer
) cbdata
);
346 static char *label_to_resname(const char *s
, const char *suffix
)
349 int capitalize
= FALSE
;
351 retval
= copy_string(NULL
, s
);
355 if (capitalize
== TRUE
) {
368 if (suffix
!= NULL
) {
369 retval
= concat_strings(retval
, suffix
);
375 static void close_dialogCB(Widget_CBData
*wcbdata
)
377 WidgetUnmanage(wcbdata
->anydata
);
380 Widget
CreateDialogWindow(Widget parent
, const char *s
)
385 bufp
= label_to_resname(s
, "Dialog");
386 dialog
= XmCreateDialogShell(parent
, bufp
, NULL
, 0);
389 AddWindowCloseCB(dialog
, close_dialogCB
, dialog
);
391 bufp
= copy_string(NULL
, "Grace: ");
392 bufp
= concat_strings(bufp
, s
);
393 XtVaSetValues(dialog
, XmNtitle
, bufp
, NULL
);
400 Widget
CreateDialog(Widget parent
, const char *s
)
404 w
= CreateDialogWindow(parent
, s
);
410 void DialogRaise(Widget form
)
412 Widget w
= XtParent(form
);
415 XMapRaised(XtDisplay(w
), XtWindow(w
));
418 void DialogClose(Widget form
)
420 WidgetUnmanage(XtParent(form
));
423 void DialogSetResizable(Widget form
, int onoff
)
426 XmNresizePolicy
, onoff
? XmRESIZE_ANY
:XmRESIZE_NONE
,
428 XtVaSetValues(XtParent(form
),
429 XmNallowShellResize
, onoff
? True
:False
,
433 /* File selection box */
434 Widget
CreateFileSelectionBox(Widget parent
)
438 w
= XmCreateFileSelectionBox(parent
, "FSB", NULL
, 0);
440 AddMouseWheelSupport(XmFileSelectionBoxGetChild(w
, XmDIALOG_LIST
));
441 AddMouseWheelSupport(XmFileSelectionBoxGetChild(w
, XmDIALOG_DIR_LIST
));
446 /* File selection filter */
447 #if XmVersion >= 2000
448 static void show_hidden_cb(Widget but
, int onoff
, void *data
)
450 Widget fsb
= (Widget
) data
;
451 XtVaSetValues(fsb
, XmNfileFilterStyle
,
452 onoff
? XmFILTER_NONE
:XmFILTER_HIDDEN_FILES
, NULL
);
456 void CreateFileSelectionFilter(Widget parent
, Widget fsb
)
458 #if XmVersion >= 2000
461 button
= CreateToggleButton(parent
, "Show hidden files");
462 AddToggleButtonCB(button
, show_hidden_cb
, fsb
);
463 XtVaSetValues(fsb
, XmNfileFilterStyle
, XmFILTER_HIDDEN_FILES
, NULL
);
467 /* File selection dialog */
468 static XmStringCharSet charset
= XmFONTLIST_DEFAULT_TAG
;
470 static char *GetStringSimple(XmString xms
)
474 if (XmStringGetLtoR(xms
, charset
, &s
)) {
481 static void fsb_setcwd_cb(Widget but
, void *data
)
485 Widget fsb
= (Widget
) data
;
487 XtVaGetValues(fsb
, XmNdirectory
, &directory
, NULL
);
488 bufp
= GetStringSimple(directory
);
489 XmStringFree(directory
);
491 set_workingdir(gapp
, bufp
);
501 static void fsb_cd_cb(OptionStructure
*opt
, int value
, void *data
)
504 FSBStructure
*fsb
= (FSBStructure
*) data
;
508 dir
= get_workingdir(gapp
);
511 dir
= grace_get_userhome(gapp
->grace
);
523 FSBDialogSetDirectory(fsb
, dir
);
526 static OptionItem fsb_items
[] = {
531 ,{FSB_CYGDRV
, "My Computer"}
535 #define FSB_ITEMS_NUM sizeof(fsb_items)/sizeof(OptionItem)
537 FSBStructure
*CreateFSBDialog(Widget parent
, char *s
)
539 FSBStructure
*retval
;
540 OptionStructure
*opt
;
541 Widget dialog
, fr
, form
, button
;
543 retval
= xmalloc(sizeof(FSBStructure
));
545 dialog
= CreateDialogWindow(parent
, s
);
546 retval
->FSB
= CreateFileSelectionBox(dialog
);
548 FSBDialogSetDirectory(retval
, get_workingdir(gapp
));
549 AddWidgetCB(retval
->FSB
, "cancel", close_dialogCB
, dialog
);
550 AddHelpCB(retval
->FSB
, "doc/UsersGuide.html#FS-dialog");
552 retval
->rc
= CreateVContainer(retval
->FSB
);
554 CreateFileSelectionFilter(retval
->rc
, retval
->FSB
);
556 fr
= CreateFrame(retval
->rc
, NULL
);
558 form
= CreateForm(fr
);
560 opt
= CreateOptionChoice(form
, "Chdir to:", 1, FSB_ITEMS_NUM
, fsb_items
);
561 AddOptionChoiceCB(opt
, fsb_cd_cb
, retval
);
562 FormAddHChild(form
, opt
->menu
);
564 button
= CreateButton(form
, "Set as cwd");
565 AddButtonCB(button
, fsb_setcwd_cb
, retval
->FSB
);
566 FormAddHChild(form
, button
);
567 FormFixateHChild(button
);
580 static void fsb_int_cb_proc(Widget_CBData
*wcbdata
)
585 FSB_CBdata
*cbdata
= (FSB_CBdata
*) wcbdata
->anydata
;
586 XmFileSelectionBoxCallbackStruct
*cbs
=
587 (XmFileSelectionBoxCallbackStruct
*) wcbdata
->calldata
;
589 s
= GetStringSimple(cbs
->value
);
591 errmsg("Error converting XmString to char string");
597 ok
= cbdata
->cbproc(cbdata
->fsb
, s
, cbdata
->anydata
);
600 DialogClose(cbdata
->fsb
->FSB
);
605 void AddFSBDialogCB(FSBStructure
*fsb
, FSB_CBProc cbproc
, void *anydata
)
609 cbdata
= xmalloc(sizeof(FSB_CBdata
));
611 cbdata
->cbproc
= (FSB_CBProc
) cbproc
;
612 cbdata
->anydata
= anydata
;
614 AddWidgetCB(fsb
->FSB
, "ok", fsb_int_cb_proc
, cbdata
);
617 void FSBDialogSetPattern(FSBStructure
*fsb
, char *pattern
)
621 if (pattern
!= NULL
) {
622 xmstr
= XmStringCreateLocalized(pattern
);
623 XtVaSetValues(fsb
->FSB
, XmNpattern
, xmstr
, NULL
);
628 void FSBDialogSetDirectory(FSBStructure
*fsb
, char *directory
)
632 if (directory
!= NULL
) {
633 xmstr
= XmStringCreateLocalized(directory
);
634 XtVaSetValues(fsb
->FSB
, XmNdirectory
, xmstr
, NULL
);
640 Widget
CreateVContainer(Widget parent
)
644 rc
= XmCreateRowColumn(parent
, "VContainer", NULL
, 0);
650 Widget
CreateHContainer(Widget parent
)
654 rc
= XmCreateRowColumn(parent
, "HContainer", NULL
, 0);
655 XtVaSetValues(rc
, XmNorientation
, XmHORIZONTAL
, NULL
);
662 Widget
CreateForm(Widget parent
)
666 w
= XmCreateForm(parent
, "form", NULL
, 0);
671 void FormAddHChild(Widget form
, Widget child
)
675 last_widget
= WidgetGetUserData(form
);
678 XmNleftAttachment
, XmATTACH_WIDGET
,
679 XmNleftWidget
, last_widget
,
681 XtVaSetValues(last_widget
,
682 XmNrightAttachment
, XmATTACH_NONE
,
686 XmNleftAttachment
, XmATTACH_FORM
,
690 XmNtopAttachment
, XmATTACH_FORM
,
691 XmNbottomAttachment
, XmATTACH_FORM
,
692 XmNrightAttachment
, XmATTACH_FORM
,
694 WidgetSetUserData(form
, child
);
697 void FormAddVChild(Widget form
, Widget child
)
701 if (XtIsSubclass(child
, listtreeWidgetClass
) ||
702 (XmIsText(child
) && XmIsScrolledWindow(XtParent(child
)))) {
703 child
= XtParent(child
);
706 last_widget
= WidgetGetUserData(form
);
709 XmNtopAttachment
, XmATTACH_WIDGET
,
710 XmNtopWidget
, last_widget
,
712 XtVaSetValues(last_widget
,
713 XmNbottomAttachment
, XmATTACH_NONE
,
717 XmNtopAttachment
, XmATTACH_FORM
,
721 XmNleftAttachment
, XmATTACH_FORM
,
722 XmNrightAttachment
, XmATTACH_FORM
,
723 XmNbottomAttachment
, XmATTACH_FORM
,
725 WidgetSetUserData(form
, child
);
728 void FormFixateHChild(Widget w
)
731 XtVaGetValues(w
, XmNleftWidget
, &prev
, NULL
);
732 XtVaSetValues(w
, XmNleftAttachment
, XmATTACH_NONE
, NULL
);
733 XtVaSetValues(prev
, XmNrightAttachment
, XmATTACH_WIDGET
,
738 void FormFixateVChild(Widget w
)
741 XtVaGetValues(w
, XmNtopWidget
, &prev
, NULL
);
742 XtVaSetValues(w
, XmNtopAttachment
, XmATTACH_NONE
, NULL
);
743 XtVaSetValues(prev
, XmNbottomAttachment
, XmATTACH_WIDGET
,
754 Widget
CreateGrid(Widget parent
, int ncols
, int nrows
)
760 if (ncols
<= 0 || nrows
<= 0) {
761 errmsg("Wrong call to CreateGrid()");
769 } while (nfractions
% ncols
|| nfractions
% nrows
);
771 gd
= xmalloc(sizeof(GridData
));
775 w
= CreateForm(parent
);
778 XmNfractionBase
, nfractions
,
787 void PlaceGridChild(Widget grid
, Widget w
, int col
, int row
)
789 int nfractions
, w1
, h1
;
793 XmNfractionBase
, &nfractions
,
798 /* errmsg("PlaceGridChild() called with a non-grid widget"); */
801 if (col
< 0 || col
>= gd
->ncols
) {
802 errmsg("PlaceGridChild() called with wrong `col' argument");
805 if (row
< 0 || row
>= gd
->nrows
) {
806 errmsg("PlaceGridChild() called with wrong `row' argument");
810 w1
= nfractions
/gd
->ncols
;
811 h1
= nfractions
/gd
->nrows
;
814 XmNleftAttachment
, XmATTACH_POSITION
,
815 XmNleftPosition
, col
*w1
,
816 XmNrightAttachment
, XmATTACH_POSITION
,
817 XmNrightPosition
, (col
+ 1)*w1
,
818 XmNtopAttachment
, XmATTACH_POSITION
,
819 XmNtopPosition
, row
*h1
,
820 XmNbottomAttachment
, XmATTACH_POSITION
,
821 XmNbottomPosition
, (row
+ 1)*h1
,
826 Widget
CreateFrame(Widget parent
, char *s
)
830 fr
= XtVaCreateManagedWidget("frame", xmFrameWidgetClass
, parent
, NULL
);
832 XtVaCreateManagedWidget(s
, xmLabelGadgetClass
, fr
,
833 XmNchildType
, XmFRAME_TITLE_CHILD
,
840 /* Scrolled window */
841 Widget
CreateScrolledWindow(Widget parent
)
843 return XtVaCreateManagedWidget("scrolledWindow",
844 xmScrolledWindowWidgetClass
, parent
,
845 XmNscrollingPolicy
, XmAUTOMATIC
,
850 Widget
CreatePanedWindow(Widget parent
)
853 return XtVaCreateManagedWidget("panedWindow",
854 xmPanedWindowWidgetClass
, parent
,
855 XmNorientation
, XmHORIZONTAL
,
858 return CreateGrid(parent
, 2, 1);
862 void PanedWindowSetMinWidth(Widget w
, unsigned int width
)
864 XtVaSetValues(w
, XmNpaneMinimum
, (Dimension
) width
, NULL
);
868 Widget
CreateTab(Widget parent
)
872 tab
= XtVaCreateManagedWidget("tab", xmTabWidgetClass
, parent
, NULL
);
877 Widget
CreateTabPage(Widget parent
, char *s
)
882 w
= CreateVContainer(parent
);
883 str
= XmStringCreateLocalized(s
);
884 XtVaSetValues(w
, XmNtabLabel
, str
, NULL
);
890 void SelectTabPage(Widget tab
, Widget w
)
892 XmTabSetTabWidget(tab
, w
, True
);
896 Widget
CreateSeparator(Widget parent
)
900 sep
= XmCreateSeparator(parent
, "sep", NULL
, 0);
907 Widget
CreateLabel(Widget parent
, char *s
)
911 label
= XtVaCreateManagedWidget("label",
912 xmLabelWidgetClass
, parent
,
913 XmNalignment
, XmALIGNMENT_BEGINNING
,
914 XmNrecomputeSize
, True
,
917 LabelSetString(label
, s
);
922 void LabelSetString(Widget w
, char *s
)
926 if (s
== NULL
) return;
928 str
= XmStringCreateLocalized(s
);
929 XtVaSetValues(w
, XmNlabelString
, str
, NULL
);
934 void LabelSetPixmap(Widget w
, int width
, int height
, const unsigned char *bits
)
938 X11Stuff
*xstuff
= gapp
->gui
->xstuff
;
946 pm
= XCreatePixmapFromBitmapData(xstuff
->disp
,
947 xstuff
->root
, (char *) bits
, width
, height
, fg
, bg
, xstuff
->depth
);
950 XmNlabelType
, XmPIXMAP
,
956 Widget
CreateLineTextEdit(Widget parent
, int len
)
960 w
= XtVaCreateManagedWidget("text", xmTextWidgetClass
, parent
,
961 XmNtraversalOn
, True
,
964 XtVaSetValues(w
, XmNcolumns
, len
, NULL
);
970 Widget
CreateMultiLineTextEdit(Widget parent
, int nrows
)
978 XtSetArg(args
[ac
], XmNrows
, nrows
); ac
++;
980 XtSetArg(args
[ac
], XmNeditMode
, XmMULTI_LINE_EDIT
); ac
++;
981 XtSetArg(args
[ac
], XmNvisualPolicy
, XmVARIABLE
); ac
++;
983 w
= XmCreateScrolledText(parent
, "text", args
, ac
);
989 char *TextEditGetString(Widget w
)
993 s
= XmTextGetString(w
);
994 buf
= copy_string(NULL
, s
);
1000 void TextEditSetString(Widget w
, char *s
)
1002 XmTextSetString(w
, s
? s
: "");
1006 void TextSetLength(TextStructure
*cst
, int len
)
1008 XtVaSetValues(cst
->text
, XmNcolumns
, len
, NULL
);
1011 char *TextGetString(TextStructure
*cst
)
1013 return TextEditGetString(cst
->text
);
1016 void TextSetString(TextStructure
*cst
, char *s
)
1019 TextEditSetString(cst
->text
, s
);
1020 XmTextSetInsertionPosition(cst
->text
, s
? strlen(s
):0);
1021 cst
->locked
= FALSE
;
1026 TextValidate_CBProc cbproc
;
1028 } TextValidate_CBData
;
1030 static void text_int_validate_cb_proc(Widget_CBData
*wcbdata
)
1033 TextValidate_CBData
*cbdata
= (TextValidate_CBData
*) wcbdata
->anydata
;
1034 XmTextVerifyCallbackStruct
*tcbs
=
1035 (XmTextVerifyCallbackStruct
*) wcbdata
->calldata
;
1037 if (cbdata
->cst
->locked
) return;
1041 if (!cbdata
->cbproc(&text
->ptr
, &text
->length
, cbdata
->anydata
)) {
1046 void AddTextValidateCB(TextStructure
*cst
, TextValidate_CBProc cbproc
, void *anydata
)
1048 TextValidate_CBData
*cbdata
;
1050 cbdata
= (TextValidate_CBData
*) xmalloc(sizeof(TextValidate_CBData
));
1052 cbdata
->cbproc
= cbproc
;
1053 cbdata
->anydata
= anydata
;
1054 cst
->locked
= FALSE
;
1056 AddWidgetCB(cst
->text
, "modifyVerify", text_int_validate_cb_proc
, cbdata
);
1059 int TextGetCursorPos(TextStructure
*cst
)
1061 return XmTextGetInsertionPosition(cst
->text
);
1064 void TextSetCursorPos(TextStructure
*cst
, int pos
)
1066 XmTextSetInsertionPosition(cst
->text
, pos
);
1069 int TextGetLastPosition(TextStructure
*cst
)
1071 return XmTextGetLastPosition(cst
->text
);
1074 void TextInsert(TextStructure
*cst
, int pos
, char *s
)
1076 XmTextInsert(cst
->text
, pos
, s
);
1079 void TextSetEditable(TextStructure
*cst
, int onoff
)
1081 XtVaSetValues(cst
->text
, XmNeditable
, onoff
? True
:False
, NULL
);
1085 Widget
CreateButton(Widget parent
, char *label
)
1089 button
= XtVaCreateManagedWidget(label
,
1090 xmPushButtonWidgetClass
, parent
,
1093 XtVaSetValues(button
,
1094 XmNalignment
, XmALIGNMENT_CENTER
,
1100 Widget
CreateBitmapButton(Widget parent
,
1101 int width
, int height
, const unsigned char *bits
)
1105 button
= XtVaCreateWidget("button",
1106 xmPushButtonWidgetClass
, parent
,
1108 LabelSetPixmap(button
, width
, height
, bits
);
1109 WidgetManage(button
);
1114 Widget
CreateArrowButton(Widget parent
, int arrow_type
)
1118 w
= XtVaCreateManagedWidget("arrow", xmArrowButtonGadgetClass
, parent
,
1119 XmNarrowDirection
, (arrow_type
== ARROW_UP
) ? XmARROW_UP
: XmARROW_DOWN
,
1126 Widget
CreateToggleButton(Widget parent
, char *s
)
1128 return (XtVaCreateManagedWidget(s
, xmToggleButtonWidgetClass
, parent
, NULL
));
1131 int GetToggleButtonState(Widget w
)
1134 errmsg("Internal error: GetToggleButtonState() called with NULL widget");
1137 return XmToggleButtonGetState(w
);
1141 void SetToggleButtonState(Widget w
, int value
)
1146 XmToggleButtonSetState(w
, value
? True
:False
, False
);
1152 Widget
CreateScale(Widget parent
, char *s
, int min
, int max
, int delta
)
1157 str
= XmStringCreateLocalized(s
);
1159 w
= XtVaCreateManagedWidget("scroll",
1160 xmScaleWidgetClass
, parent
,
1161 XmNtitleString
, str
,
1164 XmNscaleMultiple
, delta
,
1167 XmNprocessingDirection
, XmMAX_ON_RIGHT
,
1168 XmNorientation
, XmHORIZONTAL
,
1169 #if XmVersion >= 2000
1170 XmNsliderMark
, XmROUND_MARK
,
1179 void SetScaleValue(Widget w
, int value
)
1181 XtVaSetValues(w
, XmNvalue
, value
, NULL
);
1184 int GetScaleValue(Widget w
)
1187 XtVaGetValues(w
, XmNvalue
, &value
, NULL
);
1192 typedef void (*Timer_CBProc
)(void *anydata
);
1194 unsigned long timer_id
;
1195 Timer_CBProc cbproc
;
1200 SpinStructure
*spin
;
1203 Timer_CBdata
*tcbdata
;
1206 static void sp_double_cb_proc(Widget_CBData
*wcbdata
)
1208 Spin_CBdata
*cbdata
= (Spin_CBdata
*) wcbdata
->anydata
;
1210 cbdata
->cbproc(cbdata
->spin
, GetSpinChoice(cbdata
->spin
), cbdata
->anydata
);
1213 static void sp_timer_proc(void *anydata
)
1215 Spin_CBdata
*cbdata
= (Spin_CBdata
*) anydata
;
1217 cbdata
->cbproc(cbdata
->spin
, GetSpinChoice(cbdata
->spin
), cbdata
->anydata
);
1220 static void timer_proc(XtPointer client_data
, XtIntervalId
*id
)
1222 Timer_CBdata
*cbdata
= (Timer_CBdata
*) client_data
;
1224 cbdata
->cbproc(cbdata
->anydata
);
1225 cbdata
->timer_id
= 0;
1228 void TimerStart(unsigned long interval
, Timer_CBdata
*cbdata
)
1230 /* we count elapsed time since the last event, so first remove
1231 an existing timeout, if there is one */
1232 if (cbdata
->timer_id
) {
1233 XtRemoveTimeOut(cbdata
->timer_id
);
1236 cbdata
->timer_id
= XtAppAddTimeOut(app_con
, interval
, timer_proc
, cbdata
);
1239 static void sp_ev_proc(void *anydata
)
1241 Spin_CBdata
*cbdata
= (Spin_CBdata
*) anydata
;
1243 TimerStart(250 /* 0.25 second */, cbdata
->tcbdata
);
1246 void AddSpinChoiceCB(SpinStructure
*spinp
, Spin_CBProc cbproc
, void *anydata
)
1248 Timer_CBdata
*tcbdata
;
1249 Spin_CBdata
*cbdata
;
1251 tcbdata
= xmalloc(sizeof(Timer_CBdata
));
1252 cbdata
= xmalloc(sizeof(Spin_CBdata
));
1254 tcbdata
->cbproc
= sp_timer_proc
;
1255 tcbdata
->anydata
= cbdata
;
1256 tcbdata
->timer_id
= 0;
1258 cbdata
->spin
= spinp
;
1259 cbdata
->cbproc
= cbproc
;
1260 cbdata
->anydata
= anydata
;
1261 cbdata
->tcbdata
= tcbdata
;
1263 AddWidgetCB(spinp
->text
, "activate", sp_double_cb_proc
, cbdata
);
1264 AddWidgetCB(spinp
->arrow_up
, "activate", sp_double_cb_proc
, cbdata
);
1265 AddWidgetCB(spinp
->arrow_down
, "activate", sp_double_cb_proc
, cbdata
);
1267 AddWidgetButtonPressCB(spinp
->text
, WHEEL_UP_BUTTON
, sp_ev_proc
, cbdata
);
1268 AddWidgetButtonPressCB(spinp
->text
, WHEEL_DOWN_BUTTON
, sp_ev_proc
, cbdata
);
1271 static void spin_arrow_cb(Widget_CBData
*wcbdata
)
1273 SpinStructure
*spinp
;
1276 spinp
= (SpinStructure
*) wcbdata
->anydata
;
1277 value
= GetSpinChoice(spinp
);
1280 if (wcbdata
->w
== spinp
->arrow_up
) {
1282 } else if (wcbdata
->w
== spinp
->arrow_down
) {
1283 incr
= -spinp
->incr
;
1285 errmsg("Wrong call to spin_arrow_cb()");
1289 SetSpinChoice(spinp
, value
);
1290 WidgetSetFocus(spinp
->text
);
1293 static void spin_up(void *anydata
)
1295 SpinStructure
*spinp
= (SpinStructure
*) anydata
;
1298 value
= GetSpinChoice(spinp
) + spinp
->incr
;
1299 SetSpinChoice(spinp
, value
);
1302 static void spin_down(void *anydata
)
1304 SpinStructure
*spinp
= (SpinStructure
*) anydata
;
1307 value
= GetSpinChoice(spinp
) - spinp
->incr
;
1308 SetSpinChoice(spinp
, value
);
1311 SpinStructure
*CreateSpinChoice(Widget parent
, char *s
, int len
,
1312 int type
, double min
, double max
, double incr
)
1314 SpinStructure
*retval
;
1318 errmsg("min >= max in CreateSpinChoice()!");
1322 retval
= xmalloc(sizeof(SpinStructure
));
1324 retval
->type
= type
;
1327 retval
->incr
= incr
;
1329 retval
->rc
= CreateHContainer(parent
);
1331 CreateLabel(retval
->rc
, s
);
1332 fr
= CreateFrame(retval
->rc
, NULL
);
1334 form
= CreateForm(fr
);
1336 retval
->text
= CreateLineTextEdit(form
, len
);
1337 FormAddHChild(form
, retval
->text
);
1339 AddWidgetButtonPressCB(retval
->text
, WHEEL_UP_BUTTON
, spin_up
, retval
);
1340 AddWidgetButtonPressCB(retval
->text
, WHEEL_DOWN_BUTTON
, spin_down
, retval
);
1342 retval
->arrow_down
= CreateArrowButton(form
, ARROW_DOWN
);
1343 AddWidgetCB(retval
->arrow_down
, "activate", spin_arrow_cb
, retval
);
1344 FormAddHChild(form
, retval
->arrow_down
);
1346 retval
->arrow_up
= CreateArrowButton(form
, ARROW_UP
);
1347 AddWidgetCB(retval
->arrow_up
, "activate", spin_arrow_cb
, retval
);
1348 FormAddHChild(form
, retval
->arrow_up
);
1355 void SetSpinChoice(SpinStructure
*spinp
, double value
)
1357 X11Stuff
*xstuff
= gapp
->gui
->xstuff
;
1360 if (value
< spinp
->min
) {
1361 XBell(xstuff
->disp
, 50);
1363 } else if (value
> spinp
->max
) {
1364 XBell(xstuff
->disp
, 50);
1368 if (spinp
->type
== SPIN_TYPE_FLOAT
) {
1369 sprintf(buf
, "%g", value
);
1371 sprintf(buf
, "%d", (int) rint(value
));
1373 TextEditSetString(spinp
->text
, buf
);
1376 double GetSpinChoice(SpinStructure
*spinp
)
1381 s
= TextEditGetString(spinp
->text
);
1383 graal_eval_expr(grace_get_graal(gapp
->grace
),
1385 gproject_get_top(gapp
->gp
));
1389 if (retval
< spinp
->min
) {
1390 errmsg("Input value below min limit in GetSpinChoice()");
1391 retval
= spinp
->min
;
1392 SetSpinChoice(spinp
, retval
);
1393 } else if (retval
> spinp
->max
) {
1394 errmsg("Input value above max limit in GetSpinChoice()");
1395 retval
= spinp
->max
;
1396 SetSpinChoice(spinp
, retval
);
1399 if (spinp
->type
== SPIN_TYPE_INT
) {
1400 return rint(retval
);
1407 #define MAX_PULLDOWN_LENGTH 30
1409 OptionStructure
*CreateOptionChoice(Widget parent
, char *labelstr
,
1410 int ncols
, int nchoices
, OptionItem
*items
)
1414 OptionStructure
*retval
;
1416 retval
= xcalloc(1, sizeof(OptionStructure
));
1421 XtSetArg(args
[0], XmNpacking
, XmPACK_COLUMN
);
1422 retval
->pulldown
= XmCreatePulldownMenu(parent
, "pulldownMenu", args
, 1);
1424 retval
->ncols
= ncols
;
1426 UpdateOptionChoice(retval
, nchoices
, items
);
1428 str
= XmStringCreateLocalized(labelstr
);
1429 XtSetArg(args
[0], XmNlabelString
, str
);
1430 XtSetArg(args
[1], XmNsubMenuId
, retval
->pulldown
);
1432 retval
->menu
= XmCreateOptionMenu(parent
, "optionMenu", args
, 2);
1436 WidgetManage(retval
->menu
);
1441 OptionStructure
*CreateOptionChoiceVA(Widget parent
, char *labelstr
, ...)
1443 OptionStructure
*retval
;
1445 OptionItem
*oi
= NULL
;
1450 va_start(var
, labelstr
);
1451 while ((s
= va_arg(var
, char *)) != NULL
) {
1452 value
= va_arg(var
, int);
1454 oi
= xrealloc(oi
, nchoices
*sizeof(OptionItem
));
1455 oi
[nchoices
- 1].value
= value
;
1456 oi
[nchoices
- 1].label
= copy_string(NULL
, s
);
1460 retval
= CreateOptionChoice(parent
, labelstr
, 1, nchoices
, oi
);
1464 xfree(oi
[nchoices
].label
);
1471 static void oc_int_cb_proc(Widget_CBData
*wcbdata
)
1475 OC_CBdata
*cbdata
= (OC_CBdata
*) wcbdata
->anydata
;
1477 value
= GetOptionChoice(cbdata
->opt
);
1478 cbdata
->cbproc(cbdata
->opt
, value
, cbdata
->anydata
);
1481 void AddOptionChoiceCB(OptionStructure
*opt
, OC_CBProc cbproc
, void *anydata
)
1486 cbdata
= xmalloc(sizeof(OC_CBdata
));
1489 cbdata
->cbproc
= cbproc
;
1490 cbdata
->anydata
= anydata
;
1492 opt
->cblist
= xrealloc(opt
->cblist
, (opt
->cbnum
+ 1)*sizeof(OC_CBdata
*));
1493 opt
->cblist
[opt
->cbnum
] = cbdata
;
1496 for (i
= 0; i
< opt
->nchoices
; i
++) {
1497 AddWidgetCB(opt
->options
[i
].widget
, "activate", oc_int_cb_proc
, cbdata
);
1501 void UpdateOptionChoice(OptionStructure
*optp
, int nchoices
, OptionItem
*items
)
1503 int i
, nold
, ncols
, nw
;
1506 nold
= optp
->nchoices
;
1508 if (optp
->ncols
== 0) {
1511 ncols
= optp
->ncols
;
1514 /* Don't create too tall pulldowns */
1515 if (nchoices
> MAX_PULLDOWN_LENGTH
*ncols
) {
1516 ncols
= (nchoices
+ MAX_PULLDOWN_LENGTH
- 1)/MAX_PULLDOWN_LENGTH
;
1519 XtVaSetValues(optp
->pulldown
, XmNnumColumns
, ncols
, NULL
);
1521 nw
= nold
- nchoices
;
1523 /* Unmanage extra items before destroying to speed the things up */
1524 wlist
= xmalloc(nw
*sizeof(Widget
));
1525 for (i
= nchoices
; i
< nold
; i
++) {
1526 wlist
[i
- nchoices
] = optp
->options
[i
].widget
;
1528 XtUnmanageChildren(wlist
, nw
);
1531 for (i
= nchoices
; i
< nold
; i
++) {
1532 XtDestroyWidget(optp
->options
[i
].widget
);
1536 optp
->options
= xrealloc(optp
->options
, nchoices
*sizeof(OptionWidgetItem
));
1537 optp
->nchoices
= nchoices
;
1539 for (i
= nold
; i
< nchoices
; i
++) {
1541 optp
->options
[i
].widget
= CreateButton(optp
->pulldown
, "");
1542 for (j
= 0; j
< optp
->cbnum
; j
++) {
1543 OC_CBdata
*cbdata
= optp
->cblist
[j
];
1544 AddWidgetCB(optp
->options
[i
].widget
, "activate", oc_int_cb_proc
, cbdata
);
1548 for (i
= 0; i
< nchoices
; i
++) {
1549 optp
->options
[i
].value
= items
[i
].value
;
1550 if (items
[i
].label
!= NULL
) {
1552 XtVaGetValues(optp
->options
[i
].widget
, XmNlabelString
, &ostr
, NULL
);
1553 str
= XmStringCreateLocalized(items
[i
].label
);
1554 if (XmStringCompare(str
, ostr
) != True
) {
1555 XtVaSetValues(optp
->options
[i
].widget
, XmNlabelString
, str
, NULL
);
1561 nw
= nchoices
- nold
;
1563 wlist
= xmalloc(nw
*sizeof(Widget
));
1564 for (i
= nold
; i
< nchoices
; i
++) {
1565 wlist
[i
- nold
] = optp
->options
[i
].widget
;
1567 XtManageChildren(wlist
, nw
);
1573 Widget
CreatePopupMenu(Widget parent
)
1575 return XmCreatePopupMenu(parent
, "popupMenu", NULL
, 0);
1578 void PopupMenuShow(Widget w
, void *data
)
1580 XmMenuPosition(w
, (XButtonEvent
*) data
);
1584 Widget
CreateMenuBar(Widget parent
)
1588 menubar
= XmCreateMenuBar(parent
, "menuBar", NULL
, 0);
1592 Widget
CreateMenu(Widget parent
, char *label
, char mnemonic
, int help
)
1594 Widget menupane
, cascade
;
1597 menupane
= XmCreatePulldownMenu(parent
, "menu", NULL
, 0);
1602 cascade
= XtVaCreateManagedWidget("cascade",
1603 xmCascadeButtonGadgetClass
, parent
,
1604 XmNsubMenuId
, menupane
,
1605 XmNmnemonic
, XStringToKeysym(ms
),
1608 LabelSetString(cascade
, label
);
1611 XtVaSetValues(parent
, XmNmenuHelpWidget
, cascade
, NULL
);
1612 CreateMenuButton(menupane
, "On context", 'x',
1613 ContextHelpCB
, NULL
);
1614 CreateSeparator(menupane
);
1620 Widget
CreateMenuButton(Widget parent
, char *label
, char mnemonic
,
1621 Button_CBProc cb
, void *data
)
1623 return CreateMenuButtonA(parent
, label
, mnemonic
, NULL
, NULL
, cb
, data
);
1626 Widget
CreateMenuButtonA(Widget parent
, char *label
, char mnemonic
,
1627 char *accelerator
, char* acceleratorText
, Button_CBProc cb
, void *data
)
1636 name
= label_to_resname(label
, "Button");
1638 button
= CreateButton(parent
, name
);
1641 XtVaSetValues(button
,
1642 XmNmnemonic
, XStringToKeysym(ms
),
1643 XmNalignment
, XmALIGNMENT_BEGINNING
,
1646 if (accelerator
&& acceleratorText
) {
1647 str
= XmStringCreateLocalized(acceleratorText
);
1648 XtVaSetValues(button
,
1649 XmNaccelerator
, accelerator
,
1650 XmNacceleratorText
, str
,
1655 LabelSetString(button
, label
);
1657 AddButtonCB(button
, cb
, data
);
1662 Widget
CreateMenuHelpButton(Widget parent
, char *label
, char mnemonic
,
1663 Widget form
, char *ha
)
1667 wbut
= CreateMenuButton(parent
, label
, mnemonic
, HelpCB
, ha
);
1668 AddHelpCB(form
, ha
);
1673 Widget
CreateMenuToggle(Widget parent
, char *label
, char mnemonic
,
1674 TB_CBProc cb
, void *data
)
1682 name
= label_to_resname(label
, NULL
);
1683 button
= CreateToggleButton(parent
, name
);
1686 XtVaSetValues(button
,
1687 XmNmnemonic
, XStringToKeysym(ms
),
1688 XmNvisibleWhenOff
, True
,
1689 XmNindicatorOn
, True
,
1692 LabelSetString(button
, label
);
1695 AddToggleButtonCB(button
, cb
, data
);
1701 Widget
CreateMenuSeparator(Widget parent
)
1703 return CreateSeparator(parent
);