1 /* Widget-specific glyph objects.
2 Copyright (C) 1998, 1999, 2000 Andy Piper.
4 This file is part of XEmacs.
6 XEmacs is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with XEmacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 /* Synched up with: Not in FSF. */
23 /* written by Andy Piper <andy@xemacs.org> */
40 DEFINE_IMAGE_INSTANTIATOR_FORMAT (button);
41 DEFINE_IMAGE_INSTANTIATOR_FORMAT (combo_box);
42 Lisp_Object Qcombo_box;
43 DEFINE_IMAGE_INSTANTIATOR_FORMAT (edit_field);
44 Lisp_Object Qedit_field;
45 DEFINE_IMAGE_INSTANTIATOR_FORMAT (scrollbar);
46 Lisp_Object Qscrollbar;
47 DEFINE_IMAGE_INSTANTIATOR_FORMAT (widget);
48 DEFINE_IMAGE_INSTANTIATOR_FORMAT (label);
50 DEFINE_IMAGE_INSTANTIATOR_FORMAT (progress_gauge);
51 Lisp_Object Qprogress_gauge;
52 DEFINE_IMAGE_INSTANTIATOR_FORMAT (tree_view);
53 Lisp_Object Qtree_view;
54 DEFINE_IMAGE_INSTANTIATOR_FORMAT (tab_control);
55 Lisp_Object Qtab_control;
56 DEFINE_IMAGE_INSTANTIATOR_FORMAT (layout);
58 DEFINE_IMAGE_INSTANTIATOR_FORMAT (native_layout);
59 Lisp_Object Qnative_layout;
61 Lisp_Object Q_descriptor, Q_height, Q_width, Q_properties, Q_items;
62 Lisp_Object Q_image, Q_text, Q_orientation, Q_justify, Q_border;
63 Lisp_Object Q_margin_width;
64 Lisp_Object Qetched_in, Qetched_out, Qbevel_in, Qbevel_out;
67 int debug_widget_instances;
71 - tooltips for controls, especially buttons.
73 - lisp configurable layout.
76 /* In MS-Windows normal windows work in pixels, dialog boxes work in
77 dialog box units. Why? sigh. We could reuse the metrics for dialogs
78 if this were not the case. As it is we have to position things
79 pixel wise. I'm not even sure that X has this problem at least for
82 widget_possible_dest_types (void)
84 return IMAGE_WIDGET_MASK;
88 check_valid_glyph_or_instantiator (Lisp_Object data)
90 Lisp_Object glyph = data;
92 glyph = XSYMBOL (data)->value;
94 if (IMAGE_INSTANCEP (glyph))
95 CHECK_IMAGE_INSTANCE (glyph);
96 else if (!CONSP (glyph) && !VECTORP (glyph))
97 CHECK_BUFFER_GLYPH (glyph);
101 check_valid_orientation (Lisp_Object data)
103 if (!EQ (data, Qhorizontal)
105 !EQ (data, Qvertical))
106 signal_simple_error ("unknown orientation for layout", data);
110 check_valid_tab_orientation (Lisp_Object data)
119 signal_simple_error ("unknown orientation for tab control", data);
123 check_valid_justification (Lisp_Object data)
125 if (!EQ (data, Qleft) && !EQ (data, Qright) && !EQ (data, Qcenter))
126 signal_simple_error ("unknown justification for layout", data);
130 check_valid_border (Lisp_Object data)
132 if (!EQ (data, Qt) && !EQ (data, Qetched_in) && !EQ (data, Qetched_out)
133 && !EQ (data, Qbevel_in) && !EQ (data, Qbevel_out)
134 && !GLYPHP (data) && !VECTORP (data))
135 signal_simple_error ("unknown border style for layout", data);
139 check_valid_anything (Lisp_Object data)
144 check_valid_callback (Lisp_Object data)
147 && !COMPILED_FUNCTIONP (data)
150 signal_simple_error (":callback must be a function or expression", data);
155 check_valid_int_or_function (Lisp_Object data)
157 if (!INTP (data) && !CONSP (data))
158 signal_simple_error ("must be an integer or expresssion", data);
162 check_valid_symbol (Lisp_Object data)
168 check_valid_string_or_vector (Lisp_Object data)
170 if (!STRINGP (data) && !VECTORP (data))
171 signal_simple_error (":descriptor must be a string or a vector", data);
175 check_valid_item_list_1 (Lisp_Object items)
180 EXTERNAL_LIST_LOOP (rest, items)
182 if (STRINGP (XCAR (rest)))
183 CHECK_STRING (XCAR (rest));
184 else if (VECTORP (XCAR (rest)))
185 gui_parse_item_keywords (XCAR (rest));
186 else if (LISTP (XCAR (rest)))
187 check_valid_item_list_1 (XCAR (rest));
189 signal_simple_error ("Items must be vectors, lists or strings", items);
194 check_valid_item_list (Lisp_Object data)
198 Fcheck_valid_plist (data);
199 items = Fplist_get (data, Q_items, Qnil);
201 check_valid_item_list_1 (items);
205 check_valid_glyph_or_instantiator_list (Lisp_Object data)
210 EXTERNAL_LIST_LOOP (rest, data)
212 check_valid_glyph_or_instantiator (XCAR (rest));
217 glyph_instantiator_to_glyph (Lisp_Object sym)
219 /* This function calls lisp. */
220 Lisp_Object glyph = sym;
224 /* if we have a symbol get at the actual data */
226 glyph = XSYMBOL (glyph)->value;
229 glyph = Feval (glyph);
231 /* Be really helpful to the user. */
234 glyph = call1 (intern ("make-glyph"), glyph);
237 /* substitute the new glyph */
238 RETURN_UNGCPRO (glyph);
242 substitute_keyword_value (Lisp_Object inst, Lisp_Object key, Lisp_Object val)
245 /* substitute the new glyph */
246 for (i = 0; i < XVECTOR_LENGTH (inst); i++)
248 if (EQ (key, XVECTOR_DATA (inst)[i]))
250 XVECTOR_DATA (inst)[i+1] = val;
256 /* Wire widget property invocations to specific widgets. The problem
257 we are solving here is that when instantiators get converted to
258 instances they lose some type information (they just become
259 subwindows or widgets for example). For widgets we need to preserve
260 this type information so that we can do widget specific operations
261 on the instances. This is encoded in the widget type
262 field. widget_property gets invoked by decoding the primary type
263 (Qwidget), <widget>_property then invokes based on the secondary
264 type (Qedit_field for example). It is debatable whether we should
265 wire things in this generalised way rather than treating widgets
266 specially in image_instance_property. */
268 widget_property (Lisp_Object image_instance, Lisp_Object prop)
270 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance);
271 struct image_instantiator_methods* meths;
273 /* first see if its a general property ... */
274 if (!NILP (Fplist_member (IMAGE_INSTANCE_WIDGET_PROPS (ii), prop)))
275 return Fplist_get (IMAGE_INSTANCE_WIDGET_PROPS (ii), prop, Qnil);
277 /* .. then try device specific methods ... */
278 meths = decode_device_ii_format (image_instance_device (image_instance),
279 IMAGE_INSTANCE_WIDGET_TYPE (ii),
281 if (meths && HAS_IIFORMAT_METH_P (meths, property))
282 return IIFORMAT_METH (meths, property, (image_instance, prop));
283 /* ... then format specific methods ... */
284 meths = decode_device_ii_format (Qnil, IMAGE_INSTANCE_WIDGET_TYPE (ii),
286 if (meths && HAS_IIFORMAT_METH_P (meths, property))
287 return IIFORMAT_METH (meths, property, (image_instance, prop));
293 widget_set_property (Lisp_Object image_instance, Lisp_Object prop, Lisp_Object val)
295 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance);
296 struct image_instantiator_methods* meths;
299 /* PIck up any generic properties that we might need to keep hold
301 if (EQ (prop, Q_text))
303 IMAGE_INSTANCE_WIDGET_TEXT (ii) = val;
304 IMAGE_INSTANCE_TEXT_CHANGED (ii) = 1;
307 /* Now try device specific methods first ... */
308 meths = decode_device_ii_format (image_instance_device (image_instance),
309 IMAGE_INSTANCE_WIDGET_TYPE (ii),
311 if (meths && HAS_IIFORMAT_METH_P (meths, set_property)
314 IIFORMAT_METH (meths, set_property, (image_instance, prop, val))))
318 /* ... then format specific methods ... */
319 meths = decode_device_ii_format (Qnil, IMAGE_INSTANCE_WIDGET_TYPE (ii),
321 if (meths && HAS_IIFORMAT_METH_P (meths, set_property)
324 IIFORMAT_METH (meths, set_property, (image_instance, prop, val))))
328 /* we didn't do any device specific properties, so shove the property in our plist */
329 IMAGE_INSTANCE_WIDGET_PROPS (ii)
330 = Fplist_put (IMAGE_INSTANCE_WIDGET_PROPS (ii), prop, val);
334 /* Like the rest of redisplay, we want widget updates to occur
335 asynchronously. Thus toolkit specific methods for setting
336 properties must be called by redisplay instead of by
337 *_set_property. Thus *_set_property records the change and this
338 function actually implements it. We want to be slightly clever
339 about this however by supplying format specific functions for the
340 updates instead of lumping them all into this function. Note that
341 there is no need for format generic functions. */
343 update_widget (Lisp_Object widget)
345 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (widget);
346 struct image_instantiator_methods* meths;
348 if (!WIDGET_IMAGE_INSTANCEP (widget)
349 || EQ (IMAGE_INSTANCE_WIDGET_TYPE (ii), Qlayout)
350 || EQ (IMAGE_INSTANCE_WIDGET_TYPE (ii), Qnative_layout))
353 /* Device generic methods. We must update the widget's size as it
354 may have been changed by the the layout routines. We also do this
355 here so that explicit resizing from lisp does not result in
356 synchronous updates. */
357 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain), update_widget, (ii));
359 /* Device-format specific methods */
360 meths = decode_device_ii_format (image_instance_device (widget),
361 IMAGE_INSTANCE_WIDGET_TYPE (ii),
363 MAYBE_IIFORMAT_METH (meths, update, (widget));
365 /* Pick up the items we recorded earlier. */
366 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii))
368 IMAGE_INSTANCE_WIDGET_ITEMS (ii) =
369 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii);
370 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii) = Qnil;
374 /* Query for a widgets desired geometry. If no type specific method is
375 provided then use the widget text to calculate sizes. */
377 widget_query_geometry (Lisp_Object image_instance,
378 unsigned int* width, unsigned int* height,
379 enum image_instance_geometry disp, Lisp_Object domain)
381 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance);
382 struct image_instantiator_methods* meths;
383 Lisp_Object dynamic_width = Qnil;
384 Lisp_Object dynamic_height = Qnil;
386 /* First just set up what we already have. */
387 if (width) *width = IMAGE_INSTANCE_WIDTH (ii);
388 if (height) *height = IMAGE_INSTANCE_HEIGHT (ii);
390 if (IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii)
392 IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii))
394 /* .. then try device specific methods ... */
395 meths = decode_device_ii_format (image_instance_device (image_instance),
396 IMAGE_INSTANCE_WIDGET_TYPE (ii),
398 if (meths && HAS_IIFORMAT_METH_P (meths, query_geometry))
399 IIFORMAT_METH (meths, query_geometry, (image_instance,
404 /* ... then format specific methods ... */
405 meths = decode_device_ii_format (Qnil, IMAGE_INSTANCE_WIDGET_TYPE (ii),
407 if (meths && HAS_IIFORMAT_METH_P (meths, query_geometry))
408 IIFORMAT_METH (meths, query_geometry, (image_instance,
415 /* Then if we are allowed to resize the widget, make the
416 size the same as the text dimensions. */
417 query_string_geometry (IMAGE_INSTANCE_WIDGET_TEXT (ii),
418 IMAGE_INSTANCE_WIDGET_FACE (ii),
420 /* Adjust the size for borders. */
421 if (IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii))
422 *width = w + 2 * WIDGET_BORDER_WIDTH;
423 if (IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii))
424 *height = h + 2 * WIDGET_BORDER_HEIGHT;
427 /* Finish off with dynamic sizing. */
428 if (!NILP (IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (ii)))
430 dynamic_width = Feval (IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (ii));
431 if (INTP (dynamic_width))
432 *width = XINT (dynamic_width);
434 if (!NILP (IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (ii)))
436 dynamic_height = Feval (IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (ii));
437 if (INTP (dynamic_height))
438 *height = XINT (dynamic_height);
444 widget_layout (Lisp_Object image_instance,
445 unsigned int width, unsigned int height, Lisp_Object domain)
447 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance);
448 struct image_instantiator_methods* meths;
450 /* .. then try device specific methods ... */
451 meths = decode_device_ii_format (image_instance_device (image_instance),
452 IMAGE_INSTANCE_WIDGET_TYPE (ii),
454 if (meths && HAS_IIFORMAT_METH_P (meths, layout))
455 return IIFORMAT_METH (meths, layout, (image_instance,
456 width, height, domain));
459 /* ... then format specific methods ... */
460 meths = decode_device_ii_format (Qnil, IMAGE_INSTANCE_WIDGET_TYPE (ii),
462 if (meths && HAS_IIFORMAT_METH_P (meths, layout))
463 return IIFORMAT_METH (meths, layout, (image_instance,
464 width, height, domain));
470 widget_validate (Lisp_Object instantiator)
472 Lisp_Object desc = find_keyword_in_vector (instantiator, Q_descriptor);
475 signal_simple_error ("Must supply :descriptor", instantiator);
478 gui_parse_item_keywords (desc);
480 if (!NILP (find_keyword_in_vector (instantiator, Q_width))
481 && !NILP (find_keyword_in_vector (instantiator, Q_pixel_width)))
482 signal_simple_error ("Must supply only one of :width and :pixel-width", instantiator);
484 if (!NILP (find_keyword_in_vector (instantiator, Q_height))
485 && !NILP (find_keyword_in_vector (instantiator, Q_pixel_height)))
486 signal_simple_error ("Must supply only one of :height and :pixel-height", instantiator);
490 combo_box_validate (Lisp_Object instantiator)
492 widget_validate (instantiator);
493 if (NILP (find_keyword_in_vector (instantiator, Q_properties)))
494 signal_simple_error ("Must supply item list", instantiator);
497 /* we need to convert things like glyphs to images, eval expressions
500 widget_normalize (Lisp_Object inst, Lisp_Object console_type)
502 /* This function can call lisp */
503 Lisp_Object glyph = find_keyword_in_vector (inst, Q_image);
505 /* we need to eval glyph if its an expression, we do this for the
506 same reasons we normalize file to data. */
509 substitute_keyword_value (inst, Q_image, glyph_instantiator_to_glyph (glyph));
516 initialize_widget_image_instance (Lisp_Image_Instance *ii, Lisp_Object type)
518 /* initialize_subwindow_image_instance (ii);*/
519 IMAGE_INSTANCE_WIDGET_TYPE (ii) = type;
520 IMAGE_INSTANCE_WIDGET_PROPS (ii) = Qnil;
521 SET_IMAGE_INSTANCE_WIDGET_FACE (ii, Qnil);
522 IMAGE_INSTANCE_WIDGET_ITEMS (ii) = allocate_gui_item ();
523 IMAGE_INSTANCE_LAYOUT_CHILDREN (ii) = Qnil;
524 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii) = Qnil;
525 IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (ii) = Qnil;
526 IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (ii) = Qnil;
527 IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii) = 1;
528 IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii) = 1;
529 IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) = LAYOUT_HORIZONTAL;
530 IMAGE_INSTANCE_SUBWINDOW_JUSTIFY (ii) = 0;
533 /* Instantiate a button widget. Unfortunately instantiated widgets are
534 particular to a frame since they need to have a parent. It's not
535 like images where you just select the image into the context you
536 want to display it in and BitBlt it. So image instances can have a
537 many-to-one relationship with things you see, whereas widgets can
538 only be one-to-one (i.e. per frame) */
540 widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
541 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
542 int dest_mask, Lisp_Object domain)
544 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
545 Lisp_Object face = find_keyword_in_vector (instantiator, Q_face);
546 Lisp_Object height = find_keyword_in_vector (instantiator, Q_height);
547 Lisp_Object width = find_keyword_in_vector (instantiator, Q_width);
548 Lisp_Object pixwidth = find_keyword_in_vector (instantiator, Q_pixel_width);
549 Lisp_Object pixheight = find_keyword_in_vector (instantiator, Q_pixel_height);
550 Lisp_Object desc = find_keyword_in_vector (instantiator, Q_descriptor);
551 Lisp_Object glyph = find_keyword_in_vector (instantiator, Q_image);
552 Lisp_Object props = find_keyword_in_vector (instantiator, Q_properties);
553 Lisp_Object items = find_keyword_in_vector (instantiator, Q_items);
554 Lisp_Object orient = find_keyword_in_vector (instantiator, Q_orientation);
555 Lisp_Object mwidth = find_keyword_in_vector (instantiator, Q_margin_width);
556 int pw=0, ph=0, tw=0, th=0;
558 /* this just does pixel type sizing */
559 subwindow_instantiate (image_instance, instantiator, pointer_fg, pointer_bg,
562 if (!(dest_mask & IMAGE_WIDGET_MASK))
563 incompatible_image_types (instantiator, dest_mask, IMAGE_WIDGET_MASK);
565 initialize_widget_image_instance (ii, XVECTOR_DATA (instantiator)[0]);
567 IMAGE_INSTANCE_TYPE (ii) = IMAGE_WIDGET;
568 IMAGE_INSTANCE_WIDGET_PROPS (ii) = props;
570 /* retrieve the fg and bg colors */
572 SET_IMAGE_INSTANCE_WIDGET_FACE (ii, Fget_face (face));
574 /* retrieve the gui item information. This is easy if we have been
575 provided with a vector, more difficult if we have just been given
577 if (STRINGP (desc) || NILP (desc))
579 /* big cheat - we rely on the fact that a gui item looks like an instantiator */
580 IMAGE_INSTANCE_WIDGET_ITEMS (ii) =
581 gui_parse_item_keywords_no_errors (instantiator);
582 IMAGE_INSTANCE_WIDGET_TEXT (ii) = desc;
585 IMAGE_INSTANCE_WIDGET_ITEMS (ii) =
586 gui_parse_item_keywords_no_errors (desc);
588 /* Pick up the orientation before we do our first layout. */
589 if (EQ (orient, Qleft) || EQ (orient, Qright) || EQ (orient, Qvertical))
590 IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) = LAYOUT_VERTICAL;
592 /* parse more gui items out of the properties */
595 !EQ (IMAGE_INSTANCE_WIDGET_TYPE (ii), Qlayout)
596 && !EQ (IMAGE_INSTANCE_WIDGET_TYPE (ii), Qnative_layout))
600 items = Fplist_get (props, Q_items, Qnil);
604 IMAGE_INSTANCE_WIDGET_ITEMS (ii) =
605 Fcons (IMAGE_INSTANCE_WIDGET_ITEMS (ii),
606 parse_gui_item_tree_children (items));
610 /* Normalize size information. We now only assign sizes if the user
611 gives us some explicitly, or there are some constraints that we
612 can't change later on. Otherwise we postpone sizing until query
613 geometry gets called. */
614 if (!NILP (pixwidth)) /* pixwidth takes precendent */
616 if (!INTP (pixwidth))
617 IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (ii) = pixwidth;
620 pw = XINT (pixwidth);
621 IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii) = 0;
624 else if (!NILP (width))
627 IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii) = 0;
630 if (!NILP (pixheight))
632 if (!INTP (pixheight))
633 IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (ii) = pixheight;
636 ph = XINT (pixheight);
637 IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii) = 0;
640 else if (!NILP (height) && XINT (height) > 1)
643 IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii) = 0;
646 /* Taking the default face information when the user has specified
647 size in characters is probably as good as any since the widget
648 face is more likely to be proportional and thus give inadequate
649 results. Using character sizes can only ever be approximate
653 int charwidth, charheight;
654 default_face_font_info (domain, 0, 0, &charheight, &charwidth, 0);
658 ph = charheight * th;
661 /* for a widget with an image pick up the dimensions from that */
665 pw = glyph_width (glyph, domain) + 2 * WIDGET_BORDER_WIDTH;
667 ph = glyph_height (glyph, domain) + 2 * WIDGET_BORDER_HEIGHT;
668 IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii) = 0;
669 IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii) = 0;
672 /* Pick up the margin width. */
674 IMAGE_INSTANCE_MARGIN_WIDTH (ii) = XINT (mwidth);
676 /* Layout for the layout widget is premature at this point since the
677 children will not have been instantiated. We can't instantiate
678 them until the device instantiation method for the layout has
679 been executed. We do however want to record any specified
681 if (pw) IMAGE_INSTANCE_WIDTH (ii) = pw;
682 if (ph) IMAGE_INSTANCE_HEIGHT (ii) = ph;
686 widget_post_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
690 debug_widget_instances++;
691 stderr_out ("instantiated ");
692 debug_print (instantiator);
693 stderr_out ("%d widgets instantiated\n", debug_widget_instances);
697 /* Get the geometry of a button control. We need to adjust the size
698 depending on the type of button. */
700 button_query_geometry (Lisp_Object image_instance,
701 unsigned int* width, unsigned int* height,
702 enum image_instance_geometry disp, Lisp_Object domain)
704 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
706 query_string_geometry (IMAGE_INSTANCE_WIDGET_TEXT (ii),
707 IMAGE_INSTANCE_WIDGET_FACE (ii),
709 /* Adjust the size for borders. */
710 if (IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii))
712 *width = w + 2 * WIDGET_BORDER_WIDTH;
714 if (EQ (XGUI_ITEM (IMAGE_INSTANCE_WIDGET_ITEM (ii))->style, Qradio)
716 EQ (XGUI_ITEM (IMAGE_INSTANCE_WIDGET_ITEM (ii))->style, Qtoggle))
717 /* This is an approximation to the size of the actual button bit. */
720 if (IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii))
721 *height = h + 2 * WIDGET_BORDER_HEIGHT;
724 /* tree-view geometry - get the height right */
726 tree_view_query_geometry (Lisp_Object image_instance,
727 unsigned int* width, unsigned int* height,
728 enum image_instance_geometry disp, Lisp_Object domain)
730 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
731 Lisp_Object items = IMAGE_INSTANCE_WIDGET_ITEMS (ii);
736 /* #### what should this be. reconsider when X has tree views. */
737 query_string_geometry (IMAGE_INSTANCE_WIDGET_TEXT (ii),
738 IMAGE_INSTANCE_WIDGET_FACE (ii),
739 width, 0, 0, domain);
744 default_face_font_info (domain, 0, 0, &h, 0, 0);
745 GET_LIST_LENGTH (items, len);
750 /* Get the geometry of a tab control. This is based on the number of
751 items and text therin in the tab control. */
753 tab_control_query_geometry (Lisp_Object image_instance,
754 unsigned int* width, unsigned int* height,
755 enum image_instance_geometry disp, Lisp_Object domain)
757 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
758 Lisp_Object items = XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii));
760 unsigned int tw = 0, th = 0;
762 LIST_LOOP (rest, items)
766 query_string_geometry (XGUI_ITEM (XCAR (rest))->name,
767 IMAGE_INSTANCE_WIDGET_FACE (ii),
769 tw += 5 * WIDGET_BORDER_WIDTH; /* some bias */
771 th = max (th, h + 2 * WIDGET_BORDER_HEIGHT);
774 /* Fixup returned values depending on orientation. */
775 if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii))
777 if (height) *height = tw;
778 if (width) *width = th;
782 if (height) *height = th;
783 if (width) *width = tw;
787 /* Get the geometry of a tab control. This is based on the number of
788 items and text therin in the tab control. */
790 tab_control_set_property (Lisp_Object image_instance,
794 /* Record new items for update. *_tab_control_update will do the
796 if (EQ (prop, Q_items))
798 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance);
800 check_valid_item_list_1 (val);
802 /* Don't set the actual items since we might decide not to use
803 the new ones (because nothing has really changed). If we did
804 set them and didn't use them then we would get into whole
805 heaps of trouble when the old items get GC'd. */
806 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii) =
807 Fcons (XCAR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)),
808 parse_gui_item_tree_children (val));
809 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 1;
816 /* set the properties of a progres guage */
818 progress_gauge_set_property (Lisp_Object image_instance,
822 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
824 if (EQ (prop, Q_value))
827 #ifdef DEBUG_WIDGET_OUTPUT
828 printf ("progress gauge value set to %ld\n", XINT (val));
830 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii) =
831 copy_gui_item_tree (IMAGE_INSTANCE_WIDGET_ITEMS (ii));
832 #ifdef ERROR_CHECK_GLYPHS
833 assert (GUI_ITEMP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)));
835 if (GUI_ITEMP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)))
836 XGUI_ITEM (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii))->value = val;
838 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 1;
846 /*****************************************************************************
848 *****************************************************************************/
849 /* we need to convert things like glyphs to images, eval expressions
852 layout_normalize (Lisp_Object inst, Lisp_Object console_type)
854 /* This function can call lisp */
855 Lisp_Object items = find_keyword_in_vector (inst, Q_items);
856 Lisp_Object border = find_keyword_in_vector (inst, Q_border);
857 /* we need to eval glyph if its an expression, we do this for the
858 same reasons we normalize file to data. */
862 LIST_LOOP (rest, items)
864 /* substitute the new glyph */
865 Fsetcar (rest, glyph_instantiator_to_glyph (XCAR (rest)));
868 /* normalize the border spec. */
869 if (VECTORP (border) || CONSP (border))
871 substitute_keyword_value (inst, Q_border, glyph_instantiator_to_glyph (border));
877 layout_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
878 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
879 int dest_mask, Lisp_Object domain)
881 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
882 Lisp_Object orient = find_keyword_in_vector (instantiator, Q_orientation);
883 Lisp_Object border = find_keyword_in_vector (instantiator, Q_border);
885 /* Do widget type instantiation first. */
886 widget_instantiate (image_instance, instantiator, pointer_fg, pointer_bg,
891 IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) = LAYOUT_VERTICAL;
896 IMAGE_INSTANCE_LAYOUT_BORDER (ii) = Qetched_in;
900 IMAGE_INSTANCE_LAYOUT_BORDER (ii) = border;
902 /* We don't do the children yet as we might not have a containing
907 layout_post_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
910 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
911 Lisp_Object items = find_keyword_in_vector (instantiator, Q_items);
912 Lisp_Object rest, children = Qnil;
914 if (GLYPHP (IMAGE_INSTANCE_LAYOUT_BORDER (ii)))
916 /* We are going to be sneaky here and add the border text as
917 just another child, the layout and output routines don't know
918 this and will just display at the offsets we prescribe. */
919 Lisp_Object gii = glyph_image_instance
920 (IMAGE_INSTANCE_LAYOUT_BORDER (ii),
921 image_instance, ERROR_ME, 1);
923 if (!IMAGE_INSTANCEP (gii))
925 /* make sure we are designated as the parent. */
926 XIMAGE_INSTANCE_PARENT (gii) = image_instance;
927 children = Fcons (gii, children);
928 IMAGE_INSTANCE_LAYOUT_BORDER (ii) = make_int (0);
931 /* Pick up the sub-widgets. */
932 LIST_LOOP (rest, items)
934 /* make sure the image is instantiated */
935 Lisp_Object gii = glyph_image_instance (XCAR (rest),
936 image_instance, ERROR_ME, 1);
937 if (!IMAGE_INSTANCEP (gii))
939 /* make sure we are designated as the parent. */
940 XIMAGE_INSTANCE_PARENT (gii) = image_instance;
941 children = Fcons (gii, children);
943 /* Make sure elements in the layout are in the order the
945 children = Fnreverse (children);
946 IMAGE_INSTANCE_LAYOUT_CHILDREN (ii) = children;
949 /* Layout widget. Sizing commentary: we have a number of problems that
950 we would like to address. Some consider some of these more
951 important than others. It used to be that size information was
952 determined at instantiation time and was then fixed forever
953 after. Generally this is not what we want. Users want size to be
954 "big enough" to accommodate whatever they are trying to show and
955 this is dependent on text length, lines, font metrics etc. Of
956 course these attributes can change dynamically and so the size
957 should changed dynamically also. Only in a few limited cases should
958 the size be fixed and remain fixed. Of course this actually means
959 that we don't really want to specifiy the size *at all* for most
960 widgets - we want it to be discovered dynamically. Thus we can
961 envisage the following scenarios:
963 1. A button is sized to accommodate its text, the text changes and the
964 button should change size also.
966 2. A button is given an explicit size. Its size should never change.
968 3. Layout is put inside an area. The size of the area changes, the
969 layout should change with it.
971 4. A button grows to accommodate additional text. The whitespace
972 around it should be modified to cope with the new layout
975 5. A button grows. The area surrounding it should grow also if
978 What metrics are important?
979 1. Actual width and height.
981 2. Whether the width and height are what the widget actually wants, or
982 whether it can grow or shrink.
984 Text glyphs are particularly troublesome since their metrics depend
985 on the context in which they are being viewed. For instance they
986 can appear differently depending on the window face, frame face or
987 glyph face. In order to simplify this text glyphs can now only have
988 a glyph-face or image-instance face. All other glyphs are
989 essentially fixed in appearance. Perhaps the problem is that text
990 glyphs are cached on a device basis like most other glyphs. Instead
991 they should be cached per-window and then the instance would be
992 fixed and we wouldn't have to mess around with font metrics and the
995 /* Query the geometry of a layout widget. We assume that we can only
996 get here if the size is not already fixed. */
998 layout_query_geometry (Lisp_Object image_instance, unsigned int* width,
999 unsigned int* height, enum image_instance_geometry disp,
1002 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1003 Lisp_Object items = IMAGE_INSTANCE_LAYOUT_CHILDREN (ii), rest;
1004 int maxph = 0, maxpw = 0, nitems = 0, ph_adjust = 0;
1005 unsigned int gheight, gwidth;
1007 /* If we are not initialized then we won't have any children. */
1008 if (!IMAGE_INSTANCE_INITIALIZED (ii))
1011 /* First just set up what we already have. */
1012 if (width) *width = IMAGE_INSTANCE_WIDTH (ii);
1013 if (height) *height = IMAGE_INSTANCE_HEIGHT (ii);
1015 /* If we are not allowed to dynamically size then return. */
1016 if (!IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii)
1018 !IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii))
1021 /* Pick up the border text if we have one. */
1022 if (INTP (IMAGE_INSTANCE_LAYOUT_BORDER (ii)))
1024 image_instance_query_geometry (XCAR (items), &gwidth, &gheight, disp, domain);
1025 ph_adjust = gheight / 2;
1026 items = XCDR (items);
1029 /* Flip through the items to work out how much stuff we have to display */
1030 LIST_LOOP (rest, items)
1032 Lisp_Object glyph = XCAR (rest);
1033 image_instance_query_geometry (glyph, &gwidth, &gheight, disp, domain);
1036 if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii)
1037 == LAYOUT_HORIZONTAL)
1039 maxph = max (maxph, gheight);
1044 maxpw = max (maxpw, gwidth);
1049 /* Work out minimum space we need to fit all the items. This could
1050 have been fixed by the user. */
1051 if (!NILP (IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (ii)))
1053 Lisp_Object dynamic_width =
1054 Feval (IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (ii));
1055 if (INTP (dynamic_width))
1056 *width = XINT (dynamic_width);
1058 else if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii)
1059 == LAYOUT_HORIZONTAL)
1060 *width = maxpw + ((nitems + 1) * WIDGET_BORDER_WIDTH +
1061 IMAGE_INSTANCE_MARGIN_WIDTH (ii)) * 2;
1063 *width = maxpw + 2 * (WIDGET_BORDER_WIDTH * 2 +
1064 IMAGE_INSTANCE_MARGIN_WIDTH (ii));
1066 /* Work out vertical spacings. */
1067 if (!NILP (IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (ii)))
1069 Lisp_Object dynamic_height =
1070 Feval (IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (ii));
1071 if (INTP (dynamic_height))
1072 *height = XINT (dynamic_height);
1074 else if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii)
1076 *height = maxph + ((nitems + 1) * WIDGET_BORDER_HEIGHT +
1077 IMAGE_INSTANCE_MARGIN_WIDTH (ii)) * 2 + ph_adjust;
1079 *height = maxph + (2 * WIDGET_BORDER_HEIGHT +
1080 IMAGE_INSTANCE_MARGIN_WIDTH (ii)) * 2 + ph_adjust;
1084 layout_layout (Lisp_Object image_instance,
1085 unsigned int width, unsigned int height, Lisp_Object domain)
1087 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1089 Lisp_Object items = IMAGE_INSTANCE_LAYOUT_CHILDREN (ii);
1090 int x, y, maxph = 0, maxpw = 0, nitems = 0,
1091 horiz_spacing, vert_spacing, ph_adjust = 0;
1092 unsigned int gheight, gwidth;
1094 /* If we are not initialized then we won't have any children. */
1095 if (!IMAGE_INSTANCE_INITIALIZED (ii))
1098 /* Pick up the border text if we have one. */
1099 if (INTP (IMAGE_INSTANCE_LAYOUT_BORDER (ii)))
1101 Lisp_Object border = XCAR (items);
1102 items = XCDR (items);
1103 image_instance_query_geometry (border, &gwidth, &gheight,
1104 IMAGE_DESIRED_GEOMETRY, domain);
1105 /* #### Really, what should this be? */
1106 XIMAGE_INSTANCE_XOFFSET (border) = 10;
1107 XIMAGE_INSTANCE_YOFFSET (border) = 0;
1108 ph_adjust = gheight / 2;
1109 IMAGE_INSTANCE_LAYOUT_BORDER (ii) = make_int (ph_adjust);
1111 image_instance_layout (border, gwidth, gheight, domain);
1114 /* Flip through the items to work out how much stuff we have to display. */
1115 LIST_LOOP (rest, items)
1117 Lisp_Object glyph = XCAR (rest);
1119 image_instance_query_geometry (glyph, &gwidth, &gheight,
1120 IMAGE_DESIRED_GEOMETRY, domain);
1122 if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii)
1123 == LAYOUT_HORIZONTAL)
1125 maxph = max (maxph, gheight);
1130 maxpw = max (maxpw, gwidth);
1135 /* work out spacing between items and bounds of the layout */
1137 /* The user wants a smaller space than the largest item, so we
1138 just provide default spacing and will let the output routines
1140 horiz_spacing = WIDGET_BORDER_WIDTH * 2;
1141 else if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii)
1142 == LAYOUT_HORIZONTAL)
1143 /* We have a larger area to display in so distribute the space
1145 horiz_spacing = (width - (maxpw +
1146 IMAGE_INSTANCE_MARGIN_WIDTH (ii) * 2))
1149 horiz_spacing = (width - maxpw) / 2
1150 - IMAGE_INSTANCE_MARGIN_WIDTH (ii);
1153 vert_spacing = WIDGET_BORDER_HEIGHT * 2;
1154 else if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii)
1156 vert_spacing = (height - (maxph + ph_adjust +
1157 IMAGE_INSTANCE_MARGIN_WIDTH (ii) * 2))
1160 vert_spacing = (height - (maxph + ph_adjust)) / 2
1161 - IMAGE_INSTANCE_MARGIN_WIDTH (ii);
1163 y = vert_spacing + ph_adjust + IMAGE_INSTANCE_MARGIN_WIDTH (ii);
1164 x = horiz_spacing + IMAGE_INSTANCE_MARGIN_WIDTH (ii);
1166 /* Now flip through putting items where we want them, paying
1167 attention to justification. Make sure we don't mess with the
1169 LIST_LOOP (rest, items)
1171 Lisp_Object glyph = XCAR (rest);
1173 image_instance_query_geometry (glyph, &gwidth, &gheight,
1174 IMAGE_DESIRED_GEOMETRY, domain);
1176 if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii)
1177 == LAYOUT_HORIZONTAL)
1179 if (IMAGE_INSTANCE_SUBWINDOW_JUSTIFY (ii)
1180 == LAYOUT_JUSTIFY_RIGHT)
1181 y = height - (gheight + vert_spacing);
1182 if (IMAGE_INSTANCE_SUBWINDOW_JUSTIFY (ii)
1183 == LAYOUT_JUSTIFY_CENTER)
1184 y = (height - gheight) / 2;
1188 if (IMAGE_INSTANCE_SUBWINDOW_JUSTIFY (ii)
1189 == LAYOUT_JUSTIFY_RIGHT)
1190 x = width - (gwidth + horiz_spacing);
1191 if (IMAGE_INSTANCE_SUBWINDOW_JUSTIFY (ii)
1192 == LAYOUT_JUSTIFY_CENTER)
1193 x = (width - gwidth) / 2;
1196 XIMAGE_INSTANCE_XOFFSET (glyph) = x;
1197 XIMAGE_INSTANCE_YOFFSET (glyph) = y;
1199 if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii)
1200 == LAYOUT_HORIZONTAL)
1202 x += (gwidth + horiz_spacing);
1206 y += (gheight + vert_spacing);
1209 /* Now layout subwidgets if they require it. */
1210 image_instance_layout (glyph, gwidth, gheight, domain);
1215 /* Layout subwindows if they are real subwindows. */
1217 native_layout_layout (Lisp_Object image_instance,
1218 unsigned int width, unsigned int height,
1221 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance);
1224 /* The first time this gets called, the layout will be only
1225 partially instantiated. The children get done in
1226 post_instantiate. */
1227 if (!IMAGE_INSTANCE_INITIALIZED (ii))
1230 /* Defining this overrides the default layout_layout so we first have to call that to get
1231 suitable instances and values set up. */
1232 layout_layout (image_instance, width, height, domain);
1234 LIST_LOOP (rest, IMAGE_INSTANCE_LAYOUT_CHILDREN (ii))
1236 struct display_glyph_area dga;
1239 dga.width = IMAGE_INSTANCE_WIDTH (ii);
1240 dga.height = IMAGE_INSTANCE_HEIGHT (ii);
1242 map_subwindow (XCAR (rest),
1243 IMAGE_INSTANCE_XOFFSET (ii),
1244 IMAGE_INSTANCE_YOFFSET (ii), &dga);
1250 /************************************************************************/
1251 /* initialization */
1252 /************************************************************************/
1255 syms_of_glyphs_widget (void)
1257 defkeyword (&Q_descriptor, ":descriptor");
1258 defkeyword (&Q_height, ":height");
1259 defkeyword (&Q_width, ":width");
1260 defkeyword (&Q_properties, ":properties");
1261 defkeyword (&Q_items, ":items");
1262 defkeyword (&Q_image, ":image");
1263 defkeyword (&Q_text, ":text");
1264 defkeyword (&Q_orientation, ":orientation");
1265 defkeyword (&Q_justify, ":justify");
1266 defkeyword (&Q_border, ":border");
1267 defkeyword (&Q_margin_width, ":margin-width");
1269 defsymbol (&Qetched_in, "etched-in");
1270 defsymbol (&Qetched_out, "etched-out");
1271 defsymbol (&Qbevel_in, "bevel-in");
1272 defsymbol (&Qbevel_out, "bevel-out");
1275 #define VALID_GUI_KEYWORDS(type) do { \
1276 IIFORMAT_VALID_NONCOPY_KEYWORD (type, Q_active, check_valid_anything); \
1277 IIFORMAT_VALID_KEYWORD (type, Q_suffix, check_valid_anything); \
1278 IIFORMAT_VALID_KEYWORD (type, Q_keys, check_valid_string); \
1279 IIFORMAT_VALID_KEYWORD (type, Q_style, check_valid_symbol); \
1280 IIFORMAT_VALID_NONCOPY_KEYWORD (type, Q_selected, check_valid_anything); \
1281 IIFORMAT_VALID_KEYWORD (type, Q_filter, check_valid_anything); \
1282 IIFORMAT_VALID_KEYWORD (type, Q_config, check_valid_symbol); \
1283 IIFORMAT_VALID_KEYWORD (type, Q_included, check_valid_anything); \
1284 IIFORMAT_VALID_KEYWORD (type, Q_key_sequence, check_valid_string); \
1285 IIFORMAT_VALID_KEYWORD (type, Q_accelerator, check_valid_string); \
1286 IIFORMAT_VALID_KEYWORD (type, Q_label, check_valid_anything); \
1287 IIFORMAT_VALID_NONCOPY_KEYWORD (type, Q_callback, check_valid_callback); \
1288 IIFORMAT_VALID_NONCOPY_KEYWORD (type, Q_callback_ex, check_valid_callback); \
1289 IIFORMAT_VALID_NONCOPY_KEYWORD (type, Q_descriptor, check_valid_string_or_vector); \
1292 #define VALID_WIDGET_KEYWORDS(type) do { \
1293 IIFORMAT_VALID_KEYWORD (type, Q_width, check_valid_int); \
1294 IIFORMAT_VALID_KEYWORD (type, Q_height, check_valid_int); \
1295 IIFORMAT_VALID_KEYWORD (type, Q_pixel_width, check_valid_int_or_function);\
1296 IIFORMAT_VALID_KEYWORD (type, Q_pixel_height, check_valid_int_or_function);\
1297 IIFORMAT_VALID_KEYWORD (type, Q_face, check_valid_face); \
1301 static void image_instantiator_widget (void)
1302 { /* we only do this for properties */
1303 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT_NO_SYM (widget, "widget");
1304 IIFORMAT_HAS_METHOD (widget, property);
1305 IIFORMAT_HAS_METHOD (widget, set_property);
1306 IIFORMAT_HAS_METHOD (widget, query_geometry);
1307 IIFORMAT_HAS_METHOD (widget, layout);
1310 static void image_instantiator_buttons (void)
1312 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (button, "button");
1313 IIFORMAT_HAS_SHARED_METHOD (button, validate, widget);
1314 IIFORMAT_HAS_SHARED_METHOD (button, possible_dest_types, widget);
1315 IIFORMAT_HAS_SHARED_METHOD (button, instantiate, widget);
1316 IIFORMAT_HAS_SHARED_METHOD (button, post_instantiate, widget);
1317 IIFORMAT_HAS_SHARED_METHOD (button, normalize, widget);
1318 IIFORMAT_HAS_SHARED_METHOD (button, governing_domain, subwindow);
1319 IIFORMAT_HAS_METHOD (button, query_geometry);
1320 IIFORMAT_VALID_KEYWORD (button,
1321 Q_image, check_valid_glyph_or_instantiator);
1322 VALID_WIDGET_KEYWORDS (button);
1323 VALID_GUI_KEYWORDS (button);
1326 static void image_instantiator_edit_fields (void)
1328 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (edit_field, "edit-field");
1329 IIFORMAT_HAS_SHARED_METHOD (edit_field, validate, widget);
1330 IIFORMAT_HAS_SHARED_METHOD (edit_field, possible_dest_types, widget);
1331 IIFORMAT_HAS_SHARED_METHOD (edit_field, instantiate, widget);
1332 IIFORMAT_HAS_SHARED_METHOD (edit_field, post_instantiate, widget);
1333 IIFORMAT_HAS_SHARED_METHOD (edit_field, governing_domain, subwindow);
1334 VALID_WIDGET_KEYWORDS (edit_field);
1335 VALID_GUI_KEYWORDS (edit_field);
1338 static void image_instantiator_combo_box (void)
1340 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (combo_box, "combo-box");
1341 IIFORMAT_HAS_METHOD (combo_box, validate);
1342 IIFORMAT_HAS_SHARED_METHOD (combo_box, possible_dest_types, widget);
1343 IIFORMAT_HAS_SHARED_METHOD (combo_box, governing_domain, subwindow);
1345 VALID_GUI_KEYWORDS (combo_box);
1347 IIFORMAT_VALID_KEYWORD (combo_box, Q_width, check_valid_int);
1348 IIFORMAT_VALID_KEYWORD (combo_box, Q_height, check_valid_int);
1349 IIFORMAT_VALID_KEYWORD (combo_box, Q_pixel_width, check_valid_int_or_function);
1350 IIFORMAT_VALID_KEYWORD (combo_box, Q_face, check_valid_face);
1351 IIFORMAT_VALID_KEYWORD (combo_box, Q_properties, check_valid_item_list);
1354 static void image_instantiator_scrollbar (void)
1356 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (scrollbar, "scrollbar");
1357 IIFORMAT_HAS_SHARED_METHOD (scrollbar, validate, widget);
1358 IIFORMAT_HAS_SHARED_METHOD (scrollbar, possible_dest_types, widget);
1359 IIFORMAT_HAS_SHARED_METHOD (scrollbar, instantiate, widget);
1360 IIFORMAT_HAS_SHARED_METHOD (scrollbar, post_instantiate, widget);
1361 IIFORMAT_HAS_SHARED_METHOD (scrollbar, governing_domain, subwindow);
1362 VALID_GUI_KEYWORDS (scrollbar);
1364 IIFORMAT_VALID_KEYWORD (scrollbar, Q_pixel_width, check_valid_int_or_function);
1365 IIFORMAT_VALID_KEYWORD (scrollbar, Q_pixel_height, check_valid_int_or_function);
1366 IIFORMAT_VALID_KEYWORD (scrollbar, Q_face, check_valid_face);
1369 static void image_instantiator_progress_guage (void)
1371 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (progress_gauge, "progress-gauge");
1372 IIFORMAT_HAS_SHARED_METHOD (progress_gauge, validate, widget);
1373 IIFORMAT_HAS_SHARED_METHOD (progress_gauge, possible_dest_types, widget);
1374 IIFORMAT_HAS_SHARED_METHOD (progress_gauge, instantiate, widget);
1375 IIFORMAT_HAS_SHARED_METHOD (progress_gauge, post_instantiate, widget);
1376 IIFORMAT_HAS_SHARED_METHOD (progress_gauge, governing_domain, subwindow);
1377 IIFORMAT_HAS_METHOD (progress_gauge, set_property);
1378 VALID_WIDGET_KEYWORDS (progress_gauge);
1379 VALID_GUI_KEYWORDS (progress_gauge);
1382 static void image_instantiator_tree_view (void)
1384 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (tree_view, "tree-view");
1385 IIFORMAT_HAS_SHARED_METHOD (tree_view, validate, combo_box);
1386 IIFORMAT_HAS_SHARED_METHOD (tree_view, possible_dest_types, widget);
1387 IIFORMAT_HAS_SHARED_METHOD (tree_view, instantiate, widget);
1388 IIFORMAT_HAS_SHARED_METHOD (tree_view, post_instantiate, widget);
1389 IIFORMAT_HAS_SHARED_METHOD (tree_view, governing_domain, subwindow);
1390 IIFORMAT_HAS_METHOD (tree_view, query_geometry);
1391 VALID_WIDGET_KEYWORDS (tree_view);
1392 VALID_GUI_KEYWORDS (tree_view);
1393 IIFORMAT_VALID_KEYWORD (tree_view, Q_properties, check_valid_item_list);
1396 static void image_instantiator_tab_control (void)
1398 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (tab_control, "tab-control");
1399 IIFORMAT_HAS_SHARED_METHOD (tab_control, validate, combo_box);
1400 IIFORMAT_HAS_SHARED_METHOD (tab_control, possible_dest_types, widget);
1401 IIFORMAT_HAS_SHARED_METHOD (tab_control, instantiate, widget);
1402 IIFORMAT_HAS_SHARED_METHOD (tab_control, post_instantiate, widget);
1403 IIFORMAT_HAS_SHARED_METHOD (tab_control, governing_domain, subwindow);
1404 IIFORMAT_HAS_METHOD (tab_control, query_geometry);
1405 IIFORMAT_HAS_METHOD (tab_control, set_property);
1406 VALID_WIDGET_KEYWORDS (tab_control);
1407 VALID_GUI_KEYWORDS (tab_control);
1408 IIFORMAT_VALID_KEYWORD (tab_control, Q_orientation, check_valid_tab_orientation);
1409 IIFORMAT_VALID_KEYWORD (tab_control, Q_properties, check_valid_item_list);
1412 static void image_instantiator_labels (void)
1414 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (label, "label");
1415 IIFORMAT_HAS_SHARED_METHOD (label, possible_dest_types, widget);
1416 IIFORMAT_HAS_SHARED_METHOD (label, instantiate, widget);
1417 IIFORMAT_HAS_SHARED_METHOD (label, post_instantiate, widget);
1418 IIFORMAT_HAS_SHARED_METHOD (label, governing_domain, subwindow);
1419 VALID_WIDGET_KEYWORDS (label);
1420 IIFORMAT_VALID_KEYWORD (label, Q_descriptor, check_valid_string);
1423 #define VALID_LAYOUT_KEYWORDS(layout) \
1424 VALID_WIDGET_KEYWORDS (layout); \
1425 IIFORMAT_VALID_KEYWORD (layout, Q_orientation, check_valid_orientation); \
1426 IIFORMAT_VALID_KEYWORD (layout, Q_justify, check_valid_justification); \
1427 IIFORMAT_VALID_KEYWORD (layout, Q_border, check_valid_border); \
1428 IIFORMAT_VALID_KEYWORD (layout, Q_margin_width, check_valid_int); \
1429 IIFORMAT_VALID_KEYWORD (layout, Q_items, \
1430 check_valid_glyph_or_instantiator_list)
1432 static void image_instantiator_layout (void)
1434 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (layout, "layout");
1435 IIFORMAT_HAS_SHARED_METHOD (layout, possible_dest_types, widget);
1436 IIFORMAT_HAS_METHOD (layout, instantiate);
1437 IIFORMAT_HAS_METHOD (layout, post_instantiate);
1438 IIFORMAT_HAS_SHARED_METHOD (layout, governing_domain, subwindow);
1439 IIFORMAT_HAS_METHOD (layout, normalize);
1440 IIFORMAT_HAS_METHOD (layout, query_geometry);
1441 IIFORMAT_HAS_METHOD (layout, layout);
1443 VALID_GUI_KEYWORDS (layout);
1444 VALID_LAYOUT_KEYWORDS (layout);
1447 static void image_instantiator_native_layout (void)
1449 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (native_layout, "native-layout");
1450 IIFORMAT_HAS_SHARED_METHOD (native_layout, possible_dest_types, widget);
1451 IIFORMAT_HAS_SHARED_METHOD (native_layout, instantiate, layout);
1452 IIFORMAT_HAS_SHARED_METHOD (native_layout, post_instantiate, layout);
1453 IIFORMAT_HAS_METHOD (native_layout, layout);
1454 IIFORMAT_HAS_SHARED_METHOD (native_layout, governing_domain, subwindow);
1455 IIFORMAT_HAS_SHARED_METHOD (native_layout, normalize, layout);
1456 IIFORMAT_HAS_SHARED_METHOD (native_layout, query_geometry, layout);
1457 IIFORMAT_HAS_SHARED_METHOD (native_layout, layout, layout);
1459 VALID_GUI_KEYWORDS (native_layout);
1460 VALID_LAYOUT_KEYWORDS (native_layout);
1464 image_instantiator_format_create_glyphs_widget (void)
1466 image_instantiator_widget();
1467 image_instantiator_buttons();
1468 image_instantiator_edit_fields();
1469 image_instantiator_combo_box();
1470 image_instantiator_scrollbar();
1471 image_instantiator_progress_guage();
1472 image_instantiator_tree_view();
1473 image_instantiator_tab_control();
1474 image_instantiator_labels();
1475 image_instantiator_layout();
1476 image_instantiator_native_layout();
1480 reinit_vars_of_glyphs_widget (void)
1482 #ifdef DEBUG_WIDGETS
1483 debug_widget_instances = 0;
1488 vars_of_glyphs_widget (void)
1490 reinit_vars_of_glyphs_widget ();