Mercurial > hg > xemacs-beta
comparison src/glyphs-widget.c @ 863:42375619fa45
[xemacs-hg @ 2002-06-04 06:03:59 by andyp]
merge 21.4 windows changes, minimally tested
author | andyp |
---|---|
date | Tue, 04 Jun 2002 06:05:53 +0000 |
parents | 2b6fa2618f76 |
children | 613552a02607 |
comparison
equal
deleted
inserted
replaced
862:278c743f1578 | 863:42375619fa45 |
---|---|
1 /* Widget-specific glyph objects. | 1 /* Widget-specific glyph objects. |
2 Copyright (C) 1998, 1999, 2000 Andy Piper. | 2 Copyright (C) 1998, 1999, 2000, 2002 Andy Piper. |
3 | 3 |
4 This file is part of XEmacs. | 4 This file is part of XEmacs. |
5 | 5 |
6 XEmacs is free software; you can redistribute it and/or modify it | 6 XEmacs is free software; you can redistribute it and/or modify it |
7 under the terms of the GNU General Public License as published by the | 7 under the terms of the GNU General Public License as published by the |
59 DEFINE_IMAGE_INSTANTIATOR_FORMAT (native_layout); | 59 DEFINE_IMAGE_INSTANTIATOR_FORMAT (native_layout); |
60 Lisp_Object Qnative_layout; | 60 Lisp_Object Qnative_layout; |
61 | 61 |
62 Lisp_Object Qetched_in, Qetched_out, Qbevel_in, Qbevel_out; | 62 Lisp_Object Qetched_in, Qetched_out, Qbevel_in, Qbevel_out; |
63 Lisp_Object Qmake_glyph; | 63 Lisp_Object Qmake_glyph; |
64 Lisp_Object Vwidget_border_width; | |
65 | |
66 static int widget_border_width (Lisp_Object domain); | |
67 static int widget_spacing (Lisp_Object domain); | |
68 static void widget_query_string_geometry (Lisp_Object string, Lisp_Object face, | |
69 int *width, int *height, Lisp_Object domain); | |
64 | 70 |
65 #ifdef DEBUG_WIDGETS | 71 #ifdef DEBUG_WIDGETS |
66 int debug_widget_instances; | 72 int debug_widget_instances; |
67 #endif | 73 #endif |
68 | 74 |
117 } | 123 } |
118 | 124 |
119 static void | 125 static void |
120 check_valid_justification (Lisp_Object data) | 126 check_valid_justification (Lisp_Object data) |
121 { | 127 { |
122 if (!EQ (data, Qleft) && !EQ (data, Qright) && !EQ (data, Qcenter)) | 128 if (!EQ (data, Qleft) |
129 && | |
130 !EQ (data, Qright) | |
131 && | |
132 !EQ (data, Qtop) | |
133 && | |
134 !EQ (data, Qbottom) | |
135 && | |
136 !EQ (data, Qcenter)) | |
123 invalid_constant ("unknown justification for layout", data); | 137 invalid_constant ("unknown justification for layout", data); |
124 } | 138 } |
125 | 139 |
126 static void | 140 static void |
127 check_valid_border (Lisp_Object data) | 141 check_valid_border (Lisp_Object data) |
235 { | 249 { |
236 XVECTOR_DATA (inst)[i+1] = val; | 250 XVECTOR_DATA (inst)[i+1] = val; |
237 break; | 251 break; |
238 } | 252 } |
239 } | 253 } |
254 } | |
255 | |
256 /* Determine the border with of the widget. */ | |
257 static int | |
258 widget_border_width (Lisp_Object domain) | |
259 { | |
260 /* #### FIXME -- need to use specifiers (Vwidget_border_width) for | |
261 some portion of this. */ | |
262 if (HAS_DEVMETH_P (DOMAIN_XDEVICE (domain), | |
263 widget_border_width)) | |
264 return DEVMETH (DOMAIN_XDEVICE (domain), widget_border_width, ()); | |
265 else | |
266 return DEFAULT_WIDGET_BORDER_WIDTH; | |
267 } | |
268 | |
269 static int | |
270 widget_instance_border_width (Lisp_Image_Instance* ii) | |
271 { | |
272 return widget_border_width (IMAGE_INSTANCE_DOMAIN (ii)); | |
273 } | |
274 | |
275 /* #### Its not clear to me what the value of logical_unit_height should | |
276 be, or whether it should even depend on the current | |
277 image_instance. It really should probably only depend on the | |
278 default widget face and the domain, however you can envisage users | |
279 wanting different logical units for nested layouts - so using the | |
280 properties of the current lahyout is probably not so dumb. */ | |
281 static int | |
282 logical_unit_height (Lisp_Object text, Lisp_Object face, Lisp_Object domain) | |
283 { | |
284 int charheight = 0; | |
285 widget_query_string_geometry (text, face, | |
286 0, &charheight, domain); | |
287 /* For the returned value to be useful it needs to be big enough to | |
288 accomodate the largest single-height widget. This is currently | |
289 the edit-field. */ | |
290 return charheight + 2 * widget_spacing (domain) | |
291 + 4 * widget_border_width (domain); | |
292 } | |
293 | |
294 static int | |
295 widget_logical_unit_height (Lisp_Image_Instance* ii) | |
296 { | |
297 return logical_unit_height (NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)) ? | |
298 IMAGE_INSTANCE_NAME (ii) | |
299 : IMAGE_INSTANCE_WIDGET_TEXT (ii), | |
300 IMAGE_INSTANCE_WIDGET_FACE (ii), | |
301 IMAGE_INSTANCE_DOMAIN (ii)); | |
240 } | 302 } |
241 | 303 |
242 /* Wire widget property invocations to specific widgets. The problem | 304 /* Wire widget property invocations to specific widgets. The problem |
243 we are solving here is that when instantiators get converted to | 305 we are solving here is that when instantiators get converted to |
244 instances they lose some type information (they just become | 306 instances they lose some type information (they just become |
423 update the widget's size as it may have been changed by the the | 485 update the widget's size as it may have been changed by the the |
424 layout routines. We also do this here so that explicit resizing | 486 layout routines. We also do this here so that explicit resizing |
425 from lisp does not result in synchronous updates. Do this last so | 487 from lisp does not result in synchronous updates. Do this last so |
426 that format-specific methods have an opportunity to prevent | 488 that format-specific methods have an opportunity to prevent |
427 wholesale changes - e.g. rebuilding tabs. */ | 489 wholesale changes - e.g. rebuilding tabs. */ |
428 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain), redisplay_widget, (ii)); | 490 MAYBE_DEVMETH (DOMAIN_XDEVICE (IMAGE_INSTANCE_DOMAIN (ii)), |
491 redisplay_widget, (ii)); | |
429 | 492 |
430 /* Pick up the items we recorded earlier. */ | 493 /* Pick up the items we recorded earlier. */ |
431 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii)) | 494 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii)) |
432 { | 495 { |
433 IMAGE_INSTANCE_WIDGET_ITEMS (ii) = | 496 IMAGE_INSTANCE_WIDGET_ITEMS (ii) = |
446 DEVMETH (d, widget_query_string_geometry, | 509 DEVMETH (d, widget_query_string_geometry, |
447 (string, face, width, height, domain)); | 510 (string, face, width, height, domain)); |
448 else | 511 else |
449 query_string_geometry (string, face, width, height, 0, domain); | 512 query_string_geometry (string, face, width, height, 0, domain); |
450 | 513 |
514 } | |
515 | |
516 /* Determine the spacing of the widget. */ | |
517 static int | |
518 widget_spacing (Lisp_Object domain) | |
519 { | |
520 if (HAS_DEVMETH_P (DOMAIN_XDEVICE (domain), widget_spacing)) | |
521 return DEVMETH (DOMAIN_XDEVICE (domain), | |
522 widget_spacing, (0)); | |
523 else | |
524 return DEFAULT_WIDGET_SPACING; | |
451 } | 525 } |
452 | 526 |
453 /* Query for a widgets desired geometry. If no type specific method is | 527 /* Query for a widgets desired geometry. If no type specific method is |
454 provided then use the widget text to calculate sizes. */ | 528 provided then use the widget text to calculate sizes. */ |
455 static void | 529 static void |
496 widget_query_string_geometry (IMAGE_INSTANCE_WIDGET_TEXT (ii), | 570 widget_query_string_geometry (IMAGE_INSTANCE_WIDGET_TEXT (ii), |
497 IMAGE_INSTANCE_WIDGET_FACE (ii), | 571 IMAGE_INSTANCE_WIDGET_FACE (ii), |
498 &w, &h, domain); | 572 &w, &h, domain); |
499 /* Adjust the size for borders. */ | 573 /* Adjust the size for borders. */ |
500 if (IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii)) | 574 if (IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii)) |
501 *width = w + 2 * WIDGET_BORDER_WIDTH; | 575 *width = w + 2 * widget_instance_border_width (ii); |
502 if (IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii)) | 576 if (IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii)) |
503 *height = h + 2 * WIDGET_BORDER_HEIGHT; | 577 *height = h + 2 * widget_instance_border_width (ii); |
504 } | 578 } |
505 } | 579 } |
506 /* Finish off with dynamic sizing. */ | 580 /* Finish off with dynamic sizing. */ |
507 if (!NILP (IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (ii))) | 581 if (!NILP (IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (ii))) |
508 { | 582 { |
612 IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (ii) = Qnil; | 686 IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (ii) = Qnil; |
613 IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (ii) = Qnil; | 687 IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (ii) = Qnil; |
614 IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii) = 1; | 688 IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii) = 1; |
615 IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii) = 1; | 689 IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii) = 1; |
616 IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) = LAYOUT_HORIZONTAL; | 690 IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) = LAYOUT_HORIZONTAL; |
617 IMAGE_INSTANCE_SUBWINDOW_JUSTIFY (ii) = 0; | 691 IMAGE_INSTANCE_SUBWINDOW_H_JUSTIFY (ii) = 0; |
692 IMAGE_INSTANCE_SUBWINDOW_V_JUSTIFY (ii) = 0; | |
618 } | 693 } |
619 | 694 |
620 /* Instantiate a button widget. Unfortunately instantiated widgets are | 695 /* Instantiate a button widget. Unfortunately instantiated widgets are |
621 particular to a frame since they need to have a parent. It's not | 696 particular to a frame since they need to have a parent. It's not |
622 like images where you just select the image into the context you | 697 like images where you just select the image into the context you |
730 | 805 |
731 /* Taking the default face information when the user has specified | 806 /* Taking the default face information when the user has specified |
732 size in characters is probably as good as any since the widget | 807 size in characters is probably as good as any since the widget |
733 face is more likely to be proportional and thus give inadequate | 808 face is more likely to be proportional and thus give inadequate |
734 results. Using character sizes can only ever be approximate | 809 results. Using character sizes can only ever be approximate |
735 anyway. */ | 810 anyway. :height is measured in logical characters which take into |
736 if (tw || th) | 811 account the borders and spacing on widgets. */ |
737 { | 812 if (tw) |
738 int charwidth, charheight; | 813 { |
739 default_face_font_info (domain, 0, 0, &charheight, &charwidth, 0); | 814 int charwidth; |
740 if (tw) | 815 default_face_font_info (domain, 0, 0, 0, &charwidth, 0); |
741 pw = charwidth * tw; | 816 pw = ROUND_UP (charwidth * tw + 4 * widget_instance_border_width (ii), charwidth); |
742 if (th) | 817 } |
743 ph = charheight * th; | 818 |
819 /* For heights the widget face is more appropriate. */ | |
820 if (th == 1) | |
821 { | |
822 int charheight; | |
823 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii))) | |
824 { | |
825 widget_query_string_geometry (IMAGE_INSTANCE_WIDGET_TEXT (ii), | |
826 IMAGE_INSTANCE_WIDGET_FACE (ii), | |
827 0, &charheight, domain); | |
828 } | |
829 else | |
830 { | |
831 default_face_font_info (domain, 0, 0, &charheight, 0, 0); | |
832 } | |
833 ph = (charheight + 2 * widget_instance_border_width (ii)) * th; | |
834 } | |
835 /* For heights > 1 use logical units. */ | |
836 else if (th > 1) | |
837 { | |
838 ph = widget_logical_unit_height (ii) * th; | |
744 } | 839 } |
745 | 840 |
746 /* for a widget with an image pick up the dimensions from that */ | 841 /* for a widget with an image pick up the dimensions from that */ |
747 if (!NILP (glyph)) | 842 if (!NILP (glyph)) |
748 { | 843 { |
749 if (!pw) | 844 if (!pw) |
750 pw = glyph_width (glyph, image_instance) + 2 * WIDGET_BORDER_WIDTH; | 845 pw = glyph_width (glyph, image_instance) + 2 * widget_instance_border_width (ii); |
751 if (!ph) | 846 if (!ph) |
752 ph = glyph_height (glyph, image_instance) + 2 * WIDGET_BORDER_HEIGHT; | 847 ph = glyph_height (glyph, image_instance) + 2 * widget_instance_border_width (ii); |
753 IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii) = 0; | 848 IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii) = 0; |
754 IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii) = 0; | 849 IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii) = 0; |
755 } | 850 } |
756 | 851 |
757 /* Pick up the margin width. */ | 852 /* Pick up the margin width. */ |
794 IMAGE_INSTANCE_WIDGET_FACE (ii), | 889 IMAGE_INSTANCE_WIDGET_FACE (ii), |
795 &w, &h, domain); | 890 &w, &h, domain); |
796 /* Adjust the size for borders. */ | 891 /* Adjust the size for borders. */ |
797 if (IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii)) | 892 if (IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii)) |
798 { | 893 { |
799 *width = w + 2 * WIDGET_BORDER_WIDTH; | 894 *width = w + 3 * widget_instance_border_width (ii); |
800 | 895 |
801 if (EQ (XGUI_ITEM (IMAGE_INSTANCE_WIDGET_ITEM (ii))->style, Qradio) | 896 if (EQ (XGUI_ITEM (IMAGE_INSTANCE_WIDGET_ITEM (ii))->style, Qradio) |
802 || | 897 || |
803 EQ (XGUI_ITEM (IMAGE_INSTANCE_WIDGET_ITEM (ii))->style, Qtoggle)) | 898 EQ (XGUI_ITEM (IMAGE_INSTANCE_WIDGET_ITEM (ii))->style, Qtoggle)) |
804 /* This is an approximation to the size of the actual button bit. */ | 899 /* This is an approximation to the size of the actual button bit. */ |
805 *width += 12; | 900 *width += 12; |
806 } | 901 } |
807 if (IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii)) | 902 if (IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii)) |
808 *height = h + 2 * WIDGET_BORDER_HEIGHT; | 903 *height = h + 3 * widget_instance_border_width (ii); |
904 } | |
905 | |
906 /* Get the geometry of an edit field. */ | |
907 static void | |
908 edit_field_query_geometry (Lisp_Object image_instance, | |
909 int* width, int* height, | |
910 enum image_instance_geometry disp, Lisp_Object domain) | |
911 { | |
912 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | |
913 int w, h; | |
914 widget_query_string_geometry (IMAGE_INSTANCE_WIDGET_TEXT (ii), | |
915 IMAGE_INSTANCE_WIDGET_FACE (ii), | |
916 &w, &h, domain); | |
917 /* Adjust the size for borders. */ | |
918 if (IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii)) | |
919 *width = w + 4 * widget_instance_border_width (ii); | |
920 if (IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii)) | |
921 *height = h + 4 * widget_instance_border_width (ii); | |
809 } | 922 } |
810 | 923 |
811 /* tree-view geometry - get the height right */ | 924 /* tree-view geometry - get the height right */ |
812 static void | 925 static void |
813 tree_view_query_geometry (Lisp_Object image_instance, | 926 tree_view_query_geometry (Lisp_Object image_instance, |
826 width, 0, domain); | 939 width, 0, domain); |
827 } | 940 } |
828 if (*height) | 941 if (*height) |
829 { | 942 { |
830 int len, h; | 943 int len, h; |
944 /* #### widget face would be better here. */ | |
831 default_face_font_info (domain, 0, 0, &h, 0, 0); | 945 default_face_font_info (domain, 0, 0, &h, 0, 0); |
832 GET_LIST_LENGTH (items, len); | 946 GET_LIST_LENGTH (items, len); |
833 *height = len * h; | 947 *height = len * h; |
834 } | 948 } |
835 } | 949 } |
849 LIST_LOOP (rest, items) | 963 LIST_LOOP (rest, items) |
850 { | 964 { |
851 int h, w; | 965 int h, w; |
852 | 966 |
853 widget_query_string_geometry (XGUI_ITEM (XCAR (rest))->name, | 967 widget_query_string_geometry (XGUI_ITEM (XCAR (rest))->name, |
854 IMAGE_INSTANCE_WIDGET_FACE (ii), | 968 IMAGE_INSTANCE_WIDGET_FACE (ii), |
855 &w, &h, domain); | 969 &w, &h, domain); |
856 tw += 5 * WIDGET_BORDER_WIDTH; /* some bias */ | 970 tw += 5 * widget_instance_border_width (ii); /* some bias */ |
857 tw += w; | 971 tw += w; |
858 th = max (th, h + 2 * WIDGET_BORDER_HEIGHT); | 972 th = max (th, h + 2 * widget_instance_border_width (ii)); |
859 } | 973 } |
860 | 974 |
861 /* Fixup returned values depending on orientation. */ | 975 /* Fixup returned values depending on orientation. */ |
862 if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii)) | 976 if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii)) |
863 { | 977 { |
963 layout_update (Lisp_Object image_instance, Lisp_Object instantiator) | 1077 layout_update (Lisp_Object image_instance, Lisp_Object instantiator) |
964 { | 1078 { |
965 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | 1079 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
966 Lisp_Object items = find_keyword_in_vector (instantiator, Q_items); | 1080 Lisp_Object items = find_keyword_in_vector (instantiator, Q_items); |
967 Lisp_Object border_inst = find_keyword_in_vector (instantiator, Q_border); | 1081 Lisp_Object border_inst = find_keyword_in_vector (instantiator, Q_border); |
1082 Lisp_Object justify = find_keyword_in_vector (instantiator, Q_justify); | |
1083 Lisp_Object hjustify = find_keyword_in_vector (instantiator, Q_horizontally_justify); | |
1084 Lisp_Object vjustify = find_keyword_in_vector (instantiator, Q_vertically_justify); | |
968 Lisp_Object border = Qnil; | 1085 Lisp_Object border = Qnil; |
969 Lisp_Object children = IMAGE_INSTANCE_LAYOUT_CHILDREN (ii); | 1086 Lisp_Object children = IMAGE_INSTANCE_LAYOUT_CHILDREN (ii); |
970 int structure_changed = 0; | 1087 int structure_changed = 0; |
971 struct gcpro gcpro1; | 1088 struct gcpro gcpro1; |
972 | 1089 |
1090 /* Pick up horizontal justification, left is the default.*/ | |
1091 if (!NILP (hjustify)) | |
1092 { | |
1093 if (EQ (hjustify, Qright) || EQ (hjustify, Qbottom)) | |
1094 IMAGE_INSTANCE_SUBWINDOW_H_JUSTIFY (ii) = LAYOUT_JUSTIFY_RIGHT; | |
1095 else if (EQ (hjustify, Qcenter)) | |
1096 IMAGE_INSTANCE_SUBWINDOW_H_JUSTIFY (ii) = LAYOUT_JUSTIFY_CENTER; | |
1097 } | |
1098 /* If not set use general justification. */ | |
1099 else if (!NILP (justify)) | |
1100 { | |
1101 if (EQ (justify, Qright) || EQ (justify, Qbottom)) | |
1102 IMAGE_INSTANCE_SUBWINDOW_H_JUSTIFY (ii) = LAYOUT_JUSTIFY_RIGHT; | |
1103 else if (EQ (justify, Qcenter)) | |
1104 IMAGE_INSTANCE_SUBWINDOW_H_JUSTIFY (ii) = LAYOUT_JUSTIFY_CENTER; | |
1105 } | |
1106 | |
1107 /* Pick up vertical justification, top is the default. */ | |
1108 if (!NILP (vjustify)) | |
1109 { | |
1110 if (EQ (vjustify, Qright) || EQ (vjustify, Qbottom)) | |
1111 IMAGE_INSTANCE_SUBWINDOW_V_JUSTIFY (ii) = LAYOUT_JUSTIFY_BOTTOM; | |
1112 else if (EQ (vjustify, Qcenter)) | |
1113 IMAGE_INSTANCE_SUBWINDOW_V_JUSTIFY (ii) = LAYOUT_JUSTIFY_CENTER; | |
1114 } | |
1115 /* If not set use general justification. */ | |
1116 else if (!NILP (justify)) | |
1117 { | |
1118 if (EQ (justify, Qright) || EQ (justify, Qbottom)) | |
1119 IMAGE_INSTANCE_SUBWINDOW_V_JUSTIFY (ii) = LAYOUT_JUSTIFY_BOTTOM; | |
1120 else if (EQ (justify, Qcenter)) | |
1121 IMAGE_INSTANCE_SUBWINDOW_V_JUSTIFY (ii) = LAYOUT_JUSTIFY_CENTER; | |
1122 } | |
1123 | |
973 /* We want to avoid consing if we can. This is quite awkward because | 1124 /* We want to avoid consing if we can. This is quite awkward because |
974 we have to deal with the border as well as the items. */ | 1125 we have to deal with the border as well as the items. */ |
975 | |
976 GCPRO1 (border); | 1126 GCPRO1 (border); |
977 | 1127 |
978 if (INTP (IMAGE_INSTANCE_LAYOUT_BORDER (ii))) | 1128 if (INTP (IMAGE_INSTANCE_LAYOUT_BORDER (ii))) |
979 { | 1129 { |
980 border = XCAR (children); | 1130 border = XCAR (children); |
1122 a glyph-face or image-instance face. All other glyphs are | 1272 a glyph-face or image-instance face. All other glyphs are |
1123 essentially fixed in appearance. Perhaps the problem is that text | 1273 essentially fixed in appearance. Perhaps the problem is that text |
1124 glyphs are cached on a device basis like most other glyphs. Instead | 1274 glyphs are cached on a device basis like most other glyphs. Instead |
1125 they should be cached per-window and then the instance would be | 1275 they should be cached per-window and then the instance would be |
1126 fixed and we wouldn't have to mess around with font metrics and the | 1276 fixed and we wouldn't have to mess around with font metrics and the |
1127 rest. */ | 1277 rest. |
1278 | |
1279 Another sizing problem is alignment. We provide layout widgets that | |
1280 allow users to stack widgets vertically or horizontally. These | |
1281 layouts also allow the widgets to be centered (space evenly | |
1282 distributed), left or right justified (fixed spacing widgets | |
1283 stacked against the left, righ, top or bottom edge). Unfortunately | |
1284 this doesn't allow widgets in different layouts to be aligned. For | |
1285 instance how should the search dialog be organized for alignment? | |
1286 The obvious choice of two vertical columns does not work since the | |
1287 size of individual widgets will affect where they get placed. The | |
1288 same is true for several rows of widgets. To solve this problem we | |
1289 introduce the notion of `logical_unit_height'. This is a size | |
1290 quantity that is designed to be big enough to accomodate the | |
1291 largest `single height unit'. The function | |
1292 widget_logical_unit_height() determines the value of this in | |
1293 pixels. It is dependent on the widget face and some combination of | |
1294 spacing and border-width. Thus if users specify left or right | |
1295 justification in a vertical layout they get something in logical | |
1296 units. To simplify this the functions | |
1297 `widget-logical-to-character-height' and | |
1298 `widget-logical-to-character-width' allow conversion between | |
1299 characters and logical units so that frames can be sized | |
1300 appropriately. */ | |
1128 | 1301 |
1129 /* Query the geometry of a layout widget. We assume that we can only | 1302 /* Query the geometry of a layout widget. We assume that we can only |
1130 get here if the size is not already fixed. */ | 1303 get here if the size is not already fixed. */ |
1131 static void | 1304 static void |
1132 layout_query_geometry (Lisp_Object image_instance, int* width, | 1305 layout_query_geometry (Lisp_Object image_instance, int* width, |
1134 Lisp_Object domain) | 1307 Lisp_Object domain) |
1135 { | 1308 { |
1136 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | 1309 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
1137 Lisp_Object items = IMAGE_INSTANCE_LAYOUT_CHILDREN (ii), rest; | 1310 Lisp_Object items = IMAGE_INSTANCE_LAYOUT_CHILDREN (ii), rest; |
1138 int maxph = 0, maxpw = 0, nitems = 0, ph_adjust = 0; | 1311 int maxph = 0, maxpw = 0, nitems = 0, ph_adjust = 0; |
1139 int gheight, gwidth; | 1312 int gheight, gwidth, luh; |
1140 | 1313 |
1141 /* If we are not initialized then we won't have any children. */ | 1314 /* If we are not initialized then we won't have any children. */ |
1142 if (!IMAGE_INSTANCE_INITIALIZED (ii)) | 1315 if (!IMAGE_INSTANCE_INITIALIZED (ii)) |
1143 return; | 1316 return; |
1144 | 1317 |
1150 if (!IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii) | 1323 if (!IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii) |
1151 && | 1324 && |
1152 !IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii)) | 1325 !IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii)) |
1153 return; | 1326 return; |
1154 | 1327 |
1328 luh = widget_logical_unit_height (ii); | |
1329 | |
1155 /* Pick up the border text if we have one. */ | 1330 /* Pick up the border text if we have one. */ |
1156 if (INTP (IMAGE_INSTANCE_LAYOUT_BORDER (ii))) | 1331 if (INTP (IMAGE_INSTANCE_LAYOUT_BORDER (ii))) |
1157 { | 1332 { |
1158 glyph_query_geometry (XCAR (items), &gwidth, &gheight, disp, | 1333 glyph_query_geometry (XCAR (items), &gwidth, &gheight, disp, |
1159 image_instance); | 1334 image_instance); |
1160 ph_adjust = gheight / 2; | 1335 ph_adjust = gheight; |
1161 items = XCDR (items); | 1336 items = XCDR (items); |
1162 } | 1337 } |
1163 | 1338 |
1164 /* Flip through the items to work out how much stuff we have to display */ | 1339 /* Flip through the items to work out how much stuff we have to display */ |
1165 LIST_LOOP (rest, items) | 1340 LIST_LOOP (rest, items) |
1166 { | 1341 { |
1167 Lisp_Object glyph = XCAR (rest); | 1342 Lisp_Object glyph = XCAR (rest); |
1168 glyph_query_geometry (glyph, &gwidth, &gheight, disp, image_instance); | 1343 glyph_query_geometry (glyph, &gwidth, &gheight, disp, image_instance); |
1169 | 1344 |
1170 nitems ++; | 1345 nitems ++; |
1171 if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) | 1346 if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) == LAYOUT_HORIZONTAL) |
1172 == LAYOUT_HORIZONTAL) | |
1173 { | 1347 { |
1174 maxph = max (maxph, gheight); | 1348 maxph = max (maxph, gheight); |
1175 maxpw += gwidth; | 1349 maxpw += gwidth; |
1176 } | 1350 } |
1177 else | 1351 else |
1188 Lisp_Object dynamic_width = | 1362 Lisp_Object dynamic_width = |
1189 eval_within_redisplay (IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (ii)); | 1363 eval_within_redisplay (IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (ii)); |
1190 if (INTP (dynamic_width)) | 1364 if (INTP (dynamic_width)) |
1191 *width = XINT (dynamic_width); | 1365 *width = XINT (dynamic_width); |
1192 } | 1366 } |
1193 else if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) | 1367 else if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) == LAYOUT_HORIZONTAL) |
1194 == LAYOUT_HORIZONTAL) | 1368 { |
1195 *width = maxpw + ((nitems + 1) * WIDGET_BORDER_WIDTH + | 1369 *width = maxpw + ((nitems + 1) * widget_instance_border_width (ii) + |
1196 IMAGE_INSTANCE_MARGIN_WIDTH (ii)) * 2; | 1370 IMAGE_INSTANCE_MARGIN_WIDTH (ii)) * 2; |
1371 } | |
1197 else | 1372 else |
1198 *width = maxpw + 2 * (WIDGET_BORDER_WIDTH * 2 + | 1373 { |
1199 IMAGE_INSTANCE_MARGIN_WIDTH (ii)); | 1374 *width = maxpw + 2 * (widget_instance_border_width (ii) * 2 + |
1375 IMAGE_INSTANCE_MARGIN_WIDTH (ii)); | |
1376 } | |
1200 | 1377 |
1201 /* Work out vertical spacings. */ | 1378 /* Work out vertical spacings. */ |
1202 if (!NILP (IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (ii))) | 1379 if (!NILP (IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (ii))) |
1203 { | 1380 { |
1204 Lisp_Object dynamic_height = | 1381 Lisp_Object dynamic_height = |
1205 eval_within_redisplay (IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (ii)); | 1382 eval_within_redisplay (IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (ii)); |
1206 if (INTP (dynamic_height)) | 1383 if (INTP (dynamic_height)) |
1207 *height = XINT (dynamic_height); | 1384 *height = XINT (dynamic_height); |
1208 } | 1385 } |
1209 else if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) | 1386 else if (IMAGE_INSTANCE_SUBWINDOW_LOGICAL_LAYOUT (ii)) |
1210 == LAYOUT_VERTICAL) | 1387 { |
1211 *height = maxph + ((nitems + 1) * WIDGET_BORDER_HEIGHT + | 1388 *height = nitems * luh + ph_adjust; |
1212 IMAGE_INSTANCE_MARGIN_WIDTH (ii)) * 2 + ph_adjust; | 1389 } |
1390 else if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) == LAYOUT_VERTICAL) | |
1391 { | |
1392 *height = maxph + ((nitems + 1) * widget_instance_border_width (ii) + | |
1393 IMAGE_INSTANCE_MARGIN_WIDTH (ii)) * 2 + ph_adjust; | |
1394 } | |
1213 else | 1395 else |
1214 *height = maxph + (2 * WIDGET_BORDER_HEIGHT + | 1396 { |
1215 IMAGE_INSTANCE_MARGIN_WIDTH (ii)) * 2 + ph_adjust; | 1397 *height = maxph + (2 * widget_instance_border_width (ii) + |
1398 IMAGE_INSTANCE_MARGIN_WIDTH (ii)) * 2 + ph_adjust; | |
1399 } | |
1400 #ifdef DEBUG_WIDGET_OUTPUT | |
1401 stderr_out ("layout wants %dx%d\n", *width, *height); | |
1402 #endif | |
1216 } | 1403 } |
1217 | 1404 |
1218 int | 1405 int |
1219 layout_layout (Lisp_Object image_instance, | 1406 layout_layout (Lisp_Object image_instance, |
1220 int width, int height, int xoffset, int yoffset, | 1407 int width, int height, int xoffset, int yoffset, |
1224 Lisp_Object rest; | 1411 Lisp_Object rest; |
1225 Lisp_Object items = IMAGE_INSTANCE_LAYOUT_CHILDREN (ii); | 1412 Lisp_Object items = IMAGE_INSTANCE_LAYOUT_CHILDREN (ii); |
1226 int x, y, maxph = 0, maxpw = 0, nitems = 0, | 1413 int x, y, maxph = 0, maxpw = 0, nitems = 0, |
1227 horiz_spacing, vert_spacing, ph_adjust = 0; | 1414 horiz_spacing, vert_spacing, ph_adjust = 0; |
1228 int gheight, gwidth; | 1415 int gheight, gwidth; |
1416 /* See comments in widget_logical_unit_height(). */ | |
1417 int luh = widget_logical_unit_height (ii); | |
1229 | 1418 |
1230 /* If we are not initialized then we won't have any children. */ | 1419 /* If we are not initialized then we won't have any children. */ |
1231 if (!IMAGE_INSTANCE_INITIALIZED (ii)) | 1420 if (!IMAGE_INSTANCE_INITIALIZED (ii)) |
1232 return 0; | 1421 return 0; |
1233 | 1422 |
1234 /* Pick up the border text if we have one. */ | 1423 #ifdef DEBUG_WIDGET_OUTPUT |
1424 stderr_out ("layout output %dx%d\n", width, height); | |
1425 #endif | |
1426 | |
1427 /* Pick up the border text if we have one. A border can have the | |
1428 values Qetched_in, Qetched_out, Qbevel_in, Qbevel_out or an | |
1429 integer. The first four just affect the display properties of the | |
1430 border that is drawn. The last is an offset and implies that the | |
1431 first item in the list of subcontrols is a text control that | |
1432 should be displayed on the border. */ | |
1235 if (INTP (IMAGE_INSTANCE_LAYOUT_BORDER (ii))) | 1433 if (INTP (IMAGE_INSTANCE_LAYOUT_BORDER (ii))) |
1236 { | 1434 { |
1237 Lisp_Object border = XCAR (items); | 1435 Lisp_Object border = XCAR (items); |
1238 items = XCDR (items); | 1436 items = XCDR (items); |
1239 glyph_query_geometry (border, &gwidth, &gheight, | 1437 glyph_query_geometry (border, &gwidth, &gheight, |
1240 IMAGE_DESIRED_GEOMETRY, image_instance); | 1438 IMAGE_DESIRED_GEOMETRY, image_instance); |
1241 ph_adjust = gheight / 2; | 1439 /* The vertical offset for subsequent items is the full height |
1242 IMAGE_INSTANCE_LAYOUT_BORDER (ii) = make_int (ph_adjust); | 1440 of the border glyph. */ |
1441 ph_adjust = gheight; | |
1442 /* The offset for the border is half the glyph height. */ | |
1443 IMAGE_INSTANCE_LAYOUT_BORDER (ii) = make_int (gheight / 2); | |
1243 | 1444 |
1244 /* #### Really, what should this be? */ | 1445 /* #### Really, what should this be? */ |
1245 glyph_do_layout (border, gwidth, gheight, 10, 0, | 1446 glyph_do_layout (border, gwidth, gheight, 10, 0, |
1246 image_instance); | 1447 image_instance); |
1247 } | 1448 } |
1269 | 1470 |
1270 /* work out spacing between items and bounds of the layout */ | 1471 /* work out spacing between items and bounds of the layout */ |
1271 if (width < maxpw) | 1472 if (width < maxpw) |
1272 /* The user wants a smaller space than the largest item, so we | 1473 /* The user wants a smaller space than the largest item, so we |
1273 just provide default spacing and will let the output routines | 1474 just provide default spacing and will let the output routines |
1274 clip.. */ | 1475 clip. */ |
1275 horiz_spacing = WIDGET_BORDER_WIDTH * 2; | 1476 horiz_spacing = widget_spacing (IMAGE_INSTANCE_DOMAIN (ii)); |
1276 else if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) | 1477 else if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) |
1277 == LAYOUT_HORIZONTAL) | 1478 == LAYOUT_HORIZONTAL) |
1278 /* We have a larger area to display in so distribute the space | 1479 /* We have a larger area to display in so distribute the space |
1279 evenly. */ | 1480 evenly. */ |
1280 horiz_spacing = (width - (maxpw + | 1481 horiz_spacing = (width - (maxpw + |
1281 IMAGE_INSTANCE_MARGIN_WIDTH (ii) * 2)) | 1482 IMAGE_INSTANCE_MARGIN_WIDTH (ii) * 2)) |
1282 / (nitems + 1); | 1483 / (nitems + 1); |
1283 else | 1484 else |
1284 horiz_spacing = (width - maxpw) / 2 | 1485 horiz_spacing = (width - maxpw) / 2 |
1285 - IMAGE_INSTANCE_MARGIN_WIDTH (ii); | 1486 - IMAGE_INSTANCE_MARGIN_WIDTH (ii); |
1286 | 1487 |
1488 /* We are trying here to get widgets to line up when they are left | |
1489 or right justified vertically. This means that we must position | |
1490 widgets on logical unit boundaries, even though their height may | |
1491 be greater or less than a logical unit. In order to avoid | |
1492 clipping we need to determine how big the widget wants to be and | |
1493 then allocate as many logical units as necessary in order to | |
1494 accommodate it. */ | |
1287 if (height < maxph) | 1495 if (height < maxph) |
1288 vert_spacing = WIDGET_BORDER_HEIGHT * 2; | 1496 vert_spacing = widget_spacing (IMAGE_INSTANCE_DOMAIN (ii)) * 2; |
1289 else if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) | 1497 else if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) |
1290 == LAYOUT_VERTICAL) | 1498 == LAYOUT_VERTICAL) |
1291 vert_spacing = (height - (maxph + ph_adjust + | 1499 { |
1292 IMAGE_INSTANCE_MARGIN_WIDTH (ii) * 2)) | 1500 if (!IMAGE_INSTANCE_SUBWINDOW_V_CENTERED (ii)) |
1293 / (nitems + 1); | 1501 vert_spacing = widget_spacing (IMAGE_INSTANCE_DOMAIN (ii)) * 2; |
1502 else | |
1503 vert_spacing = (height - (maxph + ph_adjust + | |
1504 IMAGE_INSTANCE_MARGIN_WIDTH (ii) * 2)) | |
1505 / (nitems + 1); | |
1506 } | |
1294 else | 1507 else |
1295 vert_spacing = (height - (maxph + ph_adjust)) / 2 | 1508 vert_spacing = (height - (maxph + ph_adjust)) / 2 |
1296 - IMAGE_INSTANCE_MARGIN_WIDTH (ii); | 1509 - IMAGE_INSTANCE_MARGIN_WIDTH (ii); |
1297 | 1510 |
1298 y = vert_spacing + ph_adjust + IMAGE_INSTANCE_MARGIN_WIDTH (ii); | 1511 y = yoffset = vert_spacing + ph_adjust + IMAGE_INSTANCE_MARGIN_WIDTH (ii); |
1299 x = horiz_spacing + IMAGE_INSTANCE_MARGIN_WIDTH (ii); | 1512 x = horiz_spacing + IMAGE_INSTANCE_MARGIN_WIDTH (ii); |
1300 | 1513 |
1301 /* Now flip through putting items where we want them, paying | 1514 /* Now flip through putting items where we want them, paying |
1302 attention to justification. Make sure we don't mess with the | 1515 attention to justification. Make sure we don't mess with the |
1303 border glyph. */ | 1516 border glyph. */ |
1306 Lisp_Object glyph = XCAR (rest); | 1519 Lisp_Object glyph = XCAR (rest); |
1307 | 1520 |
1308 glyph_query_geometry (glyph, &gwidth, &gheight, | 1521 glyph_query_geometry (glyph, &gwidth, &gheight, |
1309 IMAGE_DESIRED_GEOMETRY, image_instance); | 1522 IMAGE_DESIRED_GEOMETRY, image_instance); |
1310 | 1523 |
1311 if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) | 1524 if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) == LAYOUT_HORIZONTAL) |
1312 == LAYOUT_HORIZONTAL) | 1525 { |
1313 { | 1526 if (IMAGE_INSTANCE_SUBWINDOW_BOTTOM_JUSTIFIED (ii)) |
1314 if (IMAGE_INSTANCE_SUBWINDOW_JUSTIFY (ii) | |
1315 == LAYOUT_JUSTIFY_RIGHT) | |
1316 y = height - (gheight + vert_spacing); | 1527 y = height - (gheight + vert_spacing); |
1317 if (IMAGE_INSTANCE_SUBWINDOW_JUSTIFY (ii) | 1528 else if (IMAGE_INSTANCE_SUBWINDOW_V_CENTERED (ii)) |
1318 == LAYOUT_JUSTIFY_CENTER) | |
1319 y = (height - gheight) / 2; | 1529 y = (height - gheight) / 2; |
1320 } | 1530 } |
1321 else | 1531 else |
1322 { | 1532 { |
1323 if (IMAGE_INSTANCE_SUBWINDOW_JUSTIFY (ii) | 1533 if (IMAGE_INSTANCE_SUBWINDOW_RIGHT_JUSTIFIED (ii)) |
1324 == LAYOUT_JUSTIFY_RIGHT) | |
1325 x = width - (gwidth + horiz_spacing); | 1534 x = width - (gwidth + horiz_spacing); |
1326 if (IMAGE_INSTANCE_SUBWINDOW_JUSTIFY (ii) | 1535 else if (IMAGE_INSTANCE_SUBWINDOW_H_CENTERED (ii)) |
1327 == LAYOUT_JUSTIFY_CENTER) | |
1328 x = (width - gwidth) / 2; | 1536 x = (width - gwidth) / 2; |
1329 } | 1537 } |
1330 | 1538 |
1331 /* Now layout subwidgets if they require it. */ | 1539 /* Now layout subwidgets if they require it. */ |
1332 glyph_do_layout (glyph, gwidth, gheight, x, y, image_instance); | 1540 glyph_do_layout (glyph, gwidth, gheight, x, y, image_instance); |
1333 | 1541 |
1334 if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) | 1542 if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) == LAYOUT_HORIZONTAL) |
1335 == LAYOUT_HORIZONTAL) | |
1336 { | 1543 { |
1337 x += (gwidth + horiz_spacing); | 1544 x += (gwidth + horiz_spacing); |
1338 } | 1545 } |
1339 else | 1546 else |
1340 { | 1547 { |
1341 y += (gheight + vert_spacing); | 1548 y += (gheight + vert_spacing); |
1549 if (!IMAGE_INSTANCE_SUBWINDOW_V_CENTERED (ii)) | |
1550 { | |
1551 /* justified, vertical layout, try and align on logical unit | |
1552 boundaries. */ | |
1553 y = ROUND_UP (y - yoffset, luh) + yoffset; | |
1554 } | |
1342 } | 1555 } |
1343 | 1556 |
1344 } | 1557 } |
1345 return 1; | 1558 return 1; |
1346 } | 1559 } |
1401 IMAGE_INSTANCE_YOFFSET (ii), &dga); | 1614 IMAGE_INSTANCE_YOFFSET (ii), &dga); |
1402 } | 1615 } |
1403 return 1; | 1616 return 1; |
1404 } | 1617 } |
1405 | 1618 |
1619 DEFUN ("widget-logical-to-character-width", Fwidget_logical_to_character_width, 1, 3, 0, /* | |
1620 Convert the width in logical widget units to characters. | |
1621 Logical widget units do not take into account adjusments made for | |
1622 layout borders, so this adjusment is approximated. | |
1623 */ | |
1624 (width, face, domain)) | |
1625 { | |
1626 int w, neww, charwidth; | |
1627 int border_width = DEFAULT_WIDGET_BORDER_WIDTH; | |
1628 | |
1629 if (NILP (domain)) | |
1630 domain = Fselected_frame (Qnil); | |
1631 | |
1632 CHECK_INT (width); | |
1633 w = XINT (width); | |
1634 | |
1635 if (HAS_DEVMETH_P (DOMAIN_XDEVICE (domain), widget_border_width)) | |
1636 border_width = DEVMETH (DOMAIN_XDEVICE (domain), widget_border_width, ()); | |
1637 | |
1638 default_face_font_info (domain, 0, 0, 0, &charwidth, 0); | |
1639 neww = ROUND_UP (charwidth * w + 4 * border_width + 2 * widget_spacing (domain), | |
1640 charwidth) / charwidth; | |
1641 | |
1642 return make_int (neww); | |
1643 } | |
1644 | |
1645 DEFUN ("widget-logical-to-character-height", Fwidget_logical_to_character_height, 1, 3, 0, /* | |
1646 Convert the height in logical widget units to characters. | |
1647 Logical widget units do not take into account adjusments made for | |
1648 layout borders, so this adjustment is approximated. | |
1649 | |
1650 If the components of a widget layout are justified to the top or the | |
1651 bottom then they are aligned in terms of `logical units'. This is a | |
1652 size quantity that is designed to be big enough to accomodate the | |
1653 largest `single height' widget. It is dependent on the widget face and | |
1654 some combination of spacing and border-width. Thus if you specify top | |
1655 or bottom justification in a vertical layout the subcontrols are laid | |
1656 out one per logical unit. This allows adjoining layouts to have | |
1657 identical alignment for their subcontrols. | |
1658 | |
1659 Since frame sizes are measured in characters, this function allows you | |
1660 to do appropriate conversion between logical units and characters. | |
1661 */ | |
1662 (height, face, domain)) | |
1663 { | |
1664 int h, newh, charheight; | |
1665 | |
1666 CHECK_INT (height); | |
1667 if (NILP (domain)) | |
1668 domain = Fselected_frame (Qnil); | |
1669 | |
1670 h = XINT (height); | |
1671 | |
1672 default_face_font_info (domain, 0, 0, &charheight, 0, 0); | |
1673 newh = ROUND_UP (logical_unit_height (Fsymbol_name (Qwidget), | |
1674 Vwidget_face, domain) * h, charheight) | |
1675 / charheight; | |
1676 | |
1677 return make_int (newh); | |
1678 } | |
1679 | |
1406 | 1680 |
1407 /************************************************************************/ | 1681 /************************************************************************/ |
1408 /* initialization */ | 1682 /* initialization */ |
1409 /************************************************************************/ | 1683 /************************************************************************/ |
1410 | 1684 |
1414 DEFSYMBOL (Qetched_in); | 1688 DEFSYMBOL (Qetched_in); |
1415 DEFSYMBOL (Qetched_out); | 1689 DEFSYMBOL (Qetched_out); |
1416 DEFSYMBOL (Qbevel_in); | 1690 DEFSYMBOL (Qbevel_in); |
1417 DEFSYMBOL (Qbevel_out); | 1691 DEFSYMBOL (Qbevel_out); |
1418 DEFSYMBOL (Qmake_glyph); | 1692 DEFSYMBOL (Qmake_glyph); |
1693 | |
1694 DEFSUBR (Fwidget_logical_to_character_height); | |
1695 DEFSUBR (Fwidget_logical_to_character_width); | |
1419 } | 1696 } |
1420 | 1697 |
1421 #define VALID_GUI_KEYWORDS(type) do { \ | 1698 #define VALID_GUI_KEYWORDS(type) do { \ |
1422 IIFORMAT_VALID_NONCOPY_KEYWORD (type, Q_active, check_valid_anything); \ | 1699 IIFORMAT_VALID_NONCOPY_KEYWORD (type, Q_active, check_valid_anything); \ |
1423 IIFORMAT_VALID_KEYWORD (type, Q_suffix, check_valid_anything); \ | 1700 IIFORMAT_VALID_KEYWORD (type, Q_suffix, check_valid_anything); \ |
1477 IIFORMAT_HAS_SHARED_METHOD (edit_field, validate, widget); | 1754 IIFORMAT_HAS_SHARED_METHOD (edit_field, validate, widget); |
1478 IIFORMAT_HAS_SHARED_METHOD (edit_field, possible_dest_types, widget); | 1755 IIFORMAT_HAS_SHARED_METHOD (edit_field, possible_dest_types, widget); |
1479 IIFORMAT_HAS_SHARED_METHOD (edit_field, instantiate, widget); | 1756 IIFORMAT_HAS_SHARED_METHOD (edit_field, instantiate, widget); |
1480 IIFORMAT_HAS_SHARED_METHOD (edit_field, post_instantiate, widget); | 1757 IIFORMAT_HAS_SHARED_METHOD (edit_field, post_instantiate, widget); |
1481 IIFORMAT_HAS_SHARED_METHOD (edit_field, governing_domain, subwindow); | 1758 IIFORMAT_HAS_SHARED_METHOD (edit_field, governing_domain, subwindow); |
1759 IIFORMAT_HAS_METHOD (edit_field, query_geometry); | |
1482 VALID_WIDGET_KEYWORDS (edit_field); | 1760 VALID_WIDGET_KEYWORDS (edit_field); |
1483 VALID_GUI_KEYWORDS (edit_field); | 1761 VALID_GUI_KEYWORDS (edit_field); |
1484 } | 1762 } |
1485 | 1763 |
1486 static void image_instantiator_combo_box (void) | 1764 static void image_instantiator_combo_box (void) |
1574 | 1852 |
1575 #define VALID_LAYOUT_KEYWORDS(layout) \ | 1853 #define VALID_LAYOUT_KEYWORDS(layout) \ |
1576 VALID_WIDGET_KEYWORDS (layout); \ | 1854 VALID_WIDGET_KEYWORDS (layout); \ |
1577 IIFORMAT_VALID_KEYWORD (layout, Q_orientation, check_valid_orientation); \ | 1855 IIFORMAT_VALID_KEYWORD (layout, Q_orientation, check_valid_orientation); \ |
1578 IIFORMAT_VALID_KEYWORD (layout, Q_justify, check_valid_justification); \ | 1856 IIFORMAT_VALID_KEYWORD (layout, Q_justify, check_valid_justification); \ |
1857 IIFORMAT_VALID_KEYWORD (layout, Q_vertically_justify, check_valid_justification); \ | |
1858 IIFORMAT_VALID_KEYWORD (layout, Q_horizontally_justify, check_valid_justification); \ | |
1579 IIFORMAT_VALID_KEYWORD (layout, Q_border, check_valid_border); \ | 1859 IIFORMAT_VALID_KEYWORD (layout, Q_border, check_valid_border); \ |
1580 IIFORMAT_VALID_KEYWORD (layout, Q_margin_width, check_valid_int); \ | 1860 IIFORMAT_VALID_KEYWORD (layout, Q_margin_width, check_valid_int); \ |
1581 IIFORMAT_VALID_KEYWORD (layout, Q_items, \ | 1861 IIFORMAT_VALID_KEYWORD (layout, Q_items, \ |
1582 check_valid_instantiator_list) | 1862 check_valid_instantiator_list) |
1583 | 1863 |
1642 void | 1922 void |
1643 vars_of_glyphs_widget (void) | 1923 vars_of_glyphs_widget (void) |
1644 { | 1924 { |
1645 reinit_vars_of_glyphs_widget (); | 1925 reinit_vars_of_glyphs_widget (); |
1646 } | 1926 } |
1927 | |
1928 | |
1929 void | |
1930 specifier_vars_of_glyphs_widget (void) | |
1931 { | |
1932 DEFVAR_SPECIFIER ("widget-border-width", | |
1933 &Vwidget_border_width /* | |
1934 *Border width of widgets. | |
1935 This is a specifier; use `set-specifier' to change it. | |
1936 */ ); | |
1937 Vwidget_border_width = Fmake_specifier (Qnatnum); | |
1938 } |