comparison src/glyphs-widget.c @ 384:bbff43aa5eb7 r21-2-7

Import from CVS: tag r21-2-7
author cvs
date Mon, 13 Aug 2007 11:08:24 +0200
parents
children aabb7f5b1c81
comparison
equal deleted inserted replaced
383:6a50c6a581a5 384:bbff43aa5eb7
1 /* Widget-specific glyph objects.
2 Copyright (C) 1998 Andy Piper
3
4 This file is part of XEmacs.
5
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
9 later version.
10
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
14 for more details.
15
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. */
20
21 /* Synched up with: Not in FSF. */
22
23 #include <config.h>
24 #include "lisp.h"
25 #include "lstream.h"
26 #include "console.h"
27 #include "device.h"
28 #include "faces.h"
29 #include "glyphs.h"
30 #include "objects.h"
31
32 #include "window.h"
33 #include "buffer.h"
34 #include "frame.h"
35 #include "insdel.h"
36 #include "opaque.h"
37
38 DEFINE_IMAGE_INSTANTIATOR_FORMAT (button);
39 DEFINE_IMAGE_INSTANTIATOR_FORMAT (combo);
40 Lisp_Object Qcombo;
41 DEFINE_IMAGE_INSTANTIATOR_FORMAT (edit);
42 Lisp_Object Qedit;
43 DEFINE_IMAGE_INSTANTIATOR_FORMAT (scrollbar);
44 Lisp_Object Qscrollbar;
45 DEFINE_IMAGE_INSTANTIATOR_FORMAT (widget);
46 #if 0
47 DEFINE_IMAGE_INSTANTIATOR_FORMAT (group);
48 Lisp_Object Qgroup;
49 #endif
50 DEFINE_IMAGE_INSTANTIATOR_FORMAT (label);
51 Lisp_Object Qlabel;
52
53 Lisp_Object Q_descriptor, Q_height, Q_width, Q_properties, Q_items;
54
55 #define WIDGET_BORDER_HEIGHT 2
56 #define WIDGET_BORDER_WIDTH 4
57
58 /* TODO:
59 - more complex controls.
60 - tooltips for controls.
61 - images in controls.
62 */
63
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
68 buttons in groups. */
69 Lisp_Object
70 widget_face_font_info (Lisp_Object domain, Lisp_Object face,
71 int *height, int *width)
72 {
73 Lisp_Object font_instance = FACE_FONT (face, domain, Vcharset_ascii);
74
75 if (height)
76 *height = XFONT_INSTANCE (font_instance)->height;
77 if (width)
78 *width = XFONT_INSTANCE (font_instance)->width;
79
80 return font_instance;
81 }
82
83 void
84 widget_text_to_pixel_conversion (Lisp_Object domain, Lisp_Object face,
85 int th, int tw,
86 int* height, int* width)
87 {
88 int ch=0, cw=0;
89 widget_face_font_info (domain, face, &ch, &cw);
90 if (height)
91 *height = th * (ch + 2 * WIDGET_BORDER_HEIGHT);
92 if (width)
93 *width = tw * cw + 2 * WIDGET_BORDER_WIDTH;
94 }
95
96 static int
97 widget_possible_dest_types (void)
98 {
99 return IMAGE_WIDGET_MASK;
100 }
101
102 #if 0 /* currently unused */
103 static void
104 check_valid_glyph (Lisp_Object data)
105 {
106 if (SYMBOLP (data))
107 CHECK_BUFFER_GLYPH (XSYMBOL (data)->value);
108 else
109 CHECK_BUFFER_GLYPH (data);
110 }
111 #endif /* currently unused */
112
113 static void
114 check_valid_item_list (Lisp_Object data)
115 {
116 Lisp_Object rest;
117 Lisp_Object items;
118 Fcheck_valid_plist (data);
119
120 items = Fplist_get (data, Q_items, Qnil);
121
122 CHECK_LIST (items);
123 EXTERNAL_LIST_LOOP (rest, items)
124 {
125 CHECK_STRING (XCAR (rest));
126 }
127 }
128
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. */
140 static Lisp_Object
141 widget_property (Lisp_Object image_instance, Lisp_Object prop)
142 {
143 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance);
144 struct image_instantiator_methods* meths;
145
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);
149
150 /* .. then try device specific methods ... */
151 meths = decode_device_ii_format (IMAGE_INSTANCE_DEVICE (ii),
152 IMAGE_INSTANCE_WIDGET_TYPE (ii),
153 ERROR_ME_NOT);
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),
158 ERROR_ME_NOT);
159 if (meths && HAS_IIFORMAT_METH_P (meths, property))
160 return IIFORMAT_METH (meths, property, (image_instance, prop));
161 /* ... then fail */
162 return Qunbound;
163 }
164
165 static Lisp_Object
166 widget_set_property (Lisp_Object image_instance, Lisp_Object prop, Lisp_Object val)
167 {
168 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance);
169 struct image_instantiator_methods* meths;
170 Lisp_Object ret;
171
172 /* try device specific methods first ... */
173 meths = decode_device_ii_format (IMAGE_INSTANCE_DEVICE (ii),
174 IMAGE_INSTANCE_WIDGET_TYPE (ii),
175 ERROR_ME_NOT);
176 if (meths && HAS_IIFORMAT_METH_P (meths, set_property)
177 &&
178 !UNBOUNDP (ret =
179 IIFORMAT_METH (meths, set_property, (image_instance, prop, val))))
180 {
181 return ret;
182 }
183 /* ... then format specific methods ... */
184 meths = decode_device_ii_format (Qnil, IMAGE_INSTANCE_WIDGET_TYPE (ii),
185 ERROR_ME_NOT);
186 if (meths && HAS_IIFORMAT_METH_P (meths, set_property)
187 &&
188 !UNBOUNDP (ret =
189 IIFORMAT_METH (meths, set_property, (image_instance, prop, val))))
190 {
191 return ret;
192 }
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);
196 return val;
197 }
198
199 static void
200 widget_validate (Lisp_Object instantiator)
201 {
202 Lisp_Object desc = find_keyword_in_vector (instantiator, Q_descriptor);
203 struct gui_item gui;
204 if (NILP (desc))
205 signal_simple_error ("Must supply :descriptor", instantiator);
206
207 gui_parse_item_keywords (desc, &gui);
208
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);
212
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);
216 }
217
218 static void
219 combo_validate (Lisp_Object instantiator)
220 {
221 widget_validate (instantiator);
222 if (NILP (find_keyword_in_vector (instantiator, Q_properties)))
223 signal_simple_error ("Must supply item list", instantiator);
224 }
225
226 static void
227 initialize_widget_image_instance (struct Lisp_Image_Instance *ii, Lisp_Object type)
228 {
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));
234 }
235
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) */
242 static void
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)
247 {
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;
257
258 /* this just does pixel type sizing */
259 subwindow_instantiate (image_instance, instantiator, pointer_fg, pointer_bg,
260 dest_mask, domain);
261
262 if (!(dest_mask & IMAGE_WIDGET_MASK))
263 incompatible_image_types (instantiator, dest_mask, IMAGE_WIDGET_MASK);
264
265 initialize_widget_image_instance (ii, XVECTOR_DATA (instantiator)[0]);
266
267 /* retrieve the fg and bg colors */
268 if (!NILP (face))
269 IMAGE_INSTANCE_WIDGET_FACE (ii) = Fget_face (face);
270
271 /* data items for some widgets */
272 IMAGE_INSTANCE_WIDGET_PROPS (ii) =
273 find_keyword_in_vector (instantiator, Q_properties);
274
275 /* retrieve the gui item information */
276 if (STRINGP (desc) || NILP (desc))
277 IMAGE_INSTANCE_WIDGET_TEXT (ii) = desc;
278 else
279 gui_parse_item_keywords (find_keyword_in_vector (instantiator, Q_descriptor),
280 pgui);
281
282 /* normalize size information */
283 if (!NILP (width))
284 tw = XINT (width);
285 if (!NILP (height))
286 th = XINT (height);
287 if (!NILP (pixwidth))
288 pw = XINT (pixwidth);
289 if (!NILP (pixheight))
290 ph = XINT (pixheight);
291
292 if (!tw && !pw && !NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
293 tw = XSTRING_LENGTH (IMAGE_INSTANCE_WIDGET_TEXT (ii));
294 if (!th && !ph)
295 {
296 if (default_textheight)
297 th = default_textheight;
298 else if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
299 th = 1;
300 else
301 ph = default_pixheight;
302 }
303
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);
308
309 IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii) = pw;
310 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii) = ph;
311 }
312
313 static void
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)
317 {
318 widget_instantiate_1 (image_instance, instantiator, pointer_fg,
319 pointer_bg, dest_mask, domain, 1, 0);
320 }
321
322 static void
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)
326 {
327 Lisp_Object data = Fplist_get (find_keyword_in_vector (instantiator, Q_properties),
328 Q_items, Qnil);
329 int len;
330 GET_LIST_LENGTH (data, len);
331 widget_instantiate_1 (image_instance, instantiator, pointer_fg,
332 pointer_bg, dest_mask, domain, len + 1, 0);
333 }
334
335 /* Instantiate a static control */
336 static void
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)
340 {
341 widget_instantiate_1 (image_instance, instantiator, pointer_fg,
342 pointer_bg, dest_mask, domain, 0, 4);
343 }
344
345
346 /************************************************************************/
347 /* initialization */
348 /************************************************************************/
349
350 void
351 syms_of_glyphs_widget (void)
352 {
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");
358 }
359
360 void
361 image_instantiator_format_create_glyphs_widget (void)
362 {
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);
367
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);
373
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);
380 /* edit fields */
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);
385
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);
392 /* combo box */
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);
397
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);
404 /* scrollbar */
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);
409
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);
414 /* labels */
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);
418
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);
425 #if 0
426 /* group */
427 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (group, "group");
428 IIFORMAT_HAS_SHARED_METHOD (group, possible_dest_types, widget);
429 IIFORMAT_HAS_METHOD (group, instantiate);
430
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);
438 #endif
439 }
440
441 void
442 vars_of_glyphs_widget (void)
443 {
444 }