comparison src/glyphs-widget.c @ 412:697ef44129c6 r21-2-14

Import from CVS: tag r21-2-14
author cvs
date Mon, 13 Aug 2007 11:20:41 +0200
parents de805c49cfc1
children e804706bfb8c
comparison
equal deleted inserted replaced
411:12e008d41344 412:697ef44129c6
1 /* Widget-specific glyph objects. 1 /* Widget-specific glyph objects.
2 Copyright (C) 1998, 1999, 2000 Andy Piper. 2 Copyright (C) 1998 Andy Piper
3 3
4 This file is part of XEmacs. 4 This file is part of XEmacs.
5 5
6 XEmacs is free software; you can redistribute it and/or modify it 6 XEmacs is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the 7 under the terms of the GNU General Public License as published by the
36 #include "frame.h" 36 #include "frame.h"
37 #include "insdel.h" 37 #include "insdel.h"
38 #include "opaque.h" 38 #include "opaque.h"
39 39
40 DEFINE_IMAGE_INSTANTIATOR_FORMAT (button); 40 DEFINE_IMAGE_INSTANTIATOR_FORMAT (button);
41 DEFINE_IMAGE_INSTANTIATOR_FORMAT (combo_box); 41 DEFINE_IMAGE_INSTANTIATOR_FORMAT (combo);
42 Lisp_Object Qcombo_box; 42 Lisp_Object Qcombo;
43 DEFINE_IMAGE_INSTANTIATOR_FORMAT (edit_field); 43 DEFINE_IMAGE_INSTANTIATOR_FORMAT (edit);
44 Lisp_Object Qedit_field; 44 Lisp_Object Qedit;
45 DEFINE_IMAGE_INSTANTIATOR_FORMAT (scrollbar); 45 DEFINE_IMAGE_INSTANTIATOR_FORMAT (scrollbar);
46 Lisp_Object Qscrollbar; 46 Lisp_Object Qscrollbar;
47 DEFINE_IMAGE_INSTANTIATOR_FORMAT (widget); 47 DEFINE_IMAGE_INSTANTIATOR_FORMAT (widget);
48 #if 0
49 DEFINE_IMAGE_INSTANTIATOR_FORMAT (group);
50 Lisp_Object Qgroup;
51 #endif
48 DEFINE_IMAGE_INSTANTIATOR_FORMAT (label); 52 DEFINE_IMAGE_INSTANTIATOR_FORMAT (label);
49 Lisp_Object Qlabel; 53 Lisp_Object Qlabel;
50 DEFINE_IMAGE_INSTANTIATOR_FORMAT (progress_gauge); 54 DEFINE_IMAGE_INSTANTIATOR_FORMAT (progress);
51 Lisp_Object Qprogress_gauge; 55 Lisp_Object Qprogress;
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;
58 DEFINE_IMAGE_INSTANTIATOR_FORMAT (native_layout);
59 Lisp_Object Qnative_layout;
60 56
61 Lisp_Object Q_descriptor, Q_height, Q_width, Q_properties, Q_items; 57 Lisp_Object Q_descriptor, Q_height, Q_width, Q_properties, Q_items;
62 Lisp_Object Q_image, Q_text, Q_orientation, Q_justify, Q_border; 58 Lisp_Object Q_image, Q_text, Q_percent;
63 Lisp_Object Q_margin_width; 59
64 Lisp_Object Qetched_in, Qetched_out, Qbevel_in, Qbevel_out; 60 #define WIDGET_BORDER_HEIGHT 2
65 61 #define WIDGET_BORDER_WIDTH 4
66 #ifdef DEBUG_WIDGETS
67 int debug_widget_instances;
68 #endif
69 62
70 /* TODO: 63 /* TODO:
71 - tooltips for controls, especially buttons. 64 - more complex controls.
72 - keyboard traversal. 65 - tooltips for controls.
73 - lisp configurable layout.
74 */ 66 */
75 67
76 /* In MS-Windows normal windows work in pixels, dialog boxes work in 68 /* In windows normal windows work in pixels, dialog boxes work in
77 dialog box units. Why? sigh. We could reuse the metrics for dialogs 69 dialog box units. Why? sigh. We could reuse the metrics for dialogs
78 if this were not the case. As it is we have to position things 70 if this were not the case. As it is we have to position things
79 pixel wise. I'm not even sure that X has this problem at least for 71 pixel wise. I'm not even sure that X has this problem at least for
80 buttons in groups. */ 72 buttons in groups. */
73 Lisp_Object
74 widget_face_font_info (Lisp_Object domain, Lisp_Object face,
75 int *height, int *width)
76 {
77 Lisp_Object font_instance = FACE_FONT (face, domain, Vcharset_ascii);
78
79 if (height)
80 *height = XFONT_INSTANCE (font_instance)->height;
81 if (width)
82 *width = XFONT_INSTANCE (font_instance)->width;
83
84 return font_instance;
85 }
86
87 void
88 widget_text_to_pixel_conversion (Lisp_Object domain, Lisp_Object face,
89 int th, int tw,
90 int* height, int* width)
91 {
92 int ch=0, cw=0;
93 widget_face_font_info (domain, face, &ch, &cw);
94 if (height)
95 *height = th * (ch + 2 * WIDGET_BORDER_HEIGHT);
96 if (width)
97 *width = tw * cw + 2 * WIDGET_BORDER_WIDTH;
98 }
99
81 static int 100 static int
82 widget_possible_dest_types (void) 101 widget_possible_dest_types (void)
83 { 102 {
84 return IMAGE_WIDGET_MASK; 103 return IMAGE_WIDGET_MASK;
85 } 104 }
86 105
87 static void 106 static void
88 check_valid_glyph_or_instantiator (Lisp_Object data) 107 check_valid_glyph_or_image (Lisp_Object data)
89 { 108 {
90 Lisp_Object glyph = data; 109 Lisp_Object glyph = data;
91 if (SYMBOLP (data)) 110 if (SYMBOLP (data))
92 glyph = XSYMBOL (data)->value; 111 glyph = XSYMBOL (data)->value;
93 112
94 if (IMAGE_INSTANCEP (glyph)) 113 if (IMAGE_INSTANCEP (glyph))
95 CHECK_IMAGE_INSTANCE (glyph); 114 CHECK_IMAGE_INSTANCE (glyph);
96 else if (!CONSP (glyph) && !VECTORP (glyph)) 115 else if (!CONSP (glyph))
97 CHECK_BUFFER_GLYPH (glyph); 116 CHECK_BUFFER_GLYPH (glyph);
98 }
99
100 static void
101 check_valid_orientation (Lisp_Object data)
102 {
103 if (!EQ (data, Qhorizontal)
104 &&
105 !EQ (data, Qvertical))
106 signal_simple_error ("unknown orientation for layout", data);
107 }
108
109 static void
110 check_valid_tab_orientation (Lisp_Object data)
111 {
112 if (!EQ (data, Qtop)
113 &&
114 !EQ (data, Qbottom)
115 &&
116 !EQ (data, Qleft)
117 &&
118 !EQ (data, Qright))
119 signal_simple_error ("unknown orientation for tab control", data);
120 }
121
122 static void
123 check_valid_justification (Lisp_Object data)
124 {
125 if (!EQ (data, Qleft) && !EQ (data, Qright) && !EQ (data, Qcenter))
126 signal_simple_error ("unknown justification for layout", data);
127 }
128
129 static void
130 check_valid_border (Lisp_Object data)
131 {
132 if (!EQ (data, Qt) && !EQ (data, Qetched_in) && !EQ (data, Qetched_out)
133 && !EQ (data, Qbevel_in) && !EQ (data, Qbevel_out)
134 && !GLYPHP (data) && !VECTORP (data))
135 signal_simple_error ("unknown border style for layout", data);
136 } 117 }
137 118
138 static void 119 static void
139 check_valid_anything (Lisp_Object data) 120 check_valid_anything (Lisp_Object data)
140 { 121 {
150 signal_simple_error (":callback must be a function or expression", data); 131 signal_simple_error (":callback must be a function or expression", data);
151 } 132 }
152 } 133 }
153 134
154 static void 135 static void
155 check_valid_int_or_function (Lisp_Object data)
156 {
157 if (!INTP (data) && !CONSP (data))
158 signal_simple_error ("must be an integer or expresssion", data);
159 }
160
161 static void
162 check_valid_symbol (Lisp_Object data) 136 check_valid_symbol (Lisp_Object data)
163 { 137 {
164 CHECK_SYMBOL (data); 138 CHECK_SYMBOL (data);
165 } 139 }
166 140
169 { 143 {
170 if (!STRINGP (data) && !VECTORP (data)) 144 if (!STRINGP (data) && !VECTORP (data))
171 signal_simple_error (":descriptor must be a string or a vector", data); 145 signal_simple_error (":descriptor must be a string or a vector", data);
172 } 146 }
173 147
174 void 148 static void
175 check_valid_item_list_1 (Lisp_Object items) 149 check_valid_item_list (Lisp_Object data)
176 { 150 {
177 Lisp_Object rest; 151 Lisp_Object rest;
152 Lisp_Object items;
153 Fcheck_valid_plist (data);
154
155 items = Fplist_get (data, Q_items, Qnil);
178 156
179 CHECK_LIST (items); 157 CHECK_LIST (items);
180 EXTERNAL_LIST_LOOP (rest, items) 158 EXTERNAL_LIST_LOOP (rest, items)
181 { 159 {
182 if (STRINGP (XCAR (rest))) 160 CHECK_STRING (XCAR (rest));
183 CHECK_STRING (XCAR (rest)); 161 }
184 else if (VECTORP (XCAR (rest))) 162 }
185 gui_parse_item_keywords (XCAR (rest)); 163
186 else if (LISTP (XCAR (rest))) 164 /* wire widget property invocations to specific widgets ... The
187 check_valid_item_list_1 (XCAR (rest)); 165 problem we are solving here is that when instantiators get converted
188 else 166 to instances they lose some type information (they just become
189 signal_simple_error ("Items must be vectors, lists or strings", items); 167 subwindows or widgets for example). For widgets we need to preserve
190 } 168 this type information so that we can do widget specific operations on
191 } 169 the instances. This is encoded in the widget type
192 170 field. widget_property gets invoked by decoding the primary type
193 static void 171 (Qwidget), widget property then invokes based on the secondary type
194 check_valid_item_list (Lisp_Object data) 172 (Qedit for example). It is debatable that we should wire things in this
195 { 173 generalised way rather than treating widgets specially in
196 Lisp_Object items; 174 image_instance_property. */
197
198 Fcheck_valid_plist (data);
199 items = Fplist_get (data, Q_items, Qnil);
200
201 check_valid_item_list_1 (items);
202 }
203
204 static void
205 check_valid_glyph_or_instantiator_list (Lisp_Object data)
206 {
207 Lisp_Object rest;
208
209 CHECK_LIST (data);
210 EXTERNAL_LIST_LOOP (rest, data)
211 {
212 check_valid_glyph_or_instantiator (XCAR (rest));
213 }
214 }
215
216 static Lisp_Object
217 glyph_instantiator_to_glyph (Lisp_Object sym)
218 {
219 /* This function calls lisp. */
220 Lisp_Object glyph = sym;
221 struct gcpro gcpro1;
222
223 GCPRO1 (glyph);
224 /* if we have a symbol get at the actual data */
225 if (SYMBOLP (glyph))
226 glyph = XSYMBOL (glyph)->value;
227
228 if (CONSP (glyph))
229 glyph = Feval (glyph);
230
231 /* Be really helpful to the user. */
232 if (VECTORP (glyph))
233 {
234 glyph = call1 (intern ("make-glyph"), glyph);
235 }
236
237 /* substitute the new glyph */
238 RETURN_UNGCPRO (glyph);
239 }
240
241 static void
242 substitute_keyword_value (Lisp_Object inst, Lisp_Object key, Lisp_Object val)
243 {
244 int i;
245 /* substitute the new glyph */
246 for (i = 0; i < XVECTOR_LENGTH (inst); i++)
247 {
248 if (EQ (key, XVECTOR_DATA (inst)[i]))
249 {
250 XVECTOR_DATA (inst)[i+1] = val;
251 break;
252 }
253 }
254 }
255
256 /* Wire widget property invocations to specific widgets. The problem
257 we are solving here is that when instantiators get converted to
258 instances they lose some type information (they just become
259 subwindows or widgets for example). For widgets we need to preserve
260 this type information so that we can do widget specific operations
261 on the instances. This is encoded in the widget type
262 field. widget_property gets invoked by decoding the primary type
263 (Qwidget), <widget>_property then invokes based on the secondary
264 type (Qedit_field for example). It is debatable whether we should
265 wire things in this generalised way rather than treating widgets
266 specially in image_instance_property. */
267 static Lisp_Object 175 static Lisp_Object
268 widget_property (Lisp_Object image_instance, Lisp_Object prop) 176 widget_property (Lisp_Object image_instance, Lisp_Object prop)
269 { 177 {
270 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance); 178 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance);
271 struct image_instantiator_methods* meths; 179 struct image_instantiator_methods* meths;
272 180
273 /* first see if its a general property ... */ 181 /* first see if its a general property ... */
274 if (!NILP (Fplist_member (IMAGE_INSTANCE_WIDGET_PROPS (ii), prop))) 182 if (!NILP (Fplist_member (IMAGE_INSTANCE_WIDGET_PROPS (ii), prop)))
275 return Fplist_get (IMAGE_INSTANCE_WIDGET_PROPS (ii), prop, Qnil); 183 return Fplist_get (IMAGE_INSTANCE_WIDGET_PROPS (ii), prop, Qnil);
276 184
277 /* .. then try device specific methods ... */ 185 /* .. then try device specific methods ... */
278 meths = decode_device_ii_format (image_instance_device (image_instance), 186 meths = decode_device_ii_format (IMAGE_INSTANCE_DEVICE (ii),
279 IMAGE_INSTANCE_WIDGET_TYPE (ii), 187 IMAGE_INSTANCE_WIDGET_TYPE (ii),
280 ERROR_ME_NOT); 188 ERROR_ME_NOT);
281 if (meths && HAS_IIFORMAT_METH_P (meths, property)) 189 if (meths && HAS_IIFORMAT_METH_P (meths, property))
282 return IIFORMAT_METH (meths, property, (image_instance, prop)); 190 return IIFORMAT_METH (meths, property, (image_instance, prop));
283 /* ... then format specific methods ... */ 191 /* ... then format specific methods ... */
290 } 198 }
291 199
292 static Lisp_Object 200 static Lisp_Object
293 widget_set_property (Lisp_Object image_instance, Lisp_Object prop, Lisp_Object val) 201 widget_set_property (Lisp_Object image_instance, Lisp_Object prop, Lisp_Object val)
294 { 202 {
295 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance); 203 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance);
296 struct image_instantiator_methods* meths; 204 struct image_instantiator_methods* meths;
297 Lisp_Object ret; 205 Lisp_Object ret;
298 206
299 /* PIck up any generic properties that we might need to keep hold 207 /* try device specific methods first ... */
300 of. */ 208 meths = decode_device_ii_format (IMAGE_INSTANCE_DEVICE (ii),
301 if (EQ (prop, Q_text))
302 {
303 IMAGE_INSTANCE_WIDGET_TEXT (ii) = val;
304 IMAGE_INSTANCE_TEXT_CHANGED (ii) = 1;
305 }
306
307 /* Now try device specific methods first ... */
308 meths = decode_device_ii_format (image_instance_device (image_instance),
309 IMAGE_INSTANCE_WIDGET_TYPE (ii), 209 IMAGE_INSTANCE_WIDGET_TYPE (ii),
310 ERROR_ME_NOT); 210 ERROR_ME_NOT);
311 if (meths && HAS_IIFORMAT_METH_P (meths, set_property) 211 if (meths && HAS_IIFORMAT_METH_P (meths, set_property)
312 && 212 &&
313 !UNBOUNDP (ret = 213 !UNBOUNDP (ret =
329 IMAGE_INSTANCE_WIDGET_PROPS (ii) 229 IMAGE_INSTANCE_WIDGET_PROPS (ii)
330 = Fplist_put (IMAGE_INSTANCE_WIDGET_PROPS (ii), prop, val); 230 = Fplist_put (IMAGE_INSTANCE_WIDGET_PROPS (ii), prop, val);
331 return val; 231 return val;
332 } 232 }
333 233
334 /* Like the rest of redisplay, we want widget updates to occur
335 asynchronously. Thus toolkit specific methods for setting
336 properties must be called by redisplay instead of by
337 *_set_property. Thus *_set_property records the change and this
338 function actually implements it. We want to be slightly clever
339 about this however by supplying format specific functions for the
340 updates instead of lumping them all into this function. Note that
341 there is no need for format generic functions. */
342 void
343 update_widget (Lisp_Object widget)
344 {
345 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (widget);
346 struct image_instantiator_methods* meths;
347
348 if (!WIDGET_IMAGE_INSTANCEP (widget)
349 || EQ (IMAGE_INSTANCE_WIDGET_TYPE (ii), Qlayout)
350 || EQ (IMAGE_INSTANCE_WIDGET_TYPE (ii), Qnative_layout))
351 return;
352
353 /* Device generic methods. We must update the widget's size as it
354 may have been changed by the the layout routines. We also do this
355 here so that explicit resizing from lisp does not result in
356 synchronous updates. */
357 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain), update_widget, (ii));
358
359 /* Device-format specific methods */
360 meths = decode_device_ii_format (image_instance_device (widget),
361 IMAGE_INSTANCE_WIDGET_TYPE (ii),
362 ERROR_ME_NOT);
363 MAYBE_IIFORMAT_METH (meths, update, (widget));
364
365 /* Pick up the items we recorded earlier. */
366 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii))
367 {
368 IMAGE_INSTANCE_WIDGET_ITEMS (ii) =
369 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii);
370 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii) = Qnil;
371 }
372 }
373
374 /* Query for a widgets desired geometry. If no type specific method is
375 provided then use the widget text to calculate sizes. */
376 static void
377 widget_query_geometry (Lisp_Object image_instance,
378 int* width, int* height,
379 enum image_instance_geometry disp, Lisp_Object domain)
380 {
381 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance);
382 struct image_instantiator_methods* meths;
383 Lisp_Object dynamic_width = Qnil;
384 Lisp_Object dynamic_height = Qnil;
385
386 /* First just set up what we already have. */
387 if (width) *width = IMAGE_INSTANCE_WIDTH (ii);
388 if (height) *height = IMAGE_INSTANCE_HEIGHT (ii);
389
390 if (IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii)
391 ||
392 IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii))
393 {
394 /* .. then try device specific methods ... */
395 meths = decode_device_ii_format (image_instance_device (image_instance),
396 IMAGE_INSTANCE_WIDGET_TYPE (ii),
397 ERROR_ME_NOT);
398 if (meths && HAS_IIFORMAT_METH_P (meths, query_geometry))
399 IIFORMAT_METH (meths, query_geometry, (image_instance,
400 width, height, disp,
401 domain));
402 else
403 {
404 /* ... then format specific methods ... */
405 meths = decode_device_ii_format (Qnil, IMAGE_INSTANCE_WIDGET_TYPE (ii),
406 ERROR_ME_NOT);
407 if (meths && HAS_IIFORMAT_METH_P (meths, query_geometry))
408 IIFORMAT_METH (meths, query_geometry, (image_instance,
409 width, height, disp,
410 domain));
411 else
412 {
413 int w, h;
414
415 /* Then if we are allowed to resize the widget, make the
416 size the same as the text dimensions. */
417 query_string_geometry (IMAGE_INSTANCE_WIDGET_TEXT (ii),
418 IMAGE_INSTANCE_WIDGET_FACE (ii),
419 &w, &h, 0, domain);
420 /* Adjust the size for borders. */
421 if (IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii))
422 *width = w + 2 * WIDGET_BORDER_WIDTH;
423 if (IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii))
424 *height = h + 2 * WIDGET_BORDER_HEIGHT;
425 }
426 }
427 /* Finish off with dynamic sizing. */
428 if (!NILP (IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (ii)))
429 {
430 dynamic_width = Feval (IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (ii));
431 if (INTP (dynamic_width))
432 *width = XINT (dynamic_width);
433 }
434 if (!NILP (IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (ii)))
435 {
436 dynamic_height = Feval (IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (ii));
437 if (INTP (dynamic_height))
438 *height = XINT (dynamic_height);
439 }
440 }
441 }
442
443 static int
444 widget_layout (Lisp_Object image_instance,
445 int width, int height, Lisp_Object domain)
446 {
447 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance);
448 struct image_instantiator_methods* meths;
449
450 /* .. then try device specific methods ... */
451 meths = decode_device_ii_format (image_instance_device (image_instance),
452 IMAGE_INSTANCE_WIDGET_TYPE (ii),
453 ERROR_ME_NOT);
454 if (meths && HAS_IIFORMAT_METH_P (meths, layout))
455 return IIFORMAT_METH (meths, layout, (image_instance,
456 width, height, domain));
457 else
458 {
459 /* ... then format specific methods ... */
460 meths = decode_device_ii_format (Qnil, IMAGE_INSTANCE_WIDGET_TYPE (ii),
461 ERROR_ME_NOT);
462 if (meths && HAS_IIFORMAT_METH_P (meths, layout))
463 return IIFORMAT_METH (meths, layout, (image_instance,
464 width, height, domain));
465 }
466 return 1;
467 }
468
469 static void 234 static void
470 widget_validate (Lisp_Object instantiator) 235 widget_validate (Lisp_Object instantiator)
471 { 236 {
472 Lisp_Object desc = find_keyword_in_vector (instantiator, Q_descriptor); 237 Lisp_Object desc = find_keyword_in_vector (instantiator, Q_descriptor);
473 238 struct gui_item gui;
474 if (NILP (desc)) 239 if (NILP (desc))
475 signal_simple_error ("Must supply :descriptor", instantiator); 240 signal_simple_error ("Must supply :descriptor", instantiator);
476 241
477 if (VECTORP (desc)) 242 if (VECTORP (desc))
478 gui_parse_item_keywords (desc); 243 gui_parse_item_keywords (desc, &gui);
479 244
480 if (!NILP (find_keyword_in_vector (instantiator, Q_width)) 245 if (!NILP (find_keyword_in_vector (instantiator, Q_width))
481 && !NILP (find_keyword_in_vector (instantiator, Q_pixel_width))) 246 && !NILP (find_keyword_in_vector (instantiator, Q_pixel_width)))
482 signal_simple_error ("Must supply only one of :width and :pixel-width", instantiator); 247 signal_simple_error ("Must supply only one of :width and :pixel-width", instantiator);
483 248
484 if (!NILP (find_keyword_in_vector (instantiator, Q_height)) 249 if (!NILP (find_keyword_in_vector (instantiator, Q_height))
485 && !NILP (find_keyword_in_vector (instantiator, Q_pixel_height))) 250 && !NILP (find_keyword_in_vector (instantiator, Q_pixel_height)))
486 signal_simple_error ("Must supply only one of :height and :pixel-height", instantiator); 251 signal_simple_error ("Must supply only one of :height and :pixel-height", instantiator);
487 } 252 }
488 253
489 static void 254 static void
490 combo_box_validate (Lisp_Object instantiator) 255 combo_validate (Lisp_Object instantiator)
491 { 256 {
492 widget_validate (instantiator); 257 widget_validate (instantiator);
493 if (NILP (find_keyword_in_vector (instantiator, Q_properties))) 258 if (NILP (find_keyword_in_vector (instantiator, Q_properties)))
494 signal_simple_error ("Must supply item list", instantiator); 259 signal_simple_error ("Must supply item list", instantiator);
495 } 260 }
504 269
505 /* we need to eval glyph if its an expression, we do this for the 270 /* we need to eval glyph if its an expression, we do this for the
506 same reasons we normalize file to data. */ 271 same reasons we normalize file to data. */
507 if (!NILP (glyph)) 272 if (!NILP (glyph))
508 { 273 {
509 substitute_keyword_value (inst, Q_image, glyph_instantiator_to_glyph (glyph)); 274 int i;
510 } 275 struct gcpro gcpro1;
511 276 if (SYMBOLP (glyph))
277 glyph = XSYMBOL (glyph)->value;
278 GCPRO1 (glyph);
279
280 if (CONSP (glyph))
281 glyph = Feval (glyph);
282 /* substitute the new glyph */
283 for (i = 0; i < XVECTOR_LENGTH (inst); i++)
284 {
285 if (EQ (Q_image, XVECTOR_DATA (inst)[i]))
286 {
287 XVECTOR_DATA (inst)[i+1] = glyph;
288 break;
289 }
290 }
291 UNGCPRO;
292 }
512 return inst; 293 return inst;
513 } 294 }
514 295
515 static void 296 static void
516 initialize_widget_image_instance (Lisp_Image_Instance *ii, Lisp_Object type) 297 initialize_widget_image_instance (struct Lisp_Image_Instance *ii, Lisp_Object type)
517 { 298 {
518 /* initialize_subwindow_image_instance (ii);*/ 299 /* initialize_subwindow_image_instance (ii);*/
519 IMAGE_INSTANCE_WIDGET_TYPE (ii) = type; 300 IMAGE_INSTANCE_WIDGET_TYPE (ii) = type;
520 IMAGE_INSTANCE_WIDGET_PROPS (ii) = Qnil; 301 IMAGE_INSTANCE_WIDGET_PROPS (ii) = Qnil;
521 SET_IMAGE_INSTANCE_WIDGET_FACE (ii, Qnil); 302 IMAGE_INSTANCE_WIDGET_FACE (ii) = Vwidget_face;
522 IMAGE_INSTANCE_WIDGET_ITEMS (ii) = allocate_gui_item (); 303 gui_item_init (&IMAGE_INSTANCE_WIDGET_ITEM (ii));
523 IMAGE_INSTANCE_LAYOUT_CHILDREN (ii) = Qnil;
524 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii) = Qnil;
525 IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (ii) = Qnil;
526 IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (ii) = Qnil;
527 IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii) = 1;
528 IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii) = 1;
529 IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) = LAYOUT_HORIZONTAL;
530 IMAGE_INSTANCE_SUBWINDOW_JUSTIFY (ii) = 0;
531 } 304 }
532 305
533 /* Instantiate a button widget. Unfortunately instantiated widgets are 306 /* Instantiate a button widget. Unfortunately instantiated widgets are
534 particular to a frame since they need to have a parent. It's not 307 particular to a frame since they need to have a parent. It's not
535 like images where you just select the image into the context you 308 like images where you just select the image into the context you
536 want to display it in and BitBlt it. So image instances can have a 309 want to display it in and BitBlt it. So images instances can have a
537 many-to-one relationship with things you see, whereas widgets can 310 many-to-one relationship with things you see, whereas widgets can
538 only be one-to-one (i.e. per frame) */ 311 only be one-to-one (i.e. per frame) */
539 void 312 static void
540 widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, 313 widget_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator,
541 Lisp_Object pointer_fg, Lisp_Object pointer_bg, 314 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
542 int dest_mask, Lisp_Object domain) 315 int dest_mask, Lisp_Object domain, int default_textheight,
543 { 316 int default_pixheight)
544 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); 317 {
318 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
319 struct gui_item* pgui = &IMAGE_INSTANCE_WIDGET_ITEM (ii);
545 Lisp_Object face = find_keyword_in_vector (instantiator, Q_face); 320 Lisp_Object face = find_keyword_in_vector (instantiator, Q_face);
546 Lisp_Object height = find_keyword_in_vector (instantiator, Q_height); 321 Lisp_Object height = find_keyword_in_vector (instantiator, Q_height);
547 Lisp_Object width = find_keyword_in_vector (instantiator, Q_width); 322 Lisp_Object width = find_keyword_in_vector (instantiator, Q_width);
548 Lisp_Object pixwidth = find_keyword_in_vector (instantiator, Q_pixel_width); 323 Lisp_Object pixwidth = find_keyword_in_vector (instantiator, Q_pixel_width);
549 Lisp_Object pixheight = find_keyword_in_vector (instantiator, Q_pixel_height); 324 Lisp_Object pixheight = find_keyword_in_vector (instantiator, Q_pixel_height);
550 Lisp_Object desc = find_keyword_in_vector (instantiator, Q_descriptor); 325 Lisp_Object desc = find_keyword_in_vector (instantiator, Q_descriptor);
551 Lisp_Object glyph = find_keyword_in_vector (instantiator, Q_image); 326 Lisp_Object glyph = find_keyword_in_vector (instantiator, Q_image);
552 Lisp_Object props = find_keyword_in_vector (instantiator, Q_properties);
553 Lisp_Object items = find_keyword_in_vector (instantiator, Q_items);
554 Lisp_Object orient = find_keyword_in_vector (instantiator, Q_orientation);
555 Lisp_Object mwidth = find_keyword_in_vector (instantiator, Q_margin_width);
556 int pw=0, ph=0, tw=0, th=0; 327 int pw=0, ph=0, tw=0, th=0;
557 328
558 /* this just does pixel type sizing */ 329 /* this just does pixel type sizing */
559 subwindow_instantiate (image_instance, instantiator, pointer_fg, pointer_bg, 330 subwindow_instantiate (image_instance, instantiator, pointer_fg, pointer_bg,
560 dest_mask, domain); 331 dest_mask, domain);
561 332
562 if (!(dest_mask & IMAGE_WIDGET_MASK)) 333 if (!(dest_mask & IMAGE_WIDGET_MASK))
563 incompatible_image_types (instantiator, dest_mask, IMAGE_WIDGET_MASK); 334 incompatible_image_types (instantiator, dest_mask, IMAGE_WIDGET_MASK);
564 335
565 initialize_widget_image_instance (ii, XVECTOR_DATA (instantiator)[0]); 336 initialize_widget_image_instance (ii, XVECTOR_DATA (instantiator)[0]);
566 337
567 IMAGE_INSTANCE_TYPE (ii) = IMAGE_WIDGET;
568 IMAGE_INSTANCE_WIDGET_PROPS (ii) = props;
569
570 /* retrieve the fg and bg colors */ 338 /* retrieve the fg and bg colors */
571 if (!NILP (face)) 339 if (!NILP (face))
572 SET_IMAGE_INSTANCE_WIDGET_FACE (ii, Fget_face (face)); 340 IMAGE_INSTANCE_WIDGET_FACE (ii) = Fget_face (face);
573 341
342 /* data items for some widgets */
343 IMAGE_INSTANCE_WIDGET_PROPS (ii) =
344 find_keyword_in_vector (instantiator, Q_properties);
345
574 /* retrieve the gui item information. This is easy if we have been 346 /* retrieve the gui item information. This is easy if we have been
575 provided with a vector, more difficult if we have just been given 347 provided with a vector, more difficult if we have just been given
576 keywords */ 348 keywords */
577 if (STRINGP (desc) || NILP (desc)) 349 if (STRINGP (desc) || NILP (desc))
578 { 350 {
579 /* big cheat - we rely on the fact that a gui item looks like an instantiator */ 351 /* big cheat - we rely on the fact that a gui item looks like an instantiator */
580 IMAGE_INSTANCE_WIDGET_ITEMS (ii) = 352 gui_parse_item_keywords_no_errors (instantiator, pgui);
581 gui_parse_item_keywords_no_errors (instantiator);
582 IMAGE_INSTANCE_WIDGET_TEXT (ii) = desc; 353 IMAGE_INSTANCE_WIDGET_TEXT (ii) = desc;
583 } 354 }
584 else 355 else
585 IMAGE_INSTANCE_WIDGET_ITEMS (ii) = 356 gui_parse_item_keywords_no_errors (desc, pgui);
586 gui_parse_item_keywords_no_errors (desc); 357
587 358 /* normalize size information */
588 /* Pick up the orientation before we do our first layout. */ 359 if (!NILP (width))
589 if (EQ (orient, Qleft) || EQ (orient, Qright) || EQ (orient, Qvertical)) 360 tw = XINT (width);
590 IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) = LAYOUT_VERTICAL; 361 if (!NILP (height))
591 362 th = XINT (height);
592 /* parse more gui items out of the properties */ 363 if (!NILP (pixwidth))
593 if (!NILP (props) 364 pw = XINT (pixwidth);
594 &&
595 !EQ (IMAGE_INSTANCE_WIDGET_TYPE (ii), Qlayout)
596 && !EQ (IMAGE_INSTANCE_WIDGET_TYPE (ii), Qnative_layout))
597 {
598 if (NILP (items))
599 {
600 items = Fplist_get (props, Q_items, Qnil);
601 }
602 if (!NILP (items))
603 {
604 IMAGE_INSTANCE_WIDGET_ITEMS (ii) =
605 Fcons (IMAGE_INSTANCE_WIDGET_ITEMS (ii),
606 parse_gui_item_tree_children (items));
607 }
608 }
609
610 /* Normalize size information. We now only assign sizes if the user
611 gives us some explicitly, or there are some constraints that we
612 can't change later on. Otherwise we postpone sizing until query
613 geometry gets called. */
614 if (!NILP (pixwidth)) /* pixwidth takes precendent */
615 {
616 if (!INTP (pixwidth))
617 IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (ii) = pixwidth;
618 else
619 {
620 pw = XINT (pixwidth);
621 IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii) = 0;
622 }
623 }
624 else if (!NILP (width))
625 {
626 tw = XINT (width);
627 IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii) = 0;
628 }
629
630 if (!NILP (pixheight)) 365 if (!NILP (pixheight))
631 { 366 ph = XINT (pixheight);
632 if (!INTP (pixheight))
633 IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (ii) = pixheight;
634 else
635 {
636 ph = XINT (pixheight);
637 IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii) = 0;
638 }
639 }
640 else if (!NILP (height) && XINT (height) > 1)
641 {
642 th = XINT (height);
643 IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii) = 0;
644 }
645
646 /* Taking the default face information when the user has specified
647 size in characters is probably as good as any since the widget
648 face is more likely to be proportional and thus give inadequate
649 results. Using character sizes can only ever be approximate
650 anyway. */
651 if (tw || th)
652 {
653 int charwidth, charheight;
654 default_face_font_info (domain, 0, 0, &charheight, &charwidth, 0);
655 if (tw)
656 pw = charwidth * tw;
657 if (th)
658 ph = charheight * th;
659 }
660 367
661 /* for a widget with an image pick up the dimensions from that */ 368 /* for a widget with an image pick up the dimensions from that */
662 if (!NILP (glyph)) 369 if (!NILP (glyph))
663 { 370 {
664 if (!pw) 371 if (!pw && !tw)
665 pw = glyph_width (glyph, domain) + 2 * WIDGET_BORDER_WIDTH; 372 pw = glyph_width (glyph, Qnil, DEFAULT_INDEX, domain)
666 if (!ph) 373 + 2 * WIDGET_BORDER_WIDTH;
667 ph = glyph_height (glyph, domain) + 2 * WIDGET_BORDER_HEIGHT; 374 if (!ph && !th)
668 IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii) = 0; 375 ph = glyph_height (glyph, Qnil, DEFAULT_INDEX, domain)
669 IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii) = 0; 376 + 2 * WIDGET_BORDER_HEIGHT;
670 } 377 }
671 378
672 /* Pick up the margin width. */ 379 /* if we still don' t have sizes, guess from text size */
673 if (!NILP (mwidth)) 380 if (!tw && !pw && !NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
674 IMAGE_INSTANCE_MARGIN_WIDTH (ii) = XINT (mwidth); 381 tw = XSTRING_LENGTH (IMAGE_INSTANCE_WIDGET_TEXT (ii));
675 382 if (!th && !ph)
676 /* Layout for the layout widget is premature at this point since the 383 {
677 children will not have been instantiated. We can't instantiate 384 if (default_textheight)
678 them until the device instantiation method for the layout has 385 th = default_textheight;
679 been executed. We do however want to record any specified 386 else if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
680 dimensions. */ 387 th = 1;
681 if (pw) IMAGE_INSTANCE_WIDTH (ii) = pw; 388 else
682 if (ph) IMAGE_INSTANCE_HEIGHT (ii) = ph; 389 ph = default_pixheight;
683 } 390 }
684
685 static void
686 widget_post_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
687 Lisp_Object domain)
688 {
689 #ifdef DEBUG_WIDGETS
690 debug_widget_instances++;
691 stderr_out ("instantiated ");
692 debug_print (instantiator);
693 stderr_out ("%d widgets instantiated\n", debug_widget_instances);
694 #endif
695 }
696
697 /* Get the geometry of a button control. We need to adjust the size
698 depending on the type of button. */
699 static void
700 button_query_geometry (Lisp_Object image_instance,
701 int* width, int* height,
702 enum image_instance_geometry disp, Lisp_Object domain)
703 {
704 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
705 int w, h;
706 query_string_geometry (IMAGE_INSTANCE_WIDGET_TEXT (ii),
707 IMAGE_INSTANCE_WIDGET_FACE (ii),
708 &w, &h, 0, domain);
709 /* Adjust the size for borders. */
710 if (IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii))
711 {
712 *width = w + 2 * WIDGET_BORDER_WIDTH;
713
714 if (EQ (XGUI_ITEM (IMAGE_INSTANCE_WIDGET_ITEM (ii))->style, Qradio)
715 ||
716 EQ (XGUI_ITEM (IMAGE_INSTANCE_WIDGET_ITEM (ii))->style, Qtoggle))
717 /* This is an approximation to the size of the actual button bit. */
718 *width += 12;
719 }
720 if (IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii))
721 *height = h + 2 * WIDGET_BORDER_HEIGHT;
722 }
723
724 /* tree-view geometry - get the height right */
725 static void
726 tree_view_query_geometry (Lisp_Object image_instance,
727 int* width, int* height,
728 enum image_instance_geometry disp, Lisp_Object domain)
729 {
730 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
731 Lisp_Object items = IMAGE_INSTANCE_WIDGET_ITEMS (ii);
732
733 391
734 if (*width) 392 if (tw !=0 || th !=0)
735 { 393 widget_text_to_pixel_conversion (domain,
736 /* #### what should this be. reconsider when X has tree views. */ 394 IMAGE_INSTANCE_WIDGET_FACE (ii),
737 query_string_geometry (IMAGE_INSTANCE_WIDGET_TEXT (ii), 395 th, tw, th ? &ph : 0, tw ? &pw : 0);
738 IMAGE_INSTANCE_WIDGET_FACE (ii), 396
739 width, 0, 0, domain); 397 IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii) = pw;
740 } 398 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii) = ph;
741 if (*height) 399 }
742 { 400
743 int len, h; 401 static void
744 default_face_font_info (domain, 0, 0, &h, 0, 0); 402 widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
745 GET_LIST_LENGTH (items, len);
746 *height = len * h;
747 }
748 }
749
750 /* Get the geometry of a tab control. This is based on the number of
751 items and text therin in the tab control. */
752 static void
753 tab_control_query_geometry (Lisp_Object image_instance,
754 int* width, int* height,
755 enum image_instance_geometry disp, Lisp_Object domain)
756 {
757 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
758 Lisp_Object items = XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii));
759 Lisp_Object rest;
760 unsigned int tw = 0, th = 0;
761
762 LIST_LOOP (rest, items)
763 {
764 int h, w;
765
766 query_string_geometry (XGUI_ITEM (XCAR (rest))->name,
767 IMAGE_INSTANCE_WIDGET_FACE (ii),
768 &w, &h, 0, domain);
769 tw += 5 * WIDGET_BORDER_WIDTH; /* some bias */
770 tw += w;
771 th = max (th, h + 2 * WIDGET_BORDER_HEIGHT);
772 }
773
774 /* Fixup returned values depending on orientation. */
775 if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii))
776 {
777 if (height) *height = tw;
778 if (width) *width = th;
779 }
780 else
781 {
782 if (height) *height = th;
783 if (width) *width = tw;
784 }
785 }
786
787 /* Get the geometry of a tab control. This is based on the number of
788 items and text therin in the tab control. */
789 static Lisp_Object
790 tab_control_set_property (Lisp_Object image_instance,
791 Lisp_Object prop,
792 Lisp_Object val)
793 {
794 /* Record new items for update. *_tab_control_update will do the
795 rest. */
796 if (EQ (prop, Q_items))
797 {
798 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance);
799
800 check_valid_item_list_1 (val);
801
802 /* Don't set the actual items since we might decide not to use
803 the new ones (because nothing has really changed). If we did
804 set them and didn't use them then we would get into whole
805 heaps of trouble when the old items get GC'd. */
806 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii) =
807 Fcons (XCAR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)),
808 parse_gui_item_tree_children (val));
809 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 1;
810
811 return Qt;
812 }
813 return Qunbound;
814 }
815
816 /* set the properties of a progres guage */
817 static Lisp_Object
818 progress_gauge_set_property (Lisp_Object image_instance,
819 Lisp_Object prop,
820 Lisp_Object val)
821 {
822 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
823
824 if (EQ (prop, Q_value))
825 {
826 CHECK_INT (val);
827 #ifdef DEBUG_WIDGET_OUTPUT
828 printf ("progress gauge value set to %ld\n", XINT (val));
829 #endif
830 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii) =
831 copy_gui_item_tree (IMAGE_INSTANCE_WIDGET_ITEMS (ii));
832 #ifdef ERROR_CHECK_GLYPHS
833 assert (GUI_ITEMP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)));
834 #endif
835 if (GUI_ITEMP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)))
836 XGUI_ITEM (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii))->value = val;
837
838 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 1;
839
840 return Qt;
841 }
842 return Qunbound;
843 }
844
845
846 /*****************************************************************************
847 * widget layout *
848 *****************************************************************************/
849 /* we need to convert things like glyphs to images, eval expressions
850 etc.*/
851 static Lisp_Object
852 layout_normalize (Lisp_Object inst, Lisp_Object console_type)
853 {
854 /* This function can call lisp */
855 Lisp_Object items = find_keyword_in_vector (inst, Q_items);
856 Lisp_Object border = find_keyword_in_vector (inst, Q_border);
857 /* we need to eval glyph if its an expression, we do this for the
858 same reasons we normalize file to data. */
859 if (!NILP (items))
860 {
861 Lisp_Object rest;
862 LIST_LOOP (rest, items)
863 {
864 /* substitute the new glyph */
865 Fsetcar (rest, glyph_instantiator_to_glyph (XCAR (rest)));
866 }
867 }
868 /* normalize the border spec. */
869 if (VECTORP (border) || CONSP (border))
870 {
871 substitute_keyword_value (inst, Q_border, glyph_instantiator_to_glyph (border));
872 }
873 return inst;
874 }
875
876 static void
877 layout_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
878 Lisp_Object pointer_fg, Lisp_Object pointer_bg, 403 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
879 int dest_mask, Lisp_Object domain) 404 int dest_mask, Lisp_Object domain)
880 { 405 {
881 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); 406 widget_instantiate_1 (image_instance, instantiator, pointer_fg,
882 Lisp_Object orient = find_keyword_in_vector (instantiator, Q_orientation); 407 pointer_bg, dest_mask, domain, 1, 0);
883 Lisp_Object border = find_keyword_in_vector (instantiator, Q_border); 408 }
884 409
885 /* Do widget type instantiation first. */ 410 static void
886 widget_instantiate (image_instance, instantiator, pointer_fg, pointer_bg, 411 combo_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
887 dest_mask, domain); 412 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
888 413 int dest_mask, Lisp_Object domain)
889 if (NILP (orient)) 414 {
890 { 415 Lisp_Object data = Fplist_get (find_keyword_in_vector (instantiator, Q_properties),
891 IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) = LAYOUT_VERTICAL; 416 Q_items, Qnil);
892 } 417 int len;
893 418 GET_LIST_LENGTH (data, len);
894 if (EQ (border, Qt)) 419 widget_instantiate_1 (image_instance, instantiator, pointer_fg,
895 { 420 pointer_bg, dest_mask, domain, len + 1, 0);
896 IMAGE_INSTANCE_LAYOUT_BORDER (ii) = Qetched_in; 421 }
897 } 422
898 else 423 /* Instantiate a static control */
899 { 424 static void
900 IMAGE_INSTANCE_LAYOUT_BORDER (ii) = border; 425 static_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
901 } 426 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
902 /* We don't do the children yet as we might not have a containing 427 int dest_mask, Lisp_Object domain)
903 window. */ 428 {
904 } 429 widget_instantiate_1 (image_instance, instantiator, pointer_fg,
905 430 pointer_bg, dest_mask, domain, 0, 4);
906 static void
907 layout_post_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
908 Lisp_Object domain)
909 {
910 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
911 Lisp_Object items = find_keyword_in_vector (instantiator, Q_items);
912 Lisp_Object rest, children = Qnil;
913
914 if (GLYPHP (IMAGE_INSTANCE_LAYOUT_BORDER (ii)))
915 {
916 /* We are going to be sneaky here and add the border text as
917 just another child, the layout and output routines don't know
918 this and will just display at the offsets we prescribe. */
919 Lisp_Object gii = glyph_image_instance
920 (IMAGE_INSTANCE_LAYOUT_BORDER (ii),
921 image_instance, ERROR_ME, 1);
922
923 if (!IMAGE_INSTANCEP (gii))
924 return;
925 /* make sure we are designated as the parent. */
926 XIMAGE_INSTANCE_PARENT (gii) = image_instance;
927 children = Fcons (gii, children);
928 IMAGE_INSTANCE_LAYOUT_BORDER (ii) = make_int (0);
929 }
930
931 /* Pick up the sub-widgets. */
932 LIST_LOOP (rest, items)
933 {
934 /* make sure the image is instantiated */
935 Lisp_Object gii = glyph_image_instance (XCAR (rest),
936 image_instance, ERROR_ME, 1);
937 if (!IMAGE_INSTANCEP (gii))
938 return;
939 /* make sure we are designated as the parent. */
940 XIMAGE_INSTANCE_PARENT (gii) = image_instance;
941 children = Fcons (gii, children);
942 }
943 /* Make sure elements in the layout are in the order the
944 user expected. */
945 children = Fnreverse (children);
946 IMAGE_INSTANCE_LAYOUT_CHILDREN (ii) = children;
947 }
948
949 /* Layout widget. Sizing commentary: we have a number of problems that
950 we would like to address. Some consider some of these more
951 important than others. It used to be that size information was
952 determined at instantiation time and was then fixed forever
953 after. Generally this is not what we want. Users want size to be
954 "big enough" to accommodate whatever they are trying to show and
955 this is dependent on text length, lines, font metrics etc. Of
956 course these attributes can change dynamically and so the size
957 should changed dynamically also. Only in a few limited cases should
958 the size be fixed and remain fixed. Of course this actually means
959 that we don't really want to specifiy the size *at all* for most
960 widgets - we want it to be discovered dynamically. Thus we can
961 envisage the following scenarios:
962
963 1. A button is sized to accommodate its text, the text changes and the
964 button should change size also.
965
966 2. A button is given an explicit size. Its size should never change.
967
968 3. Layout is put inside an area. The size of the area changes, the
969 layout should change with it.
970
971 4. A button grows to accommodate additional text. The whitespace
972 around it should be modified to cope with the new layout
973 requirements.
974
975 5. A button grows. The area surrounding it should grow also if
976 possible.
977
978 What metrics are important?
979 1. Actual width and height.
980
981 2. Whether the width and height are what the widget actually wants, or
982 whether it can grow or shrink.
983
984 Text glyphs are particularly troublesome since their metrics depend
985 on the context in which they are being viewed. For instance they
986 can appear differently depending on the window face, frame face or
987 glyph face. In order to simplify this text glyphs can now only have
988 a glyph-face or image-instance face. All other glyphs are
989 essentially fixed in appearance. Perhaps the problem is that text
990 glyphs are cached on a device basis like most other glyphs. Instead
991 they should be cached per-window and then the instance would be
992 fixed and we wouldn't have to mess around with font metrics and the
993 rest. */
994
995 /* Query the geometry of a layout widget. We assume that we can only
996 get here if the size is not already fixed. */
997 static void
998 layout_query_geometry (Lisp_Object image_instance, int* width,
999 int* height, enum image_instance_geometry disp,
1000 Lisp_Object domain)
1001 {
1002 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1003 Lisp_Object items = IMAGE_INSTANCE_LAYOUT_CHILDREN (ii), rest;
1004 int maxph = 0, maxpw = 0, nitems = 0, ph_adjust = 0;
1005 int gheight, gwidth;
1006
1007 /* If we are not initialized then we won't have any children. */
1008 if (!IMAGE_INSTANCE_INITIALIZED (ii))
1009 return;
1010
1011 /* First just set up what we already have. */
1012 if (width) *width = IMAGE_INSTANCE_WIDTH (ii);
1013 if (height) *height = IMAGE_INSTANCE_HEIGHT (ii);
1014
1015 /* If we are not allowed to dynamically size then return. */
1016 if (!IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii)
1017 &&
1018 !IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii))
1019 return;
1020
1021 /* Pick up the border text if we have one. */
1022 if (INTP (IMAGE_INSTANCE_LAYOUT_BORDER (ii)))
1023 {
1024 image_instance_query_geometry (XCAR (items), &gwidth, &gheight, disp, domain);
1025 ph_adjust = gheight / 2;
1026 items = XCDR (items);
1027 }
1028
1029 /* Flip through the items to work out how much stuff we have to display */
1030 LIST_LOOP (rest, items)
1031 {
1032 Lisp_Object glyph = XCAR (rest);
1033 image_instance_query_geometry (glyph, &gwidth, &gheight, disp, domain);
1034
1035 nitems ++;
1036 if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii)
1037 == LAYOUT_HORIZONTAL)
1038 {
1039 maxph = max (maxph, gheight);
1040 maxpw += gwidth;
1041 }
1042 else
1043 {
1044 maxpw = max (maxpw, gwidth);
1045 maxph += gheight;
1046 }
1047 }
1048
1049 /* Work out minimum space we need to fit all the items. This could
1050 have been fixed by the user. */
1051 if (!NILP (IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (ii)))
1052 {
1053 Lisp_Object dynamic_width =
1054 Feval (IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (ii));
1055 if (INTP (dynamic_width))
1056 *width = XINT (dynamic_width);
1057 }
1058 else if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii)
1059 == LAYOUT_HORIZONTAL)
1060 *width = maxpw + ((nitems + 1) * WIDGET_BORDER_WIDTH +
1061 IMAGE_INSTANCE_MARGIN_WIDTH (ii)) * 2;
1062 else
1063 *width = maxpw + 2 * (WIDGET_BORDER_WIDTH * 2 +
1064 IMAGE_INSTANCE_MARGIN_WIDTH (ii));
1065
1066 /* Work out vertical spacings. */
1067 if (!NILP (IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (ii)))
1068 {
1069 Lisp_Object dynamic_height =
1070 Feval (IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (ii));
1071 if (INTP (dynamic_height))
1072 *height = XINT (dynamic_height);
1073 }
1074 else if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii)
1075 == LAYOUT_VERTICAL)
1076 *height = maxph + ((nitems + 1) * WIDGET_BORDER_HEIGHT +
1077 IMAGE_INSTANCE_MARGIN_WIDTH (ii)) * 2 + ph_adjust;
1078 else
1079 *height = maxph + (2 * WIDGET_BORDER_HEIGHT +
1080 IMAGE_INSTANCE_MARGIN_WIDTH (ii)) * 2 + ph_adjust;
1081 }
1082
1083 int
1084 layout_layout (Lisp_Object image_instance,
1085 int width, int height, Lisp_Object domain)
1086 {
1087 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1088 Lisp_Object rest;
1089 Lisp_Object items = IMAGE_INSTANCE_LAYOUT_CHILDREN (ii);
1090 int x, y, maxph = 0, maxpw = 0, nitems = 0,
1091 horiz_spacing, vert_spacing, ph_adjust = 0;
1092 int gheight, gwidth;
1093
1094 /* If we are not initialized then we won't have any children. */
1095 if (!IMAGE_INSTANCE_INITIALIZED (ii))
1096 return 0;
1097
1098 /* Pick up the border text if we have one. */
1099 if (INTP (IMAGE_INSTANCE_LAYOUT_BORDER (ii)))
1100 {
1101 Lisp_Object border = XCAR (items);
1102 items = XCDR (items);
1103 image_instance_query_geometry (border, &gwidth, &gheight,
1104 IMAGE_DESIRED_GEOMETRY, domain);
1105 /* #### Really, what should this be? */
1106 XIMAGE_INSTANCE_XOFFSET (border) = 10;
1107 XIMAGE_INSTANCE_YOFFSET (border) = 0;
1108 ph_adjust = gheight / 2;
1109 IMAGE_INSTANCE_LAYOUT_BORDER (ii) = make_int (ph_adjust);
1110
1111 image_instance_layout (border, gwidth, gheight, domain);
1112 }
1113
1114 /* Flip through the items to work out how much stuff we have to display. */
1115 LIST_LOOP (rest, items)
1116 {
1117 Lisp_Object glyph = XCAR (rest);
1118
1119 image_instance_query_geometry (glyph, &gwidth, &gheight,
1120 IMAGE_DESIRED_GEOMETRY, domain);
1121 nitems ++;
1122 if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii)
1123 == LAYOUT_HORIZONTAL)
1124 {
1125 maxph = max (maxph, gheight);
1126 maxpw += gwidth;
1127 }
1128 else
1129 {
1130 maxpw = max (maxpw, gwidth);
1131 maxph += gheight;
1132 }
1133 }
1134
1135 /* work out spacing between items and bounds of the layout */
1136 if (width < maxpw)
1137 /* The user wants a smaller space than the largest item, so we
1138 just provide default spacing and will let the output routines
1139 clip.. */
1140 horiz_spacing = WIDGET_BORDER_WIDTH * 2;
1141 else if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii)
1142 == LAYOUT_HORIZONTAL)
1143 /* We have a larger area to display in so distribute the space
1144 evenly. */
1145 horiz_spacing = (width - (maxpw +
1146 IMAGE_INSTANCE_MARGIN_WIDTH (ii) * 2))
1147 / (nitems + 1);
1148 else
1149 horiz_spacing = (width - maxpw) / 2
1150 - IMAGE_INSTANCE_MARGIN_WIDTH (ii);
1151
1152 if (height < maxph)
1153 vert_spacing = WIDGET_BORDER_HEIGHT * 2;
1154 else if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii)
1155 == LAYOUT_VERTICAL)
1156 vert_spacing = (height - (maxph + ph_adjust +
1157 IMAGE_INSTANCE_MARGIN_WIDTH (ii) * 2))
1158 / (nitems + 1);
1159 else
1160 vert_spacing = (height - (maxph + ph_adjust)) / 2
1161 - IMAGE_INSTANCE_MARGIN_WIDTH (ii);
1162
1163 y = vert_spacing + ph_adjust + IMAGE_INSTANCE_MARGIN_WIDTH (ii);
1164 x = horiz_spacing + IMAGE_INSTANCE_MARGIN_WIDTH (ii);
1165
1166 /* Now flip through putting items where we want them, paying
1167 attention to justification. Make sure we don't mess with the
1168 border glyph. */
1169 LIST_LOOP (rest, items)
1170 {
1171 Lisp_Object glyph = XCAR (rest);
1172
1173 image_instance_query_geometry (glyph, &gwidth, &gheight,
1174 IMAGE_DESIRED_GEOMETRY, domain);
1175
1176 if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii)
1177 == LAYOUT_HORIZONTAL)
1178 {
1179 if (IMAGE_INSTANCE_SUBWINDOW_JUSTIFY (ii)
1180 == LAYOUT_JUSTIFY_RIGHT)
1181 y = height - (gheight + vert_spacing);
1182 if (IMAGE_INSTANCE_SUBWINDOW_JUSTIFY (ii)
1183 == LAYOUT_JUSTIFY_CENTER)
1184 y = (height - gheight) / 2;
1185 }
1186 else
1187 {
1188 if (IMAGE_INSTANCE_SUBWINDOW_JUSTIFY (ii)
1189 == LAYOUT_JUSTIFY_RIGHT)
1190 x = width - (gwidth + horiz_spacing);
1191 if (IMAGE_INSTANCE_SUBWINDOW_JUSTIFY (ii)
1192 == LAYOUT_JUSTIFY_CENTER)
1193 x = (width - gwidth) / 2;
1194 }
1195
1196 XIMAGE_INSTANCE_XOFFSET (glyph) = x;
1197 XIMAGE_INSTANCE_YOFFSET (glyph) = y;
1198
1199 if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii)
1200 == LAYOUT_HORIZONTAL)
1201 {
1202 x += (gwidth + horiz_spacing);
1203 }
1204 else
1205 {
1206 y += (gheight + vert_spacing);
1207 }
1208
1209 /* Now layout subwidgets if they require it. */
1210 image_instance_layout (glyph, gwidth, gheight, domain);
1211 }
1212 return 1;
1213 }
1214
1215 /* Layout subwindows if they are real subwindows. */
1216 static int
1217 native_layout_layout (Lisp_Object image_instance,
1218 int width, int height,
1219 Lisp_Object domain)
1220 {
1221 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance);
1222 Lisp_Object rest;
1223
1224 /* The first time this gets called, the layout will be only
1225 partially instantiated. The children get done in
1226 post_instantiate. */
1227 if (!IMAGE_INSTANCE_INITIALIZED (ii))
1228 return 0;
1229
1230 /* Defining this overrides the default layout_layout so we first have to call that to get
1231 suitable instances and values set up. */
1232 layout_layout (image_instance, width, height, domain);
1233
1234 LIST_LOOP (rest, IMAGE_INSTANCE_LAYOUT_CHILDREN (ii))
1235 {
1236 struct display_glyph_area dga;
1237 dga.xoffset = 0;
1238 dga.yoffset = 0;
1239 dga.width = IMAGE_INSTANCE_WIDTH (ii);
1240 dga.height = IMAGE_INSTANCE_HEIGHT (ii);
1241
1242 map_subwindow (XCAR (rest),
1243 IMAGE_INSTANCE_XOFFSET (ii),
1244 IMAGE_INSTANCE_YOFFSET (ii), &dga);
1245 }
1246 return 1;
1247 } 431 }
1248 432
1249 433
1250 /************************************************************************/ 434 /************************************************************************/
1251 /* initialization */ 435 /* initialization */
1258 defkeyword (&Q_height, ":height"); 442 defkeyword (&Q_height, ":height");
1259 defkeyword (&Q_width, ":width"); 443 defkeyword (&Q_width, ":width");
1260 defkeyword (&Q_properties, ":properties"); 444 defkeyword (&Q_properties, ":properties");
1261 defkeyword (&Q_items, ":items"); 445 defkeyword (&Q_items, ":items");
1262 defkeyword (&Q_image, ":image"); 446 defkeyword (&Q_image, ":image");
1263 defkeyword (&Q_text, ":text"); 447 defkeyword (&Q_percent, ":percent");
1264 defkeyword (&Q_orientation, ":orientation"); 448 defkeyword (&Q_text, "text");
1265 defkeyword (&Q_justify, ":justify"); 449 }
1266 defkeyword (&Q_border, ":border"); 450
1267 defkeyword (&Q_margin_width, ":margin-width"); 451 void
1268 452 image_instantiator_format_create_glyphs_widget (void)
1269 defsymbol (&Qetched_in, "etched-in"); 453 {
1270 defsymbol (&Qetched_out, "etched-out"); 454 #define VALID_GUI_KEYWORDS(type) \
1271 defsymbol (&Qbevel_in, "bevel-in"); 455 IIFORMAT_VALID_KEYWORD (type, Q_active, check_valid_anything); \
1272 defsymbol (&Qbevel_out, "bevel-out"); 456 IIFORMAT_VALID_KEYWORD (type, Q_suffix, check_valid_anything); \
1273 } 457 IIFORMAT_VALID_KEYWORD (type, Q_keys, check_valid_string); \
1274 458 IIFORMAT_VALID_KEYWORD (type, Q_style, check_valid_symbol); \
1275 #define VALID_GUI_KEYWORDS(type) do { \ 459 IIFORMAT_VALID_KEYWORD (type, Q_selected, check_valid_anything); \
1276 IIFORMAT_VALID_NONCOPY_KEYWORD (type, Q_active, check_valid_anything); \ 460 IIFORMAT_VALID_KEYWORD (type, Q_filter, check_valid_anything); \
1277 IIFORMAT_VALID_KEYWORD (type, Q_suffix, check_valid_anything); \ 461 IIFORMAT_VALID_KEYWORD (type, Q_config, check_valid_symbol); \
1278 IIFORMAT_VALID_KEYWORD (type, Q_keys, check_valid_string); \ 462 IIFORMAT_VALID_KEYWORD (type, Q_included, check_valid_anything); \
1279 IIFORMAT_VALID_KEYWORD (type, Q_style, check_valid_symbol); \ 463 IIFORMAT_VALID_KEYWORD (type, Q_key_sequence, check_valid_string); \
1280 IIFORMAT_VALID_NONCOPY_KEYWORD (type, Q_selected, check_valid_anything); \ 464 IIFORMAT_VALID_KEYWORD (type, Q_accelerator, check_valid_string); \
1281 IIFORMAT_VALID_KEYWORD (type, Q_filter, check_valid_anything); \ 465 IIFORMAT_VALID_KEYWORD (type, Q_label, check_valid_anything); \
1282 IIFORMAT_VALID_KEYWORD (type, Q_config, check_valid_symbol); \ 466 IIFORMAT_VALID_KEYWORD (type, Q_callback, check_valid_callback); \
1283 IIFORMAT_VALID_KEYWORD (type, Q_included, check_valid_anything); \ 467 IIFORMAT_VALID_KEYWORD (type, Q_descriptor, check_valid_string_or_vector)
1284 IIFORMAT_VALID_KEYWORD (type, Q_key_sequence, check_valid_string); \ 468
1285 IIFORMAT_VALID_KEYWORD (type, Q_accelerator, check_valid_string); \ 469 #define VALID_WIDGET_KEYWORDS(type) \
1286 IIFORMAT_VALID_KEYWORD (type, Q_label, check_valid_anything); \
1287 IIFORMAT_VALID_NONCOPY_KEYWORD (type, Q_callback, check_valid_callback); \
1288 IIFORMAT_VALID_NONCOPY_KEYWORD (type, Q_callback_ex, check_valid_callback); \
1289 IIFORMAT_VALID_NONCOPY_KEYWORD (type, Q_descriptor, check_valid_string_or_vector); \
1290 } while (0)
1291
1292 #define VALID_WIDGET_KEYWORDS(type) do { \
1293 IIFORMAT_VALID_KEYWORD (type, Q_width, check_valid_int); \ 470 IIFORMAT_VALID_KEYWORD (type, Q_width, check_valid_int); \
1294 IIFORMAT_VALID_KEYWORD (type, Q_height, check_valid_int); \ 471 IIFORMAT_VALID_KEYWORD (type, Q_height, check_valid_int); \
1295 IIFORMAT_VALID_KEYWORD (type, Q_pixel_width, check_valid_int_or_function);\ 472 IIFORMAT_VALID_KEYWORD (type, Q_pixel_width, check_valid_int); \
1296 IIFORMAT_VALID_KEYWORD (type, Q_pixel_height, check_valid_int_or_function);\ 473 IIFORMAT_VALID_KEYWORD (type, Q_pixel_height, check_valid_int); \
1297 IIFORMAT_VALID_KEYWORD (type, Q_face, check_valid_face); \ 474 IIFORMAT_VALID_KEYWORD (type, Q_face, check_valid_face)
1298 } while (0) 475
1299 476 /* we only do this for properties */
1300
1301 static void image_instantiator_widget (void)
1302 { /* we only do this for properties */
1303 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT_NO_SYM (widget, "widget"); 477 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT_NO_SYM (widget, "widget");
1304 IIFORMAT_HAS_METHOD (widget, property); 478 IIFORMAT_HAS_METHOD (widget, property);
1305 IIFORMAT_HAS_METHOD (widget, set_property); 479 IIFORMAT_HAS_METHOD (widget, set_property);
1306 IIFORMAT_HAS_METHOD (widget, query_geometry); 480
1307 IIFORMAT_HAS_METHOD (widget, layout); 481 /* widget image-instantiator types - buttons */
1308 }
1309
1310 static void image_instantiator_buttons (void)
1311 {
1312 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (button, "button"); 482 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (button, "button");
1313 IIFORMAT_HAS_SHARED_METHOD (button, validate, widget); 483 IIFORMAT_HAS_SHARED_METHOD (button, validate, widget);
1314 IIFORMAT_HAS_SHARED_METHOD (button, possible_dest_types, widget); 484 IIFORMAT_HAS_SHARED_METHOD (button, possible_dest_types, widget);
1315 IIFORMAT_HAS_SHARED_METHOD (button, instantiate, widget); 485 IIFORMAT_HAS_SHARED_METHOD (button, instantiate, widget);
1316 IIFORMAT_HAS_SHARED_METHOD (button, post_instantiate, widget);
1317 IIFORMAT_HAS_SHARED_METHOD (button, normalize, widget); 486 IIFORMAT_HAS_SHARED_METHOD (button, normalize, widget);
1318 IIFORMAT_HAS_SHARED_METHOD (button, governing_domain, subwindow); 487 IIFORMAT_VALID_KEYWORD (button, Q_image, check_valid_glyph_or_image);
1319 IIFORMAT_HAS_METHOD (button, query_geometry);
1320 IIFORMAT_VALID_KEYWORD (button,
1321 Q_image, check_valid_glyph_or_instantiator);
1322 VALID_WIDGET_KEYWORDS (button); 488 VALID_WIDGET_KEYWORDS (button);
1323 VALID_GUI_KEYWORDS (button); 489 VALID_GUI_KEYWORDS (button);
1324 } 490
1325 491 /* edit fields */
1326 static void image_instantiator_edit_fields (void) 492 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (edit, "edit");
1327 { 493 IIFORMAT_HAS_SHARED_METHOD (edit, validate, widget);
1328 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (edit_field, "edit-field"); 494 IIFORMAT_HAS_SHARED_METHOD (edit, possible_dest_types, widget);
1329 IIFORMAT_HAS_SHARED_METHOD (edit_field, validate, widget); 495 IIFORMAT_HAS_SHARED_METHOD (edit, instantiate, widget);
1330 IIFORMAT_HAS_SHARED_METHOD (edit_field, possible_dest_types, widget); 496 VALID_WIDGET_KEYWORDS (edit);
1331 IIFORMAT_HAS_SHARED_METHOD (edit_field, instantiate, widget); 497 VALID_GUI_KEYWORDS (edit);
1332 IIFORMAT_HAS_SHARED_METHOD (edit_field, post_instantiate, widget); 498
1333 IIFORMAT_HAS_SHARED_METHOD (edit_field, governing_domain, subwindow); 499 /* combo box */
1334 VALID_WIDGET_KEYWORDS (edit_field); 500 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (combo, "combo");
1335 VALID_GUI_KEYWORDS (edit_field); 501 IIFORMAT_HAS_METHOD (combo, validate);
1336 } 502 IIFORMAT_HAS_SHARED_METHOD (combo, possible_dest_types, widget);
1337 503 IIFORMAT_HAS_METHOD (combo, instantiate);
1338 static void image_instantiator_combo_box (void) 504 VALID_GUI_KEYWORDS (combo);
1339 { 505
1340 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (combo_box, "combo-box"); 506 IIFORMAT_VALID_KEYWORD (combo, Q_width, check_valid_int);
1341 IIFORMAT_HAS_METHOD (combo_box, validate); 507 IIFORMAT_VALID_KEYWORD (combo, Q_height, check_valid_int);
1342 IIFORMAT_HAS_SHARED_METHOD (combo_box, possible_dest_types, widget); 508 IIFORMAT_VALID_KEYWORD (combo, Q_pixel_width, check_valid_int);
1343 IIFORMAT_HAS_SHARED_METHOD (combo_box, governing_domain, subwindow); 509 IIFORMAT_VALID_KEYWORD (combo, Q_face, check_valid_face);
1344 510 IIFORMAT_VALID_KEYWORD (combo, Q_properties, check_valid_item_list);
1345 VALID_GUI_KEYWORDS (combo_box); 511
1346 512 /* scrollbar */
1347 IIFORMAT_VALID_KEYWORD (combo_box, Q_width, check_valid_int);
1348 IIFORMAT_VALID_KEYWORD (combo_box, Q_height, check_valid_int);
1349 IIFORMAT_VALID_KEYWORD (combo_box, Q_pixel_width, check_valid_int_or_function);
1350 IIFORMAT_VALID_KEYWORD (combo_box, Q_face, check_valid_face);
1351 IIFORMAT_VALID_KEYWORD (combo_box, Q_properties, check_valid_item_list);
1352 }
1353
1354 static void image_instantiator_scrollbar (void)
1355 {
1356 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (scrollbar, "scrollbar"); 513 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (scrollbar, "scrollbar");
1357 IIFORMAT_HAS_SHARED_METHOD (scrollbar, validate, widget); 514 IIFORMAT_HAS_SHARED_METHOD (scrollbar, validate, widget);
1358 IIFORMAT_HAS_SHARED_METHOD (scrollbar, possible_dest_types, widget); 515 IIFORMAT_HAS_SHARED_METHOD (scrollbar, possible_dest_types, widget);
1359 IIFORMAT_HAS_SHARED_METHOD (scrollbar, instantiate, widget); 516 IIFORMAT_HAS_SHARED_METHOD (scrollbar, instantiate, widget);
1360 IIFORMAT_HAS_SHARED_METHOD (scrollbar, post_instantiate, widget);
1361 IIFORMAT_HAS_SHARED_METHOD (scrollbar, governing_domain, subwindow);
1362 VALID_GUI_KEYWORDS (scrollbar); 517 VALID_GUI_KEYWORDS (scrollbar);
1363 518
1364 IIFORMAT_VALID_KEYWORD (scrollbar, Q_pixel_width, check_valid_int_or_function); 519 IIFORMAT_VALID_KEYWORD (scrollbar, Q_pixel_width, check_valid_int);
1365 IIFORMAT_VALID_KEYWORD (scrollbar, Q_pixel_height, check_valid_int_or_function); 520 IIFORMAT_VALID_KEYWORD (scrollbar, Q_pixel_height, check_valid_int);
1366 IIFORMAT_VALID_KEYWORD (scrollbar, Q_face, check_valid_face); 521 IIFORMAT_VALID_KEYWORD (scrollbar, Q_face, check_valid_face);
1367 } 522
1368 523 /* progress guage */
1369 static void image_instantiator_progress_guage (void) 524 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (progress, "progress");
1370 { 525 IIFORMAT_HAS_SHARED_METHOD (progress, validate, widget);
1371 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (progress_gauge, "progress-gauge"); 526 IIFORMAT_HAS_SHARED_METHOD (progress, possible_dest_types, widget);
1372 IIFORMAT_HAS_SHARED_METHOD (progress_gauge, validate, widget); 527 IIFORMAT_HAS_SHARED_METHOD (progress, instantiate, widget);
1373 IIFORMAT_HAS_SHARED_METHOD (progress_gauge, possible_dest_types, widget); 528 VALID_WIDGET_KEYWORDS (progress);
1374 IIFORMAT_HAS_SHARED_METHOD (progress_gauge, instantiate, widget); 529 VALID_GUI_KEYWORDS (progress);
1375 IIFORMAT_HAS_SHARED_METHOD (progress_gauge, post_instantiate, widget); 530
1376 IIFORMAT_HAS_SHARED_METHOD (progress_gauge, governing_domain, subwindow); 531 /* labels */
1377 IIFORMAT_HAS_METHOD (progress_gauge, set_property);
1378 VALID_WIDGET_KEYWORDS (progress_gauge);
1379 VALID_GUI_KEYWORDS (progress_gauge);
1380 }
1381
1382 static void image_instantiator_tree_view (void)
1383 {
1384 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (tree_view, "tree-view");
1385 IIFORMAT_HAS_SHARED_METHOD (tree_view, validate, combo_box);
1386 IIFORMAT_HAS_SHARED_METHOD (tree_view, possible_dest_types, widget);
1387 IIFORMAT_HAS_SHARED_METHOD (tree_view, instantiate, widget);
1388 IIFORMAT_HAS_SHARED_METHOD (tree_view, post_instantiate, widget);
1389 IIFORMAT_HAS_SHARED_METHOD (tree_view, governing_domain, subwindow);
1390 IIFORMAT_HAS_METHOD (tree_view, query_geometry);
1391 VALID_WIDGET_KEYWORDS (tree_view);
1392 VALID_GUI_KEYWORDS (tree_view);
1393 IIFORMAT_VALID_KEYWORD (tree_view, Q_properties, check_valid_item_list);
1394 }
1395
1396 static void image_instantiator_tab_control (void)
1397 {
1398 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (tab_control, "tab-control");
1399 IIFORMAT_HAS_SHARED_METHOD (tab_control, validate, combo_box);
1400 IIFORMAT_HAS_SHARED_METHOD (tab_control, possible_dest_types, widget);
1401 IIFORMAT_HAS_SHARED_METHOD (tab_control, instantiate, widget);
1402 IIFORMAT_HAS_SHARED_METHOD (tab_control, post_instantiate, widget);
1403 IIFORMAT_HAS_SHARED_METHOD (tab_control, governing_domain, subwindow);
1404 IIFORMAT_HAS_METHOD (tab_control, query_geometry);
1405 IIFORMAT_HAS_METHOD (tab_control, set_property);
1406 VALID_WIDGET_KEYWORDS (tab_control);
1407 VALID_GUI_KEYWORDS (tab_control);
1408 IIFORMAT_VALID_KEYWORD (tab_control, Q_orientation, check_valid_tab_orientation);
1409 IIFORMAT_VALID_KEYWORD (tab_control, Q_properties, check_valid_item_list);
1410 }
1411
1412 static void image_instantiator_labels (void)
1413 {
1414 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (label, "label"); 532 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (label, "label");
1415 IIFORMAT_HAS_SHARED_METHOD (label, possible_dest_types, widget); 533 IIFORMAT_HAS_SHARED_METHOD (label, possible_dest_types, widget);
1416 IIFORMAT_HAS_SHARED_METHOD (label, instantiate, widget); 534 IIFORMAT_HAS_SHARED_METHOD (label, instantiate, static);
1417 IIFORMAT_HAS_SHARED_METHOD (label, post_instantiate, widget);
1418 IIFORMAT_HAS_SHARED_METHOD (label, governing_domain, subwindow);
1419 VALID_WIDGET_KEYWORDS (label); 535 VALID_WIDGET_KEYWORDS (label);
1420 IIFORMAT_VALID_KEYWORD (label, Q_descriptor, check_valid_string); 536 IIFORMAT_VALID_KEYWORD (label, Q_descriptor, check_valid_string);
1421 } 537
1422 538 #if 0
1423 #define VALID_LAYOUT_KEYWORDS(layout) \ 539 /* group */
1424 VALID_WIDGET_KEYWORDS (layout); \ 540 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (group, "group");
1425 IIFORMAT_VALID_KEYWORD (layout, Q_orientation, check_valid_orientation); \ 541 IIFORMAT_HAS_SHARED_METHOD (group, possible_dest_types, widget);
1426 IIFORMAT_VALID_KEYWORD (layout, Q_justify, check_valid_justification); \ 542 IIFORMAT_HAS_METHOD (group, instantiate);
1427 IIFORMAT_VALID_KEYWORD (layout, Q_border, check_valid_border); \ 543
1428 IIFORMAT_VALID_KEYWORD (layout, Q_margin_width, check_valid_int); \ 544 IIFORMAT_VALID_KEYWORD (group, Q_width, check_valid_int);
1429 IIFORMAT_VALID_KEYWORD (layout, Q_items, \ 545 IIFORMAT_VALID_KEYWORD (group, Q_height, check_valid_int);
1430 check_valid_glyph_or_instantiator_list) 546 IIFORMAT_VALID_KEYWORD (group, Q_pixel_width, check_valid_int);
1431 547 IIFORMAT_VALID_KEYWORD (group, Q_pixel_height, check_valid_int);
1432 static void image_instantiator_layout (void) 548 IIFORMAT_VALID_KEYWORD (group, Q_face, check_valid_face);
1433 { 549 IIFORMAT_VALID_KEYWORD (group, Q_background, check_valid_string);
1434 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (layout, "layout"); 550 IIFORMAT_VALID_KEYWORD (group, Q_descriptor, check_valid_string);
1435 IIFORMAT_HAS_SHARED_METHOD (layout, possible_dest_types, widget);
1436 IIFORMAT_HAS_METHOD (layout, instantiate);
1437 IIFORMAT_HAS_METHOD (layout, post_instantiate);
1438 IIFORMAT_HAS_SHARED_METHOD (layout, governing_domain, subwindow);
1439 IIFORMAT_HAS_METHOD (layout, normalize);
1440 IIFORMAT_HAS_METHOD (layout, query_geometry);
1441 IIFORMAT_HAS_METHOD (layout, layout);
1442
1443 VALID_GUI_KEYWORDS (layout);
1444 VALID_LAYOUT_KEYWORDS (layout);
1445 }
1446
1447 static void image_instantiator_native_layout (void)
1448 {
1449 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (native_layout, "native-layout");
1450 IIFORMAT_HAS_SHARED_METHOD (native_layout, possible_dest_types, widget);
1451 IIFORMAT_HAS_SHARED_METHOD (native_layout, instantiate, layout);
1452 IIFORMAT_HAS_SHARED_METHOD (native_layout, post_instantiate, layout);
1453 IIFORMAT_HAS_METHOD (native_layout, layout);
1454 IIFORMAT_HAS_SHARED_METHOD (native_layout, governing_domain, subwindow);
1455 IIFORMAT_HAS_SHARED_METHOD (native_layout, normalize, layout);
1456 IIFORMAT_HAS_SHARED_METHOD (native_layout, query_geometry, layout);
1457 IIFORMAT_HAS_SHARED_METHOD (native_layout, layout, layout);
1458
1459 VALID_GUI_KEYWORDS (native_layout);
1460 VALID_LAYOUT_KEYWORDS (native_layout);
1461 }
1462
1463 void
1464 image_instantiator_format_create_glyphs_widget (void)
1465 {
1466 image_instantiator_widget();
1467 image_instantiator_buttons();
1468 image_instantiator_edit_fields();
1469 image_instantiator_combo_box();
1470 image_instantiator_scrollbar();
1471 image_instantiator_progress_guage();
1472 image_instantiator_tree_view();
1473 image_instantiator_tab_control();
1474 image_instantiator_labels();
1475 image_instantiator_layout();
1476 image_instantiator_native_layout();
1477 }
1478
1479 void
1480 reinit_vars_of_glyphs_widget (void)
1481 {
1482 #ifdef DEBUG_WIDGETS
1483 debug_widget_instances = 0;
1484 #endif 551 #endif
1485 } 552 }
1486 553
1487 void 554 void
1488 vars_of_glyphs_widget (void) 555 vars_of_glyphs_widget (void)
1489 { 556 {
1490 reinit_vars_of_glyphs_widget (); 557 }
1491 }