Mercurial > hg > xemacs-beta
annotate src/glyphs-widget.c @ 5636:07256dcc0c8b
Add missing foreback specifier values to the GUI Element face.
They were missing for an unexplicable reason in my initial patch, leading to
nil color instances in the whole hierarchy of widget faces.
-------------------- ChangeLog entries follow: --------------------
src/ChangeLog addition:
2012-01-03 Didier Verna <didier@xemacs.org>
* faces.c (complex_vars_of_faces): Add missing foreback specifier
values to the GUI Element face.
author | Didier Verna <didier@lrde.epita.fr> |
---|---|
date | Tue, 03 Jan 2012 11:25:06 +0100 |
parents | 56144c8593a8 |
children |
rev | line source |
---|---|
428 | 1 /* Widget-specific glyph objects. |
863 | 2 Copyright (C) 1998, 1999, 2000, 2002 Andy Piper. |
1318 | 3 Copyright (C) 2003 Ben Wing. |
428 | 4 |
5 This file is part of XEmacs. | |
6 | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5176
diff
changeset
|
7 XEmacs is free software: you can redistribute it and/or modify it |
428 | 8 under the terms of the GNU General Public License as published by the |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5176
diff
changeset
|
9 Free Software Foundation, either version 3 of the License, or (at your |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5176
diff
changeset
|
10 option) any later version. |
428 | 11 |
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5176
diff
changeset
|
18 along with XEmacs. If not, see <http://www.gnu.org/licenses/>. */ |
428 | 19 |
20 /* Synched up with: Not in FSF. */ | |
21 | |
22 /* written by Andy Piper <andy@xemacs.org> */ | |
23 | |
24 #include <config.h> | |
25 #include "lisp.h" | |
800 | 26 |
27 #include "bytecode.h" | |
428 | 28 #include "console.h" |
872 | 29 #include "device-impl.h" |
428 | 30 #include "faces.h" |
800 | 31 #include "frame.h" |
428 | 32 #include "glyphs.h" |
800 | 33 #include "gui.h" |
34 #include "insdel.h" | |
35 #include "lstream.h" | |
5176
8b2f75cecb89
rename objects* (.c, .h and .el files) to fontcolor*
Ben Wing <ben@xemacs.org>
parents:
5047
diff
changeset
|
36 #include "fontcolor.h" |
800 | 37 #include "opaque.h" |
428 | 38 #include "window.h" |
39 | |
40 DEFINE_IMAGE_INSTANTIATOR_FORMAT (button); | |
41 DEFINE_IMAGE_INSTANTIATOR_FORMAT (combo_box); | |
42 Lisp_Object Qcombo_box; | |
43 DEFINE_IMAGE_INSTANTIATOR_FORMAT (edit_field); | |
44 Lisp_Object Qedit_field; | |
45 DEFINE_IMAGE_INSTANTIATOR_FORMAT (scrollbar); | |
46 Lisp_Object Qscrollbar; | |
47 DEFINE_IMAGE_INSTANTIATOR_FORMAT (widget); | |
48 DEFINE_IMAGE_INSTANTIATOR_FORMAT (label); | |
49 Lisp_Object Qlabel; | |
50 DEFINE_IMAGE_INSTANTIATOR_FORMAT (progress_gauge); | |
51 Lisp_Object Qprogress_gauge; | |
52 DEFINE_IMAGE_INSTANTIATOR_FORMAT (tree_view); | |
53 Lisp_Object Qtree_view; | |
54 DEFINE_IMAGE_INSTANTIATOR_FORMAT (tab_control); | |
55 Lisp_Object Qtab_control; | |
56 DEFINE_IMAGE_INSTANTIATOR_FORMAT (layout); | |
57 Lisp_Object Qlayout; | |
442 | 58 DEFINE_IMAGE_INSTANTIATOR_FORMAT (native_layout); |
59 Lisp_Object Qnative_layout; | |
428 | 60 |
61 Lisp_Object Qetched_in, Qetched_out, Qbevel_in, Qbevel_out; | |
442 | 62 Lisp_Object Qmake_glyph; |
863 | 63 Lisp_Object Vwidget_border_width; |
64 | |
65 static int widget_border_width (Lisp_Object domain); | |
66 static int widget_spacing (Lisp_Object domain); | |
67 static void widget_query_string_geometry (Lisp_Object string, Lisp_Object face, | |
68 int *width, int *height, Lisp_Object domain); | |
428 | 69 |
1068 | 70 #define BORDER_FIDDLE_FACTOR 10 |
428 | 71 #ifdef DEBUG_WIDGETS |
72 int debug_widget_instances; | |
73 #endif | |
74 | |
75 /* TODO: | |
438 | 76 - tooltips for controls, especially buttons. |
440 | 77 - keyboard traversal. |
78 - lisp configurable layout. | |
428 | 79 */ |
80 | |
438 | 81 /* In MS-Windows normal windows work in pixels, dialog boxes work in |
428 | 82 dialog box units. Why? sigh. We could reuse the metrics for dialogs |
83 if this were not the case. As it is we have to position things | |
84 pixel wise. I'm not even sure that X has this problem at least for | |
85 buttons in groups. */ | |
86 static int | |
87 widget_possible_dest_types (void) | |
88 { | |
89 return IMAGE_WIDGET_MASK; | |
90 } | |
91 | |
92 static void | |
442 | 93 check_valid_instantiator (Lisp_Object data) |
428 | 94 { |
95 Lisp_Object glyph = data; | |
96 if (SYMBOLP (data)) | |
97 glyph = XSYMBOL (data)->value; | |
98 | |
442 | 99 if (!CONSP (glyph) && !VECTORP (glyph)) |
100 invalid_argument ("instantiator item must be a vector", data); | |
428 | 101 } |
102 | |
103 static void | |
104 check_valid_orientation (Lisp_Object data) | |
105 { | |
106 if (!EQ (data, Qhorizontal) | |
107 && | |
108 !EQ (data, Qvertical)) | |
563 | 109 invalid_constant ("unknown orientation for layout", data); |
428 | 110 } |
111 | |
112 static void | |
438 | 113 check_valid_tab_orientation (Lisp_Object data) |
114 { | |
115 if (!EQ (data, Qtop) | |
116 && | |
117 !EQ (data, Qbottom) | |
118 && | |
119 !EQ (data, Qleft) | |
120 && | |
121 !EQ (data, Qright)) | |
563 | 122 invalid_constant ("unknown orientation for tab control", data); |
438 | 123 } |
124 | |
125 static void | |
428 | 126 check_valid_justification (Lisp_Object data) |
127 { | |
863 | 128 if (!EQ (data, Qleft) |
129 && | |
130 !EQ (data, Qright) | |
131 && | |
132 !EQ (data, Qtop) | |
133 && | |
134 !EQ (data, Qbottom) | |
135 && | |
136 !EQ (data, Qcenter)) | |
563 | 137 invalid_constant ("unknown justification for layout", data); |
428 | 138 } |
139 | |
140 static void | |
141 check_valid_border (Lisp_Object data) | |
142 { | |
143 if (!EQ (data, Qt) && !EQ (data, Qetched_in) && !EQ (data, Qetched_out) | |
144 && !EQ (data, Qbevel_in) && !EQ (data, Qbevel_out) | |
145 && !GLYPHP (data) && !VECTORP (data)) | |
442 | 146 invalid_argument ("unknown border style for layout", data); |
428 | 147 } |
148 | |
149 static void | |
2286 | 150 check_valid_anything (Lisp_Object UNUSED (data)) |
428 | 151 { |
152 } | |
153 | |
154 static void | |
155 check_valid_callback (Lisp_Object data) | |
156 { | |
157 if (!SYMBOLP (data) | |
158 && !COMPILED_FUNCTIONP (data) | |
159 && !CONSP (data)) | |
160 { | |
442 | 161 invalid_argument (":callback must be a function or expression", data); |
428 | 162 } |
163 } | |
164 | |
165 static void | |
442 | 166 check_valid_int_or_function (Lisp_Object data) |
167 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
168 if (!FIXNUMP (data) && !CONSP (data) && !SYMBOLP (data)) |
442 | 169 invalid_argument ("must be an integer or expresssion", data); |
170 } | |
171 | |
172 static void | |
428 | 173 check_valid_symbol (Lisp_Object data) |
174 { | |
175 CHECK_SYMBOL (data); | |
176 } | |
177 | |
178 static void | |
179 check_valid_string_or_vector (Lisp_Object data) | |
180 { | |
181 if (!STRINGP (data) && !VECTORP (data)) | |
442 | 182 invalid_argument (":descriptor must be a string or a vector", data); |
428 | 183 } |
184 | |
793 | 185 static void |
442 | 186 check_valid_item_list (Lisp_Object items) |
428 | 187 { |
2367 | 188 EXTERNAL_LIST_LOOP_2 (elt, items) |
428 | 189 { |
2367 | 190 if (STRINGP (elt)) |
191 CHECK_STRING (elt); | |
192 else if (VECTORP (elt)) | |
193 gui_parse_item_keywords (elt); | |
194 else if (LISTP (elt)) | |
195 check_valid_item_list (elt); | |
428 | 196 else |
2367 | 197 invalid_argument ("Item must be vector, list or string", elt); |
428 | 198 } |
199 } | |
200 | |
201 static void | |
442 | 202 check_valid_instantiator_list (Lisp_Object data) |
428 | 203 { |
2367 | 204 EXTERNAL_LIST_LOOP_2 (elt, data) |
428 | 205 { |
2367 | 206 check_valid_instantiator (elt); |
428 | 207 } |
208 } | |
209 | |
210 static Lisp_Object | |
211 glyph_instantiator_to_glyph (Lisp_Object sym) | |
212 { | |
213 /* This function calls lisp. */ | |
214 Lisp_Object glyph = sym; | |
215 struct gcpro gcpro1; | |
442 | 216 |
428 | 217 GCPRO1 (glyph); |
218 /* if we have a symbol get at the actual data */ | |
219 if (SYMBOLP (glyph)) | |
220 glyph = XSYMBOL (glyph)->value; | |
442 | 221 |
428 | 222 if (CONSP (glyph)) |
4677
8f1ee2d15784
Support full Common Lisp multiple values in C.
Aidan Kehoe <kehoea@parhasard.net>
parents:
3466
diff
changeset
|
223 glyph = IGNORE_MULTIPLE_VALUES (Feval (glyph)); |
428 | 224 |
225 /* Be really helpful to the user. */ | |
226 if (VECTORP (glyph)) | |
227 { | |
442 | 228 glyph = call1 (Qmake_glyph, glyph); |
428 | 229 } |
230 | |
231 /* substitute the new glyph */ | |
232 RETURN_UNGCPRO (glyph); | |
233 } | |
234 | |
442 | 235 static void |
428 | 236 substitute_keyword_value (Lisp_Object inst, Lisp_Object key, Lisp_Object val) |
237 { | |
238 int i; | |
239 /* substitute the new glyph */ | |
240 for (i = 0; i < XVECTOR_LENGTH (inst); i++) | |
241 { | |
242 if (EQ (key, XVECTOR_DATA (inst)[i])) | |
243 { | |
244 XVECTOR_DATA (inst)[i+1] = val; | |
245 break; | |
246 } | |
247 } | |
248 } | |
249 | |
863 | 250 /* Determine the border with of the widget. */ |
251 static int | |
252 widget_border_width (Lisp_Object domain) | |
253 { | |
254 /* #### FIXME -- need to use specifiers (Vwidget_border_width) for | |
255 some portion of this. */ | |
256 if (HAS_DEVMETH_P (DOMAIN_XDEVICE (domain), | |
257 widget_border_width)) | |
258 return DEVMETH (DOMAIN_XDEVICE (domain), widget_border_width, ()); | |
259 else | |
260 return DEFAULT_WIDGET_BORDER_WIDTH; | |
261 } | |
262 | |
263 static int | |
264 widget_instance_border_width (Lisp_Image_Instance* ii) | |
265 { | |
266 return widget_border_width (IMAGE_INSTANCE_DOMAIN (ii)); | |
267 } | |
268 | |
2297 | 269 /* #### It's not clear to me what the value of logical_unit_height should |
270 be, or whether it should even depend on the current image_instance. It | |
271 really should probably only depend on the default widget face and the | |
272 domain, however you can envisage users wanting different logical units | |
273 for nested layouts - so using the properties of the current layout is | |
274 probably not so dumb. */ | |
863 | 275 static int |
276 logical_unit_height (Lisp_Object text, Lisp_Object face, Lisp_Object domain) | |
277 { | |
278 int charheight = 0; | |
279 widget_query_string_geometry (text, face, | |
280 0, &charheight, domain); | |
281 /* For the returned value to be useful it needs to be big enough to | |
5384
3889ef128488
Fix misspelled words, and some grammar, across the entire source tree.
Jerry James <james@xemacs.org>
parents:
5176
diff
changeset
|
282 accommodate the largest single-height widget. This is currently |
863 | 283 the edit-field. */ |
284 return charheight + 2 * widget_spacing (domain) | |
285 + 4 * widget_border_width (domain); | |
286 } | |
287 | |
288 static int | |
289 widget_logical_unit_height (Lisp_Image_Instance* ii) | |
290 { | |
291 return logical_unit_height (NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)) ? | |
866 | 292 NILP (IMAGE_INSTANCE_NAME (ii)) ? |
293 Fsymbol_name (Qwidget) | |
294 : IMAGE_INSTANCE_NAME (ii) | |
863 | 295 : IMAGE_INSTANCE_WIDGET_TEXT (ii), |
296 IMAGE_INSTANCE_WIDGET_FACE (ii), | |
297 IMAGE_INSTANCE_DOMAIN (ii)); | |
298 } | |
299 | |
438 | 300 /* Wire widget property invocations to specific widgets. The problem |
301 we are solving here is that when instantiators get converted to | |
302 instances they lose some type information (they just become | |
303 subwindows or widgets for example). For widgets we need to preserve | |
304 this type information so that we can do widget specific operations | |
305 on the instances. This is encoded in the widget type | |
306 field. widget_property gets invoked by decoding the primary type | |
307 (Qwidget), <widget>_property then invokes based on the secondary | |
308 type (Qedit_field for example). It is debatable whether we should | |
309 wire things in this generalised way rather than treating widgets | |
310 specially in image_instance_property. */ | |
442 | 311 static Lisp_Object |
428 | 312 widget_property (Lisp_Object image_instance, Lisp_Object prop) |
313 { | |
440 | 314 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance); |
428 | 315 struct image_instantiator_methods* meths; |
442 | 316 #if 0 /* The usefulness of this is dubious. */ |
428 | 317 /* first see if its a general property ... */ |
318 if (!NILP (Fplist_member (IMAGE_INSTANCE_WIDGET_PROPS (ii), prop))) | |
319 return Fplist_get (IMAGE_INSTANCE_WIDGET_PROPS (ii), prop, Qnil); | |
442 | 320 #endif |
428 | 321 /* .. then try device specific methods ... */ |
442 | 322 meths = decode_device_ii_format (image_instance_device (image_instance), |
323 IMAGE_INSTANCE_WIDGET_TYPE (ii), | |
428 | 324 ERROR_ME_NOT); |
325 if (meths && HAS_IIFORMAT_METH_P (meths, property)) | |
326 return IIFORMAT_METH (meths, property, (image_instance, prop)); | |
327 /* ... then format specific methods ... */ | |
442 | 328 meths = decode_device_ii_format (Qnil, IMAGE_INSTANCE_WIDGET_TYPE (ii), |
428 | 329 ERROR_ME_NOT); |
330 if (meths && HAS_IIFORMAT_METH_P (meths, property)) | |
331 return IIFORMAT_METH (meths, property, (image_instance, prop)); | |
332 /* ... then fail */ | |
333 return Qunbound; | |
334 } | |
335 | |
442 | 336 /* Update the displayed properties of a widget. |
337 | |
338 #### This has been adapted from the original set_property functions | |
339 and thus reuses the state management of that. A better solution is | |
340 to simply re-parse the instantiator when items need updating. This | |
341 make comparing differences much simpler and obviates the need for a | |
342 lot of the state variables. | |
343 | |
344 #### property is still a valid function since we have to be able to | |
345 extract information from the actual widget. | |
346 | |
3094 | 347 #### widget_update should probably be re-written to use the |
442 | 348 instantiator. We probably want to keep a record of the differences |
349 also to make this easy. We would also need a pending_instantiator | |
350 so that changes could be delayed. */ | |
351 static void | |
352 widget_update (Lisp_Object image_instance, Lisp_Object instantiator) | |
428 | 353 { |
440 | 354 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance); |
428 | 355 struct image_instantiator_methods* meths; |
454 | 356 struct gcpro gcpro1; |
428 | 357 |
442 | 358 Lisp_Object text = find_keyword_in_vector (instantiator, Q_text); |
454 | 359 Lisp_Object desc = find_keyword_in_vector (instantiator, Q_descriptor); |
360 Lisp_Object items = find_keyword_in_vector (instantiator, Q_items); | |
361 Lisp_Object descriptor_item = Qnil; | |
362 | |
363 GCPRO1 (descriptor_item); | |
364 | |
442 | 365 /* Pick up any generic properties that we might need to keep hold |
454 | 366 of. |
367 #### This is potentially bogus because it is changing the items | |
368 in place rather than in the pending items. */ | |
442 | 369 if (!NILP (text)) |
438 | 370 { |
442 | 371 IMAGE_INSTANCE_WIDGET_TEXT (ii) = text; |
372 IMAGE_INSTANCE_TEXT_CHANGED (ii) = 1; | |
438 | 373 } |
374 | |
454 | 375 /* Retrieve the gui item information. This is easy if we have been |
376 provided with a vector, more difficult if we have just been given | |
377 keywords. | |
378 | |
379 #### This is inconsistent with instantiation in that you have to | |
380 have the :descriptor keyword for updates in order to recognise | |
381 changes. */ | |
382 if (VECTORP (desc)) | |
383 { | |
384 descriptor_item = gui_parse_item_keywords_no_errors (desc); | |
385 } | |
386 else | |
387 { | |
388 /* Since we are updating the instantiator could be incomplete | |
389 and hence the gui item descriptor not well formed. We | |
390 therefore try updating and discard the results if nothing | |
391 changed. */ | |
392 descriptor_item = copy_gui_item (IMAGE_INSTANCE_WIDGET_ITEM (ii)); | |
393 if (!update_gui_item_keywords (descriptor_item, instantiator)) | |
394 descriptor_item = Qnil; | |
395 } | |
396 | |
397 /* Record new items for update. *_redisplay will do the | |
398 rest. */ | |
399 if (!EQ (IMAGE_INSTANCE_WIDGET_TYPE (ii), Qlayout) | |
400 && | |
401 !EQ (IMAGE_INSTANCE_WIDGET_TYPE (ii), Qnative_layout)) | |
402 { | |
403 if (!NILP (items)) | |
404 { | |
405 if (NILP (descriptor_item)) | |
406 descriptor_item = IMAGE_INSTANCE_WIDGET_ITEM (ii); | |
407 | |
408 check_valid_item_list (items); | |
409 #ifdef DEBUG_WIDGET_OUTPUT | |
410 stderr_out ("items for widget %p updated\n", | |
411 IMAGE_INSTANCE_SUBWINDOW_ID (ii)); | |
412 #endif | |
413 /* Don't set the actual items since we might decide not to use | |
414 the new ones (because nothing has really changed). If we did | |
415 set them and didn't use them then we would get into whole | |
416 heaps of trouble when the old items get GC'd. */ | |
417 descriptor_item = Fcons (descriptor_item, parse_gui_item_tree_children (items)); | |
418 } | |
419 /* If the descriptor was updated but not the items we need to fill | |
420 in the `new' items. */ | |
421 else if (!NILP (descriptor_item) | |
422 && | |
423 CONSP (IMAGE_INSTANCE_WIDGET_ITEMS (ii))) | |
424 { | |
425 descriptor_item = Fcons | |
426 (descriptor_item, | |
427 copy_gui_item_tree (XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))); | |
428 } | |
429 } | |
430 | |
431 if (!NILP (descriptor_item)) | |
432 { | |
433 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii) = descriptor_item; | |
434 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 1; | |
435 } | |
436 | |
437 UNGCPRO; | |
438 | |
438 | 439 /* Now try device specific methods first ... */ |
442 | 440 meths = decode_device_ii_format (image_instance_device (image_instance), |
441 IMAGE_INSTANCE_WIDGET_TYPE (ii), | |
442 ERROR_ME_NOT); | |
443 MAYBE_IIFORMAT_METH (meths, update, (image_instance, instantiator)); | |
444 /* ... then format specific methods ... */ | |
445 meths = decode_device_ii_format (Qnil, IMAGE_INSTANCE_WIDGET_TYPE (ii), | |
446 ERROR_ME_NOT); | |
447 MAYBE_IIFORMAT_METH (meths, update, (image_instance, instantiator)); | |
448 #if 0 /* The usefulness of this is dubious. */ | |
449 /* we didn't do any device specific properties, so shove the property in our plist. */ | |
450 IMAGE_INSTANCE_WIDGET_PROPS (ii) | |
451 = Fplist_put (IMAGE_INSTANCE_WIDGET_PROPS (ii), prop, val); | |
452 #endif | |
453 } | |
454 | |
455 /* Like the rest of redisplay, we want widget updates to occur | |
456 asynchronously. Thus toolkit specific methods for setting | |
457 properties must be called by redisplay instead of by *_update. Thus | |
458 *_update records the change and this function actually implements | |
459 it. We want to be slightly clever about this however by supplying | |
460 format specific functions for the updates instead of lumping them | |
461 all into this function. Note that there is no need for format | |
462 generic functions. This is not the same as widget_update! */ | |
463 void | |
464 redisplay_widget (Lisp_Object widget) | |
465 { | |
466 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (widget); | |
467 struct image_instantiator_methods* meths; | |
468 | |
469 if (!WIDGET_IMAGE_INSTANCEP (widget) | |
470 || EQ (IMAGE_INSTANCE_WIDGET_TYPE (ii), Qlayout) | |
471 || EQ (IMAGE_INSTANCE_WIDGET_TYPE (ii), Qnative_layout)) | |
472 return; | |
473 | |
474 /* Device-format specific methods - e.g. x_tab_control_redisplay () */ | |
475 meths = decode_device_ii_format (image_instance_device (widget), | |
428 | 476 IMAGE_INSTANCE_WIDGET_TYPE (ii), |
477 ERROR_ME_NOT); | |
442 | 478 MAYBE_IIFORMAT_METH (meths, redisplay, (widget)); |
479 | |
480 /* Device generic methods - e.g. x_redisplay_widget (). We must | |
481 update the widget's size as it may have been changed by the the | |
482 layout routines. We also do this here so that explicit resizing | |
483 from lisp does not result in synchronous updates. Do this last so | |
484 that format-specific methods have an opportunity to prevent | |
485 wholesale changes - e.g. rebuilding tabs. */ | |
863 | 486 MAYBE_DEVMETH (DOMAIN_XDEVICE (IMAGE_INSTANCE_DOMAIN (ii)), |
487 redisplay_widget, (ii)); | |
442 | 488 |
489 /* Pick up the items we recorded earlier. */ | |
490 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii)) | |
428 | 491 { |
442 | 492 IMAGE_INSTANCE_WIDGET_ITEMS (ii) = |
493 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii); | |
494 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii) = Qnil; | |
428 | 495 } |
496 } | |
497 | |
771 | 498 static void |
499 widget_query_string_geometry (Lisp_Object string, Lisp_Object face, | |
500 int *width, int *height, Lisp_Object domain) | |
501 { | |
502 struct device *d = DOMAIN_XDEVICE (domain); | |
503 | |
504 if (HAS_DEVMETH_P (d, widget_query_string_geometry)) | |
505 DEVMETH (d, widget_query_string_geometry, | |
506 (string, face, width, height, domain)); | |
507 else | |
508 query_string_geometry (string, face, width, height, 0, domain); | |
509 | |
510 } | |
511 | |
863 | 512 /* Determine the spacing of the widget. */ |
513 static int | |
514 widget_spacing (Lisp_Object domain) | |
515 { | |
516 if (HAS_DEVMETH_P (DOMAIN_XDEVICE (domain), widget_spacing)) | |
517 return DEVMETH (DOMAIN_XDEVICE (domain), | |
518 widget_spacing, (0)); | |
519 else | |
520 return DEFAULT_WIDGET_SPACING; | |
521 } | |
522 | |
438 | 523 /* Query for a widgets desired geometry. If no type specific method is |
524 provided then use the widget text to calculate sizes. */ | |
442 | 525 static void |
526 widget_query_geometry (Lisp_Object image_instance, | |
527 int* width, int* height, | |
438 | 528 enum image_instance_geometry disp, Lisp_Object domain) |
529 { | |
440 | 530 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance); |
438 | 531 struct image_instantiator_methods* meths; |
442 | 532 Lisp_Object dynamic_width = Qnil; |
533 Lisp_Object dynamic_height = Qnil; | |
438 | 534 |
535 /* First just set up what we already have. */ | |
536 if (width) *width = IMAGE_INSTANCE_WIDTH (ii); | |
537 if (height) *height = IMAGE_INSTANCE_HEIGHT (ii); | |
442 | 538 |
438 | 539 if (IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii) |
540 || | |
541 IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii)) | |
542 { | |
543 /* .. then try device specific methods ... */ | |
442 | 544 meths = decode_device_ii_format (image_instance_device (image_instance), |
545 IMAGE_INSTANCE_WIDGET_TYPE (ii), | |
438 | 546 ERROR_ME_NOT); |
547 if (meths && HAS_IIFORMAT_METH_P (meths, query_geometry)) | |
442 | 548 IIFORMAT_METH (meths, query_geometry, (image_instance, |
438 | 549 width, height, disp, |
550 domain)); | |
551 else | |
552 { | |
553 /* ... then format specific methods ... */ | |
442 | 554 meths = decode_device_ii_format (Qnil, IMAGE_INSTANCE_WIDGET_TYPE (ii), |
438 | 555 ERROR_ME_NOT); |
556 if (meths && HAS_IIFORMAT_METH_P (meths, query_geometry)) | |
442 | 557 IIFORMAT_METH (meths, query_geometry, (image_instance, |
438 | 558 width, height, disp, |
559 domain)); | |
442 | 560 else |
438 | 561 { |
442 | 562 int w, h; |
563 | |
438 | 564 /* Then if we are allowed to resize the widget, make the |
565 size the same as the text dimensions. */ | |
771 | 566 widget_query_string_geometry (IMAGE_INSTANCE_WIDGET_TEXT (ii), |
567 IMAGE_INSTANCE_WIDGET_FACE (ii), | |
568 &w, &h, domain); | |
438 | 569 /* Adjust the size for borders. */ |
3466 | 570 if (width && IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii)) |
863 | 571 *width = w + 2 * widget_instance_border_width (ii); |
3466 | 572 if (height && IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii)) |
863 | 573 *height = h + 2 * widget_instance_border_width (ii); |
438 | 574 } |
575 } | |
442 | 576 /* Finish off with dynamic sizing. */ |
3466 | 577 if (width && !NILP (IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (ii))) |
442 | 578 { |
853 | 579 dynamic_width = |
580 eval_within_redisplay (IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (ii)); | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
581 if (FIXNUMP (dynamic_width)) |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
582 *width = XFIXNUM (dynamic_width); |
442 | 583 } |
3466 | 584 if (height && !NILP (IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (ii))) |
442 | 585 { |
853 | 586 dynamic_height = |
587 eval_within_redisplay (IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (ii)); | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
588 if (FIXNUMP (dynamic_height)) |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
589 *height = XFIXNUM (dynamic_height); |
442 | 590 } |
438 | 591 } |
592 } | |
593 | |
442 | 594 static int |
595 widget_layout (Lisp_Object image_instance, | |
596 int width, int height, int xoffset, int yoffset, | |
597 Lisp_Object domain) | |
438 | 598 { |
440 | 599 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance); |
438 | 600 struct image_instantiator_methods* meths; |
601 | |
602 /* .. then try device specific methods ... */ | |
442 | 603 meths = decode_device_ii_format (image_instance_device (image_instance), |
604 IMAGE_INSTANCE_WIDGET_TYPE (ii), | |
438 | 605 ERROR_ME_NOT); |
606 if (meths && HAS_IIFORMAT_METH_P (meths, layout)) | |
442 | 607 return IIFORMAT_METH (meths, layout, (image_instance, |
608 width, height, xoffset, yoffset, | |
609 domain)); | |
438 | 610 else |
611 { | |
612 /* ... then format specific methods ... */ | |
442 | 613 meths = decode_device_ii_format (Qnil, IMAGE_INSTANCE_WIDGET_TYPE (ii), |
438 | 614 ERROR_ME_NOT); |
615 if (meths && HAS_IIFORMAT_METH_P (meths, layout)) | |
442 | 616 return IIFORMAT_METH (meths, layout, (image_instance, |
617 width, height, xoffset, yoffset, | |
618 domain)); | |
438 | 619 } |
442 | 620 return 1; |
438 | 621 } |
622 | |
428 | 623 static void |
624 widget_validate (Lisp_Object instantiator) | |
625 { | |
626 Lisp_Object desc = find_keyword_in_vector (instantiator, Q_descriptor); | |
627 | |
628 if (NILP (desc)) | |
563 | 629 invalid_argument ("Must supply :descriptor", instantiator); |
428 | 630 |
631 if (VECTORP (desc)) | |
632 gui_parse_item_keywords (desc); | |
633 | |
634 if (!NILP (find_keyword_in_vector (instantiator, Q_width)) | |
635 && !NILP (find_keyword_in_vector (instantiator, Q_pixel_width))) | |
563 | 636 invalid_argument ("Must supply only one of :width and :pixel-width", instantiator); |
428 | 637 |
638 if (!NILP (find_keyword_in_vector (instantiator, Q_height)) | |
639 && !NILP (find_keyword_in_vector (instantiator, Q_pixel_height))) | |
563 | 640 invalid_argument ("Must supply only one of :height and :pixel-height", instantiator); |
428 | 641 } |
642 | |
643 static void | |
644 combo_box_validate (Lisp_Object instantiator) | |
645 { | |
646 widget_validate (instantiator); | |
442 | 647 if (NILP (find_keyword_in_vector (instantiator, Q_items))) |
563 | 648 invalid_argument ("Must supply item list", instantiator); |
428 | 649 } |
650 | |
651 /* we need to convert things like glyphs to images, eval expressions | |
652 etc.*/ | |
653 static Lisp_Object | |
2286 | 654 widget_normalize (Lisp_Object inst, Lisp_Object UNUSED (console_type), |
655 Lisp_Object UNUSED (dest_mask)) | |
428 | 656 { |
657 /* This function can call lisp */ | |
658 Lisp_Object glyph = find_keyword_in_vector (inst, Q_image); | |
659 | |
660 /* we need to eval glyph if its an expression, we do this for the | |
442 | 661 same reasons we normalize file to data. |
662 | |
663 #### should just normalize the data. */ | |
428 | 664 if (!NILP (glyph)) |
665 { | |
1318 | 666 substitute_keyword_value (inst, Q_image, |
667 glyph_instantiator_to_glyph (glyph)); | |
428 | 668 } |
669 | |
670 return inst; | |
671 } | |
672 | |
673 static void | |
440 | 674 initialize_widget_image_instance (Lisp_Image_Instance *ii, Lisp_Object type) |
428 | 675 { |
676 /* initialize_subwindow_image_instance (ii);*/ | |
677 IMAGE_INSTANCE_WIDGET_TYPE (ii) = type; | |
678 IMAGE_INSTANCE_WIDGET_PROPS (ii) = Qnil; | |
438 | 679 SET_IMAGE_INSTANCE_WIDGET_FACE (ii, Qnil); |
428 | 680 IMAGE_INSTANCE_WIDGET_ITEMS (ii) = allocate_gui_item (); |
442 | 681 IMAGE_INSTANCE_LAYOUT_CHILDREN (ii) = Qnil; |
682 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii) = Qnil; | |
683 IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (ii) = Qnil; | |
684 IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (ii) = Qnil; | |
438 | 685 IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii) = 1; |
686 IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii) = 1; | |
442 | 687 IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) = LAYOUT_HORIZONTAL; |
863 | 688 IMAGE_INSTANCE_SUBWINDOW_H_JUSTIFY (ii) = 0; |
689 IMAGE_INSTANCE_SUBWINDOW_V_JUSTIFY (ii) = 0; | |
428 | 690 } |
691 | |
692 /* Instantiate a button widget. Unfortunately instantiated widgets are | |
693 particular to a frame since they need to have a parent. It's not | |
694 like images where you just select the image into the context you | |
695 want to display it in and BitBlt it. So image instances can have a | |
696 many-to-one relationship with things you see, whereas widgets can | |
697 only be one-to-one (i.e. per frame) */ | |
698 void | |
438 | 699 widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, |
700 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | |
701 int dest_mask, Lisp_Object domain) | |
428 | 702 { |
442 | 703 /* #### practically all of this should be moved to widget_update() |
704 so that users can dynamically change all possible widget | |
705 properties. */ | |
440 | 706 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 707 Lisp_Object face = find_keyword_in_vector (instantiator, Q_face); |
708 Lisp_Object height = find_keyword_in_vector (instantiator, Q_height); | |
709 Lisp_Object width = find_keyword_in_vector (instantiator, Q_width); | |
710 Lisp_Object pixwidth = find_keyword_in_vector (instantiator, Q_pixel_width); | |
711 Lisp_Object pixheight = find_keyword_in_vector (instantiator, Q_pixel_height); | |
712 Lisp_Object desc = find_keyword_in_vector (instantiator, Q_descriptor); | |
713 Lisp_Object glyph = find_keyword_in_vector (instantiator, Q_image); | |
440 | 714 Lisp_Object items = find_keyword_in_vector (instantiator, Q_items); |
438 | 715 Lisp_Object orient = find_keyword_in_vector (instantiator, Q_orientation); |
442 | 716 Lisp_Object mwidth = find_keyword_in_vector (instantiator, Q_margin_width); |
717 Lisp_Object ifocus = find_keyword_in_vector (instantiator, Q_initial_focus); | |
428 | 718 int pw=0, ph=0, tw=0, th=0; |
442 | 719 |
428 | 720 /* this just does pixel type sizing */ |
721 subwindow_instantiate (image_instance, instantiator, pointer_fg, pointer_bg, | |
722 dest_mask, domain); | |
723 | |
442 | 724 if (!(dest_mask & IMAGE_WIDGET_MASK)) |
725 incompatible_image_types (instantiator, dest_mask, IMAGE_WIDGET_MASK); | |
428 | 726 |
727 initialize_widget_image_instance (ii, XVECTOR_DATA (instantiator)[0]); | |
728 | |
440 | 729 IMAGE_INSTANCE_TYPE (ii) = IMAGE_WIDGET; |
730 | |
428 | 731 /* retrieve the fg and bg colors */ |
732 if (!NILP (face)) | |
438 | 733 SET_IMAGE_INSTANCE_WIDGET_FACE (ii, Fget_face (face)); |
428 | 734 |
454 | 735 /* Retrieve the gui item information. This is easy if we have been |
428 | 736 provided with a vector, more difficult if we have just been given |
454 | 737 keywords. Note that standard gui descriptor shortcuts will not work |
738 because of keyword parsing. | |
739 | |
740 #### This is bogus in that descriptor and items share the same slot, | |
741 we should rationalize. */ | |
742 if (VECTORP (desc)) | |
743 { | |
744 IMAGE_INSTANCE_WIDGET_ITEMS (ii) = | |
745 gui_parse_item_keywords_no_errors (desc); | |
746 } | |
747 else | |
428 | 748 { |
749 /* big cheat - we rely on the fact that a gui item looks like an instantiator */ | |
442 | 750 IMAGE_INSTANCE_WIDGET_ITEMS (ii) = |
454 | 751 widget_gui_parse_item_keywords (instantiator); |
428 | 752 } |
753 | |
440 | 754 /* Pick up the orientation before we do our first layout. */ |
755 if (EQ (orient, Qleft) || EQ (orient, Qright) || EQ (orient, Qvertical)) | |
442 | 756 IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) = LAYOUT_VERTICAL; |
440 | 757 |
428 | 758 /* parse more gui items out of the properties */ |
442 | 759 if (!NILP (items) && !EQ (IMAGE_INSTANCE_WIDGET_TYPE (ii), Qlayout) |
760 && !EQ (IMAGE_INSTANCE_WIDGET_TYPE (ii), Qnative_layout)) | |
428 | 761 { |
442 | 762 IMAGE_INSTANCE_WIDGET_ITEMS (ii) = |
763 Fcons (IMAGE_INSTANCE_WIDGET_ITEMS (ii), | |
764 parse_gui_item_tree_children (items)); | |
428 | 765 } |
766 | |
438 | 767 /* Normalize size information. We now only assign sizes if the user |
768 gives us some explicitly, or there are some constraints that we | |
769 can't change later on. Otherwise we postpone sizing until query | |
770 geometry gets called. */ | |
771 if (!NILP (pixwidth)) /* pixwidth takes precendent */ | |
772 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
773 if (!FIXNUMP (pixwidth)) |
442 | 774 IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (ii) = pixwidth; |
775 else | |
776 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
777 pw = XFIXNUM (pixwidth); |
442 | 778 IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii) = 0; |
779 } | |
438 | 780 } |
781 else if (!NILP (width)) | |
782 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
783 tw = XFIXNUM (width); |
438 | 784 IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii) = 0; |
785 } | |
786 | |
428 | 787 if (!NILP (pixheight)) |
438 | 788 { |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
789 if (!FIXNUMP (pixheight)) |
442 | 790 IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (ii) = pixheight; |
791 else | |
792 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
793 ph = XFIXNUM (pixheight); |
442 | 794 IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii) = 0; |
795 } | |
438 | 796 } |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
797 else if (!NILP (height) && XFIXNUM (height) > 1) |
438 | 798 { |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
799 th = XFIXNUM (height); |
438 | 800 IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii) = 0; |
801 } | |
802 | |
803 /* Taking the default face information when the user has specified | |
804 size in characters is probably as good as any since the widget | |
805 face is more likely to be proportional and thus give inadequate | |
806 results. Using character sizes can only ever be approximate | |
863 | 807 anyway. :height is measured in logical characters which take into |
808 account the borders and spacing on widgets. */ | |
809 if (tw) | |
810 { | |
811 int charwidth; | |
5047
07dcc7000bbf
put width before height consistently, fix a real bug found in the process
Ben Wing <ben@xemacs.org>
parents:
4677
diff
changeset
|
812 default_face_font_info (domain, 0, 0, &charwidth, 0, 0); |
863 | 813 pw = ROUND_UP (charwidth * tw + 4 * widget_instance_border_width (ii), charwidth); |
814 } | |
815 | |
816 /* For heights the widget face is more appropriate. */ | |
817 if (th == 1) | |
438 | 818 { |
863 | 819 int charheight; |
820 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii))) | |
821 { | |
822 widget_query_string_geometry (IMAGE_INSTANCE_WIDGET_TEXT (ii), | |
823 IMAGE_INSTANCE_WIDGET_FACE (ii), | |
824 0, &charheight, domain); | |
825 } | |
826 else | |
827 { | |
5047
07dcc7000bbf
put width before height consistently, fix a real bug found in the process
Ben Wing <ben@xemacs.org>
parents:
4677
diff
changeset
|
828 default_face_font_info (domain, 0, 0, 0, &charheight, 0); |
863 | 829 } |
830 ph = (charheight + 2 * widget_instance_border_width (ii)) * th; | |
831 } | |
832 /* For heights > 1 use logical units. */ | |
833 else if (th > 1) | |
834 { | |
835 ph = widget_logical_unit_height (ii) * th; | |
438 | 836 } |
428 | 837 |
838 /* for a widget with an image pick up the dimensions from that */ | |
839 if (!NILP (glyph)) | |
840 { | |
438 | 841 if (!pw) |
863 | 842 pw = glyph_width (glyph, image_instance) + 2 * widget_instance_border_width (ii); |
438 | 843 if (!ph) |
863 | 844 ph = glyph_height (glyph, image_instance) + 2 * widget_instance_border_width (ii); |
438 | 845 IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii) = 0; |
846 IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii) = 0; | |
428 | 847 } |
848 | |
442 | 849 /* Pick up the margin width. */ |
850 if (!NILP (mwidth)) | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
851 IMAGE_INSTANCE_MARGIN_WIDTH (ii) = XFIXNUM (mwidth); |
442 | 852 |
853 IMAGE_INSTANCE_WANTS_INITIAL_FOCUS (ii) = !NILP (ifocus); | |
438 | 854 |
442 | 855 /* Layout for the layout widget is premature at this point since the |
856 children will not have been instantiated. We can't instantiate | |
857 them until the device instantiation method for the layout has | |
858 been executed. We do however want to record any specified | |
859 dimensions. */ | |
860 if (pw) IMAGE_INSTANCE_WIDTH (ii) = pw; | |
861 if (ph) IMAGE_INSTANCE_HEIGHT (ii) = ph; | |
862 } | |
863 | |
864 static void | |
2286 | 865 widget_post_instantiate (Lisp_Object UNUSED (image_instance), |
866 #ifdef DEBUG_WIDGETS | |
867 Lisp_Object instantiator, | |
868 #else | |
869 Lisp_Object UNUSED (instantiator), | |
870 #endif | |
871 Lisp_Object UNUSED (domain)) | |
442 | 872 { |
428 | 873 #ifdef DEBUG_WIDGETS |
874 debug_widget_instances++; | |
875 stderr_out ("instantiated "); | |
876 debug_print (instantiator); | |
877 stderr_out ("%d widgets instantiated\n", debug_widget_instances); | |
878 #endif | |
879 } | |
880 | |
442 | 881 /* Get the geometry of a button control. We need to adjust the size |
882 depending on the type of button. */ | |
883 static void | |
884 button_query_geometry (Lisp_Object image_instance, | |
885 int* width, int* height, | |
2286 | 886 enum image_instance_geometry UNUSED (disp), |
887 Lisp_Object domain) | |
442 | 888 { |
889 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | |
890 int w, h; | |
771 | 891 widget_query_string_geometry (IMAGE_INSTANCE_WIDGET_TEXT (ii), |
892 IMAGE_INSTANCE_WIDGET_FACE (ii), | |
893 &w, &h, domain); | |
442 | 894 /* Adjust the size for borders. */ |
895 if (IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii)) | |
896 { | |
863 | 897 *width = w + 3 * widget_instance_border_width (ii); |
442 | 898 |
899 if (EQ (XGUI_ITEM (IMAGE_INSTANCE_WIDGET_ITEM (ii))->style, Qradio) | |
900 || | |
901 EQ (XGUI_ITEM (IMAGE_INSTANCE_WIDGET_ITEM (ii))->style, Qtoggle)) | |
902 /* This is an approximation to the size of the actual button bit. */ | |
903 *width += 12; | |
904 } | |
905 if (IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii)) | |
863 | 906 *height = h + 3 * widget_instance_border_width (ii); |
907 } | |
908 | |
909 /* Get the geometry of an edit field. */ | |
910 static void | |
911 edit_field_query_geometry (Lisp_Object image_instance, | |
2286 | 912 int* width, int* height, |
913 enum image_instance_geometry UNUSED (disp), | |
914 Lisp_Object domain) | |
863 | 915 { |
916 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | |
917 int w, h; | |
918 widget_query_string_geometry (IMAGE_INSTANCE_WIDGET_TEXT (ii), | |
919 IMAGE_INSTANCE_WIDGET_FACE (ii), | |
920 &w, &h, domain); | |
921 /* Adjust the size for borders. */ | |
922 if (IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii)) | |
923 *width = w + 4 * widget_instance_border_width (ii); | |
924 if (IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii)) | |
925 *height = h + 4 * widget_instance_border_width (ii); | |
442 | 926 } |
927 | |
438 | 928 /* tree-view geometry - get the height right */ |
428 | 929 static void |
442 | 930 tree_view_query_geometry (Lisp_Object image_instance, |
931 int* width, int* height, | |
2286 | 932 enum image_instance_geometry UNUSED (disp), |
933 Lisp_Object domain) | |
428 | 934 { |
440 | 935 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
438 | 936 Lisp_Object items = IMAGE_INSTANCE_WIDGET_ITEMS (ii); |
937 | |
442 | 938 |
438 | 939 if (*width) |
940 { | |
941 /* #### what should this be. reconsider when X has tree views. */ | |
771 | 942 widget_query_string_geometry (IMAGE_INSTANCE_WIDGET_TEXT (ii), |
943 IMAGE_INSTANCE_WIDGET_FACE (ii), | |
944 width, 0, domain); | |
438 | 945 } |
946 if (*height) | |
947 { | |
948 int len, h; | |
863 | 949 /* #### widget face would be better here. */ |
5047
07dcc7000bbf
put width before height consistently, fix a real bug found in the process
Ben Wing <ben@xemacs.org>
parents:
4677
diff
changeset
|
950 default_face_font_info (domain, 0, 0, 0, &h, 0); |
438 | 951 GET_LIST_LENGTH (items, len); |
952 *height = len * h; | |
953 } | |
428 | 954 } |
955 | |
2297 | 956 /* Get the geometry of a tab control. This is based on the number of |
957 items and text therein in the tab control. */ | |
428 | 958 static void |
442 | 959 tab_control_query_geometry (Lisp_Object image_instance, |
960 int* width, int* height, | |
2286 | 961 enum image_instance_geometry UNUSED (disp), |
962 Lisp_Object domain) | |
428 | 963 { |
440 | 964 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
442 | 965 Lisp_Object items = XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)); |
428 | 966 Lisp_Object rest; |
442 | 967 int tw = 0, th = 0; |
428 | 968 |
438 | 969 LIST_LOOP (rest, items) |
428 | 970 { |
442 | 971 int h, w; |
438 | 972 |
2297 | 973 /* #### Maybe we should allow items to be a list of strings? |
974 Ie, autoconvert "label" -> ["label" "label" :selected maybe-t]. | |
975 Maybe there's a better place (or several places) to do this? | |
976 If so, change image_instantiator_tab_control back to use | |
977 check_valid_item_list for checking Q_items. -- sjt */ | |
771 | 978 widget_query_string_geometry (XGUI_ITEM (XCAR (rest))->name, |
863 | 979 IMAGE_INSTANCE_WIDGET_FACE (ii), |
980 &w, &h, domain); | |
981 tw += 5 * widget_instance_border_width (ii); /* some bias */ | |
438 | 982 tw += w; |
863 | 983 th = max (th, h + 2 * widget_instance_border_width (ii)); |
428 | 984 } |
985 | |
438 | 986 /* Fixup returned values depending on orientation. */ |
987 if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii)) | |
988 { | |
989 if (height) *height = tw; | |
990 if (width) *width = th; | |
991 } | |
992 else | |
993 { | |
994 if (height) *height = th; | |
995 if (width) *width = tw; | |
996 } | |
428 | 997 } |
998 | |
442 | 999 /* Determine whether only the order has changed for a tab. */ |
1318 | 1000 int |
1001 tab_control_order_only_changed (Lisp_Object image_instance) | |
442 | 1002 { |
1318 | 1003 /* Called within redisplay */ |
442 | 1004 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
1005 int found = 0, len, pending_len; | |
1006 Lisp_Object rest; | |
1007 | |
1008 /* Degenerate case. */ | |
1009 if (NILP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii))) | |
1010 return 1; | |
1011 | |
1012 /* See whether we just need a change in order. */ | |
1013 GET_LIST_LENGTH (IMAGE_INSTANCE_WIDGET_ITEMS (ii), len); | |
1014 GET_LIST_LENGTH (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii), | |
1015 pending_len); | |
1016 if (len == pending_len) | |
1017 { | |
1018 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii))) | |
1019 { | |
1020 Lisp_Object pending_rest; | |
1021 found = 0; | |
1022 LIST_LOOP (pending_rest, | |
1023 XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii))) | |
1024 { | |
1025 if (gui_item_equal_sans_selected (XCAR (rest), | |
1913 | 1026 XCAR (pending_rest), 0)) |
442 | 1027 { |
1028 found = 1; | |
1029 break; | |
1030 } | |
1031 } | |
1032 if (!found) | |
1033 break; | |
1034 } | |
1035 } | |
1036 return found; | |
1037 } | |
1038 | |
428 | 1039 |
1040 /***************************************************************************** | |
1041 * widget layout * | |
1042 *****************************************************************************/ | |
442 | 1043 /* We need to cascade normalization.*/ |
428 | 1044 static Lisp_Object |
442 | 1045 layout_normalize (Lisp_Object inst, Lisp_Object console_type, |
1046 Lisp_Object dest_mask) | |
428 | 1047 { |
1048 /* This function can call lisp */ | |
442 | 1049 struct gcpro gcpro1, gcpro2; |
1050 Lisp_Object alist = Qnil, new_items = Qnil, border; | |
1051 /* This function can call lisp */ | |
1052 Lisp_Object items; | |
1053 | |
1054 GCPRO2 (alist, new_items); | |
1055 alist = tagged_vector_to_alist (inst); | |
1056 items = assq_no_quit (Q_items, alist); | |
1057 | |
1058 /* We need to normalize sub-objects. */ | |
428 | 1059 if (!NILP (items)) |
1060 { | |
1061 Lisp_Object rest; | |
442 | 1062 LIST_LOOP (rest, XCDR (items)) |
428 | 1063 { |
442 | 1064 /* Substitute the new instantiator */ |
1065 new_items = Fcons (normalize_image_instantiator (XCAR (rest), | |
1066 console_type, dest_mask), | |
1067 new_items); | |
1068 } | |
1069 new_items = Fnreverse (new_items); | |
1070 Fsetcdr (items, new_items); | |
1071 } | |
1072 /* Normalize the border spec. */ | |
1073 border = assq_no_quit (Q_border, alist); | |
1074 if (!NILP (border) && VECTORP (XCDR (border))) | |
1075 { | |
1076 Fsetcdr (border, normalize_image_instantiator (XCDR (border), | |
1077 console_type, dest_mask)); | |
1078 } | |
1079 | |
1080 { | |
1081 Lisp_Object result = alist_to_tagged_vector (XVECTOR_DATA (inst)[0], | |
1082 alist); | |
1083 free_alist (alist); | |
1084 RETURN_UNGCPRO (result); | |
1085 } | |
1086 } | |
1087 | |
1088 /* Update the instances in the layout. */ | |
1089 static void | |
1090 layout_update (Lisp_Object image_instance, Lisp_Object instantiator) | |
1091 { | |
1092 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | |
1093 Lisp_Object items = find_keyword_in_vector (instantiator, Q_items); | |
1094 Lisp_Object border_inst = find_keyword_in_vector (instantiator, Q_border); | |
863 | 1095 Lisp_Object justify = find_keyword_in_vector (instantiator, Q_justify); |
1096 Lisp_Object hjustify = find_keyword_in_vector (instantiator, Q_horizontally_justify); | |
1097 Lisp_Object vjustify = find_keyword_in_vector (instantiator, Q_vertically_justify); | |
442 | 1098 Lisp_Object border = Qnil; |
1099 Lisp_Object children = IMAGE_INSTANCE_LAYOUT_CHILDREN (ii); | |
1100 int structure_changed = 0; | |
1101 struct gcpro gcpro1; | |
1102 | |
863 | 1103 /* Pick up horizontal justification, left is the default.*/ |
1104 if (!NILP (hjustify)) | |
1105 { | |
1106 if (EQ (hjustify, Qright) || EQ (hjustify, Qbottom)) | |
1107 IMAGE_INSTANCE_SUBWINDOW_H_JUSTIFY (ii) = LAYOUT_JUSTIFY_RIGHT; | |
1108 else if (EQ (hjustify, Qcenter)) | |
1109 IMAGE_INSTANCE_SUBWINDOW_H_JUSTIFY (ii) = LAYOUT_JUSTIFY_CENTER; | |
1110 } | |
1111 /* If not set use general justification. */ | |
1112 else if (!NILP (justify)) | |
1113 { | |
1114 if (EQ (justify, Qright) || EQ (justify, Qbottom)) | |
1115 IMAGE_INSTANCE_SUBWINDOW_H_JUSTIFY (ii) = LAYOUT_JUSTIFY_RIGHT; | |
1116 else if (EQ (justify, Qcenter)) | |
1117 IMAGE_INSTANCE_SUBWINDOW_H_JUSTIFY (ii) = LAYOUT_JUSTIFY_CENTER; | |
1118 } | |
1119 | |
1120 /* Pick up vertical justification, top is the default. */ | |
1121 if (!NILP (vjustify)) | |
1122 { | |
1123 if (EQ (vjustify, Qright) || EQ (vjustify, Qbottom)) | |
1124 IMAGE_INSTANCE_SUBWINDOW_V_JUSTIFY (ii) = LAYOUT_JUSTIFY_BOTTOM; | |
1125 else if (EQ (vjustify, Qcenter)) | |
1126 IMAGE_INSTANCE_SUBWINDOW_V_JUSTIFY (ii) = LAYOUT_JUSTIFY_CENTER; | |
1127 } | |
1128 /* If not set use general justification. */ | |
1129 else if (!NILP (justify)) | |
1130 { | |
1131 if (EQ (justify, Qright) || EQ (justify, Qbottom)) | |
1132 IMAGE_INSTANCE_SUBWINDOW_V_JUSTIFY (ii) = LAYOUT_JUSTIFY_BOTTOM; | |
1133 else if (EQ (justify, Qcenter)) | |
1134 IMAGE_INSTANCE_SUBWINDOW_V_JUSTIFY (ii) = LAYOUT_JUSTIFY_CENTER; | |
1135 } | |
1136 | |
442 | 1137 /* We want to avoid consing if we can. This is quite awkward because |
1138 we have to deal with the border as well as the items. */ | |
1139 GCPRO1 (border); | |
1140 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1141 if (FIXNUMP (IMAGE_INSTANCE_LAYOUT_BORDER (ii))) |
442 | 1142 { |
1143 border = XCAR (children); | |
1144 children = XCDR (children); | |
1145 } | |
1146 | |
1147 #ifdef DEBUG_WIDGET_OUTPUT | |
1148 stderr_out ("layout updated\n"); | |
1149 #endif | |
1150 /* Update the border. */ | |
1151 if (!NILP (border_inst)) | |
1152 { | |
1153 if (VECTORP (border_inst)) | |
1154 { | |
1155 /* We are going to be sneaky here and add the border text as | |
1156 just another child, the layout and output routines don't know | |
1157 this and will just display at the offsets we prescribe. */ | |
1158 if (!NILP (border)) | |
1159 call3 (Qset_glyph_image, border, border_inst, | |
1160 IMAGE_INSTANCE_DOMAIN (ii)); | |
1161 else | |
1162 { | |
1163 border = Fcons (call1 (Qmake_glyph, border_inst), Qnil); | |
1164 structure_changed = 1; | |
1165 } | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1166 IMAGE_INSTANCE_LAYOUT_BORDER (ii) = make_fixnum (0); |
442 | 1167 } |
1168 else | |
1169 { | |
1170 if (!NILP (border)) | |
1171 { | |
1172 border = Qnil; | |
1173 structure_changed = 1; | |
1174 } | |
1175 if (EQ (border_inst, Qt)) | |
1176 IMAGE_INSTANCE_LAYOUT_BORDER (ii) = Qetched_in; | |
1177 else | |
1178 IMAGE_INSTANCE_LAYOUT_BORDER (ii) = border_inst; | |
428 | 1179 } |
1180 } | |
442 | 1181 |
1182 /* Pick up the sub-widgets. */ | |
1183 if (!NILP (items)) | |
428 | 1184 { |
442 | 1185 int len1, len2; |
1186 GET_LIST_LENGTH (items, len1); | |
1187 GET_LIST_LENGTH (children, len2); | |
1188 /* The structure hasn't changed so just update the images. */ | |
1189 if (!structure_changed && len1 == len2) | |
1190 { | |
1191 /* Pick up the sub-widgets. */ | |
1192 for (; !NILP (children); children = XCDR (children), items = XCDR (items)) | |
1193 { | |
1194 call3 (Qset_glyph_image, XCAR (children), XCAR (items), | |
1195 IMAGE_INSTANCE_DOMAIN (ii)); | |
1196 } | |
1197 } | |
1198 /* The structure has changed so start over. */ | |
1199 else | |
1200 { | |
1201 /* Instantiate any new glyphs. */ | |
1202 for (; !NILP (items); items = XCDR (items)) | |
1203 { | |
458 | 1204 /* #### We really want to use call_with_suspended_errors |
1205 here, but it won't allow us to call lisp. */ | |
442 | 1206 border = Fcons (call1 (Qmake_glyph, XCAR (items)), border); |
1207 } | |
1208 IMAGE_INSTANCE_LAYOUT_CHILDREN (ii) = Fnreverse (border); | |
1209 } | |
428 | 1210 } |
442 | 1211 UNGCPRO; |
1212 } | |
1213 | |
1214 static void | |
1215 layout_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
1216 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | |
1217 int dest_mask, Lisp_Object domain) | |
1218 { | |
1219 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | |
1220 Lisp_Object orient = find_keyword_in_vector (instantiator, Q_orientation); | |
1221 | |
1222 #ifdef DEBUG_WIDGET_OUTPUT | |
1223 stderr_out ("layout instantiated\n"); | |
1224 #endif | |
1225 /* Do widget type instantiation first. */ | |
1226 widget_instantiate (image_instance, instantiator, pointer_fg, pointer_bg, | |
1227 dest_mask, domain); | |
1228 | |
1229 if (NILP (orient)) | |
1230 { | |
1231 IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) = LAYOUT_VERTICAL; | |
1232 } | |
1233 | |
1234 /* Get child glyphs and finish instantiation. We can't do image | |
1235 instance children yet as we might not have a containing | |
1236 window. */ | |
1237 layout_update (image_instance, instantiator); | |
1238 } | |
1239 | |
1240 static void | |
2286 | 1241 layout_post_instantiate (Lisp_Object UNUSED (image_instance), |
1242 Lisp_Object UNUSED (instantiator), | |
1243 Lisp_Object UNUSED (domain)) | |
442 | 1244 { |
428 | 1245 } |
1246 | |
440 | 1247 /* Layout widget. Sizing commentary: we have a number of problems that |
1248 we would like to address. Some consider some of these more | |
1249 important than others. It used to be that size information was | |
1250 determined at instantiation time and was then fixed forever | |
434 | 1251 after. Generally this is not what we want. Users want size to be |
1252 "big enough" to accommodate whatever they are trying to show and | |
1253 this is dependent on text length, lines, font metrics etc. Of | |
1254 course these attributes can change dynamically and so the size | |
1255 should changed dynamically also. Only in a few limited cases should | |
1256 the size be fixed and remain fixed. Of course this actually means | |
442 | 1257 that we don't really want to specify the size *at all* for most |
434 | 1258 widgets - we want it to be discovered dynamically. Thus we can |
1259 envisage the following scenarios: | |
442 | 1260 |
434 | 1261 1. A button is sized to accommodate its text, the text changes and the |
442 | 1262 button should change size also. |
434 | 1263 |
1264 2. A button is given an explicit size. Its size should never change. | |
1265 | |
1266 3. Layout is put inside an area. The size of the area changes, the | |
442 | 1267 layout should change with it. |
434 | 1268 |
1269 4. A button grows to accommodate additional text. The whitespace | |
1270 around it should be modified to cope with the new layout | |
442 | 1271 requirements. |
434 | 1272 |
1273 5. A button grows. The area surrounding it should grow also if | |
442 | 1274 possible. |
434 | 1275 |
1276 What metrics are important? | |
1277 1. Actual width and height. | |
442 | 1278 |
434 | 1279 2. Whether the width and height are what the widget actually wants, or |
442 | 1280 whether it can grow or shrink. |
434 | 1281 |
1282 Text glyphs are particularly troublesome since their metrics depend | |
1283 on the context in which they are being viewed. For instance they | |
1284 can appear differently depending on the window face, frame face or | |
440 | 1285 glyph face. In order to simplify this text glyphs can now only have |
1286 a glyph-face or image-instance face. All other glyphs are | |
1287 essentially fixed in appearance. Perhaps the problem is that text | |
1288 glyphs are cached on a device basis like most other glyphs. Instead | |
1289 they should be cached per-window and then the instance would be | |
1290 fixed and we wouldn't have to mess around with font metrics and the | |
863 | 1291 rest. |
1292 | |
1293 Another sizing problem is alignment. We provide layout widgets that | |
1294 allow users to stack widgets vertically or horizontally. These | |
1295 layouts also allow the widgets to be centered (space evenly | |
1296 distributed), left or right justified (fixed spacing widgets | |
3094 | 1297 stacked against the left, right, top or bottom edge). Unfortunately |
863 | 1298 this doesn't allow widgets in different layouts to be aligned. For |
1299 instance how should the search dialog be organized for alignment? | |
1300 The obvious choice of two vertical columns does not work since the | |
1301 size of individual widgets will affect where they get placed. The | |
1302 same is true for several rows of widgets. To solve this problem we | |
1303 introduce the notion of `logical_unit_height'. This is a size | |
5384
3889ef128488
Fix misspelled words, and some grammar, across the entire source tree.
Jerry James <james@xemacs.org>
parents:
5176
diff
changeset
|
1304 quantity that is designed to be big enough to accommodate the |
863 | 1305 largest `single height unit'. The function |
1306 widget_logical_unit_height() determines the value of this in | |
1307 pixels. It is dependent on the widget face and some combination of | |
1308 spacing and border-width. Thus if users specify left or right | |
1309 justification in a vertical layout they get something in logical | |
1310 units. To simplify this the functions | |
1311 `widget-logical-to-character-height' and | |
1312 `widget-logical-to-character-width' allow conversion between | |
1313 characters and logical units so that frames can be sized | |
1314 appropriately. */ | |
440 | 1315 |
1065 | 1316 /* Query the geometry of a layout widget. */ |
428 | 1317 static void |
442 | 1318 layout_query_geometry (Lisp_Object image_instance, int* width, |
1319 int* height, enum image_instance_geometry disp, | |
2286 | 1320 Lisp_Object UNUSED (domain)) |
428 | 1321 { |
440 | 1322 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
1323 Lisp_Object items = IMAGE_INSTANCE_LAYOUT_CHILDREN (ii), rest; | |
1324 int maxph = 0, maxpw = 0, nitems = 0, ph_adjust = 0; | |
863 | 1325 int gheight, gwidth, luh; |
442 | 1326 |
1327 /* If we are not initialized then we won't have any children. */ | |
1328 if (!IMAGE_INSTANCE_INITIALIZED (ii)) | |
1329 return; | |
1330 | |
1331 /* First just set up what we already have. */ | |
1332 if (width) *width = IMAGE_INSTANCE_WIDTH (ii); | |
1333 if (height) *height = IMAGE_INSTANCE_HEIGHT (ii); | |
1334 | |
1335 /* If we are not allowed to dynamically size then return. */ | |
1336 if (!IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii) | |
1337 && | |
1338 !IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii)) | |
1339 return; | |
1340 | |
863 | 1341 luh = widget_logical_unit_height (ii); |
1342 | |
442 | 1343 /* Pick up the border text if we have one. */ |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1344 if (FIXNUMP (IMAGE_INSTANCE_LAYOUT_BORDER (ii))) |
442 | 1345 { |
1346 glyph_query_geometry (XCAR (items), &gwidth, &gheight, disp, | |
1347 image_instance); | |
863 | 1348 ph_adjust = gheight; |
1068 | 1349 /* Include text width in vertical layouts. */ |
1350 if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) == LAYOUT_VERTICAL) | |
1351 maxpw = gwidth + BORDER_FIDDLE_FACTOR; | |
442 | 1352 items = XCDR (items); |
1353 } | |
440 | 1354 |
1355 /* Flip through the items to work out how much stuff we have to display */ | |
1356 LIST_LOOP (rest, items) | |
1357 { | |
1358 Lisp_Object glyph = XCAR (rest); | |
442 | 1359 glyph_query_geometry (glyph, &gwidth, &gheight, disp, image_instance); |
440 | 1360 |
442 | 1361 nitems ++; |
863 | 1362 if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) == LAYOUT_HORIZONTAL) |
440 | 1363 { |
442 | 1364 maxph = max (maxph, gheight); |
1365 maxpw += gwidth; | |
440 | 1366 } |
1367 else | |
1368 { | |
442 | 1369 maxpw = max (maxpw, gwidth); |
1370 maxph += gheight; | |
440 | 1371 } |
1372 } | |
428 | 1373 |
442 | 1374 /* Work out minimum space we need to fit all the items. This could |
1375 have been fixed by the user. */ | |
1318 | 1376 if (IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii)) |
1377 { | |
1065 | 1378 if (!NILP (IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (ii))) |
1318 | 1379 { |
1065 | 1380 Lisp_Object dynamic_width = |
1318 | 1381 eval_within_redisplay (IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (ii)); |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1382 if (FIXNUMP (dynamic_width)) |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1383 *width = XFIXNUM (dynamic_width); |
1318 | 1384 } |
1065 | 1385 else if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) == LAYOUT_HORIZONTAL) |
1318 | 1386 { |
1065 | 1387 *width = maxpw + ((nitems + 1) * widget_instance_border_width (ii) + |
1388 IMAGE_INSTANCE_MARGIN_WIDTH (ii)) * 2; | |
1318 | 1389 } |
1065 | 1390 else |
1318 | 1391 { |
1065 | 1392 *width = maxpw + 2 * (widget_instance_border_width (ii) * 2 + |
1393 IMAGE_INSTANCE_MARGIN_WIDTH (ii)); | |
1318 | 1394 } |
1065 | 1395 } |
1396 | |
440 | 1397 /* Work out vertical spacings. */ |
1318 | 1398 if (IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii)) |
1399 { | |
1065 | 1400 if (!NILP (IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (ii))) |
1318 | 1401 { |
1065 | 1402 Lisp_Object dynamic_height = |
1318 | 1403 eval_within_redisplay (IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (ii)); |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1404 if (FIXNUMP (dynamic_height)) |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1405 *height = XFIXNUM (dynamic_height); |
1318 | 1406 } |
1065 | 1407 else if (IMAGE_INSTANCE_SUBWINDOW_LOGICAL_LAYOUT (ii)) |
1318 | 1408 { |
1065 | 1409 *height = nitems * luh + ph_adjust; |
1318 | 1410 } |
1065 | 1411 else if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) == LAYOUT_VERTICAL) |
1318 | 1412 { |
1065 | 1413 *height = maxph + ((nitems + 1) * widget_instance_border_width (ii) + |
1414 IMAGE_INSTANCE_MARGIN_WIDTH (ii)) * 2 + ph_adjust; | |
1318 | 1415 } |
1065 | 1416 else |
1318 | 1417 { |
1065 | 1418 *height = maxph + (2 * widget_instance_border_width (ii) + |
1419 IMAGE_INSTANCE_MARGIN_WIDTH (ii)) * 2 + ph_adjust; | |
1318 | 1420 } |
1065 | 1421 } |
863 | 1422 #ifdef DEBUG_WIDGET_OUTPUT |
1423 stderr_out ("layout wants %dx%d\n", *width, *height); | |
1424 #endif | |
440 | 1425 } |
1426 | |
442 | 1427 int |
1428 layout_layout (Lisp_Object image_instance, | |
2286 | 1429 int width, int height, int UNUSED (xoffset), int yoffset, |
1430 Lisp_Object UNUSED (domain)) | |
440 | 1431 { |
1432 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | |
1433 Lisp_Object rest; | |
1434 Lisp_Object items = IMAGE_INSTANCE_LAYOUT_CHILDREN (ii); | |
1435 int x, y, maxph = 0, maxpw = 0, nitems = 0, | |
1436 horiz_spacing, vert_spacing, ph_adjust = 0; | |
442 | 1437 int gheight, gwidth; |
863 | 1438 /* See comments in widget_logical_unit_height(). */ |
1439 int luh = widget_logical_unit_height (ii); | |
442 | 1440 |
1441 /* If we are not initialized then we won't have any children. */ | |
1442 if (!IMAGE_INSTANCE_INITIALIZED (ii)) | |
1443 return 0; | |
428 | 1444 |
863 | 1445 #ifdef DEBUG_WIDGET_OUTPUT |
1446 stderr_out ("layout output %dx%d\n", width, height); | |
1447 #endif | |
1448 | |
1449 /* Pick up the border text if we have one. A border can have the | |
1450 values Qetched_in, Qetched_out, Qbevel_in, Qbevel_out or an | |
1451 integer. The first four just affect the display properties of the | |
1452 border that is drawn. The last is an offset and implies that the | |
1453 first item in the list of subcontrols is a text control that | |
1454 should be displayed on the border. */ | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1455 if (FIXNUMP (IMAGE_INSTANCE_LAYOUT_BORDER (ii))) |
442 | 1456 { |
1457 Lisp_Object border = XCAR (items); | |
1458 items = XCDR (items); | |
1459 glyph_query_geometry (border, &gwidth, &gheight, | |
1460 IMAGE_DESIRED_GEOMETRY, image_instance); | |
863 | 1461 /* The vertical offset for subsequent items is the full height |
1462 of the border glyph. */ | |
1463 ph_adjust = gheight; | |
1464 /* The offset for the border is half the glyph height. */ | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1465 IMAGE_INSTANCE_LAYOUT_BORDER (ii) = make_fixnum (gheight / 2); |
442 | 1466 |
1467 /* #### Really, what should this be? */ | |
1068 | 1468 glyph_do_layout (border, gwidth, gheight, BORDER_FIDDLE_FACTOR, 0, |
442 | 1469 image_instance); |
1470 } | |
1471 | |
1472 /* Flip through the items to work out how much stuff we have to display. */ | |
428 | 1473 LIST_LOOP (rest, items) |
1474 { | |
1475 Lisp_Object glyph = XCAR (rest); | |
440 | 1476 |
442 | 1477 glyph_query_geometry (glyph, &gwidth, &gheight, |
1478 IMAGE_DESIRED_GEOMETRY, image_instance); | |
1479 nitems ++; | |
1480 if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) | |
1481 == LAYOUT_HORIZONTAL) | |
428 | 1482 { |
442 | 1483 maxph = max (maxph, gheight); |
1484 maxpw += gwidth; | |
428 | 1485 } |
440 | 1486 else |
428 | 1487 { |
442 | 1488 maxpw = max (maxpw, gwidth); |
1489 maxph += gheight; | |
428 | 1490 } |
1491 } | |
1492 | |
1493 /* work out spacing between items and bounds of the layout */ | |
440 | 1494 if (width < maxpw) |
428 | 1495 /* The user wants a smaller space than the largest item, so we |
1496 just provide default spacing and will let the output routines | |
863 | 1497 clip. */ |
1498 horiz_spacing = widget_spacing (IMAGE_INSTANCE_DOMAIN (ii)); | |
442 | 1499 else if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) |
863 | 1500 == LAYOUT_HORIZONTAL) |
428 | 1501 /* We have a larger area to display in so distribute the space |
1502 evenly. */ | |
442 | 1503 horiz_spacing = (width - (maxpw + |
1504 IMAGE_INSTANCE_MARGIN_WIDTH (ii) * 2)) | |
1505 / (nitems + 1); | |
428 | 1506 else |
442 | 1507 horiz_spacing = (width - maxpw) / 2 |
1508 - IMAGE_INSTANCE_MARGIN_WIDTH (ii); | |
428 | 1509 |
863 | 1510 /* We are trying here to get widgets to line up when they are left |
1511 or right justified vertically. This means that we must position | |
1512 widgets on logical unit boundaries, even though their height may | |
1513 be greater or less than a logical unit. In order to avoid | |
1514 clipping we need to determine how big the widget wants to be and | |
1515 then allocate as many logical units as necessary in order to | |
1516 accommodate it. */ | |
440 | 1517 if (height < maxph) |
863 | 1518 vert_spacing = widget_spacing (IMAGE_INSTANCE_DOMAIN (ii)) * 2; |
442 | 1519 else if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) |
440 | 1520 == LAYOUT_VERTICAL) |
863 | 1521 { |
1522 if (!IMAGE_INSTANCE_SUBWINDOW_V_CENTERED (ii)) | |
1523 vert_spacing = widget_spacing (IMAGE_INSTANCE_DOMAIN (ii)) * 2; | |
1524 else | |
1525 vert_spacing = (height - (maxph + ph_adjust + | |
1526 IMAGE_INSTANCE_MARGIN_WIDTH (ii) * 2)) | |
1527 / (nitems + 1); | |
1528 } | |
428 | 1529 else |
442 | 1530 vert_spacing = (height - (maxph + ph_adjust)) / 2 |
1531 - IMAGE_INSTANCE_MARGIN_WIDTH (ii); | |
428 | 1532 |
863 | 1533 y = yoffset = vert_spacing + ph_adjust + IMAGE_INSTANCE_MARGIN_WIDTH (ii); |
442 | 1534 x = horiz_spacing + IMAGE_INSTANCE_MARGIN_WIDTH (ii); |
428 | 1535 |
1536 /* Now flip through putting items where we want them, paying | |
440 | 1537 attention to justification. Make sure we don't mess with the |
1538 border glyph. */ | |
428 | 1539 LIST_LOOP (rest, items) |
1540 { | |
1541 Lisp_Object glyph = XCAR (rest); | |
1542 | |
442 | 1543 glyph_query_geometry (glyph, &gwidth, &gheight, |
1544 IMAGE_DESIRED_GEOMETRY, image_instance); | |
1545 | |
863 | 1546 if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) == LAYOUT_HORIZONTAL) |
442 | 1547 { |
863 | 1548 if (IMAGE_INSTANCE_SUBWINDOW_BOTTOM_JUSTIFIED (ii)) |
442 | 1549 y = height - (gheight + vert_spacing); |
863 | 1550 else if (IMAGE_INSTANCE_SUBWINDOW_V_CENTERED (ii)) |
442 | 1551 y = (height - gheight) / 2; |
1552 } | |
1553 else | |
1554 { | |
863 | 1555 if (IMAGE_INSTANCE_SUBWINDOW_RIGHT_JUSTIFIED (ii)) |
442 | 1556 x = width - (gwidth + horiz_spacing); |
863 | 1557 else if (IMAGE_INSTANCE_SUBWINDOW_H_CENTERED (ii)) |
442 | 1558 x = (width - gwidth) / 2; |
1559 } | |
1560 | |
1561 /* Now layout subwidgets if they require it. */ | |
1562 glyph_do_layout (glyph, gwidth, gheight, x, y, image_instance); | |
1563 | |
863 | 1564 if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) == LAYOUT_HORIZONTAL) |
442 | 1565 { |
1566 x += (gwidth + horiz_spacing); | |
1567 } | |
1568 else | |
1569 { | |
1570 y += (gheight + vert_spacing); | |
863 | 1571 if (!IMAGE_INSTANCE_SUBWINDOW_V_CENTERED (ii)) |
1572 { | |
1573 /* justified, vertical layout, try and align on logical unit | |
1574 boundaries. */ | |
1575 y = ROUND_UP (y - yoffset, luh) + yoffset; | |
1576 } | |
442 | 1577 } |
1578 | |
1579 } | |
1580 return 1; | |
1581 } | |
1582 | |
1583 /* Get the glyphs that comprise a layout. These are created internally | |
1584 and so are otherwise inaccessible to lisp. We need some way of getting | |
1585 properties from the widgets that comprise a layout and this is the | |
1586 simplest way of doing it. | |
428 | 1587 |
442 | 1588 #### Eventually we should allow some more intelligent access to |
1589 sub-widgets. */ | |
1590 static Lisp_Object | |
1591 layout_property (Lisp_Object image_instance, Lisp_Object prop) | |
1592 { | |
1593 /* This function can GC. */ | |
1594 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | |
1595 if (EQ (prop, Q_items)) | |
1596 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1597 if (FIXNUMP (IMAGE_INSTANCE_LAYOUT_BORDER (ii)) && |
442 | 1598 CONSP (IMAGE_INSTANCE_LAYOUT_CHILDREN (ii))) |
1599 return Fcopy_sequence (XCDR | |
1600 (IMAGE_INSTANCE_LAYOUT_CHILDREN (ii))); | |
1601 else | |
1602 return Fcopy_sequence (IMAGE_INSTANCE_LAYOUT_CHILDREN (ii)); | |
428 | 1603 } |
442 | 1604 return Qunbound; |
1605 } | |
428 | 1606 |
442 | 1607 /* Layout subwindows if they are real subwindows. */ |
1608 static int | |
1609 native_layout_layout (Lisp_Object image_instance, | |
1610 int width, int height, int xoffset, int yoffset, | |
1611 Lisp_Object domain) | |
1612 { | |
1613 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance); | |
1614 Lisp_Object rest; | |
1615 | |
1616 /* The first time this gets called, the layout will be only | |
1617 partially instantiated. The children get done in | |
1618 post_instantiate. */ | |
1619 if (!IMAGE_INSTANCE_INITIALIZED (ii)) | |
1620 return 0; | |
1621 | |
1622 /* Defining this overrides the default layout_layout so we first have to call that to get | |
1623 suitable instances and values set up. */ | |
1624 layout_layout (image_instance, width, height, xoffset, yoffset, domain); | |
1625 | |
1626 LIST_LOOP (rest, IMAGE_INSTANCE_LAYOUT_CHILDREN (ii)) | |
1627 { | |
1628 struct display_glyph_area dga; | |
1629 dga.xoffset = 0; | |
1630 dga.yoffset = 0; | |
1631 dga.width = IMAGE_INSTANCE_WIDTH (ii); | |
1632 dga.height = IMAGE_INSTANCE_HEIGHT (ii); | |
1633 | |
1634 map_subwindow (XCAR (rest), | |
1635 IMAGE_INSTANCE_XOFFSET (ii), | |
1636 IMAGE_INSTANCE_YOFFSET (ii), &dga); | |
1637 } | |
1638 return 1; | |
428 | 1639 } |
1640 | |
863 | 1641 DEFUN ("widget-logical-to-character-width", Fwidget_logical_to_character_width, 1, 3, 0, /* |
1642 Convert the width in logical widget units to characters. | |
3094 | 1643 Logical widget units do not take into account adjustments made for |
1644 layout borders, so this adjustment is approximated. | |
863 | 1645 */ |
2286 | 1646 (width, UNUSED (face), domain)) |
863 | 1647 { |
1648 int w, neww, charwidth; | |
1649 int border_width = DEFAULT_WIDGET_BORDER_WIDTH; | |
1650 | |
1651 if (NILP (domain)) | |
1652 domain = Fselected_frame (Qnil); | |
1653 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1654 CHECK_FIXNUM (width); |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1655 w = XFIXNUM (width); |
863 | 1656 |
1657 if (HAS_DEVMETH_P (DOMAIN_XDEVICE (domain), widget_border_width)) | |
1658 border_width = DEVMETH (DOMAIN_XDEVICE (domain), widget_border_width, ()); | |
1659 | |
5047
07dcc7000bbf
put width before height consistently, fix a real bug found in the process
Ben Wing <ben@xemacs.org>
parents:
4677
diff
changeset
|
1660 default_face_font_info (domain, 0, 0, &charwidth, 0, 0); |
863 | 1661 neww = ROUND_UP (charwidth * w + 4 * border_width + 2 * widget_spacing (domain), |
1662 charwidth) / charwidth; | |
1663 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1664 return make_fixnum (neww); |
863 | 1665 } |
1666 | |
1667 DEFUN ("widget-logical-to-character-height", Fwidget_logical_to_character_height, 1, 3, 0, /* | |
1668 Convert the height in logical widget units to characters. | |
3094 | 1669 Logical widget units do not take into account adjustments made for |
863 | 1670 layout borders, so this adjustment is approximated. |
1671 | |
1672 If the components of a widget layout are justified to the top or the | |
1673 bottom then they are aligned in terms of `logical units'. This is a | |
5384
3889ef128488
Fix misspelled words, and some grammar, across the entire source tree.
Jerry James <james@xemacs.org>
parents:
5176
diff
changeset
|
1674 size quantity that is designed to be big enough to accommodate the |
863 | 1675 largest `single height' widget. It is dependent on the widget face and |
1676 some combination of spacing and border-width. Thus if you specify top | |
1677 or bottom justification in a vertical layout the subcontrols are laid | |
1678 out one per logical unit. This allows adjoining layouts to have | |
1679 identical alignment for their subcontrols. | |
1680 | |
1681 Since frame sizes are measured in characters, this function allows you | |
1682 to do appropriate conversion between logical units and characters. | |
1683 */ | |
2286 | 1684 (height, UNUSED (face), domain)) |
863 | 1685 { |
1686 int h, newh, charheight; | |
1687 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1688 CHECK_FIXNUM (height); |
863 | 1689 if (NILP (domain)) |
1690 domain = Fselected_frame (Qnil); | |
1691 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1692 h = XFIXNUM (height); |
863 | 1693 |
5047
07dcc7000bbf
put width before height consistently, fix a real bug found in the process
Ben Wing <ben@xemacs.org>
parents:
4677
diff
changeset
|
1694 default_face_font_info (domain, 0, 0, 0, &charheight, 0); |
863 | 1695 newh = ROUND_UP (logical_unit_height (Fsymbol_name (Qwidget), |
1696 Vwidget_face, domain) * h, charheight) | |
1697 / charheight; | |
1698 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1699 return make_fixnum (newh); |
863 | 1700 } |
1701 | |
428 | 1702 |
1703 /************************************************************************/ | |
1704 /* initialization */ | |
1705 /************************************************************************/ | |
1706 | |
1707 void | |
1708 syms_of_glyphs_widget (void) | |
1709 { | |
442 | 1710 DEFSYMBOL (Qetched_in); |
1711 DEFSYMBOL (Qetched_out); | |
1712 DEFSYMBOL (Qbevel_in); | |
1713 DEFSYMBOL (Qbevel_out); | |
1714 DEFSYMBOL (Qmake_glyph); | |
863 | 1715 |
1716 DEFSUBR (Fwidget_logical_to_character_height); | |
1717 DEFSUBR (Fwidget_logical_to_character_width); | |
428 | 1718 } |
1719 | |
442 | 1720 #define VALID_GUI_KEYWORDS(type) do { \ |
1721 IIFORMAT_VALID_NONCOPY_KEYWORD (type, Q_active, check_valid_anything); \ | |
1722 IIFORMAT_VALID_KEYWORD (type, Q_suffix, check_valid_anything); \ | |
1723 IIFORMAT_VALID_KEYWORD (type, Q_keys, check_valid_string); \ | |
1724 IIFORMAT_VALID_KEYWORD (type, Q_style, check_valid_symbol); \ | |
1725 IIFORMAT_VALID_NONCOPY_KEYWORD (type, Q_selected, check_valid_anything); \ | |
1726 IIFORMAT_VALID_KEYWORD (type, Q_filter, check_valid_anything); \ | |
1727 IIFORMAT_VALID_KEYWORD (type, Q_config, check_valid_symbol); \ | |
1728 IIFORMAT_VALID_KEYWORD (type, Q_included, check_valid_anything); \ | |
1729 IIFORMAT_VALID_KEYWORD (type, Q_initial_focus, check_valid_anything); \ | |
1730 IIFORMAT_VALID_KEYWORD (type, Q_key_sequence, check_valid_string); \ | |
1731 IIFORMAT_VALID_KEYWORD (type, Q_accelerator, check_valid_string); \ | |
1732 IIFORMAT_VALID_KEYWORD (type, Q_label, check_valid_anything); \ | |
1733 IIFORMAT_VALID_NONCOPY_KEYWORD (type, Q_callback, check_valid_callback); \ | |
1734 IIFORMAT_VALID_NONCOPY_KEYWORD (type, Q_callback_ex, check_valid_callback); \ | |
1735 IIFORMAT_VALID_NONCOPY_KEYWORD (type, Q_descriptor, \ | |
1736 check_valid_string_or_vector); \ | |
440 | 1737 } while (0) |
428 | 1738 |
442 | 1739 #define VALID_WIDGET_KEYWORDS(type) do { \ |
1740 IIFORMAT_VALID_KEYWORD (type, Q_width, check_valid_int); \ | |
1741 IIFORMAT_VALID_KEYWORD (type, Q_height, check_valid_int); \ | |
1742 IIFORMAT_VALID_KEYWORD (type, Q_pixel_width, check_valid_int_or_function); \ | |
1743 IIFORMAT_VALID_KEYWORD (type, Q_pixel_height, check_valid_int_or_function); \ | |
1744 IIFORMAT_VALID_KEYWORD (type, Q_face, check_valid_face); \ | |
440 | 1745 } while (0) |
428 | 1746 |
440 | 1747 |
1748 static void image_instantiator_widget (void) | |
1749 { /* we only do this for properties */ | |
428 | 1750 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT_NO_SYM (widget, "widget"); |
1751 IIFORMAT_HAS_METHOD (widget, property); | |
442 | 1752 IIFORMAT_HAS_METHOD (widget, update); |
438 | 1753 IIFORMAT_HAS_METHOD (widget, query_geometry); |
1754 IIFORMAT_HAS_METHOD (widget, layout); | |
440 | 1755 } |
428 | 1756 |
440 | 1757 static void image_instantiator_buttons (void) |
1758 { | |
428 | 1759 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (button, "button"); |
1760 IIFORMAT_HAS_SHARED_METHOD (button, validate, widget); | |
1761 IIFORMAT_HAS_SHARED_METHOD (button, possible_dest_types, widget); | |
1762 IIFORMAT_HAS_SHARED_METHOD (button, instantiate, widget); | |
442 | 1763 IIFORMAT_HAS_SHARED_METHOD (button, post_instantiate, widget); |
428 | 1764 IIFORMAT_HAS_SHARED_METHOD (button, normalize, widget); |
442 | 1765 IIFORMAT_HAS_SHARED_METHOD (button, governing_domain, subwindow); |
1766 IIFORMAT_HAS_METHOD (button, query_geometry); | |
440 | 1767 IIFORMAT_VALID_KEYWORD (button, |
442 | 1768 Q_image, check_valid_instantiator); |
428 | 1769 VALID_WIDGET_KEYWORDS (button); |
1770 VALID_GUI_KEYWORDS (button); | |
440 | 1771 } |
428 | 1772 |
440 | 1773 static void image_instantiator_edit_fields (void) |
1774 { | |
428 | 1775 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (edit_field, "edit-field"); |
1776 IIFORMAT_HAS_SHARED_METHOD (edit_field, validate, widget); | |
1777 IIFORMAT_HAS_SHARED_METHOD (edit_field, possible_dest_types, widget); | |
1778 IIFORMAT_HAS_SHARED_METHOD (edit_field, instantiate, widget); | |
442 | 1779 IIFORMAT_HAS_SHARED_METHOD (edit_field, post_instantiate, widget); |
1780 IIFORMAT_HAS_SHARED_METHOD (edit_field, governing_domain, subwindow); | |
863 | 1781 IIFORMAT_HAS_METHOD (edit_field, query_geometry); |
428 | 1782 VALID_WIDGET_KEYWORDS (edit_field); |
1783 VALID_GUI_KEYWORDS (edit_field); | |
440 | 1784 } |
428 | 1785 |
440 | 1786 static void image_instantiator_combo_box (void) |
1787 { | |
428 | 1788 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (combo_box, "combo-box"); |
1789 IIFORMAT_HAS_METHOD (combo_box, validate); | |
1790 IIFORMAT_HAS_SHARED_METHOD (combo_box, possible_dest_types, widget); | |
442 | 1791 IIFORMAT_HAS_SHARED_METHOD (combo_box, governing_domain, subwindow); |
1792 | |
428 | 1793 VALID_GUI_KEYWORDS (combo_box); |
1794 | |
1795 IIFORMAT_VALID_KEYWORD (combo_box, Q_width, check_valid_int); | |
1796 IIFORMAT_VALID_KEYWORD (combo_box, Q_height, check_valid_int); | |
442 | 1797 IIFORMAT_VALID_KEYWORD (combo_box, Q_pixel_width, |
1798 check_valid_int_or_function); | |
428 | 1799 IIFORMAT_VALID_KEYWORD (combo_box, Q_face, check_valid_face); |
442 | 1800 IIFORMAT_VALID_KEYWORD (combo_box, Q_items, check_valid_item_list); |
440 | 1801 } |
428 | 1802 |
440 | 1803 static void image_instantiator_scrollbar (void) |
1804 { | |
428 | 1805 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (scrollbar, "scrollbar"); |
1806 IIFORMAT_HAS_SHARED_METHOD (scrollbar, validate, widget); | |
1807 IIFORMAT_HAS_SHARED_METHOD (scrollbar, possible_dest_types, widget); | |
1808 IIFORMAT_HAS_SHARED_METHOD (scrollbar, instantiate, widget); | |
442 | 1809 IIFORMAT_HAS_SHARED_METHOD (scrollbar, post_instantiate, widget); |
1810 IIFORMAT_HAS_SHARED_METHOD (scrollbar, governing_domain, subwindow); | |
428 | 1811 VALID_GUI_KEYWORDS (scrollbar); |
1812 | |
442 | 1813 IIFORMAT_VALID_KEYWORD (scrollbar, Q_pixel_width, |
1814 check_valid_int_or_function); | |
1815 IIFORMAT_VALID_KEYWORD (scrollbar, Q_pixel_height, | |
1816 check_valid_int_or_function); | |
428 | 1817 IIFORMAT_VALID_KEYWORD (scrollbar, Q_face, check_valid_face); |
440 | 1818 } |
428 | 1819 |
3094 | 1820 static void image_instantiator_progress_gauge (void) |
440 | 1821 { |
428 | 1822 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (progress_gauge, "progress-gauge"); |
1823 IIFORMAT_HAS_SHARED_METHOD (progress_gauge, validate, widget); | |
1824 IIFORMAT_HAS_SHARED_METHOD (progress_gauge, possible_dest_types, widget); | |
1825 IIFORMAT_HAS_SHARED_METHOD (progress_gauge, instantiate, widget); | |
442 | 1826 IIFORMAT_HAS_SHARED_METHOD (progress_gauge, post_instantiate, widget); |
1827 IIFORMAT_HAS_SHARED_METHOD (progress_gauge, governing_domain, subwindow); | |
428 | 1828 VALID_WIDGET_KEYWORDS (progress_gauge); |
1829 VALID_GUI_KEYWORDS (progress_gauge); | |
442 | 1830 |
1831 IIFORMAT_VALID_KEYWORD (progress_gauge, Q_value, check_valid_int); | |
440 | 1832 } |
428 | 1833 |
440 | 1834 static void image_instantiator_tree_view (void) |
1835 { | |
428 | 1836 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (tree_view, "tree-view"); |
1837 IIFORMAT_HAS_SHARED_METHOD (tree_view, validate, combo_box); | |
1838 IIFORMAT_HAS_SHARED_METHOD (tree_view, possible_dest_types, widget); | |
438 | 1839 IIFORMAT_HAS_SHARED_METHOD (tree_view, instantiate, widget); |
442 | 1840 IIFORMAT_HAS_SHARED_METHOD (tree_view, post_instantiate, widget); |
1841 IIFORMAT_HAS_SHARED_METHOD (tree_view, governing_domain, subwindow); | |
438 | 1842 IIFORMAT_HAS_METHOD (tree_view, query_geometry); |
428 | 1843 VALID_WIDGET_KEYWORDS (tree_view); |
1844 VALID_GUI_KEYWORDS (tree_view); | |
442 | 1845 IIFORMAT_VALID_KEYWORD (tree_view, Q_items, check_valid_item_list); |
440 | 1846 } |
428 | 1847 |
440 | 1848 static void image_instantiator_tab_control (void) |
1849 { | |
428 | 1850 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (tab_control, "tab-control"); |
1851 IIFORMAT_HAS_SHARED_METHOD (tab_control, validate, combo_box); | |
1852 IIFORMAT_HAS_SHARED_METHOD (tab_control, possible_dest_types, widget); | |
438 | 1853 IIFORMAT_HAS_SHARED_METHOD (tab_control, instantiate, widget); |
442 | 1854 IIFORMAT_HAS_SHARED_METHOD (tab_control, post_instantiate, widget); |
1855 IIFORMAT_HAS_SHARED_METHOD (tab_control, governing_domain, subwindow); | |
438 | 1856 IIFORMAT_HAS_METHOD (tab_control, query_geometry); |
428 | 1857 VALID_WIDGET_KEYWORDS (tab_control); |
1858 VALID_GUI_KEYWORDS (tab_control); | |
442 | 1859 IIFORMAT_VALID_KEYWORD (tab_control, Q_orientation, |
1860 check_valid_tab_orientation); | |
1861 IIFORMAT_VALID_KEYWORD (tab_control, Q_items, check_valid_item_list); | |
440 | 1862 } |
428 | 1863 |
440 | 1864 static void image_instantiator_labels (void) |
1865 { | |
428 | 1866 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (label, "label"); |
1867 IIFORMAT_HAS_SHARED_METHOD (label, possible_dest_types, widget); | |
438 | 1868 IIFORMAT_HAS_SHARED_METHOD (label, instantiate, widget); |
442 | 1869 IIFORMAT_HAS_SHARED_METHOD (label, post_instantiate, widget); |
1870 IIFORMAT_HAS_SHARED_METHOD (label, governing_domain, subwindow); | |
428 | 1871 VALID_WIDGET_KEYWORDS (label); |
1872 IIFORMAT_VALID_KEYWORD (label, Q_descriptor, check_valid_string); | |
440 | 1873 } |
428 | 1874 |
442 | 1875 #define VALID_LAYOUT_KEYWORDS(layout) \ |
1876 VALID_WIDGET_KEYWORDS (layout); \ | |
1877 IIFORMAT_VALID_KEYWORD (layout, Q_orientation, check_valid_orientation); \ | |
1878 IIFORMAT_VALID_KEYWORD (layout, Q_justify, check_valid_justification); \ | |
863 | 1879 IIFORMAT_VALID_KEYWORD (layout, Q_vertically_justify, check_valid_justification); \ |
1880 IIFORMAT_VALID_KEYWORD (layout, Q_horizontally_justify, check_valid_justification); \ | |
442 | 1881 IIFORMAT_VALID_KEYWORD (layout, Q_border, check_valid_border); \ |
1882 IIFORMAT_VALID_KEYWORD (layout, Q_margin_width, check_valid_int); \ | |
1883 IIFORMAT_VALID_KEYWORD (layout, Q_items, \ | |
1884 check_valid_instantiator_list) | |
1885 | |
440 | 1886 static void image_instantiator_layout (void) |
1887 { | |
428 | 1888 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (layout, "layout"); |
442 | 1889 IIFORMAT_HAS_SHARED_METHOD (layout, possible_dest_types, widget); |
1890 IIFORMAT_HAS_METHOD (layout, instantiate); | |
1891 IIFORMAT_HAS_METHOD (layout, post_instantiate); | |
1892 IIFORMAT_HAS_SHARED_METHOD (layout, governing_domain, subwindow); | |
428 | 1893 IIFORMAT_HAS_METHOD (layout, normalize); |
440 | 1894 IIFORMAT_HAS_METHOD (layout, query_geometry); |
1895 IIFORMAT_HAS_METHOD (layout, layout); | |
442 | 1896 IIFORMAT_HAS_METHOD (layout, update); |
1897 IIFORMAT_HAS_METHOD (layout, property); | |
1898 | |
1899 VALID_GUI_KEYWORDS (layout); | |
1900 VALID_LAYOUT_KEYWORDS (layout); | |
1901 } | |
1902 | |
1903 static void image_instantiator_native_layout (void) | |
1904 { | |
1905 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (native_layout, "native-layout"); | |
1906 IIFORMAT_HAS_SHARED_METHOD (native_layout, possible_dest_types, widget); | |
1907 IIFORMAT_HAS_SHARED_METHOD (native_layout, instantiate, layout); | |
1908 IIFORMAT_HAS_SHARED_METHOD (native_layout, post_instantiate, layout); | |
1909 IIFORMAT_HAS_METHOD (native_layout, layout); | |
1910 IIFORMAT_HAS_SHARED_METHOD (native_layout, governing_domain, subwindow); | |
1911 IIFORMAT_HAS_SHARED_METHOD (native_layout, normalize, layout); | |
1912 IIFORMAT_HAS_SHARED_METHOD (native_layout, query_geometry, layout); | |
1913 IIFORMAT_HAS_SHARED_METHOD (native_layout, layout, layout); | |
1914 IIFORMAT_HAS_SHARED_METHOD (native_layout, property, layout); | |
1915 | |
1916 VALID_GUI_KEYWORDS (native_layout); | |
1917 VALID_LAYOUT_KEYWORDS (native_layout); | |
428 | 1918 } |
1919 | |
1920 void | |
440 | 1921 image_instantiator_format_create_glyphs_widget (void) |
1922 { | |
1923 image_instantiator_widget(); | |
1924 image_instantiator_buttons(); | |
1925 image_instantiator_edit_fields(); | |
1926 image_instantiator_combo_box(); | |
1927 image_instantiator_scrollbar(); | |
3094 | 1928 image_instantiator_progress_gauge(); |
440 | 1929 image_instantiator_tree_view(); |
1930 image_instantiator_tab_control(); | |
1931 image_instantiator_labels(); | |
1932 image_instantiator_layout(); | |
442 | 1933 image_instantiator_native_layout(); |
440 | 1934 } |
1935 | |
1936 void | |
428 | 1937 reinit_vars_of_glyphs_widget (void) |
1938 { | |
1939 #ifdef DEBUG_WIDGETS | |
1940 debug_widget_instances = 0; | |
1941 #endif | |
1942 } | |
1943 | |
1944 void | |
1945 vars_of_glyphs_widget (void) | |
1946 { | |
1947 } | |
863 | 1948 |
1949 | |
1950 void | |
1951 specifier_vars_of_glyphs_widget (void) | |
1952 { | |
1953 DEFVAR_SPECIFIER ("widget-border-width", | |
1954 &Vwidget_border_width /* | |
1955 *Border width of widgets. | |
1956 This is a specifier; use `set-specifier' to change it. | |
1957 */ ); | |
1958 Vwidget_border_width = Fmake_specifier (Qnatnum); | |
1959 } |