Mercurial > hg > xemacs-beta
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 } |