1 /*************************************<+>*************************************
2 *****************************************************************************
8 ** Description: Code and class record for Bulletin Board Widget.
10 *****************************************************************************
12 ** Copyright (c) 1988 by Hewlett-Packard Company
13 ** Copyright (c) 1988 by the Massachusetts Institute of Technology
15 ** Permission to use, copy, modify, and distribute this software
16 ** and its documentation for any purpose and without fee is hereby
17 ** granted, provided that the above copyright notice appear in all
18 ** copies and that both that copyright notice and this permission
19 ** notice appear in supporting documentation, and that the names of
20 ** Hewlett-Packard or M.I.T. not be used in advertising or publicity
21 ** pertaining to distribution of the software without specific, written
24 *****************************************************************************
25 *************************************<+>*************************************/
27 #include <X11/IntrinsicP.h>
28 #include <X11/Intrinsic.h>
29 #include <X11/Xutil.h>
30 #include <X11/StringDefs.h>
33 #include <Xw/BBoard.h>
34 #include <Xw/BBoardP.h>
37 static void Initialize();
38 static XtGeometryResult
GeometryManager();
39 static void ChangeManaged();
43 /****************************************************************
45 * Full class record constant
47 ****************************************************************/
49 XwBulletinClassRec XwbulletinClassRec
= {
51 /* core_class fields */
52 /* superclass */ (WidgetClass
) &XwmanagerClassRec
,
53 /* class_name */ "XwBulletinBoard",
54 /* widget_size */ sizeof(XwBulletinRec
),
55 /* class_initialize */ NULL
,
56 /* class_part_init */ NULL
,
57 /* class_inited */ FALSE
,
58 /* initialize */ (XtInitProc
) Initialize
,
59 /* initialize_hook */ NULL
,
60 /* realize */ _XwRealize
,
64 /* num_resources */ 0,
65 /* xrm_class */ NULLQUARK
,
66 /* compress_motion */ TRUE
,
67 /* compress_exposure */ TRUE
,
68 /* compress_enterlv */ TRUE
,
69 /* visible_interest */ FALSE
,
73 /* set_values */ NULL
,
74 /* set_values_hook */ NULL
,
75 /* set_values_almost */ XtInheritSetValuesAlmost
,
76 /* get_values_hook */ NULL
,
77 /* accept_focus */ NULL
,
78 /* version */ XtVersion
,
79 /* callback_private */ NULL
,
81 /* query_geometry */ NULL
,
82 XtInheritDisplayAccelerator
, NULL
,
84 /* composite_class fields */
85 /* geometry_manager */ (XtGeometryHandler
) GeometryManager
,
86 /* change_managed */ (XtWidgetProc
) ChangeManaged
,
87 /* insert_child */ XtInheritInsertChild
, /* from superclass */
88 /* delete_child */ XtInheritDeleteChild
, /* from superclass */
91 /* constraint_class fields */
92 /* resource list */ NULL
,
93 /* num resources */ 0,
94 /* constraint size */ 0,
96 /* destroy proc */ NULL
,
97 /* set values proc */ NULL
,
100 /* manager_class fields */
101 /* traversal handler */ (XwTraversalProc
) XtInheritTraversalProc
,
102 /* translations */ NULL
,
104 /* bulletin board class - none */
105 /* no new fields */ 0
109 WidgetClass XwbulletinWidgetClass
= (WidgetClass
)&XwbulletinClassRec
;
110 WidgetClass XwbulletinBoardWidgetClass
= (WidgetClass
)&XwbulletinClassRec
;
114 /*************************************<->*************************************
120 * Figure out how much size we need.
122 *************************************<->***********************************/
124 static Boolean
CalcSize(bb
, width
, height
, replyWidth
, replyHeight
)
126 Dimension width
, height
;
127 Dimension
*replyWidth
, *replyHeight
;
129 Cardinal i
, j
, numItems
;
130 Dimension minWidth
, minHeight
;
131 Widget box
; /* Current item */
135 * If there are no items then any space will work
138 if ((numItems
=bb
->manager
.num_managed_children
) <= 0)
140 if ((replyWidth
!= NULL
) && (replyHeight
!= NULL
))
151 * Compute the minimum width & height for this box
152 * by summing the rectangles of all children.
155 minWidth
= minHeight
= 0;
157 for (i
=0; i
< numItems
; i
++)
159 box
= (Widget
) bb
->manager
.managed_children
[i
];
160 minWidth
= Max (minWidth
, (box
->core
.x
+ 2*box
->core
.border_width
+
162 minHeight
= Max (minHeight
, (box
->core
.y
+ 2*box
->core
.border_width
+
168 if (bb
->manager
.layout
== XwMAXIMIZE
)
170 minWidth
= Max (minWidth
, width
);
171 minHeight
= Max (minHeight
, height
);
175 if (replyWidth
!= NULL
) *replyWidth
= minWidth
;
176 if (replyHeight
!= NULL
) *replyHeight
= minHeight
;
179 if ((width
< minWidth
) || (height
< minHeight
)) return (FALSE
);
186 /*************************************<->*************************************
192 * Try to do a new layout within the current width and height;
193 * if that fails try to do it within the box returned by CalcSize
196 *************************************<->***********************************/
197 static Boolean
DoLayout(bb
)
200 Dimension width
, height
;
201 XtWidgetGeometry request
, reply
;
203 (void) CalcSize(bb
, bb
->core
.width
, bb
->core
.height
, &width
, &height
);
205 if ((bb
->manager
.layout
== XwIGNORE
) || /* don't care if it fits */
206 ((bb
->core
.width
== width
) && (bb
->core
.height
== height
) &&
207 bb
->manager
.layout
!= XwSWINDOW
))
208 return (TRUE
); /* Same size & NOT special case */
211 if (bb
->manager
.layout
== XwMAXIMIZE
)
213 width
= Max (bb
->core
.width
, width
);
214 height
= Max (bb
->core
.height
, height
);
217 switch (XtMakeResizeRequest
218 ((Widget
) bb
, width
, height
, &width
, &height
))
226 case XtGeometryAlmost
: /* TAKE WHAT YOU CAN GET! */
227 (void) XtMakeResizeRequest((Widget
) bb
, width
, height
,
234 /*************************************<->*************************************
240 * Make sure height and width are not set to zero at initialize time.
242 *************************************<->***********************************/
243 static void Initialize (request
, new)
244 XwBulletinWidget request
, new;
247 /* DON'T ALLOW HEIGHT/WIDTH TO BE 0, BECAUSE X DOESN'T HANDLE THIS WELL */
248 if (new->core
.width
== 0) new->core
.width
= 10;
249 if (new->core
.height
== 0) new->core
.height
= 10;
254 /*************************************<->*************************************
256 * GeometryManager(w, request, reply)
259 *************************************<->***********************************/
261 static XtGeometryResult
GeometryManager(w
, request
, reply
)
263 XtWidgetGeometry
*request
;
264 XtWidgetGeometry
*reply
; /* RETURN */
267 Dimension width
, height
, borderWidth
, junk
;
270 XtGeometryHandler manager
;
271 XtGeometryResult returnCode
;
274 * IF LAYOUT MODE IS XwSWINDOW ( PARENT HAD BETTER BE A SUBCLASS OF
275 * SCROLLED WINDOW) THEN SIMPLY PASS THIS REQUEST TO MY PARENT AND
276 * RETURN ITS RESPONSE TO THE REQUESTING WIDGET.
279 bb
= (XwBulletinWidget
) w
->core
.parent
;
280 if (bb
->manager
.layout
== XwSWINDOW
)
282 manager
= ((CompositeWidgetClass
) (bb
->core
.parent
->core
.widget_class
))
283 ->composite_class
.geometry_manager
;
284 returnCode
= (*manager
)(w
, request
, reply
);
288 /* Since this is a bulletin board, all position requests
291 if (request
->request_mode
& (CWX
| CWY
))
292 XtMoveWidget( w
, ((request
->request_mode
& CWX
) == 0)
293 ? w
->core
.x
: request
->x
,
294 ((request
->request_mode
& CWY
) == 0)
295 ? w
->core
.y
: request
->y
);
298 /* Fill out entire request record */
299 if ((request
->request_mode
& CWWidth
) == 0)
300 request
->width
= w
->core
.width
;
301 if ((request
->request_mode
& CWHeight
) == 0)
302 request
->height
= w
->core
.height
;
303 if ((request
->request_mode
& CWBorderWidth
) == 0)
304 request
->border_width
= w
->core
.border_width
;
306 /* Save current size and set to new size */
307 width
= w
->core
.width
;
308 height
= w
->core
.height
;
309 borderWidth
= w
->core
.border_width
;
310 w
->core
.width
= request
->width
;
311 w
->core
.height
= request
->height
;
312 w
->core
.border_width
= request
->border_width
;
314 geoFlag
= DoLayout(bb
);
316 w
->core
.width
= width
;
317 w
->core
.height
= height
;
318 w
->core
.border_width
= borderWidth
;
322 XtResizeWidget(w
, request
->width
, request
->height
,
323 request
->border_width
);
324 return(XtGeometryDone
);
326 return (XtGeometryNo
);
330 /*************************************<->*************************************
336 * Restructure the manager's "managed children" list. Then re-lay
339 *************************************<->***********************************/
340 static void ChangeManaged(bb
)
344 /* Put "managed children" info together again */
346 _XwReManageChildren ((XwManagerWidget
)bb
);
348 /* Reconfigure the bulletinboard */