Mercurial > hg > xemacs-beta
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 } |