Mercurial > emacs
annotate lwlib/lwlib-Xolmb.c @ 89407:a9b9211d250a
*** empty log message ***
author | Kenichi Handa <handa@m17n.org> |
---|---|
date | Sat, 12 Apr 2003 02:37:18 +0000 |
parents | 7fb1caba0f51 |
children |
rev | line source |
---|---|
5628 | 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 | |
14186
ee40177f6c68
Update FSF's address in the preamble.
Erik Naggum <erik@naggum.no>
parents:
5628
diff
changeset
|
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
ee40177f6c68
Update FSF's address in the preamble.
Erik Naggum <erik@naggum.no>
parents:
5628
diff
changeset
|
19 Boston, MA 02111-1307, USA. */ |
5628 | 20 |
41767 | 21 |
22 #include "../src/lisp.h" | |
23 | |
5628 | 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" | |
30 | |
31 #define HORIZ_SPACING 4 | |
32 #define VERT_SPACING 4 | |
33 | |
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(); | |
42 | |
43 lwMenuBarClassRec lwMenubarClassRec = | |
44 { | |
45 { | |
46 /* core_class members */ | |
47 | |
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 */ | |
80 }, | |
81 { | |
82 /* composite_class members */ | |
83 | |
84 GeometryManager, /* geometry_manager */ | |
85 ChangeManaged, /* change_managed */ | |
86 XtInheritInsertChild, /* insert_child */ | |
87 XtInheritDeleteChild, /* delete_child */ | |
88 NULL, /* extension */ | |
89 }, | |
90 { | |
91 /* Menubar class members */ | |
92 | |
93 0, /* empty */ | |
94 } | |
95 }; | |
96 WidgetClass lwMenubarWidgetClass = (WidgetClass) &lwMenubarClassRec; | |
97 | |
98 | |
99 static void Initialize (request, new) | |
100 lwMenuBarWidget request, new; | |
101 { | |
102 if (request->core.width <= 0) | |
103 new->core.width = 1; | |
104 if (request->core.height <= 0) | |
105 new->core.height = 23; | |
106 } | |
107 | |
108 static void | |
109 Resize (w) | |
110 lwMenuBarWidget w; | |
111 { | |
112 do_layout(w); | |
113 } | |
114 | |
115 static void | |
116 do_layout (parent) | |
117 lwMenuBarWidget parent; | |
118 { | |
119 Widget child; | |
120 int cnt; | |
121 int managed_children = 0; | |
122 int managed_width = 0; | |
123 int new_pos = 0; | |
124 | |
125 /* | |
126 * Determine number of children which will fit on one line. | |
127 * For now we ignore the rest, making sure they are unmanaged. | |
128 */ | |
129 | |
130 cnt = 0; | |
131 while ((cnt < (int) parent->composite.num_children) && | |
132 (managed_width < (int) parent->core.width)) | |
133 { | |
134 child = parent->composite.children[cnt++]; | |
135 managed_children++; | |
136 managed_width += child->core.width + child->core.border_width * 2 + | |
137 HORIZ_SPACING; | |
138 } | |
139 | |
140 if (managed_width > (int) parent->core.width) | |
141 managed_children--; | |
142 | |
143 /* | |
144 * Correct positioning of children. | |
145 */ | |
146 | |
147 cnt = 0; | |
148 while (managed_children) | |
149 { | |
150 child = parent->composite.children[cnt++]; | |
151 | |
152 if (!child->core.managed) | |
153 XtManageChild (child); | |
154 | |
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; | |
159 | |
160 managed_children--; | |
161 } | |
162 | |
163 /* | |
164 * Make sure all remaining children are unmanaged. | |
165 */ | |
166 | |
167 while (cnt < parent->composite.num_children) | |
168 { | |
169 child = parent->composite.children[cnt]; | |
170 | |
171 if (child->core.managed) | |
172 XtUnmanageChild (child); | |
173 | |
174 if ((child->core.x != parent->core.width) || | |
175 (child->core.y != parent->core.height)) | |
176 XtMoveWidget (child, parent->core.width, parent->core.height); | |
177 | |
178 cnt++; | |
179 } | |
180 } | |
181 | |
182 | |
183 static XtGeometryResult | |
184 PreferredSize (w, request, preferred) | |
185 lwMenuBarWidget w; | |
186 XtWidgetGeometry *request, *preferred; | |
187 { | |
188 Widget child; | |
189 int cnt; | |
190 | |
191 /* | |
192 * If no changes are being made to the width or height, just agree. | |
193 */ | |
194 | |
195 if (!(request->request_mode & CWWidth) && | |
196 !(request->request_mode & CWHeight)) | |
197 return (XtGeometryYes); | |
198 | |
199 /* | |
200 * Right now assume everything goes in one row. Calculate the | |
201 * minimum required width and height. | |
202 */ | |
203 | |
204 preferred->width = 0; | |
205 preferred->height = 0; | |
206 | |
207 for (cnt = 0; cnt < w->composite.num_children; cnt++) | |
208 { | |
209 child = w->composite.children[cnt]; | |
210 if (child->core.managed) | |
211 { | |
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; | |
218 } | |
219 } | |
220 | |
221 preferred->request_mode = CWWidth | CWHeight; | |
222 | |
223 /* | |
224 * Case: both height and width requested | |
225 */ | |
226 | |
227 if ((request->request_mode & CWWidth) && | |
228 (request->request_mode & CWHeight)) | |
229 { | |
230 /* | |
231 * Ok if same or bigger. | |
232 */ | |
233 | |
234 if (preferred->width <= request->width && | |
235 preferred->height <= request->height) | |
236 { | |
237 preferred->width = request->width; | |
238 return (XtGeometryYes); | |
239 } | |
240 | |
241 /* | |
242 * If both dimensions are too small, say no. | |
243 */ | |
244 | |
245 else | |
246 if (preferred->width > request->width && | |
247 preferred->height > request->height) | |
248 return (XtGeometryNo); | |
249 | |
250 /* | |
251 * Otherwise one must be right, so say almost. | |
252 */ | |
253 | |
254 else | |
255 return (XtGeometryAlmost); | |
256 } | |
257 | |
258 /* | |
259 * If only one dimension is requested, either its OK or it isn't. | |
260 */ | |
261 | |
262 else | |
263 { | |
264 if (request->request_mode & CWWidth) | |
265 { | |
266 if (preferred->width <= request->width) | |
267 { | |
268 preferred->width = request->width; | |
269 return (XtGeometryYes); | |
270 } | |
271 else | |
272 return (XtGeometryNo); | |
273 } | |
274 else if (request->request_mode & CWHeight) | |
275 { | |
276 if (preferred->height <= request->height) | |
277 { | |
278 return (XtGeometryYes); | |
279 } | |
280 else | |
281 return (XtGeometryNo); | |
282 } | |
283 | |
284 return (XtGeometryYes); | |
285 } | |
286 } | |
287 | |
288 | |
289 static XtGeometryResult | |
290 GeometryManager (w, request, reply) | |
291 Widget w; | |
292 XtWidgetGeometry *request; | |
293 XtWidgetGeometry *reply; | |
294 { | |
295 | |
296 lwMenuBarWidget parent = (lwMenuBarWidget) w->core.parent; | |
297 | |
298 /* | |
299 * If the widget wants to move, just say no. | |
300 */ | |
301 | |
302 if ((request->request_mode & CWX && request->x != w->core.x) || | |
303 (request->request_mode & CWY && request->y != w->core.y)) | |
304 return (XtGeometryNo); | |
305 | |
306 /* | |
307 * Since everything "fits" for now, grant all requests. | |
308 */ | |
309 | |
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; | |
316 | |
317 do_layout (parent); | |
318 return (XtGeometryYes); | |
319 } | |
320 | |
321 | |
322 static XtGeometryResult | |
323 try_layout (parent) | |
324 lwMenuBarWidget parent; | |
325 { | |
326 Widget child; | |
327 int cnt; | |
328 int managed_children = 0; | |
329 int managed_width = 0; | |
330 int new_pos = 0; | |
331 | |
332 /* | |
333 * Determine number of children which will fit on one line. | |
334 * For now we ignore the rest, making sure they are unmanaged. | |
335 */ | |
336 | |
337 cnt = 0; | |
338 while ((cnt < (int) parent->composite.num_children) && | |
339 (managed_width < (int) parent->core.width)) | |
340 { | |
341 child = parent->composite.children[cnt++]; | |
342 if (child->core.managed) | |
343 { | |
344 managed_children++; | |
345 managed_width += child->core.width + child->core.border_width * 2 + | |
346 HORIZ_SPACING; | |
347 } | |
348 } | |
349 | |
350 if (managed_width > (int) parent->core.width) | |
351 return (XtGeometryNo); | |
352 else | |
353 return (XtGeometryYes); | |
354 } | |
355 | |
356 | |
357 | |
358 static void | |
359 ChangeManaged (w) | |
360 lwMenuBarWidget w; | |
361 { | |
362 XtGeometryResult result; | |
363 | |
364 result = try_layout (w); | |
365 | |
366 if (result != XtGeometryYes) | |
367 { | |
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); | |
371 } | |
372 | |
373 do_layout (w); | |
374 } |