Merge branch 'master' into xcircuit-3.10
[xcircuit.git] / Xw / BBoard.c
blobceab3e5f6b59cf47dd2a3a56865c966909ce50ee
1 /*************************************<+>*************************************
2 *****************************************************************************
3 **
4 ** File: BBoard.c
5 **
6 ** Project: X Widgets
7 **
8 ** Description: Code and class record for Bulletin Board Widget.
9 **
10 *****************************************************************************
11 **
12 ** Copyright (c) 1988 by Hewlett-Packard Company
13 ** Copyright (c) 1988 by the Massachusetts Institute of Technology
14 **
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
22 ** prior permission.
23 **
24 *****************************************************************************
25 *************************************<+>*************************************/
27 #include <X11/IntrinsicP.h>
28 #include <X11/Intrinsic.h>
29 #include <X11/Xutil.h>
30 #include <X11/StringDefs.h>
31 #include <Xw/Xw.h>
32 #include <Xw/XwP.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,
61 /* actions */ NULL,
62 /* num_actions */ 0,
63 /* resources */ NULL,
64 /* num_resources */ 0,
65 /* xrm_class */ NULLQUARK,
66 /* compress_motion */ TRUE,
67 /* compress_exposure */ TRUE,
68 /* compress_enterlv */ TRUE,
69 /* visible_interest */ FALSE,
70 /* destroy */ NULL,
71 /* resize */ NULL,
72 /* expose */ NULL,
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,
80 /* tm_table */ NULL,
81 /* query_geometry */ NULL,
82 XtInheritDisplayAccelerator, NULL,
83 },{
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 */
89 NULL,
90 },{
91 /* constraint_class fields */
92 /* resource list */ NULL,
93 /* num resources */ 0,
94 /* constraint size */ 0,
95 /* init proc */ NULL,
96 /* destroy proc */ NULL,
97 /* set values proc */ NULL,
98 NULL
99 },{
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 /*************************************<->*************************************
116 * CalcSize
118 * Description:
119 * -----------
120 * Figure out how much size we need.
122 *************************************<->***********************************/
124 static Boolean CalcSize(bb, width, height, replyWidth, replyHeight)
125 XwBulletinWidget bb;
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))
142 *replyWidth = 10;
143 *replyHeight = 10;
145 return(TRUE);
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 +
161 box->core.width));
162 minHeight = Max (minHeight, (box->core.y + 2*box->core.border_width +
163 box->core.height));
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);
181 return (TRUE);
186 /*************************************<->*************************************
188 * DoLayout
190 * Description:
191 * -----------
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)
198 XwBulletinWidget 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))
220 case XtGeometryYes:
221 return (TRUE);
223 case XtGeometryNo:
224 return (FALSE);
226 case XtGeometryAlmost: /* TAKE WHAT YOU CAN GET! */
227 (void) XtMakeResizeRequest((Widget) bb, width, height,
228 NULL, NULL);
229 return (TRUE);
234 /*************************************<->*************************************
236 * Initialize
238 * Description:
239 * -----------
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)
262 Widget w;
263 XtWidgetGeometry *request;
264 XtWidgetGeometry *reply; /* RETURN */
267 Dimension width, height, borderWidth, junk;
268 XwBulletinWidget bb;
269 Boolean geoFlag;
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);
285 return(returnCode);
288 /* Since this is a bulletin board, all position requests
289 * are accepted.
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;
320 if (geoFlag)
322 XtResizeWidget(w, request->width, request->height,
323 request->border_width);
324 return(XtGeometryDone);
326 return (XtGeometryNo);
330 /*************************************<->*************************************
332 * ChangeManaged
334 * Description:
335 * -----------
336 * Restructure the manager's "managed children" list. Then re-lay
337 * out children.
339 *************************************<->***********************************/
340 static void ChangeManaged(bb)
341 XwBulletinWidget bb;
344 /* Put "managed children" info together again */
346 _XwReManageChildren ((XwManagerWidget)bb);
348 /* Reconfigure the bulletinboard */
350 (void) DoLayout(bb);