2 static char Xrcsid
[] = "$XConsortium: Dialog.c,v 1.37 89/12/06 15:26:31 kit Exp $";
6 /***********************************************************
7 Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
8 and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
12 Permission to use, copy, modify, and distribute this software and its
13 documentation for any purpose and without fee is hereby granted,
14 provided that the above copyright notice appear in all copies and that
15 both that copyright notice and this permission notice appear in
16 supporting documentation, and that the names of Digital or MIT not be
17 used in advertising or publicity pertaining to distribution of the
18 software without specific, written prior permission.
20 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
21 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
22 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
23 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
24 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
25 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
28 ******************************************************************/
30 /* NOTE: THIS IS NOT A WIDGET! Rather, this is an interface to a widget.
31 It implements policy, and gives a (hopefully) easier-to-use interface
32 than just directly making your own form. */
37 #include <X11/IntrinsicP.h>
38 #include <X11/StringDefs.h>
39 #include <X11/Xmu/Misc.h>
41 #include <./Xaw3_1XawInit.h>
42 #include <./Xaw3_1AsciiText.h>
43 #include <./Xaw3_1Command.h>
44 #include <./Xaw3_1Label.h>
45 #include <./Xaw3_1DialogP.h>
46 #include <./Xaw3_1Cardinals.h>
49 * After we have set the string in the value widget we set the
50 * string to a magic value. So that when a SetValues request is made
51 * on the dialog value we will notice it, and reset the string.
54 #define MAGIC_VALUE ((char *) 3)
56 #define streq(a,b) (strcmp( (a), (b) ) == 0)
58 static XtResource resources
[] = {
59 {XtNlabel
, XtCLabel
, XtRString
, sizeof(String
),
60 XtOffset(DialogWidget
, dialog
.label
), XtRString
, NULL
},
61 {XtNvalue
, XtCValue
, XtRString
, sizeof(String
),
62 XtOffset(DialogWidget
, dialog
.value
), XtRString
, NULL
},
63 {XtNicon
, XtCIcon
, XtRPixmap
, sizeof(Pixmap
),
64 XtOffset(DialogWidget
, dialog
.icon
), XtRImmediate
, 0},
67 static void Initialize(), ConstraintInitialize(), CreateDialogValueWidget();
68 static Boolean
SetValues();
70 DialogClassRec dialogClassRec
= {
71 { /* core_class fields */
72 /* superclass */ (WidgetClass
) &formClassRec
,
73 /* class_name */ "Dialog",
74 /* widget_size */ sizeof(DialogRec
),
75 /* class_initialize */ XawInitializeWidgetSet
,
76 /* class_part init */ NULL
,
77 /* class_inited */ FALSE
,
78 /* initialize */ Initialize
,
79 /* initialize_hook */ NULL
,
80 /* realize */ XtInheritRealize
,
83 /* resources */ resources
,
84 /* num_resources */ XtNumber(resources
),
85 /* xrm_class */ NULLQUARK
,
86 /* compress_motion */ TRUE
,
87 /* compress_exposure */ TRUE
,
88 /* compress_enterleave*/ TRUE
,
89 /* visible_interest */ FALSE
,
91 /* resize */ XtInheritResize
,
92 /* expose */ XtInheritExpose
,
93 /* set_values */ SetValues
,
94 /* set_values_hook */ NULL
,
95 /* set_values_almost */ XtInheritSetValuesAlmost
,
96 /* get_values_hook */ NULL
,
97 /* accept_focus */ NULL
,
98 /* version */ XtVersion
,
99 /* callback_private */ NULL
,
101 /* query_geometry */ XtInheritQueryGeometry
,
102 /* display_accelerator*/ XtInheritDisplayAccelerator
,
105 { /* composite_class fields */
106 /* geometry_manager */ XtInheritGeometryManager
,
107 /* change_managed */ XtInheritChangeManaged
,
108 /* insert_child */ XtInheritInsertChild
,
109 /* delete_child */ XtInheritDeleteChild
,
112 { /* constraint_class fields */
113 /* subresourses */ NULL
,
114 /* subresource_count */ 0,
115 /* constraint_size */ sizeof(DialogConstraintsRec
),
116 /* initialize */ ConstraintInitialize
,
118 /* set_values */ NULL
,
121 { /* form_class fields */
122 /* layout */ XtInheritLayout
124 { /* dialog_class fields */
129 WidgetClass dialogWidgetClass
= (WidgetClass
)&dialogClassRec
;
132 static void Initialize(request
, new)
135 DialogWidget dw
= (DialogWidget
)new;
137 Cardinal num_args
= 0;
139 XtSetArg(arglist
[num_args
], XtNborderWidth
, 0); num_args
++;
140 XtSetArg(arglist
[num_args
], XtNleft
, XtChainLeft
); num_args
++;
142 if (dw
->dialog
.icon
!= (Pixmap
)0) {
143 XtSetArg(arglist
[num_args
], XtNbitmap
, dw
->dialog
.icon
); num_args
++;
144 XtSetArg(arglist
[num_args
], XtNright
, XtChainLeft
); num_args
++;
146 XtCreateManagedWidget( "icon", labelWidgetClass
,
147 new, arglist
, num_args
);
149 XtSetArg(arglist
[num_args
], XtNfromHoriz
, dw
->dialog
.iconW
);num_args
++;
150 } else dw
->dialog
.iconW
= (Widget
)NULL
;
152 XtSetArg(arglist
[num_args
], XtNlabel
, dw
->dialog
.label
); num_args
++;
153 XtSetArg(arglist
[num_args
], XtNright
, XtChainRight
); num_args
++;
155 dw
->dialog
.labelW
= XtCreateManagedWidget( "label", labelWidgetClass
,
156 new, arglist
, num_args
);
158 if (dw
->dialog
.iconW
!= (Widget
)NULL
&&
159 (dw
->dialog
.labelW
->core
.height
< dw
->dialog
.iconW
->core
.height
)) {
160 XtSetArg( arglist
[0], XtNheight
, dw
->dialog
.iconW
->core
.height
);
161 XtSetValues( dw
->dialog
.labelW
, arglist
, ONE
);
163 if (dw
->dialog
.value
!= NULL
)
164 CreateDialogValueWidget( (Widget
) dw
);
166 dw
->dialog
.valueW
= NULL
;
170 static void ConstraintInitialize(request
, new)
173 DialogWidget dw
= (DialogWidget
)new->core
.parent
;
174 DialogConstraints constraint
= (DialogConstraints
)new->core
.constraints
;
176 if (!XtIsSubclass(new, commandWidgetClass
)) /* if not a button */
177 return; /* then just use defaults */
179 constraint
->form
.left
= constraint
->form
.right
= XtChainLeft
;
180 if (dw
->dialog
.valueW
== NULL
)
181 constraint
->form
.vert_base
= dw
->dialog
.labelW
;
183 constraint
->form
.vert_base
= dw
->dialog
.valueW
;
185 if (dw
->composite
.num_children
> 1) {
186 WidgetList children
= dw
->composite
.children
;
188 for (childP
= children
+ dw
->composite
.num_children
- 1;
189 childP
>= children
; childP
-- ) {
190 if (*childP
== dw
->dialog
.labelW
|| *childP
== dw
->dialog
.valueW
)
192 if (XtIsManaged(*childP
) &&
193 XtIsSubclass(*childP
, commandWidgetClass
)) {
194 constraint
->form
.horiz_base
= *childP
;
206 static Boolean
SetValues(current
, request
, new, in_args
, in_num_args
)
207 Widget current
, request
, new;
209 Cardinal
*in_num_args
;
211 DialogWidget w
= (DialogWidget
)new;
212 DialogWidget old
= (DialogWidget
)current
;
216 Boolean checks
[NUM_CHECKS
];
218 for (i
= 0; i
< NUM_CHECKS
; i
++)
221 for (i
= 0; i
< *in_num_args
; i
++) {
222 if (streq(XtNicon
, in_args
[i
].name
))
224 if (streq(XtNlabel
, in_args
[i
].name
))
225 checks
[LABEL
] = TRUE
;
229 if (w
->dialog
.icon
!= (Pixmap
)0) {
230 XtSetArg( args
[0], XtNbitmap
, w
->dialog
.icon
);
231 if (old
->dialog
.iconW
!= (Widget
)NULL
) {
232 XtSetValues( old
->dialog
.iconW
, args
, ONE
);
234 XtSetArg( args
[1], XtNborderWidth
, 0);
235 XtSetArg( args
[2], XtNleft
, XtChainLeft
);
236 XtSetArg( args
[3], XtNright
, XtChainLeft
);
238 XtCreateWidget( "icon", labelWidgetClass
,
240 ((DialogConstraints
)w
->dialog
.labelW
->core
.constraints
)->
241 form
.horiz_base
= w
->dialog
.iconW
;
242 XtManageChild(w
->dialog
.iconW
);
245 ((DialogConstraints
)w
->dialog
.labelW
->core
.constraints
)->
246 form
.horiz_base
= (Widget
)NULL
;
247 XtDestroyWidget(old
->dialog
.iconW
);
248 w
->dialog
.iconW
= (Widget
)NULL
;
252 if ( checks
[LABEL
] ) {
254 XtSetArg( args
[num_args
], XtNlabel
, w
->dialog
.label
); num_args
++;
255 if (w
->dialog
.iconW
!= (Widget
)NULL
&&
256 (w
->dialog
.labelW
->core
.height
<= w
->dialog
.iconW
->core
.height
)) {
257 XtSetArg(args
[num_args
], XtNheight
, w
->dialog
.iconW
->core
.height
);
260 XtSetValues( w
->dialog
.labelW
, args
, num_args
);
263 if ( w
->dialog
.value
!= old
->dialog
.value
) {
264 if (w
->dialog
.value
== NULL
) /* only get here if it
265 wasn't NULL before. */
266 XtDestroyWidget(old
->dialog
.valueW
);
267 else if (old
->dialog
.value
== NULL
) { /* create a new value widget. */
268 w
->core
.width
= old
->core
.width
;
269 w
->core
.height
= old
->core
.height
;
271 /* this would be correct if Form had the same semantics on Resize
272 * as on MakeGeometryRequest. Unfortunately, Form botched it, so
273 * any subclasses will currently have to deal with the fact that
274 * we're about to change our real size.
276 w
->form
.resize_in_layout
= False
;
277 CreateDialogValueWidget( (Widget
) w
);
278 w
->core
.width
= w
->form
.preferred_width
;
279 w
->core
.height
= w
->form
.preferred_height
;
280 w
->form
.resize_in_layout
= True
;
282 CreateDialogValueWidget( (Widget
) w
);
285 else { /* Widget ok, just change string. */
287 XtSetArg(args
[0], XtNstring
, w
->dialog
.value
);
288 XtSetValues(w
->dialog
.valueW
, args
, ONE
);
289 w
->dialog
.value
= MAGIC_VALUE
;
295 /* Function Name: CreateDialogValueWidget
296 * Description: Creates the dialog widgets value widget.
297 * Arguments: w - the dialog widget.
300 * must be called only when w->dialog.value is non-nil.
304 CreateDialogValueWidget(w
)
307 DialogWidget dw
= (DialogWidget
) w
;
309 Cardinal num_args
= 0;
312 XtSetArg(arglist
[num_args
], XtNwidth
,
313 dw
->dialog
.labelW
->core
.width
); num_args
++; /* ||| hack */
315 XtSetArg(arglist
[num_args
], XtNstring
, dw
->dialog
.value
); num_args
++;
316 XtSetArg(arglist
[num_args
], XtNresizable
, True
); num_args
++;
317 XtSetArg(arglist
[num_args
], XtNresize
, XawtextResizeBoth
); num_args
++;
318 XtSetArg(arglist
[num_args
], XtNeditType
, XawtextEdit
); num_args
++;
319 XtSetArg(arglist
[num_args
], XtNfromVert
, dw
->dialog
.labelW
); num_args
++;
320 XtSetArg(arglist
[num_args
], XtNleft
, XtChainLeft
); num_args
++;
321 XtSetArg(arglist
[num_args
], XtNright
, XtChainRight
); num_args
++;
323 dw
->dialog
.valueW
= XtCreateWidget("value",asciiTextWidgetClass
,
324 w
, arglist
, num_args
);
326 /* if the value widget is being added after buttons,
327 * then the buttons need new layout constraints.
329 if (dw
->composite
.num_children
> 1) {
330 WidgetList children
= dw
->composite
.children
;
332 for (childP
= children
+ dw
->composite
.num_children
- 1;
333 childP
>= children
; childP
-- ) {
334 if (*childP
== dw
->dialog
.labelW
|| *childP
== dw
->dialog
.valueW
)
336 if (XtIsManaged(*childP
) &&
337 XtIsSubclass(*childP
, commandWidgetClass
)) {
338 ((DialogConstraints
)(*childP
)->core
.constraints
)->
339 form
.vert_base
= dw
->dialog
.valueW
;
343 XtManageChild(dw
->dialog
.valueW
);
346 * Value widget gets the keyboard focus.
349 XtSetKeyboardFocus(w
, dw
->dialog
.valueW
);
350 dw
->dialog
.value
= MAGIC_VALUE
;
355 XawDialogAddButton(dialog
, name
, function
, param
)
358 XtCallbackProc function
;
362 * Correct Constraints are all set in ConstraintInitialize().
366 button
= XtCreateManagedWidget( name
, commandWidgetClass
, dialog
,
367 NULL
, (Cardinal
) 0 );
369 if (function
!= NULL
) /* don't add NULL callback func. */
370 XtAddCallback(button
, XtNcallback
, function
, param
);
374 char *XawDialogGetValueString(w
)
380 XtSetArg(args
[0], XtNstring
, &value
);
381 XtGetValues( ((DialogWidget
)w
)->dialog
.valueW
, args
, ONE
);