(gnus-uu-binhex-article, gnus-uu-reginize-string, gnus-uu-expand-numbers)
[emacs.git] / lwlib / lwlib-Xolmb.c
blobcc63ebcd39e6aee5f4876229dcc98e9ea22d3391
1 /* An OLIT menubar widget, by Chuck Thompson <cthomp@cs.uiuc.edu>
2 Copyright (C) 1993 Lucid, Inc.
4 This file is part of the Lucid Widget Library.
6 The Lucid Widget Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 1, or (at your option)
9 any later version.
11 The Lucid Widget Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
22 #include "../src/lisp.h"
24 #include <X11/IntrinsicP.h>
25 #include <X11/Intrinsic.h>
26 #include <X11/CompositeP.h>
27 #include <X11/Composite.h>
28 #include "lwlib-Xol-mbP.h"
29 #include "lwlib-Xol-mb.h"
31 #define HORIZ_SPACING 4
32 #define VERT_SPACING 4
34 static void Initialize();
35 static void Resize();
36 static void ChangeManaged();
37 static Boolean SetValues();
38 static XtGeometryResult GeometryManager();
39 static XtGeometryResult PreferredSize();
40 static void do_layout();
41 static XtGeometryResult try_layout();
43 lwMenuBarClassRec lwMenubarClassRec =
46 /* core_class members */
48 (WidgetClass) &compositeClassRec, /* superclass */
49 "Menubar", /* class_name */
50 sizeof(lwMenuBarRec), /* widget_size */
51 NULL, /* class_initialize */
52 NULL, /* class_part_initialize */
53 FALSE, /* class_inited */
54 Initialize, /* initialize */
55 NULL, /* initialize_hook */
56 XtInheritRealize, /* realize */
57 NULL, /* actions */
58 0, /* num_actions */
59 NULL, /* resources */
60 0, /* num_resources */
61 NULLQUARK, /* xrm_class */
62 TRUE, /* compress_motion */
63 XtExposeCompressMaximal, /* compress_exposure */
64 TRUE, /* compress_enterleave */
65 FALSE, /* visible_interest */
66 NULL, /* destroy */
67 Resize, /* resize */
68 NULL, /* expose */
69 NULL, /* set_values */
70 NULL, /* set_values_hook */
71 XtInheritSetValuesAlmost, /* set_values_almost */
72 NULL, /* get_values_hook */
73 NULL, /* accept_focus */
74 XtVersion, /* version */
75 NULL, /* callback_private */
76 NULL, /* tm_table */
77 PreferredSize, /* query_geometry */
78 NULL, /* display_accelerator */
79 NULL, /* extension */
82 /* composite_class members */
84 GeometryManager, /* geometry_manager */
85 ChangeManaged, /* change_managed */
86 XtInheritInsertChild, /* insert_child */
87 XtInheritDeleteChild, /* delete_child */
88 NULL, /* extension */
91 /* Menubar class members */
93 0, /* empty */
96 WidgetClass lwMenubarWidgetClass = (WidgetClass) &lwMenubarClassRec;
99 static void Initialize (request, new)
100 lwMenuBarWidget request, new;
102 if (request->core.width <= 0)
103 new->core.width = 1;
104 if (request->core.height <= 0)
105 new->core.height = 23;
108 static void
109 Resize (w)
110 lwMenuBarWidget w;
112 do_layout(w);
115 static void
116 do_layout (parent)
117 lwMenuBarWidget parent;
119 Widget child;
120 int cnt;
121 int managed_children = 0;
122 int managed_width = 0;
123 int new_pos = 0;
126 * Determine number of children which will fit on one line.
127 * For now we ignore the rest, making sure they are unmanaged.
130 cnt = 0;
131 while ((cnt < (int) parent->composite.num_children) &&
132 (managed_width < (int) parent->core.width))
134 child = parent->composite.children[cnt++];
135 managed_children++;
136 managed_width += child->core.width + child->core.border_width * 2 +
137 HORIZ_SPACING;
140 if (managed_width > (int) parent->core.width)
141 managed_children--;
144 * Correct positioning of children.
147 cnt = 0;
148 while (managed_children)
150 child = parent->composite.children[cnt++];
152 if (!child->core.managed)
153 XtManageChild (child);
155 if ((child->core.x != new_pos) || (child->core.y != 0))
156 XtMoveWidget (child, new_pos, 0);
157 new_pos += child->core.width + child->core.border_width * 2 +
158 HORIZ_SPACING;
160 managed_children--;
164 * Make sure all remaining children are unmanaged.
167 while (cnt < parent->composite.num_children)
169 child = parent->composite.children[cnt];
171 if (child->core.managed)
172 XtUnmanageChild (child);
174 if ((child->core.x != parent->core.width) ||
175 (child->core.y != parent->core.height))
176 XtMoveWidget (child, parent->core.width, parent->core.height);
178 cnt++;
183 static XtGeometryResult
184 PreferredSize (w, request, preferred)
185 lwMenuBarWidget w;
186 XtWidgetGeometry *request, *preferred;
188 Widget child;
189 int cnt;
192 * If no changes are being made to the width or height, just agree.
195 if (!(request->request_mode & CWWidth) &&
196 !(request->request_mode & CWHeight))
197 return (XtGeometryYes);
200 * Right now assume everything goes in one row. Calculate the
201 * minimum required width and height.
204 preferred->width = 0;
205 preferred->height = 0;
207 for (cnt = 0; cnt < w->composite.num_children; cnt++)
209 child = w->composite.children[cnt];
210 if (child->core.managed)
212 preferred->width += child->core.width + child->core.border_width*2 +
213 HORIZ_SPACING;
214 if (preferred->height < (Dimension) (child->core.height +
215 child->core.border_width * 2))
216 preferred->height = child->core.height +
217 child->core.border_width * 2;
221 preferred->request_mode = CWWidth | CWHeight;
224 * Case: both height and width requested
227 if ((request->request_mode & CWWidth) &&
228 (request->request_mode & CWHeight))
231 * Ok if same or bigger.
234 if (preferred->width <= request->width &&
235 preferred->height <= request->height)
237 preferred->width = request->width;
238 return (XtGeometryYes);
242 * If both dimensions are too small, say no.
245 else
246 if (preferred->width > request->width &&
247 preferred->height > request->height)
248 return (XtGeometryNo);
251 * Otherwise one must be right, so say almost.
254 else
255 return (XtGeometryAlmost);
259 * If only one dimension is requested, either its OK or it isn't.
262 else
264 if (request->request_mode & CWWidth)
266 if (preferred->width <= request->width)
268 preferred->width = request->width;
269 return (XtGeometryYes);
271 else
272 return (XtGeometryNo);
274 else if (request->request_mode & CWHeight)
276 if (preferred->height <= request->height)
278 return (XtGeometryYes);
280 else
281 return (XtGeometryNo);
284 return (XtGeometryYes);
289 static XtGeometryResult
290 GeometryManager (w, request, reply)
291 Widget w;
292 XtWidgetGeometry *request;
293 XtWidgetGeometry *reply;
296 lwMenuBarWidget parent = (lwMenuBarWidget) w->core.parent;
299 * If the widget wants to move, just say no.
302 if ((request->request_mode & CWX && request->x != w->core.x) ||
303 (request->request_mode & CWY && request->y != w->core.y))
304 return (XtGeometryNo);
307 * Since everything "fits" for now, grant all requests.
310 if (request->request_mode & CWWidth)
311 w->core.width = request->width;
312 if (request->request_mode & CWHeight)
313 w->core.height = request->height;
314 if (request->request_mode & CWBorderWidth)
315 w->core.border_width = request->border_width;
317 do_layout (parent);
318 return (XtGeometryYes);
322 static XtGeometryResult
323 try_layout (parent)
324 lwMenuBarWidget parent;
326 Widget child;
327 int cnt;
328 int managed_children = 0;
329 int managed_width = 0;
330 int new_pos = 0;
333 * Determine number of children which will fit on one line.
334 * For now we ignore the rest, making sure they are unmanaged.
337 cnt = 0;
338 while ((cnt < (int) parent->composite.num_children) &&
339 (managed_width < (int) parent->core.width))
341 child = parent->composite.children[cnt++];
342 if (child->core.managed)
344 managed_children++;
345 managed_width += child->core.width + child->core.border_width * 2 +
346 HORIZ_SPACING;
350 if (managed_width > (int) parent->core.width)
351 return (XtGeometryNo);
352 else
353 return (XtGeometryYes);
358 static void
359 ChangeManaged (w)
360 lwMenuBarWidget w;
362 XtGeometryResult result;
364 result = try_layout (w);
366 if (result != XtGeometryYes)
368 XtUnmanageChild (w->composite.children[w->composite.num_children - 1]);
369 XtMoveWidget (w->composite.children[w->composite.num_children-1],
370 w->core.width, w->core.height);
373 do_layout (w);