Mercurial > emacs
comparison lwlib/lwlib-Xolmb.c @ 5628:f999ebca00da
entered into RCS
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Tue, 18 Jan 1994 23:52:19 +0000 |
parents | |
children | ee40177f6c68 |
comparison
equal
deleted
inserted
replaced
5627:7ff2d6076466 | 5628:f999ebca00da |
---|---|
1 /* An OLIT menubar widget, by Chuck Thompson <cthomp@cs.uiuc.edu> | |
2 Copyright (C) 1993 Lucid, Inc. | |
3 | |
4 This file is part of the Lucid Widget Library. | |
5 | |
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. | |
10 | |
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. | |
15 | |
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, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
19 | |
20 #include <X11/IntrinsicP.h> | |
21 #include <X11/Intrinsic.h> | |
22 #include <X11/CompositeP.h> | |
23 #include <X11/Composite.h> | |
24 #include "lwlib-Xol-mbP.h" | |
25 #include "lwlib-Xol-mb.h" | |
26 | |
27 #define HORIZ_SPACING 4 | |
28 #define VERT_SPACING 4 | |
29 | |
30 static void Initialize(); | |
31 static void Resize(); | |
32 static void ChangeManaged(); | |
33 static Boolean SetValues(); | |
34 static XtGeometryResult GeometryManager(); | |
35 static XtGeometryResult PreferredSize(); | |
36 static void do_layout(); | |
37 static XtGeometryResult try_layout(); | |
38 | |
39 lwMenuBarClassRec lwMenubarClassRec = | |
40 { | |
41 { | |
42 /* core_class members */ | |
43 | |
44 (WidgetClass) &compositeClassRec, /* superclass */ | |
45 "Menubar", /* class_name */ | |
46 sizeof(lwMenuBarRec), /* widget_size */ | |
47 NULL, /* class_initialize */ | |
48 NULL, /* class_part_initialize */ | |
49 FALSE, /* class_inited */ | |
50 Initialize, /* initialize */ | |
51 NULL, /* initialize_hook */ | |
52 XtInheritRealize, /* realize */ | |
53 NULL, /* actions */ | |
54 0, /* num_actions */ | |
55 NULL, /* resources */ | |
56 0, /* num_resources */ | |
57 NULLQUARK, /* xrm_class */ | |
58 TRUE, /* compress_motion */ | |
59 XtExposeCompressMaximal, /* compress_exposure */ | |
60 TRUE, /* compress_enterleave */ | |
61 FALSE, /* visible_interest */ | |
62 NULL, /* destroy */ | |
63 Resize, /* resize */ | |
64 NULL, /* expose */ | |
65 NULL, /* set_values */ | |
66 NULL, /* set_values_hook */ | |
67 XtInheritSetValuesAlmost, /* set_values_almost */ | |
68 NULL, /* get_values_hook */ | |
69 NULL, /* accept_focus */ | |
70 XtVersion, /* version */ | |
71 NULL, /* callback_private */ | |
72 NULL, /* tm_table */ | |
73 PreferredSize, /* query_geometry */ | |
74 NULL, /* display_accelerator */ | |
75 NULL, /* extension */ | |
76 }, | |
77 { | |
78 /* composite_class members */ | |
79 | |
80 GeometryManager, /* geometry_manager */ | |
81 ChangeManaged, /* change_managed */ | |
82 XtInheritInsertChild, /* insert_child */ | |
83 XtInheritDeleteChild, /* delete_child */ | |
84 NULL, /* extension */ | |
85 }, | |
86 { | |
87 /* Menubar class members */ | |
88 | |
89 0, /* empty */ | |
90 } | |
91 }; | |
92 WidgetClass lwMenubarWidgetClass = (WidgetClass) &lwMenubarClassRec; | |
93 | |
94 | |
95 static void Initialize (request, new) | |
96 lwMenuBarWidget request, new; | |
97 { | |
98 if (request->core.width <= 0) | |
99 new->core.width = 1; | |
100 if (request->core.height <= 0) | |
101 new->core.height = 23; | |
102 } | |
103 | |
104 static void | |
105 Resize (w) | |
106 lwMenuBarWidget w; | |
107 { | |
108 do_layout(w); | |
109 } | |
110 | |
111 static void | |
112 do_layout (parent) | |
113 lwMenuBarWidget parent; | |
114 { | |
115 Widget child; | |
116 int cnt; | |
117 int managed_children = 0; | |
118 int managed_width = 0; | |
119 int new_pos = 0; | |
120 | |
121 /* | |
122 * Determine number of children which will fit on one line. | |
123 * For now we ignore the rest, making sure they are unmanaged. | |
124 */ | |
125 | |
126 cnt = 0; | |
127 while ((cnt < (int) parent->composite.num_children) && | |
128 (managed_width < (int) parent->core.width)) | |
129 { | |
130 child = parent->composite.children[cnt++]; | |
131 managed_children++; | |
132 managed_width += child->core.width + child->core.border_width * 2 + | |
133 HORIZ_SPACING; | |
134 } | |
135 | |
136 if (managed_width > (int) parent->core.width) | |
137 managed_children--; | |
138 | |
139 /* | |
140 * Correct positioning of children. | |
141 */ | |
142 | |
143 cnt = 0; | |
144 while (managed_children) | |
145 { | |
146 child = parent->composite.children[cnt++]; | |
147 | |
148 if (!child->core.managed) | |
149 XtManageChild (child); | |
150 | |
151 if ((child->core.x != new_pos) || (child->core.y != 0)) | |
152 XtMoveWidget (child, new_pos, 0); | |
153 new_pos += child->core.width + child->core.border_width * 2 + | |
154 HORIZ_SPACING; | |
155 | |
156 managed_children--; | |
157 } | |
158 | |
159 /* | |
160 * Make sure all remaining children are unmanaged. | |
161 */ | |
162 | |
163 while (cnt < parent->composite.num_children) | |
164 { | |
165 child = parent->composite.children[cnt]; | |
166 | |
167 if (child->core.managed) | |
168 XtUnmanageChild (child); | |
169 | |
170 if ((child->core.x != parent->core.width) || | |
171 (child->core.y != parent->core.height)) | |
172 XtMoveWidget (child, parent->core.width, parent->core.height); | |
173 | |
174 cnt++; | |
175 } | |
176 } | |
177 | |
178 | |
179 static XtGeometryResult | |
180 PreferredSize (w, request, preferred) | |
181 lwMenuBarWidget w; | |
182 XtWidgetGeometry *request, *preferred; | |
183 { | |
184 Widget child; | |
185 int cnt; | |
186 | |
187 /* | |
188 * If no changes are being made to the width or height, just agree. | |
189 */ | |
190 | |
191 if (!(request->request_mode & CWWidth) && | |
192 !(request->request_mode & CWHeight)) | |
193 return (XtGeometryYes); | |
194 | |
195 /* | |
196 * Right now assume everything goes in one row. Calculate the | |
197 * minimum required width and height. | |
198 */ | |
199 | |
200 preferred->width = 0; | |
201 preferred->height = 0; | |
202 | |
203 for (cnt = 0; cnt < w->composite.num_children; cnt++) | |
204 { | |
205 child = w->composite.children[cnt]; | |
206 if (child->core.managed) | |
207 { | |
208 preferred->width += child->core.width + child->core.border_width*2 + | |
209 HORIZ_SPACING; | |
210 if (preferred->height < (Dimension) (child->core.height + | |
211 child->core.border_width * 2)) | |
212 preferred->height = child->core.height + | |
213 child->core.border_width * 2; | |
214 } | |
215 } | |
216 | |
217 preferred->request_mode = CWWidth | CWHeight; | |
218 | |
219 /* | |
220 * Case: both height and width requested | |
221 */ | |
222 | |
223 if ((request->request_mode & CWWidth) && | |
224 (request->request_mode & CWHeight)) | |
225 { | |
226 /* | |
227 * Ok if same or bigger. | |
228 */ | |
229 | |
230 if (preferred->width <= request->width && | |
231 preferred->height <= request->height) | |
232 { | |
233 preferred->width = request->width; | |
234 return (XtGeometryYes); | |
235 } | |
236 | |
237 /* | |
238 * If both dimensions are too small, say no. | |
239 */ | |
240 | |
241 else | |
242 if (preferred->width > request->width && | |
243 preferred->height > request->height) | |
244 return (XtGeometryNo); | |
245 | |
246 /* | |
247 * Otherwise one must be right, so say almost. | |
248 */ | |
249 | |
250 else | |
251 return (XtGeometryAlmost); | |
252 } | |
253 | |
254 /* | |
255 * If only one dimension is requested, either its OK or it isn't. | |
256 */ | |
257 | |
258 else | |
259 { | |
260 if (request->request_mode & CWWidth) | |
261 { | |
262 if (preferred->width <= request->width) | |
263 { | |
264 preferred->width = request->width; | |
265 return (XtGeometryYes); | |
266 } | |
267 else | |
268 return (XtGeometryNo); | |
269 } | |
270 else if (request->request_mode & CWHeight) | |
271 { | |
272 if (preferred->height <= request->height) | |
273 { | |
274 return (XtGeometryYes); | |
275 } | |
276 else | |
277 return (XtGeometryNo); | |
278 } | |
279 | |
280 return (XtGeometryYes); | |
281 } | |
282 } | |
283 | |
284 | |
285 static XtGeometryResult | |
286 GeometryManager (w, request, reply) | |
287 Widget w; | |
288 XtWidgetGeometry *request; | |
289 XtWidgetGeometry *reply; | |
290 { | |
291 | |
292 lwMenuBarWidget parent = (lwMenuBarWidget) w->core.parent; | |
293 | |
294 /* | |
295 * If the widget wants to move, just say no. | |
296 */ | |
297 | |
298 if ((request->request_mode & CWX && request->x != w->core.x) || | |
299 (request->request_mode & CWY && request->y != w->core.y)) | |
300 return (XtGeometryNo); | |
301 | |
302 /* | |
303 * Since everything "fits" for now, grant all requests. | |
304 */ | |
305 | |
306 if (request->request_mode & CWWidth) | |
307 w->core.width = request->width; | |
308 if (request->request_mode & CWHeight) | |
309 w->core.height = request->height; | |
310 if (request->request_mode & CWBorderWidth) | |
311 w->core.border_width = request->border_width; | |
312 | |
313 do_layout (parent); | |
314 return (XtGeometryYes); | |
315 } | |
316 | |
317 | |
318 static XtGeometryResult | |
319 try_layout (parent) | |
320 lwMenuBarWidget parent; | |
321 { | |
322 Widget child; | |
323 int cnt; | |
324 int managed_children = 0; | |
325 int managed_width = 0; | |
326 int new_pos = 0; | |
327 | |
328 /* | |
329 * Determine number of children which will fit on one line. | |
330 * For now we ignore the rest, making sure they are unmanaged. | |
331 */ | |
332 | |
333 cnt = 0; | |
334 while ((cnt < (int) parent->composite.num_children) && | |
335 (managed_width < (int) parent->core.width)) | |
336 { | |
337 child = parent->composite.children[cnt++]; | |
338 if (child->core.managed) | |
339 { | |
340 managed_children++; | |
341 managed_width += child->core.width + child->core.border_width * 2 + | |
342 HORIZ_SPACING; | |
343 } | |
344 } | |
345 | |
346 if (managed_width > (int) parent->core.width) | |
347 return (XtGeometryNo); | |
348 else | |
349 return (XtGeometryYes); | |
350 } | |
351 | |
352 | |
353 | |
354 static void | |
355 ChangeManaged (w) | |
356 lwMenuBarWidget w; | |
357 { | |
358 XtGeometryResult result; | |
359 | |
360 result = try_layout (w); | |
361 | |
362 if (result != XtGeometryYes) | |
363 { | |
364 XtUnmanageChild (w->composite.children[w->composite.num_children - 1]); | |
365 XtMoveWidget (w->composite.children[w->composite.num_children-1], | |
366 w->core.width, w->core.height); | |
367 } | |
368 | |
369 do_layout (w); | |
370 } |