1 /* Widget-specific glyph objects.
2 Copyright (C) 1998 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. */
38 DEFINE_IMAGE_INSTANTIATOR_FORMAT (button);
39 DEFINE_IMAGE_INSTANTIATOR_FORMAT (combo);
41 DEFINE_IMAGE_INSTANTIATOR_FORMAT (edit);
43 DEFINE_IMAGE_INSTANTIATOR_FORMAT (scrollbar);
44 Lisp_Object Qscrollbar;
45 DEFINE_IMAGE_INSTANTIATOR_FORMAT (widget);
47 DEFINE_IMAGE_INSTANTIATOR_FORMAT (group);
50 DEFINE_IMAGE_INSTANTIATOR_FORMAT (label);
53 Lisp_Object Q_descriptor, Q_height, Q_width, Q_properties, Q_items;
55 #define WIDGET_BORDER_HEIGHT 2
56 #define WIDGET_BORDER_WIDTH 4
59 - more complex controls.
60 - tooltips for controls.
64 /* In windows normal windows work in pixels, dialog boxes work in
65 dialog box units. Why? sigh. We could reuse the metrics for dialogs
66 if this were not the case. As it is we have to position things
67 pixel wise. I'm not even sure that X has this problem at least for
70 widget_face_font_info (Lisp_Object domain, Lisp_Object face,
71 int *height, int *width)
73 Lisp_Object font_instance = FACE_FONT (face, domain, Vcharset_ascii);
76 *height = XFONT_INSTANCE (font_instance)->height;
78 *width = XFONT_INSTANCE (font_instance)->width;
84 widget_text_to_pixel_conversion (Lisp_Object domain, Lisp_Object face,
86 int* height, int* width)
89 widget_face_font_info (domain, face, &ch, &cw);
91 *height = th * (ch + 2 * WIDGET_BORDER_HEIGHT);
93 *width = tw * cw + 2 * WIDGET_BORDER_WIDTH;
97 widget_possible_dest_types (void)
99 return IMAGE_WIDGET_MASK;
102 #if 0 /* currently unused */
104 check_valid_glyph (Lisp_Object data)
107 CHECK_BUFFER_GLYPH (XSYMBOL (data)->value);
109 CHECK_BUFFER_GLYPH (data);
111 #endif /* currently unused */
114 check_valid_item_list (Lisp_Object data)
118 Fcheck_valid_plist (data);
120 items = Fplist_get (data, Q_items, Qnil);
123 EXTERNAL_LIST_LOOP (rest, items)
125 CHECK_STRING (XCAR (rest));
129 /* wire widget property invocations to specific widgets ... The
130 problem we are solving here is that when instantiators get converted
131 to instances they lose some type information (they just become
132 subwindows or widgets for example). For widgets we need to preserve
133 this type information so that we can do widget specific operations on
134 the instances. This is encoded in the widget type
135 field. widget_property gets invoked by decoding the primary type
136 (Qwidget), widget property then invokes based on the secondary type
137 (Qedit for example). It is debatable that we should wire things in this
138 generalised way rather than treating widgets specially in
139 image_instance_property. */
141 widget_property (Lisp_Object image_instance, Lisp_Object prop)
143 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance);
144 struct image_instantiator_methods* meths;
146 /* first see if its a general property ... */
147 if (!NILP (Fplist_member (IMAGE_INSTANCE_WIDGET_PROPS (ii), prop)))
148 return Fplist_get (IMAGE_INSTANCE_WIDGET_PROPS (ii), prop, Qnil);
150 /* .. then try device specific methods ... */
151 meths = decode_device_ii_format (IMAGE_INSTANCE_DEVICE (ii),
152 IMAGE_INSTANCE_WIDGET_TYPE (ii),
154 if (meths && HAS_IIFORMAT_METH_P (meths, property))
155 return IIFORMAT_METH (meths, property, (image_instance, prop));
156 /* ... then format specific methods ... */
157 meths = decode_device_ii_format (Qnil, IMAGE_INSTANCE_WIDGET_TYPE (ii),
159 if (meths && HAS_IIFORMAT_METH_P (meths, property))
160 return IIFORMAT_METH (meths, property, (image_instance, prop));
166 widget_set_property (Lisp_Object image_instance, Lisp_Object prop, Lisp_Object val)
168 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance);
169 struct image_instantiator_methods* meths;
172 /* try device specific methods first ... */
173 meths = decode_device_ii_format (IMAGE_INSTANCE_DEVICE (ii),
174 IMAGE_INSTANCE_WIDGET_TYPE (ii),
176 if (meths && HAS_IIFORMAT_METH_P (meths, set_property)
179 IIFORMAT_METH (meths, set_property, (image_instance, prop, val))))
183 /* ... then format specific methods ... */
184 meths = decode_device_ii_format (Qnil, IMAGE_INSTANCE_WIDGET_TYPE (ii),
186 if (meths && HAS_IIFORMAT_METH_P (meths, set_property)
189 IIFORMAT_METH (meths, set_property, (image_instance, prop, val))))
193 /* we didn't do any device specific properties, so shove the property in our plist */
194 IMAGE_INSTANCE_WIDGET_PROPS (ii)
195 = Fplist_put (IMAGE_INSTANCE_WIDGET_PROPS (ii), prop, val);
200 widget_validate (Lisp_Object instantiator)
202 Lisp_Object desc = find_keyword_in_vector (instantiator, Q_descriptor);
205 signal_simple_error ("Must supply :descriptor", instantiator);
207 gui_parse_item_keywords (desc, &gui);
209 if (!NILP (find_keyword_in_vector (instantiator, Q_width))
210 && !NILP (find_keyword_in_vector (instantiator, Q_pixel_width)))
211 signal_simple_error ("Must supply only one of :width and :pixel-width", instantiator);
213 if (!NILP (find_keyword_in_vector (instantiator, Q_height))
214 && !NILP (find_keyword_in_vector (instantiator, Q_pixel_height)))
215 signal_simple_error ("Must supply only one of :height and :pixel-height", instantiator);
219 combo_validate (Lisp_Object instantiator)
221 widget_validate (instantiator);
222 if (NILP (find_keyword_in_vector (instantiator, Q_properties)))
223 signal_simple_error ("Must supply item list", instantiator);
227 initialize_widget_image_instance (struct Lisp_Image_Instance *ii, Lisp_Object type)
229 /* initialize_subwindow_image_instance (ii);*/
230 IMAGE_INSTANCE_WIDGET_TYPE (ii) = type;
231 IMAGE_INSTANCE_WIDGET_PROPS (ii) = Qnil;
232 IMAGE_INSTANCE_WIDGET_FACE (ii) = Vwidget_face;
233 gui_item_init (&IMAGE_INSTANCE_WIDGET_ITEM (ii));
236 /* Instantiate a button widget. Unfortunately instantiated widgets are
237 particular to a frame since they need to have a parent. It's not
238 like images where you just select the image into the context you
239 want to display it in and BitBlt it. So images instances can have a
240 many-to-one relationship with things you see, whereas widgets can
241 only be one-to-one (i.e. per frame) */
243 widget_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator,
244 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
245 int dest_mask, Lisp_Object domain, int default_textheight,
246 int default_pixheight)
248 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
249 struct gui_item* pgui = &IMAGE_INSTANCE_WIDGET_ITEM (ii);
250 Lisp_Object face = find_keyword_in_vector (instantiator, Q_face);
251 Lisp_Object height = find_keyword_in_vector (instantiator, Q_height);
252 Lisp_Object width = find_keyword_in_vector (instantiator, Q_width);
253 Lisp_Object pixwidth = find_keyword_in_vector (instantiator, Q_pixel_width);
254 Lisp_Object pixheight = find_keyword_in_vector (instantiator, Q_pixel_height);
255 Lisp_Object desc = find_keyword_in_vector (instantiator, Q_descriptor);
256 int pw=0, ph=0, tw=0, th=0;
258 /* this just does pixel type sizing */
259 subwindow_instantiate (image_instance, instantiator, pointer_fg, pointer_bg,
262 if (!(dest_mask & IMAGE_WIDGET_MASK))
263 incompatible_image_types (instantiator, dest_mask, IMAGE_WIDGET_MASK);
265 initialize_widget_image_instance (ii, XVECTOR_DATA (instantiator)[0]);
267 /* retrieve the fg and bg colors */
269 IMAGE_INSTANCE_WIDGET_FACE (ii) = Fget_face (face);
271 /* data items for some widgets */
272 IMAGE_INSTANCE_WIDGET_PROPS (ii) =
273 find_keyword_in_vector (instantiator, Q_properties);
275 /* retrieve the gui item information */
276 if (STRINGP (desc) || NILP (desc))
277 IMAGE_INSTANCE_WIDGET_TEXT (ii) = desc;
279 gui_parse_item_keywords (find_keyword_in_vector (instantiator, Q_descriptor),
282 /* normalize size information */
287 if (!NILP (pixwidth))
288 pw = XINT (pixwidth);
289 if (!NILP (pixheight))
290 ph = XINT (pixheight);
292 if (!tw && !pw && !NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
293 tw = XSTRING_LENGTH (IMAGE_INSTANCE_WIDGET_TEXT (ii));
296 if (default_textheight)
297 th = default_textheight;
298 else if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
301 ph = default_pixheight;
304 if (tw !=0 || th !=0)
305 widget_text_to_pixel_conversion (domain,
306 IMAGE_INSTANCE_WIDGET_FACE (ii),
307 th, tw, th ? &ph : 0, tw ? &pw : 0);
309 IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii) = pw;
310 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii) = ph;
314 widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
315 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
316 int dest_mask, Lisp_Object domain)
318 widget_instantiate_1 (image_instance, instantiator, pointer_fg,
319 pointer_bg, dest_mask, domain, 1, 0);
323 combo_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
324 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
325 int dest_mask, Lisp_Object domain)
327 Lisp_Object data = Fplist_get (find_keyword_in_vector (instantiator, Q_properties),
330 GET_LIST_LENGTH (data, len);
331 widget_instantiate_1 (image_instance, instantiator, pointer_fg,
332 pointer_bg, dest_mask, domain, len + 1, 0);
335 /* Instantiate a static control */
337 static_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
338 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
339 int dest_mask, Lisp_Object domain)
341 widget_instantiate_1 (image_instance, instantiator, pointer_fg,
342 pointer_bg, dest_mask, domain, 0, 4);
346 /************************************************************************/
348 /************************************************************************/
351 syms_of_glyphs_widget (void)
353 defkeyword (&Q_descriptor, ":descriptor");
354 defkeyword (&Q_height, ":height");
355 defkeyword (&Q_width, ":width");
356 defkeyword (&Q_properties, ":properties");
357 defkeyword (&Q_items, ":items");
361 image_instantiator_format_create_glyphs_widget (void)
363 /* we only do this for properties */
364 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT_NO_SYM (widget, "widget");
365 IIFORMAT_HAS_METHOD (widget, property);
366 IIFORMAT_HAS_METHOD (widget, set_property);
368 /* widget image-instantiator types - buttons */
369 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (button, "button");
370 IIFORMAT_HAS_SHARED_METHOD (button, validate, widget);
371 IIFORMAT_HAS_SHARED_METHOD (button, possible_dest_types, widget);
372 IIFORMAT_HAS_SHARED_METHOD (button, instantiate, widget);
374 IIFORMAT_VALID_KEYWORD (button, Q_width, check_valid_int);
375 IIFORMAT_VALID_KEYWORD (button, Q_height, check_valid_int);
376 IIFORMAT_VALID_KEYWORD (button, Q_pixel_width, check_valid_int);
377 IIFORMAT_VALID_KEYWORD (button, Q_pixel_height, check_valid_int);
378 IIFORMAT_VALID_KEYWORD (button, Q_face, check_valid_face);
379 IIFORMAT_VALID_KEYWORD (button, Q_descriptor, check_valid_vector);
381 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (edit, "edit");
382 IIFORMAT_HAS_SHARED_METHOD (edit, validate, widget);
383 IIFORMAT_HAS_SHARED_METHOD (edit, possible_dest_types, widget);
384 IIFORMAT_HAS_SHARED_METHOD (edit, instantiate, widget);
386 IIFORMAT_VALID_KEYWORD (edit, Q_width, check_valid_int);
387 IIFORMAT_VALID_KEYWORD (edit, Q_height, check_valid_int);
388 IIFORMAT_VALID_KEYWORD (edit, Q_pixel_width, check_valid_int);
389 IIFORMAT_VALID_KEYWORD (edit, Q_pixel_height, check_valid_int);
390 IIFORMAT_VALID_KEYWORD (edit, Q_face, check_valid_face);
391 IIFORMAT_VALID_KEYWORD (edit, Q_descriptor, check_valid_vector);
393 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (combo, "combo");
394 IIFORMAT_HAS_METHOD (combo, validate);
395 IIFORMAT_HAS_SHARED_METHOD (combo, possible_dest_types, widget);
396 IIFORMAT_HAS_METHOD (combo, instantiate);
398 IIFORMAT_VALID_KEYWORD (combo, Q_width, check_valid_int);
399 IIFORMAT_VALID_KEYWORD (combo, Q_height, check_valid_int);
400 IIFORMAT_VALID_KEYWORD (combo, Q_pixel_width, check_valid_int);
401 IIFORMAT_VALID_KEYWORD (combo, Q_face, check_valid_face);
402 IIFORMAT_VALID_KEYWORD (combo, Q_descriptor, check_valid_vector);
403 IIFORMAT_VALID_KEYWORD (combo, Q_properties, check_valid_item_list);
405 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (scrollbar, "scrollbar");
406 IIFORMAT_HAS_SHARED_METHOD (scrollbar, validate, widget);
407 IIFORMAT_HAS_SHARED_METHOD (scrollbar, possible_dest_types, widget);
408 IIFORMAT_HAS_SHARED_METHOD (scrollbar, instantiate, widget);
410 IIFORMAT_VALID_KEYWORD (scrollbar, Q_pixel_width, check_valid_int);
411 IIFORMAT_VALID_KEYWORD (scrollbar, Q_pixel_height, check_valid_int);
412 IIFORMAT_VALID_KEYWORD (scrollbar, Q_face, check_valid_face);
413 IIFORMAT_VALID_KEYWORD (scrollbar, Q_descriptor, check_valid_vector);
415 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (label, "label");
416 IIFORMAT_HAS_SHARED_METHOD (label, possible_dest_types, widget);
417 IIFORMAT_HAS_SHARED_METHOD (label, instantiate, static);
419 IIFORMAT_VALID_KEYWORD (label, Q_pixel_width, check_valid_int);
420 IIFORMAT_VALID_KEYWORD (label, Q_pixel_height, check_valid_int);
421 IIFORMAT_VALID_KEYWORD (label, Q_width, check_valid_int);
422 IIFORMAT_VALID_KEYWORD (label, Q_height, check_valid_int);
423 IIFORMAT_VALID_KEYWORD (label, Q_face, check_valid_face);
424 IIFORMAT_VALID_KEYWORD (label, Q_descriptor, check_valid_string);
427 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (group, "group");
428 IIFORMAT_HAS_SHARED_METHOD (group, possible_dest_types, widget);
429 IIFORMAT_HAS_METHOD (group, instantiate);
431 IIFORMAT_VALID_KEYWORD (group, Q_width, check_valid_int);
432 IIFORMAT_VALID_KEYWORD (group, Q_height, check_valid_int);
433 IIFORMAT_VALID_KEYWORD (group, Q_pixel_width, check_valid_int);
434 IIFORMAT_VALID_KEYWORD (group, Q_pixel_height, check_valid_int);
435 IIFORMAT_VALID_KEYWORD (group, Q_face, check_valid_face);
436 IIFORMAT_VALID_KEYWORD (group, Q_background, check_valid_string);
437 IIFORMAT_VALID_KEYWORD (group, Q_descriptor, check_valid_string);
442 vars_of_glyphs_widget (void)