384
|
1 /* Widget-specific glyph objects.
|
424
|
2 Copyright (C) 1998, 1999 Andy Piper.
|
384
|
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
|
388
|
23 /* written by Andy Piper <andy@xemacs.org> */
|
|
24
|
384
|
25 #include <config.h>
|
|
26 #include "lisp.h"
|
|
27 #include "lstream.h"
|
|
28 #include "console.h"
|
|
29 #include "device.h"
|
|
30 #include "faces.h"
|
|
31 #include "glyphs.h"
|
|
32 #include "objects.h"
|
388
|
33 #include "bytecode.h"
|
384
|
34 #include "window.h"
|
|
35 #include "buffer.h"
|
|
36 #include "frame.h"
|
|
37 #include "insdel.h"
|
|
38 #include "opaque.h"
|
|
39
|
|
40 DEFINE_IMAGE_INSTANTIATOR_FORMAT (button);
|
420
|
41 DEFINE_IMAGE_INSTANTIATOR_FORMAT (combo_box);
|
|
42 Lisp_Object Qcombo_box;
|
|
43 DEFINE_IMAGE_INSTANTIATOR_FORMAT (edit_field);
|
|
44 Lisp_Object Qedit_field;
|
384
|
45 DEFINE_IMAGE_INSTANTIATOR_FORMAT (scrollbar);
|
|
46 Lisp_Object Qscrollbar;
|
|
47 DEFINE_IMAGE_INSTANTIATOR_FORMAT (widget);
|
|
48 DEFINE_IMAGE_INSTANTIATOR_FORMAT (label);
|
|
49 Lisp_Object Qlabel;
|
420
|
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;
|
424
|
56 DEFINE_IMAGE_INSTANTIATOR_FORMAT (layout);
|
|
57 Lisp_Object Qlayout;
|
384
|
58
|
|
59 Lisp_Object Q_descriptor, Q_height, Q_width, Q_properties, Q_items;
|
424
|
60 Lisp_Object Q_image, Q_text, Q_percent, Q_orientation, Q_justify, Q_border;
|
|
61 Lisp_Object Qetched_in, Qetched_out, Qbevel_in, Qbevel_out;
|
384
|
62
|
424
|
63 #define WIDGET_BORDER_HEIGHT 4
|
412
|
64 #define WIDGET_BORDER_WIDTH 4
|
384
|
65
|
424
|
66 #ifdef DEBUG_WIDGETS
|
|
67 int debug_widget_instances;
|
|
68 #endif
|
|
69
|
384
|
70 /* TODO:
|
412
|
71 - more complex controls.
|
|
72 - tooltips for controls.
|
384
|
73 */
|
|
74
|
412
|
75 /* In windows normal windows work in pixels, dialog boxes work in
|
384
|
76 dialog box units. Why? sigh. We could reuse the metrics for dialogs
|
|
77 if this were not the case. As it is we have to position things
|
|
78 pixel wise. I'm not even sure that X has this problem at least for
|
|
79 buttons in groups. */
|
412
|
80 Lisp_Object
|
|
81 widget_face_font_info (Lisp_Object domain, Lisp_Object face,
|
|
82 int *height, int *width)
|
|
83 {
|
|
84 Lisp_Object font_instance = FACE_FONT (face, domain, Vcharset_ascii);
|
|
85
|
|
86 if (height)
|
|
87 *height = XFONT_INSTANCE (font_instance)->height;
|
|
88 if (width)
|
|
89 *width = XFONT_INSTANCE (font_instance)->width;
|
|
90
|
|
91 return font_instance;
|
|
92 }
|
|
93
|
|
94 void
|
|
95 widget_text_to_pixel_conversion (Lisp_Object domain, Lisp_Object face,
|
|
96 int th, int tw,
|
|
97 int* height, int* width)
|
|
98 {
|
|
99 int ch=0, cw=0;
|
|
100 widget_face_font_info (domain, face, &ch, &cw);
|
|
101 if (height)
|
424
|
102 *height = th * ch + 2 * WIDGET_BORDER_HEIGHT;
|
412
|
103 if (width)
|
|
104 *width = tw * cw + 2 * WIDGET_BORDER_WIDTH;
|
|
105 }
|
|
106
|
384
|
107 static int
|
|
108 widget_possible_dest_types (void)
|
|
109 {
|
|
110 return IMAGE_WIDGET_MASK;
|
|
111 }
|
|
112
|
|
113 static void
|
424
|
114 check_valid_glyph_or_instantiator (Lisp_Object data)
|
384
|
115 {
|
388
|
116 Lisp_Object glyph = data;
|
384
|
117 if (SYMBOLP (data))
|
388
|
118 glyph = XSYMBOL (data)->value;
|
|
119
|
|
120 if (IMAGE_INSTANCEP (glyph))
|
|
121 CHECK_IMAGE_INSTANCE (glyph);
|
424
|
122 else if (!CONSP (glyph) && !VECTORP (glyph))
|
388
|
123 CHECK_BUFFER_GLYPH (glyph);
|
|
124 }
|
|
125
|
|
126 static void
|
424
|
127 check_valid_orientation (Lisp_Object data)
|
|
128 {
|
|
129 if (!EQ (data, Qhorizontal)
|
|
130 &&
|
|
131 !EQ (data, Qvertical))
|
|
132 signal_simple_error ("unknown orientation for layout", data);
|
|
133 }
|
|
134
|
|
135 static void
|
|
136 check_valid_justification (Lisp_Object data)
|
|
137 {
|
|
138 if (!EQ (data, Qleft) && !EQ (data, Qright) && !EQ (data, Qcenter))
|
|
139 signal_simple_error ("unknown justification for layout", data);
|
|
140 }
|
|
141
|
|
142 static void
|
|
143 check_valid_border (Lisp_Object data)
|
|
144 {
|
|
145 if (!EQ (data, Qt) && !EQ (data, Qetched_in) && !EQ (data, Qetched_out)
|
|
146 && !EQ (data, Qbevel_in) && !EQ (data, Qbevel_out)
|
|
147 && !GLYPHP (data) && !VECTORP (data))
|
|
148 signal_simple_error ("unknown border style for layout", data);
|
|
149 }
|
|
150
|
|
151 static void
|
388
|
152 check_valid_anything (Lisp_Object data)
|
|
153 {
|
384
|
154 }
|
388
|
155
|
|
156 static void
|
|
157 check_valid_callback (Lisp_Object data)
|
|
158 {
|
|
159 if (!SYMBOLP (data)
|
|
160 && !COMPILED_FUNCTIONP (data)
|
|
161 && !CONSP (data))
|
|
162 {
|
|
163 signal_simple_error (":callback must be a function or expression", data);
|
|
164 }
|
|
165 }
|
|
166
|
|
167 static void
|
|
168 check_valid_symbol (Lisp_Object data)
|
|
169 {
|
|
170 CHECK_SYMBOL (data);
|
|
171 }
|
|
172
|
|
173 static void
|
|
174 check_valid_string_or_vector (Lisp_Object data)
|
|
175 {
|
|
176 if (!STRINGP (data) && !VECTORP (data))
|
|
177 signal_simple_error (":descriptor must be a string or a vector", data);
|
|
178 }
|
384
|
179
|
422
|
180 void
|
418
|
181 check_valid_item_list_1 (Lisp_Object items)
|
384
|
182 {
|
|
183 Lisp_Object rest;
|
|
184
|
|
185 CHECK_LIST (items);
|
|
186 EXTERNAL_LIST_LOOP (rest, items)
|
|
187 {
|
418
|
188 if (STRINGP (XCAR (rest)))
|
|
189 CHECK_STRING (XCAR (rest));
|
|
190 else if (VECTORP (XCAR (rest)))
|
|
191 gui_parse_item_keywords (XCAR (rest));
|
|
192 else if (LISTP (XCAR (rest)))
|
|
193 check_valid_item_list_1 (XCAR (rest));
|
|
194 else
|
|
195 signal_simple_error ("Items must be vectors, lists or strings", items);
|
384
|
196 }
|
|
197 }
|
|
198
|
418
|
199 static void
|
|
200 check_valid_item_list (Lisp_Object data)
|
|
201 {
|
|
202 Lisp_Object items;
|
|
203
|
|
204 Fcheck_valid_plist (data);
|
|
205 items = Fplist_get (data, Q_items, Qnil);
|
|
206
|
|
207 check_valid_item_list_1 (items);
|
|
208 }
|
|
209
|
424
|
210 static void
|
|
211 check_valid_glyph_or_instantiator_list (Lisp_Object data)
|
|
212 {
|
|
213 Lisp_Object rest;
|
|
214
|
|
215 CHECK_LIST (data);
|
|
216 EXTERNAL_LIST_LOOP (rest, data)
|
|
217 {
|
|
218 check_valid_glyph_or_instantiator (XCAR (rest));
|
|
219 }
|
|
220 }
|
|
221
|
|
222 static Lisp_Object
|
|
223 glyph_instantiator_to_glyph (Lisp_Object sym)
|
|
224 {
|
|
225 /* This function calls lisp. */
|
|
226 Lisp_Object glyph = sym;
|
|
227 struct gcpro gcpro1;
|
|
228
|
|
229 GCPRO1 (glyph);
|
|
230 /* if we have a symbol get at the actual data */
|
|
231 if (SYMBOLP (glyph))
|
|
232 glyph = XSYMBOL (glyph)->value;
|
|
233
|
|
234 if (CONSP (glyph))
|
|
235 glyph = Feval (glyph);
|
|
236
|
|
237 /* Be really helpful to the user. */
|
|
238 if (VECTORP (glyph))
|
|
239 {
|
|
240 glyph = call1 (intern ("make-glyph"), glyph);
|
|
241 }
|
|
242
|
|
243 /* substitute the new glyph */
|
|
244 RETURN_UNGCPRO (glyph);
|
|
245 }
|
|
246
|
|
247 static void
|
|
248 substitute_keyword_value (Lisp_Object inst, Lisp_Object key, Lisp_Object val)
|
|
249 {
|
|
250 int i;
|
|
251 /* substitute the new glyph */
|
|
252 for (i = 0; i < XVECTOR_LENGTH (inst); i++)
|
|
253 {
|
|
254 if (EQ (key, XVECTOR_DATA (inst)[i]))
|
|
255 {
|
|
256 XVECTOR_DATA (inst)[i+1] = val;
|
|
257 break;
|
|
258 }
|
|
259 }
|
|
260 }
|
|
261
|
412
|
262 /* wire widget property invocations to specific widgets ... The
|
|
263 problem we are solving here is that when instantiators get converted
|
|
264 to instances they lose some type information (they just become
|
|
265 subwindows or widgets for example). For widgets we need to preserve
|
|
266 this type information so that we can do widget specific operations on
|
|
267 the instances. This is encoded in the widget type
|
|
268 field. widget_property gets invoked by decoding the primary type
|
|
269 (Qwidget), widget property then invokes based on the secondary type
|
420
|
270 (Qedit_field for example). It is debatable that we should wire things in this
|
412
|
271 generalised way rather than treating widgets specially in
|
|
272 image_instance_property. */
|
384
|
273 static Lisp_Object
|
|
274 widget_property (Lisp_Object image_instance, Lisp_Object prop)
|
|
275 {
|
412
|
276 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance);
|
384
|
277 struct image_instantiator_methods* meths;
|
|
278
|
|
279 /* first see if its a general property ... */
|
|
280 if (!NILP (Fplist_member (IMAGE_INSTANCE_WIDGET_PROPS (ii), prop)))
|
|
281 return Fplist_get (IMAGE_INSTANCE_WIDGET_PROPS (ii), prop, Qnil);
|
|
282
|
|
283 /* .. then try device specific methods ... */
|
412
|
284 meths = decode_device_ii_format (IMAGE_INSTANCE_DEVICE (ii),
|
384
|
285 IMAGE_INSTANCE_WIDGET_TYPE (ii),
|
|
286 ERROR_ME_NOT);
|
|
287 if (meths && HAS_IIFORMAT_METH_P (meths, property))
|
|
288 return IIFORMAT_METH (meths, property, (image_instance, prop));
|
|
289 /* ... then format specific methods ... */
|
|
290 meths = decode_device_ii_format (Qnil, IMAGE_INSTANCE_WIDGET_TYPE (ii),
|
|
291 ERROR_ME_NOT);
|
|
292 if (meths && HAS_IIFORMAT_METH_P (meths, property))
|
|
293 return IIFORMAT_METH (meths, property, (image_instance, prop));
|
|
294 /* ... then fail */
|
|
295 return Qunbound;
|
|
296 }
|
|
297
|
|
298 static Lisp_Object
|
|
299 widget_set_property (Lisp_Object image_instance, Lisp_Object prop, Lisp_Object val)
|
|
300 {
|
412
|
301 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance);
|
384
|
302 struct image_instantiator_methods* meths;
|
|
303 Lisp_Object ret;
|
|
304
|
412
|
305 /* try device specific methods first ... */
|
|
306 meths = decode_device_ii_format (IMAGE_INSTANCE_DEVICE (ii),
|
384
|
307 IMAGE_INSTANCE_WIDGET_TYPE (ii),
|
|
308 ERROR_ME_NOT);
|
|
309 if (meths && HAS_IIFORMAT_METH_P (meths, set_property)
|
|
310 &&
|
|
311 !UNBOUNDP (ret =
|
|
312 IIFORMAT_METH (meths, set_property, (image_instance, prop, val))))
|
|
313 {
|
|
314 return ret;
|
|
315 }
|
|
316 /* ... then format specific methods ... */
|
|
317 meths = decode_device_ii_format (Qnil, IMAGE_INSTANCE_WIDGET_TYPE (ii),
|
|
318 ERROR_ME_NOT);
|
|
319 if (meths && HAS_IIFORMAT_METH_P (meths, set_property)
|
|
320 &&
|
|
321 !UNBOUNDP (ret =
|
|
322 IIFORMAT_METH (meths, set_property, (image_instance, prop, val))))
|
|
323 {
|
|
324 return ret;
|
|
325 }
|
|
326 /* we didn't do any device specific properties, so shove the property in our plist */
|
|
327 IMAGE_INSTANCE_WIDGET_PROPS (ii)
|
|
328 = Fplist_put (IMAGE_INSTANCE_WIDGET_PROPS (ii), prop, val);
|
|
329 return val;
|
|
330 }
|
|
331
|
|
332 static void
|
|
333 widget_validate (Lisp_Object instantiator)
|
|
334 {
|
|
335 Lisp_Object desc = find_keyword_in_vector (instantiator, Q_descriptor);
|
418
|
336
|
384
|
337 if (NILP (desc))
|
|
338 signal_simple_error ("Must supply :descriptor", instantiator);
|
|
339
|
388
|
340 if (VECTORP (desc))
|
418
|
341 gui_parse_item_keywords (desc);
|
384
|
342
|
|
343 if (!NILP (find_keyword_in_vector (instantiator, Q_width))
|
418
|
344 && !NILP (find_keyword_in_vector (instantiator, Q_pixel_width)))
|
384
|
345 signal_simple_error ("Must supply only one of :width and :pixel-width", instantiator);
|
|
346
|
|
347 if (!NILP (find_keyword_in_vector (instantiator, Q_height))
|
|
348 && !NILP (find_keyword_in_vector (instantiator, Q_pixel_height)))
|
|
349 signal_simple_error ("Must supply only one of :height and :pixel-height", instantiator);
|
|
350 }
|
|
351
|
|
352 static void
|
420
|
353 combo_box_validate (Lisp_Object instantiator)
|
384
|
354 {
|
|
355 widget_validate (instantiator);
|
|
356 if (NILP (find_keyword_in_vector (instantiator, Q_properties)))
|
|
357 signal_simple_error ("Must supply item list", instantiator);
|
|
358 }
|
|
359
|
388
|
360 /* we need to convert things like glyphs to images, eval expressions
|
|
361 etc.*/
|
|
362 static Lisp_Object
|
|
363 widget_normalize (Lisp_Object inst, Lisp_Object console_type)
|
|
364 {
|
|
365 /* This function can call lisp */
|
|
366 Lisp_Object glyph = find_keyword_in_vector (inst, Q_image);
|
|
367
|
|
368 /* we need to eval glyph if its an expression, we do this for the
|
|
369 same reasons we normalize file to data. */
|
|
370 if (!NILP (glyph))
|
|
371 {
|
424
|
372 substitute_keyword_value (inst, Q_image, glyph_instantiator_to_glyph (glyph));
|
|
373 }
|
412
|
374
|
388
|
375 return inst;
|
|
376 }
|
|
377
|
384
|
378 static void
|
412
|
379 initialize_widget_image_instance (struct Lisp_Image_Instance *ii, Lisp_Object type)
|
384
|
380 {
|
|
381 /* initialize_subwindow_image_instance (ii);*/
|
|
382 IMAGE_INSTANCE_WIDGET_TYPE (ii) = type;
|
|
383 IMAGE_INSTANCE_WIDGET_PROPS (ii) = Qnil;
|
412
|
384 IMAGE_INSTANCE_WIDGET_FACE (ii) = Vwidget_face;
|
424
|
385 IMAGE_INSTANCE_WIDGET_ITEMS (ii) = allocate_gui_item ();
|
384
|
386 }
|
|
387
|
|
388 /* Instantiate a button widget. Unfortunately instantiated widgets are
|
|
389 particular to a frame since they need to have a parent. It's not
|
|
390 like images where you just select the image into the context you
|
418
|
391 want to display it in and BitBlt it. So image instances can have a
|
384
|
392 many-to-one relationship with things you see, whereas widgets can
|
|
393 only be one-to-one (i.e. per frame) */
|
424
|
394 void
|
412
|
395 widget_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator,
|
|
396 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
|
|
397 int dest_mask, Lisp_Object domain, int default_textheight,
|
418
|
398 int default_pixheight, int default_textwidth)
|
384
|
399 {
|
412
|
400 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
|
384
|
401 Lisp_Object face = find_keyword_in_vector (instantiator, Q_face);
|
|
402 Lisp_Object height = find_keyword_in_vector (instantiator, Q_height);
|
|
403 Lisp_Object width = find_keyword_in_vector (instantiator, Q_width);
|
|
404 Lisp_Object pixwidth = find_keyword_in_vector (instantiator, Q_pixel_width);
|
|
405 Lisp_Object pixheight = find_keyword_in_vector (instantiator, Q_pixel_height);
|
|
406 Lisp_Object desc = find_keyword_in_vector (instantiator, Q_descriptor);
|
388
|
407 Lisp_Object glyph = find_keyword_in_vector (instantiator, Q_image);
|
424
|
408 Lisp_Object props = find_keyword_in_vector (instantiator, Q_properties);
|
384
|
409 int pw=0, ph=0, tw=0, th=0;
|
|
410
|
|
411 /* this just does pixel type sizing */
|
|
412 subwindow_instantiate (image_instance, instantiator, pointer_fg, pointer_bg,
|
|
413 dest_mask, domain);
|
412
|
414
|
408
|
415 if (!(dest_mask & IMAGE_WIDGET_MASK))
|
|
416 incompatible_image_types (instantiator, dest_mask, IMAGE_WIDGET_MASK);
|
384
|
417
|
|
418 initialize_widget_image_instance (ii, XVECTOR_DATA (instantiator)[0]);
|
|
419
|
|
420 /* retrieve the fg and bg colors */
|
|
421 if (!NILP (face))
|
412
|
422 IMAGE_INSTANCE_WIDGET_FACE (ii) = Fget_face (face);
|
384
|
423
|
412
|
424 /* data items for some widgets */
|
424
|
425 IMAGE_INSTANCE_WIDGET_PROPS (ii) = props;
|
412
|
426
|
388
|
427 /* retrieve the gui item information. This is easy if we have been
|
|
428 provided with a vector, more difficult if we have just been given
|
|
429 keywords */
|
408
|
430 if (STRINGP (desc) || NILP (desc))
|
388
|
431 {
|
|
432 /* big cheat - we rely on the fact that a gui item looks like an instantiator */
|
424
|
433 IMAGE_INSTANCE_WIDGET_ITEMS (ii) =
|
418
|
434 gui_parse_item_keywords_no_errors (instantiator);
|
388
|
435 IMAGE_INSTANCE_WIDGET_TEXT (ii) = desc;
|
|
436 }
|
384
|
437 else
|
424
|
438 IMAGE_INSTANCE_WIDGET_ITEMS (ii) =
|
418
|
439 gui_parse_item_keywords_no_errors (desc);
|
384
|
440
|
424
|
441 /* parse more gui items out of the properties */
|
|
442 if (!NILP (props))
|
|
443 {
|
|
444 Lisp_Object items = Fplist_get (props, Q_items, Qnil);
|
|
445 if (!NILP (items))
|
|
446 IMAGE_INSTANCE_WIDGET_ITEMS (ii) =
|
|
447 Fcons (IMAGE_INSTANCE_WIDGET_ITEMS (ii),
|
|
448 parse_gui_item_tree_children (items));
|
|
449 }
|
|
450
|
412
|
451 /* normalize size information */
|
|
452 if (!NILP (width))
|
|
453 tw = XINT (width);
|
|
454 if (!NILP (height))
|
|
455 th = XINT (height);
|
|
456 if (!NILP (pixwidth))
|
|
457 pw = XINT (pixwidth);
|
384
|
458 if (!NILP (pixheight))
|
412
|
459 ph = XINT (pixheight);
|
384
|
460
|
388
|
461 /* for a widget with an image pick up the dimensions from that */
|
|
462 if (!NILP (glyph))
|
|
463 {
|
412
|
464 if (!pw && !tw)
|
|
465 pw = glyph_width (glyph, Qnil, DEFAULT_INDEX, domain)
|
|
466 + 2 * WIDGET_BORDER_WIDTH;
|
|
467 if (!ph && !th)
|
|
468 ph = glyph_height (glyph, Qnil, DEFAULT_INDEX, domain)
|
|
469 + 2 * WIDGET_BORDER_HEIGHT;
|
388
|
470 }
|
|
471
|
412
|
472 /* if we still don' t have sizes, guess from text size */
|
418
|
473 if (!tw && !pw)
|
|
474 {
|
|
475 if (default_textwidth)
|
|
476 tw = default_textwidth;
|
|
477 else if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
|
|
478 tw = XSTRING_LENGTH (IMAGE_INSTANCE_WIDGET_TEXT (ii));
|
|
479 }
|
|
480
|
412
|
481 if (!th && !ph)
|
384
|
482 {
|
412
|
483 if (default_textheight)
|
|
484 th = default_textheight;
|
|
485 else if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
|
|
486 th = 1;
|
|
487 else
|
|
488 ph = default_pixheight;
|
398
|
489 }
|
412
|
490
|
|
491 if (tw !=0 || th !=0)
|
|
492 widget_text_to_pixel_conversion (domain,
|
|
493 IMAGE_INSTANCE_WIDGET_FACE (ii),
|
|
494 th, tw, th ? &ph : 0, tw ? &pw : 0);
|
406
|
495
|
412
|
496 IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii) = pw;
|
|
497 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii) = ph;
|
424
|
498 #ifdef DEBUG_WIDGETS
|
|
499 debug_widget_instances++;
|
|
500 stderr_out ("instantiated ");
|
|
501 debug_print (instantiator);
|
|
502 stderr_out ("%d widgets instantiated\n", debug_widget_instances);
|
|
503 #endif
|
408
|
504 }
|
|
505
|
|
506 static void
|
412
|
507 widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
|
|
508 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
|
|
509 int dest_mask, Lisp_Object domain)
|
408
|
510 {
|
412
|
511 widget_instantiate_1 (image_instance, instantiator, pointer_fg,
|
418
|
512 pointer_bg, dest_mask, domain, 1, 0, 0);
|
408
|
513 }
|
|
514
|
424
|
515 /* tree-view generic instantiation - get the height right */
|
384
|
516 static void
|
424
|
517 tree_view_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
|
|
518 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
|
|
519 int dest_mask, Lisp_Object domain)
|
384
|
520 {
|
412
|
521 Lisp_Object data = Fplist_get (find_keyword_in_vector (instantiator, Q_properties),
|
|
522 Q_items, Qnil);
|
|
523 int len;
|
|
524 GET_LIST_LENGTH (data, len);
|
|
525 widget_instantiate_1 (image_instance, instantiator, pointer_fg,
|
418
|
526 pointer_bg, dest_mask, domain, len + 1, 0, 0);
|
|
527 }
|
|
528
|
|
529 static void
|
420
|
530 tab_control_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
|
418
|
531 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
|
|
532 int dest_mask, Lisp_Object domain)
|
|
533 {
|
|
534 Lisp_Object data = Fplist_get (find_keyword_in_vector (instantiator, Q_properties),
|
|
535 Q_items, Qnil);
|
|
536 Lisp_Object rest;
|
|
537 int len = 0;
|
|
538
|
|
539 LIST_LOOP (rest, data)
|
|
540 {
|
|
541 len += 3; /* some bias */
|
|
542 if (STRINGP (XCAR (rest)))
|
|
543 len += XSTRING_LENGTH (XCAR (rest));
|
|
544 else if (VECTORP (XCAR (rest)))
|
|
545 {
|
|
546 Lisp_Object gui = gui_parse_item_keywords (XCAR (rest));
|
|
547 len += XSTRING_LENGTH (XGUI_ITEM (gui)->name);
|
|
548 }
|
|
549 }
|
|
550
|
|
551 widget_instantiate_1 (image_instance, instantiator, pointer_fg,
|
|
552 pointer_bg, dest_mask, domain, 0, 0, len);
|
384
|
553 }
|
|
554
|
412
|
555 /* Instantiate a static control */
|
|
556 static void
|
|
557 static_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
|
|
558 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
|
|
559 int dest_mask, Lisp_Object domain)
|
384
|
560 {
|
412
|
561 widget_instantiate_1 (image_instance, instantiator, pointer_fg,
|
418
|
562 pointer_bg, dest_mask, domain, 0, 4, 0);
|
384
|
563 }
|
|
564
|
|
565
|
424
|
566 /*****************************************************************************
|
|
567 * widget layout *
|
|
568 *****************************************************************************/
|
|
569 static int
|
|
570 layout_possible_dest_types (void)
|
|
571 {
|
|
572 return IMAGE_LAYOUT_MASK;
|
|
573 }
|
|
574
|
|
575 /* we need to convert things like glyphs to images, eval expressions
|
|
576 etc.*/
|
|
577 static Lisp_Object
|
|
578 layout_normalize (Lisp_Object inst, Lisp_Object console_type)
|
|
579 {
|
|
580 /* This function can call lisp */
|
|
581 Lisp_Object items = find_keyword_in_vector (inst, Q_items);
|
|
582 Lisp_Object border = find_keyword_in_vector (inst, Q_border);
|
|
583 /* we need to eval glyph if its an expression, we do this for the
|
|
584 same reasons we normalize file to data. */
|
|
585 if (!NILP (items))
|
|
586 {
|
|
587 Lisp_Object rest;
|
|
588 LIST_LOOP (rest, items)
|
|
589 {
|
|
590 /* substitute the new glyph */
|
|
591 Fsetcar (rest, glyph_instantiator_to_glyph (XCAR (rest)));
|
|
592 }
|
|
593 }
|
|
594 /* normalize the border spec. */
|
|
595 if (VECTORP (border) || CONSP (border))
|
|
596 {
|
|
597 substitute_keyword_value (inst, Q_border, glyph_instantiator_to_glyph (border));
|
|
598 }
|
|
599 return inst;
|
|
600 }
|
|
601
|
|
602 /* Instantiate a layout widget. */
|
|
603 static void
|
|
604 layout_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
|
|
605 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
|
|
606 int dest_mask, Lisp_Object domain)
|
|
607 {
|
|
608 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
|
|
609 Lisp_Object rest, device = IMAGE_INSTANCE_DEVICE (ii);
|
|
610 Lisp_Object frame = FW_FRAME (domain);
|
|
611 Lisp_Object items = find_keyword_in_vector (instantiator, Q_items);
|
|
612 Lisp_Object width = find_keyword_in_vector (instantiator, Q_pixel_width);
|
|
613 Lisp_Object height = find_keyword_in_vector (instantiator, Q_pixel_height);
|
|
614 Lisp_Object orient = find_keyword_in_vector (instantiator, Q_orientation);
|
|
615 Lisp_Object justify = find_keyword_in_vector (instantiator, Q_justify);
|
|
616 Lisp_Object border = find_keyword_in_vector (instantiator, Q_border);
|
|
617 Lisp_Object children = Qnil;
|
|
618 int pw = 0, ph = 0, x, y, maxph = 0, maxpw = 0, nitems = 0,
|
|
619 horiz_spacing, vert_spacing, ph_adjust = 0;
|
|
620
|
|
621 if (NILP (frame))
|
|
622 signal_simple_error ("No selected frame", device);
|
|
623
|
|
624 if (!(dest_mask & IMAGE_LAYOUT_MASK))
|
|
625 incompatible_image_types (instantiator, dest_mask, IMAGE_LAYOUT_MASK);
|
|
626
|
|
627 if (NILP (orient))
|
|
628 orient = Qvertical;
|
|
629
|
|
630 if (EQ (border, Qt))
|
|
631 border = Qetched_in;
|
|
632
|
|
633 ii->data = 0;
|
|
634 IMAGE_INSTANCE_TYPE (ii) = IMAGE_LAYOUT;
|
|
635 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = 0;
|
|
636 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0;
|
|
637 IMAGE_INSTANCE_SUBWINDOW_FRAME (ii) = frame;
|
|
638 IMAGE_INSTANCE_LAYOUT_BORDER (ii) = border;
|
|
639
|
|
640 /* normalize size information */
|
|
641 if (!NILP (width))
|
|
642 pw = XINT (width);
|
|
643 if (!NILP (height))
|
|
644 ph = XINT (height);
|
|
645
|
|
646 /* flip through the items to work out how much stuff we have to display */
|
|
647 LIST_LOOP (rest, items)
|
|
648 {
|
|
649 Lisp_Object glyph = XCAR (rest);
|
|
650 int gheight = glyph_height (glyph, Qnil, DEFAULT_INDEX, domain);
|
|
651 int gwidth = glyph_width (glyph, Qnil, DEFAULT_INDEX, domain);
|
|
652 nitems ++;
|
|
653 if (EQ (orient, Qhorizontal))
|
|
654 {
|
|
655 maxph = max (maxph, gheight);
|
|
656 maxpw += gwidth;
|
|
657 }
|
|
658 else if (EQ (orient, Qvertical))
|
|
659 {
|
|
660 maxpw = max (maxpw, gwidth);
|
|
661 maxph += gheight;
|
|
662 }
|
|
663 }
|
|
664
|
|
665 /* work out spacing between items and bounds of the layout */
|
|
666 if (!pw)
|
|
667 {
|
|
668 /* No user provided width so we just do default spacing. */
|
|
669 horiz_spacing = WIDGET_BORDER_WIDTH * 2;
|
|
670 if (EQ (orient, Qhorizontal))
|
|
671 pw = maxpw + (nitems + 1) * horiz_spacing;
|
|
672 else
|
|
673 pw = maxpw + 2 * horiz_spacing;
|
|
674 }
|
|
675 else if (pw < maxpw)
|
|
676 /* The user wants a smaller space than the largest item, so we
|
|
677 just provide default spacing and will let the output routines
|
|
678 clip.. */
|
|
679 horiz_spacing = WIDGET_BORDER_WIDTH * 2;
|
|
680 else if (EQ (orient, Qhorizontal))
|
|
681 /* We have a larger area to display in so distribute the space
|
|
682 evenly. */
|
|
683 horiz_spacing = (pw - maxpw) / (nitems + 1);
|
|
684 else
|
|
685 horiz_spacing = (pw - maxpw) / 2;
|
|
686
|
|
687 /* Do the border now so that we can adjust the layout. */
|
|
688 if (GLYPHP (border))
|
|
689 {
|
|
690 /* We are going to be sneaky here and add the border text as
|
|
691 just another child, the layout and output routines don't know
|
|
692 this and will just display at the offsets we prescribe. */
|
|
693 Lisp_Object bglyph = glyph_image_instance (border, domain, ERROR_ME, 1);
|
|
694
|
|
695 children = Fcons (bglyph, children);
|
|
696 XIMAGE_INSTANCE_XOFFSET (bglyph) = 10; /* Really, what should this be? */
|
|
697 XIMAGE_INSTANCE_YOFFSET (bglyph) = 0;
|
|
698
|
|
699 ph_adjust = (glyph_height (border, Qnil, DEFAULT_INDEX, domain) / 2);
|
|
700 IMAGE_INSTANCE_LAYOUT_BORDER (ii) = make_int (ph_adjust);
|
|
701 }
|
|
702
|
|
703 /* Work out vertical spacings. */
|
|
704 if (!ph)
|
|
705 {
|
|
706 vert_spacing = WIDGET_BORDER_HEIGHT * 2;
|
|
707 if (EQ (orient, Qvertical))
|
|
708 ph = maxph + (nitems + 1) * vert_spacing + ph_adjust;
|
|
709 else
|
|
710 ph = maxph + 2 * vert_spacing + ph_adjust;
|
|
711 }
|
|
712 else if (ph < maxph)
|
|
713 vert_spacing = WIDGET_BORDER_HEIGHT * 2;
|
|
714 else if (EQ (orient, Qvertical))
|
|
715 vert_spacing = (ph - (maxph + ph_adjust)) / (nitems + 1);
|
|
716 else
|
|
717 vert_spacing = (ph - (maxph + ph_adjust)) / 2;
|
|
718
|
|
719 y = vert_spacing + ph_adjust;
|
|
720 x = horiz_spacing;
|
|
721
|
|
722 /* Now flip through putting items where we want them, paying
|
|
723 attention to justification. */
|
|
724 LIST_LOOP (rest, items)
|
|
725 {
|
|
726 /* make sure the image is instantiated */
|
|
727 Lisp_Object glyph = XCAR (rest);
|
|
728 Lisp_Object gii = glyph_image_instance (glyph, domain, ERROR_ME, 1);
|
|
729 int gwidth = glyph_width (glyph, Qnil, DEFAULT_INDEX, domain);
|
|
730 int gheight = glyph_height (glyph, Qnil, DEFAULT_INDEX, domain);
|
|
731
|
|
732 children = Fcons (gii, children);
|
|
733
|
|
734 if (EQ (orient, Qhorizontal))
|
|
735 {
|
|
736 if (EQ (justify, Qright))
|
|
737 y = ph - (gheight + vert_spacing);
|
|
738 else if (EQ (justify, Qcenter))
|
|
739 y = (ph - gheight) / 2;
|
|
740 }
|
|
741 else if (EQ (orient, Qvertical))
|
|
742 {
|
|
743 if (EQ (justify, Qright))
|
|
744 x = pw - (gwidth + horiz_spacing);
|
|
745 else if (EQ (justify, Qcenter))
|
|
746 x = (pw - gwidth) / 2;
|
|
747 }
|
|
748
|
|
749 XIMAGE_INSTANCE_XOFFSET (gii) = x;
|
|
750 XIMAGE_INSTANCE_YOFFSET (gii) = y;
|
|
751
|
|
752 if (EQ (orient, Qhorizontal))
|
|
753 {
|
|
754 x += (gwidth + horiz_spacing);
|
|
755 }
|
|
756 else if (EQ (orient, Qvertical))
|
|
757 {
|
|
758 y += (gheight + vert_spacing);
|
|
759 }
|
|
760 }
|
|
761
|
|
762 IMAGE_INSTANCE_LAYOUT_CHILDREN (ii) = children;
|
|
763 assert (pw && ph);
|
|
764 IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii) = pw;
|
|
765 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii) = ph;
|
|
766 }
|
|
767
|
|
768
|
384
|
769 /************************************************************************/
|
|
770 /* initialization */
|
|
771 /************************************************************************/
|
|
772
|
|
773 void
|
|
774 syms_of_glyphs_widget (void)
|
|
775 {
|
|
776 defkeyword (&Q_descriptor, ":descriptor");
|
|
777 defkeyword (&Q_height, ":height");
|
|
778 defkeyword (&Q_width, ":width");
|
|
779 defkeyword (&Q_properties, ":properties");
|
|
780 defkeyword (&Q_items, ":items");
|
388
|
781 defkeyword (&Q_image, ":image");
|
412
|
782 defkeyword (&Q_percent, ":percent");
|
418
|
783 defkeyword (&Q_text, ":text");
|
424
|
784 defkeyword (&Q_orientation, ":orientation");
|
|
785 defkeyword (&Q_justify, ":justify");
|
|
786 defkeyword (&Q_border, ":border");
|
|
787
|
|
788 defsymbol (&Qetched_in, "etched-in");
|
|
789 defsymbol (&Qetched_out, "etched-out");
|
|
790 defsymbol (&Qbevel_in, "bevel-in");
|
|
791 defsymbol (&Qbevel_out, "bevel-out");
|
398
|
792 }
|
384
|
793
|
398
|
794 void
|
|
795 image_instantiator_format_create_glyphs_widget (void)
|
|
796 {
|
412
|
797 #define VALID_GUI_KEYWORDS(type) \
|
|
798 IIFORMAT_VALID_KEYWORD (type, Q_active, check_valid_anything); \
|
|
799 IIFORMAT_VALID_KEYWORD (type, Q_suffix, check_valid_anything); \
|
|
800 IIFORMAT_VALID_KEYWORD (type, Q_keys, check_valid_string); \
|
|
801 IIFORMAT_VALID_KEYWORD (type, Q_style, check_valid_symbol); \
|
|
802 IIFORMAT_VALID_KEYWORD (type, Q_selected, check_valid_anything); \
|
|
803 IIFORMAT_VALID_KEYWORD (type, Q_filter, check_valid_anything); \
|
|
804 IIFORMAT_VALID_KEYWORD (type, Q_config, check_valid_symbol); \
|
|
805 IIFORMAT_VALID_KEYWORD (type, Q_included, check_valid_anything); \
|
|
806 IIFORMAT_VALID_KEYWORD (type, Q_key_sequence, check_valid_string); \
|
|
807 IIFORMAT_VALID_KEYWORD (type, Q_accelerator, check_valid_string); \
|
|
808 IIFORMAT_VALID_KEYWORD (type, Q_label, check_valid_anything); \
|
|
809 IIFORMAT_VALID_KEYWORD (type, Q_callback, check_valid_callback); \
|
|
810 IIFORMAT_VALID_KEYWORD (type, Q_descriptor, check_valid_string_or_vector)
|
|
811
|
|
812 #define VALID_WIDGET_KEYWORDS(type) \
|
|
813 IIFORMAT_VALID_KEYWORD (type, Q_width, check_valid_int); \
|
|
814 IIFORMAT_VALID_KEYWORD (type, Q_height, check_valid_int); \
|
|
815 IIFORMAT_VALID_KEYWORD (type, Q_pixel_width, check_valid_int); \
|
|
816 IIFORMAT_VALID_KEYWORD (type, Q_pixel_height, check_valid_int); \
|
|
817 IIFORMAT_VALID_KEYWORD (type, Q_face, check_valid_face)
|
|
818
|
|
819 /* we only do this for properties */
|
|
820 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT_NO_SYM (widget, "widget");
|
|
821 IIFORMAT_HAS_METHOD (widget, property);
|
|
822 IIFORMAT_HAS_METHOD (widget, set_property);
|
|
823
|
|
824 /* widget image-instantiator types - buttons */
|
|
825 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (button, "button");
|
|
826 IIFORMAT_HAS_SHARED_METHOD (button, validate, widget);
|
|
827 IIFORMAT_HAS_SHARED_METHOD (button, possible_dest_types, widget);
|
|
828 IIFORMAT_HAS_SHARED_METHOD (button, instantiate, widget);
|
|
829 IIFORMAT_HAS_SHARED_METHOD (button, normalize, widget);
|
424
|
830 IIFORMAT_VALID_KEYWORD (button,
|
|
831 Q_image, check_valid_glyph_or_instantiator);
|
412
|
832 VALID_WIDGET_KEYWORDS (button);
|
|
833 VALID_GUI_KEYWORDS (button);
|
|
834
|
|
835 /* edit fields */
|
420
|
836 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (edit_field, "edit-field");
|
|
837 IIFORMAT_HAS_SHARED_METHOD (edit_field, validate, widget);
|
|
838 IIFORMAT_HAS_SHARED_METHOD (edit_field, possible_dest_types, widget);
|
|
839 IIFORMAT_HAS_SHARED_METHOD (edit_field, instantiate, widget);
|
|
840 VALID_WIDGET_KEYWORDS (edit_field);
|
|
841 VALID_GUI_KEYWORDS (edit_field);
|
398
|
842
|
412
|
843 /* combo box */
|
420
|
844 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (combo_box, "combo-box");
|
|
845 IIFORMAT_HAS_METHOD (combo_box, validate);
|
|
846 IIFORMAT_HAS_SHARED_METHOD (combo_box, possible_dest_types, widget);
|
|
847 VALID_GUI_KEYWORDS (combo_box);
|
412
|
848
|
420
|
849 IIFORMAT_VALID_KEYWORD (combo_box, Q_width, check_valid_int);
|
|
850 IIFORMAT_VALID_KEYWORD (combo_box, Q_height, check_valid_int);
|
|
851 IIFORMAT_VALID_KEYWORD (combo_box, Q_pixel_width, check_valid_int);
|
|
852 IIFORMAT_VALID_KEYWORD (combo_box, Q_face, check_valid_face);
|
|
853 IIFORMAT_VALID_KEYWORD (combo_box, Q_properties, check_valid_item_list);
|
412
|
854
|
|
855 /* scrollbar */
|
|
856 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (scrollbar, "scrollbar");
|
|
857 IIFORMAT_HAS_SHARED_METHOD (scrollbar, validate, widget);
|
|
858 IIFORMAT_HAS_SHARED_METHOD (scrollbar, possible_dest_types, widget);
|
|
859 IIFORMAT_HAS_SHARED_METHOD (scrollbar, instantiate, widget);
|
|
860 VALID_GUI_KEYWORDS (scrollbar);
|
|
861
|
|
862 IIFORMAT_VALID_KEYWORD (scrollbar, Q_pixel_width, check_valid_int);
|
|
863 IIFORMAT_VALID_KEYWORD (scrollbar, Q_pixel_height, check_valid_int);
|
|
864 IIFORMAT_VALID_KEYWORD (scrollbar, Q_face, check_valid_face);
|
|
865
|
|
866 /* progress guage */
|
420
|
867 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (progress_gauge, "progress-gauge");
|
|
868 IIFORMAT_HAS_SHARED_METHOD (progress_gauge, validate, widget);
|
|
869 IIFORMAT_HAS_SHARED_METHOD (progress_gauge, possible_dest_types, widget);
|
424
|
870 IIFORMAT_HAS_SHARED_METHOD (progress_gauge, instantiate, widget);
|
420
|
871 VALID_WIDGET_KEYWORDS (progress_gauge);
|
|
872 VALID_GUI_KEYWORDS (progress_gauge);
|
412
|
873
|
418
|
874 /* tree view */
|
420
|
875 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (tree_view, "tree-view");
|
|
876 IIFORMAT_HAS_SHARED_METHOD (tree_view, validate, combo_box);
|
|
877 IIFORMAT_HAS_SHARED_METHOD (tree_view, possible_dest_types, widget);
|
424
|
878 IIFORMAT_HAS_METHOD (tree_view, instantiate);
|
420
|
879 VALID_WIDGET_KEYWORDS (tree_view);
|
|
880 VALID_GUI_KEYWORDS (tree_view);
|
|
881 IIFORMAT_VALID_KEYWORD (tree_view, Q_properties, check_valid_item_list);
|
418
|
882
|
|
883 /* tab control */
|
420
|
884 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (tab_control, "tab-control");
|
|
885 IIFORMAT_HAS_SHARED_METHOD (tab_control, validate, combo_box);
|
|
886 IIFORMAT_HAS_SHARED_METHOD (tab_control, possible_dest_types, widget);
|
|
887 IIFORMAT_HAS_METHOD (tab_control, instantiate);
|
|
888 VALID_WIDGET_KEYWORDS (tab_control);
|
|
889 VALID_GUI_KEYWORDS (tab_control);
|
|
890 IIFORMAT_VALID_KEYWORD (tab_control, Q_properties, check_valid_item_list);
|
418
|
891
|
412
|
892 /* labels */
|
|
893 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (label, "label");
|
|
894 IIFORMAT_HAS_SHARED_METHOD (label, possible_dest_types, widget);
|
|
895 IIFORMAT_HAS_SHARED_METHOD (label, instantiate, static);
|
|
896 VALID_WIDGET_KEYWORDS (label);
|
|
897 IIFORMAT_VALID_KEYWORD (label, Q_descriptor, check_valid_string);
|
|
898
|
424
|
899 /* layout */
|
|
900 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (layout, "layout");
|
|
901 IIFORMAT_HAS_METHOD (layout, possible_dest_types);
|
|
902 IIFORMAT_HAS_METHOD (layout, instantiate);
|
|
903 IIFORMAT_HAS_METHOD (layout, normalize);
|
|
904 IIFORMAT_VALID_KEYWORD (layout, Q_pixel_width, check_valid_int);
|
|
905 IIFORMAT_VALID_KEYWORD (layout, Q_pixel_height, check_valid_int);
|
|
906 IIFORMAT_VALID_KEYWORD (layout, Q_orientation, check_valid_orientation);
|
|
907 IIFORMAT_VALID_KEYWORD (layout, Q_justify, check_valid_justification);
|
|
908 IIFORMAT_VALID_KEYWORD (layout, Q_border, check_valid_border);
|
|
909 IIFORMAT_VALID_KEYWORD (layout, Q_items,
|
|
910 check_valid_glyph_or_instantiator_list);
|
|
911 }
|
412
|
912
|
424
|
913 void
|
|
914 reinit_vars_of_glyphs_widget (void)
|
|
915 {
|
|
916 #ifdef DEBUG_WIDGETS
|
|
917 debug_widget_instances = 0;
|
384
|
918 #endif
|
|
919 }
|
|
920
|
|
921 void
|
|
922 vars_of_glyphs_widget (void)
|
|
923 {
|
424
|
924 reinit_vars_of_glyphs_widget ();
|
384
|
925 }
|