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