Mercurial > hg > xemacs-beta
comparison src/glyphs-widget.c @ 438:84b14dcb0985 r21-2-27
Import from CVS: tag r21-2-27
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:32:25 +0200 |
parents | 9d177e8d4150 |
children | 8de8e3f6228a |
comparison
equal
deleted
inserted
replaced
437:e2a4e8b94b82 | 438:84b14dcb0985 |
---|---|
1 /* Widget-specific glyph objects. | 1 /* Widget-specific glyph objects. |
2 Copyright (C) 1998, 1999 Andy Piper. | 2 Copyright (C) 1998, 1999, 2000 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 |
58 | 58 |
59 Lisp_Object Q_descriptor, Q_height, Q_width, Q_properties, Q_items; | 59 Lisp_Object Q_descriptor, Q_height, Q_width, Q_properties, Q_items; |
60 Lisp_Object Q_image, Q_text, Q_percent, Q_orientation, Q_justify, Q_border; | 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; | 61 Lisp_Object Qetched_in, Qetched_out, Qbevel_in, Qbevel_out; |
62 | 62 |
63 #define WIDGET_BORDER_HEIGHT 4 | |
64 #define WIDGET_BORDER_WIDTH 4 | |
65 | |
66 #ifdef DEBUG_WIDGETS | 63 #ifdef DEBUG_WIDGETS |
67 int debug_widget_instances; | 64 int debug_widget_instances; |
68 #endif | 65 #endif |
69 | 66 |
70 /* TODO: | 67 /* TODO: |
71 - more complex controls. | 68 - more complex controls. |
72 - tooltips for controls. | 69 - tooltips for controls, especially buttons. |
73 */ | 70 */ |
74 | 71 |
75 /* In windows normal windows work in pixels, dialog boxes work in | 72 /* In MS-Windows normal windows work in pixels, dialog boxes work in |
76 dialog box units. Why? sigh. We could reuse the metrics for dialogs | 73 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 | 74 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 | 75 pixel wise. I'm not even sure that X has this problem at least for |
79 buttons in groups. */ | 76 buttons in groups. */ |
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) | |
102 *height = th * ch + 2 * WIDGET_BORDER_HEIGHT; | |
103 if (width) | |
104 *width = tw * cw + 2 * WIDGET_BORDER_WIDTH; | |
105 } | |
106 | |
107 static int | 77 static int |
108 widget_possible_dest_types (void) | 78 widget_possible_dest_types (void) |
109 { | 79 { |
110 return IMAGE_WIDGET_MASK; | 80 return IMAGE_WIDGET_MASK; |
111 } | 81 } |
128 { | 98 { |
129 if (!EQ (data, Qhorizontal) | 99 if (!EQ (data, Qhorizontal) |
130 && | 100 && |
131 !EQ (data, Qvertical)) | 101 !EQ (data, Qvertical)) |
132 signal_simple_error ("unknown orientation for layout", data); | 102 signal_simple_error ("unknown orientation for layout", data); |
103 } | |
104 | |
105 static void | |
106 check_valid_tab_orientation (Lisp_Object data) | |
107 { | |
108 if (!EQ (data, Qtop) | |
109 && | |
110 !EQ (data, Qbottom) | |
111 && | |
112 !EQ (data, Qleft) | |
113 && | |
114 !EQ (data, Qright)) | |
115 signal_simple_error ("unknown orientation for tab control", data); | |
133 } | 116 } |
134 | 117 |
135 static void | 118 static void |
136 check_valid_justification (Lisp_Object data) | 119 check_valid_justification (Lisp_Object data) |
137 { | 120 { |
257 break; | 240 break; |
258 } | 241 } |
259 } | 242 } |
260 } | 243 } |
261 | 244 |
262 /* wire widget property invocations to specific widgets ... The | 245 /* Wire widget property invocations to specific widgets. The problem |
263 problem we are solving here is that when instantiators get converted | 246 we are solving here is that when instantiators get converted to |
264 to instances they lose some type information (they just become | 247 instances they lose some type information (they just become |
265 subwindows or widgets for example). For widgets we need to preserve | 248 subwindows or widgets for example). For widgets we need to preserve |
266 this type information so that we can do widget specific operations on | 249 this type information so that we can do widget specific operations |
267 the instances. This is encoded in the widget type | 250 on the instances. This is encoded in the widget type |
268 field. widget_property gets invoked by decoding the primary type | 251 field. widget_property gets invoked by decoding the primary type |
269 (Qwidget), widget property then invokes based on the secondary type | 252 (Qwidget), <widget>_property then invokes based on the secondary |
270 (Qedit_field for example). It is debatable that we should wire things in this | 253 type (Qedit_field for example). It is debatable whether we should |
271 generalised way rather than treating widgets specially in | 254 wire things in this generalised way rather than treating widgets |
272 image_instance_property. */ | 255 specially in image_instance_property. */ |
273 static Lisp_Object | 256 static Lisp_Object |
274 widget_property (Lisp_Object image_instance, Lisp_Object prop) | 257 widget_property (Lisp_Object image_instance, Lisp_Object prop) |
275 { | 258 { |
276 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance); | 259 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance); |
277 struct image_instantiator_methods* meths; | 260 struct image_instantiator_methods* meths; |
300 { | 283 { |
301 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance); | 284 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance); |
302 struct image_instantiator_methods* meths; | 285 struct image_instantiator_methods* meths; |
303 Lisp_Object ret; | 286 Lisp_Object ret; |
304 | 287 |
305 /* try device specific methods first ... */ | 288 /* PIck up any generic properties that we might need to keep hold |
289 of. */ | |
290 if (EQ (prop, Q_text)) | |
291 { | |
292 IMAGE_INSTANCE_WIDGET_TEXT (ii) = val; | |
293 } | |
294 | |
295 /* Now try device specific methods first ... */ | |
306 meths = decode_device_ii_format (IMAGE_INSTANCE_DEVICE (ii), | 296 meths = decode_device_ii_format (IMAGE_INSTANCE_DEVICE (ii), |
307 IMAGE_INSTANCE_WIDGET_TYPE (ii), | 297 IMAGE_INSTANCE_WIDGET_TYPE (ii), |
308 ERROR_ME_NOT); | 298 ERROR_ME_NOT); |
309 if (meths && HAS_IIFORMAT_METH_P (meths, set_property) | 299 if (meths && HAS_IIFORMAT_METH_P (meths, set_property) |
310 && | 300 && |
327 IMAGE_INSTANCE_WIDGET_PROPS (ii) | 317 IMAGE_INSTANCE_WIDGET_PROPS (ii) |
328 = Fplist_put (IMAGE_INSTANCE_WIDGET_PROPS (ii), prop, val); | 318 = Fplist_put (IMAGE_INSTANCE_WIDGET_PROPS (ii), prop, val); |
329 return val; | 319 return val; |
330 } | 320 } |
331 | 321 |
322 /* Query for a widgets desired geometry. If no type specific method is | |
323 provided then use the widget text to calculate sizes. */ | |
324 static void | |
325 widget_query_geometry (Lisp_Object image_instance, | |
326 unsigned int* width, unsigned int* height, | |
327 enum image_instance_geometry disp, Lisp_Object domain) | |
328 { | |
329 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance); | |
330 struct image_instantiator_methods* meths; | |
331 | |
332 /* First just set up what we already have. */ | |
333 if (width) *width = IMAGE_INSTANCE_WIDTH (ii); | |
334 if (height) *height = IMAGE_INSTANCE_HEIGHT (ii); | |
335 | |
336 if (IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii) | |
337 || | |
338 IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii)) | |
339 { | |
340 /* .. then try device specific methods ... */ | |
341 meths = decode_device_ii_format (IMAGE_INSTANCE_DEVICE (ii), | |
342 IMAGE_INSTANCE_WIDGET_TYPE (ii), | |
343 ERROR_ME_NOT); | |
344 if (meths && HAS_IIFORMAT_METH_P (meths, query_geometry)) | |
345 IIFORMAT_METH (meths, query_geometry, (image_instance, | |
346 width, height, disp, | |
347 domain)); | |
348 else | |
349 { | |
350 /* ... then format specific methods ... */ | |
351 meths = decode_device_ii_format (Qnil, IMAGE_INSTANCE_WIDGET_TYPE (ii), | |
352 ERROR_ME_NOT); | |
353 if (meths && HAS_IIFORMAT_METH_P (meths, query_geometry)) | |
354 IIFORMAT_METH (meths, query_geometry, (image_instance, | |
355 width, height, disp, | |
356 domain)); | |
357 else | |
358 { | |
359 unsigned int w, h; | |
360 | |
361 /* Then if we are allowed to resize the widget, make the | |
362 size the same as the text dimensions. */ | |
363 query_string_geometry (IMAGE_INSTANCE_WIDGET_TEXT (ii), | |
364 IMAGE_INSTANCE_WIDGET_FACE (ii), | |
365 &w, &h, 0, domain); | |
366 /* Adjust the size for borders. */ | |
367 if (IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii)) | |
368 *width = w + 2 * WIDGET_BORDER_WIDTH; | |
369 if (IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii)) | |
370 *height = h + 2 * WIDGET_BORDER_HEIGHT; | |
371 } | |
372 } | |
373 } | |
374 } | |
375 | |
376 static void | |
377 widget_layout (Lisp_Object image_instance, | |
378 unsigned int width, unsigned int height, Lisp_Object domain) | |
379 { | |
380 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance); | |
381 struct image_instantiator_methods* meths; | |
382 | |
383 /* .. then try device specific methods ... */ | |
384 meths = decode_device_ii_format (IMAGE_INSTANCE_DEVICE (ii), | |
385 IMAGE_INSTANCE_WIDGET_TYPE (ii), | |
386 ERROR_ME_NOT); | |
387 if (meths && HAS_IIFORMAT_METH_P (meths, layout)) | |
388 IIFORMAT_METH (meths, layout, (image_instance, | |
389 width, height, domain)); | |
390 else | |
391 { | |
392 /* ... then format specific methods ... */ | |
393 meths = decode_device_ii_format (Qnil, IMAGE_INSTANCE_WIDGET_TYPE (ii), | |
394 ERROR_ME_NOT); | |
395 if (meths && HAS_IIFORMAT_METH_P (meths, layout)) | |
396 IIFORMAT_METH (meths, layout, (image_instance, | |
397 width, height, domain)); | |
398 } | |
399 } | |
400 | |
332 static void | 401 static void |
333 widget_validate (Lisp_Object instantiator) | 402 widget_validate (Lisp_Object instantiator) |
334 { | 403 { |
335 Lisp_Object desc = find_keyword_in_vector (instantiator, Q_descriptor); | 404 Lisp_Object desc = find_keyword_in_vector (instantiator, Q_descriptor); |
336 | 405 |
379 initialize_widget_image_instance (struct Lisp_Image_Instance *ii, Lisp_Object type) | 448 initialize_widget_image_instance (struct Lisp_Image_Instance *ii, Lisp_Object type) |
380 { | 449 { |
381 /* initialize_subwindow_image_instance (ii);*/ | 450 /* initialize_subwindow_image_instance (ii);*/ |
382 IMAGE_INSTANCE_WIDGET_TYPE (ii) = type; | 451 IMAGE_INSTANCE_WIDGET_TYPE (ii) = type; |
383 IMAGE_INSTANCE_WIDGET_PROPS (ii) = Qnil; | 452 IMAGE_INSTANCE_WIDGET_PROPS (ii) = Qnil; |
384 IMAGE_INSTANCE_WIDGET_FACE (ii) = Vwidget_face; | 453 SET_IMAGE_INSTANCE_WIDGET_FACE (ii, Qnil); |
385 IMAGE_INSTANCE_WIDGET_ITEMS (ii) = allocate_gui_item (); | 454 IMAGE_INSTANCE_WIDGET_ITEMS (ii) = allocate_gui_item (); |
455 IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii) = 1; | |
456 IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii) = 1; | |
457 IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) = 0; | |
458 IMAGE_INSTANCE_SUBWINDOW_JUSTIFY (ii) = 0; | |
386 } | 459 } |
387 | 460 |
388 /* Instantiate a button widget. Unfortunately instantiated widgets are | 461 /* Instantiate a button widget. Unfortunately instantiated widgets are |
389 particular to a frame since they need to have a parent. It's not | 462 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 | 463 like images where you just select the image into the context you |
391 want to display it in and BitBlt it. So image instances can have a | 464 want to display it in and BitBlt it. So image instances can have a |
392 many-to-one relationship with things you see, whereas widgets can | 465 many-to-one relationship with things you see, whereas widgets can |
393 only be one-to-one (i.e. per frame) */ | 466 only be one-to-one (i.e. per frame) */ |
394 void | 467 void |
395 widget_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator, | 468 widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, |
396 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | 469 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
397 int dest_mask, Lisp_Object domain, int default_textheight, | 470 int dest_mask, Lisp_Object domain) |
398 int default_pixheight, int default_textwidth) | |
399 { | 471 { |
400 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | 472 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
401 Lisp_Object face = find_keyword_in_vector (instantiator, Q_face); | 473 Lisp_Object face = find_keyword_in_vector (instantiator, Q_face); |
402 Lisp_Object height = find_keyword_in_vector (instantiator, Q_height); | 474 Lisp_Object height = find_keyword_in_vector (instantiator, Q_height); |
403 Lisp_Object width = find_keyword_in_vector (instantiator, Q_width); | 475 Lisp_Object width = find_keyword_in_vector (instantiator, Q_width); |
404 Lisp_Object pixwidth = find_keyword_in_vector (instantiator, Q_pixel_width); | 476 Lisp_Object pixwidth = find_keyword_in_vector (instantiator, Q_pixel_width); |
405 Lisp_Object pixheight = find_keyword_in_vector (instantiator, Q_pixel_height); | 477 Lisp_Object pixheight = find_keyword_in_vector (instantiator, Q_pixel_height); |
406 Lisp_Object desc = find_keyword_in_vector (instantiator, Q_descriptor); | 478 Lisp_Object desc = find_keyword_in_vector (instantiator, Q_descriptor); |
407 Lisp_Object glyph = find_keyword_in_vector (instantiator, Q_image); | 479 Lisp_Object glyph = find_keyword_in_vector (instantiator, Q_image); |
408 Lisp_Object props = find_keyword_in_vector (instantiator, Q_properties); | 480 Lisp_Object props = find_keyword_in_vector (instantiator, Q_properties); |
481 Lisp_Object orient = find_keyword_in_vector (instantiator, Q_orientation); | |
409 int pw=0, ph=0, tw=0, th=0; | 482 int pw=0, ph=0, tw=0, th=0; |
410 | 483 |
411 /* this just does pixel type sizing */ | 484 /* this just does pixel type sizing */ |
412 subwindow_instantiate (image_instance, instantiator, pointer_fg, pointer_bg, | 485 subwindow_instantiate (image_instance, instantiator, pointer_fg, pointer_bg, |
413 dest_mask, domain); | 486 dest_mask, domain); |
417 | 490 |
418 initialize_widget_image_instance (ii, XVECTOR_DATA (instantiator)[0]); | 491 initialize_widget_image_instance (ii, XVECTOR_DATA (instantiator)[0]); |
419 | 492 |
420 /* retrieve the fg and bg colors */ | 493 /* retrieve the fg and bg colors */ |
421 if (!NILP (face)) | 494 if (!NILP (face)) |
422 IMAGE_INSTANCE_WIDGET_FACE (ii) = Fget_face (face); | 495 SET_IMAGE_INSTANCE_WIDGET_FACE (ii, Fget_face (face)); |
423 | 496 |
424 /* data items for some widgets */ | 497 /* data items for some widgets */ |
425 IMAGE_INSTANCE_WIDGET_PROPS (ii) = props; | 498 IMAGE_INSTANCE_WIDGET_PROPS (ii) = props; |
499 | |
500 /* Pick up the orientation before we do our first layout. */ | |
501 if (EQ (orient, Qleft) || EQ (orient, Qright) || EQ (orient, Qvertical)) | |
502 IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) = 1; | |
426 | 503 |
427 /* retrieve the gui item information. This is easy if we have been | 504 /* 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 | 505 provided with a vector, more difficult if we have just been given |
429 keywords */ | 506 keywords */ |
430 if (STRINGP (desc) || NILP (desc)) | 507 if (STRINGP (desc) || NILP (desc)) |
446 IMAGE_INSTANCE_WIDGET_ITEMS (ii) = | 523 IMAGE_INSTANCE_WIDGET_ITEMS (ii) = |
447 Fcons (IMAGE_INSTANCE_WIDGET_ITEMS (ii), | 524 Fcons (IMAGE_INSTANCE_WIDGET_ITEMS (ii), |
448 parse_gui_item_tree_children (items)); | 525 parse_gui_item_tree_children (items)); |
449 } | 526 } |
450 | 527 |
451 /* normalize size information */ | 528 /* Normalize size information. We now only assign sizes if the user |
452 if (!NILP (width)) | 529 gives us some explicitly, or there are some constraints that we |
453 tw = XINT (width); | 530 can't change later on. Otherwise we postpone sizing until query |
454 if (!NILP (height)) | 531 geometry gets called. */ |
455 th = XINT (height); | 532 if (!NILP (pixwidth)) /* pixwidth takes precendent */ |
456 if (!NILP (pixwidth)) | 533 { |
457 pw = XINT (pixwidth); | 534 pw = XINT (pixwidth); |
535 IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii) = 0; | |
536 } | |
537 else if (!NILP (width)) | |
538 { | |
539 tw = XINT (width); | |
540 IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii) = 0; | |
541 } | |
542 | |
458 if (!NILP (pixheight)) | 543 if (!NILP (pixheight)) |
459 ph = XINT (pixheight); | 544 { |
545 ph = XINT (pixheight); | |
546 IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii) = 0; | |
547 } | |
548 else if (!NILP (height) && XINT (height) > 1) | |
549 { | |
550 th = XINT (height); | |
551 IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii) = 0; | |
552 } | |
553 | |
554 /* Taking the default face information when the user has specified | |
555 size in characters is probably as good as any since the widget | |
556 face is more likely to be proportional and thus give inadequate | |
557 results. Using character sizes can only ever be approximate | |
558 anyway. */ | |
559 if (tw || th) | |
560 { | |
561 int charwidth, charheight; | |
562 default_face_font_info (domain, 0, 0, &charheight, &charwidth, 0); | |
563 if (tw) | |
564 pw = charwidth * tw; | |
565 if (th) | |
566 ph = charheight * th; | |
567 } | |
460 | 568 |
461 /* for a widget with an image pick up the dimensions from that */ | 569 /* for a widget with an image pick up the dimensions from that */ |
462 if (!NILP (glyph)) | 570 if (!NILP (glyph)) |
463 { | 571 { |
464 if (!pw && !tw) | 572 if (!pw) |
465 pw = glyph_width (glyph, Qnil, DEFAULT_INDEX, domain) | 573 pw = glyph_width (glyph, domain) + 2 * WIDGET_BORDER_WIDTH; |
466 + 2 * WIDGET_BORDER_WIDTH; | 574 if (!ph) |
467 if (!ph && !th) | 575 ph = glyph_height (glyph, domain) + 2 * WIDGET_BORDER_HEIGHT; |
468 ph = glyph_height (glyph, Qnil, DEFAULT_INDEX, domain) | 576 IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii) = 0; |
469 + 2 * WIDGET_BORDER_HEIGHT; | 577 IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii) = 0; |
470 } | 578 } |
471 | 579 |
472 /* if we still don' t have sizes, guess from text size */ | 580 /* have to set the type this late in case there is no device |
473 if (!tw && !pw) | 581 instantiation for a widget */ |
474 { | 582 IMAGE_INSTANCE_TYPE (ii) = IMAGE_WIDGET; |
475 if (default_textwidth) | 583 |
476 tw = default_textwidth; | 584 /* When we create the widgets the window system expects a valid |
477 else if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii))) | 585 size, so If we still don' t have sizes, call layout to pick them |
478 tw = XSTRING_LENGTH (IMAGE_INSTANCE_WIDGET_TEXT (ii)); | 586 up. If query_geometry or layout relies on the widget being in |
479 } | 587 existence then we are in catch 22. */ |
480 | 588 image_instance_layout (image_instance, |
481 if (!th && !ph) | 589 pw ? pw : IMAGE_UNSPECIFIED_GEOMETRY, |
482 { | 590 ph ? ph : IMAGE_UNSPECIFIED_GEOMETRY, |
483 if (default_textheight) | 591 domain); |
484 th = default_textheight; | 592 /* Layout has already been done so we don't need to re-layout. */ |
485 else if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii))) | 593 IMAGE_INSTANCE_DIRTYP (ii) = 0; |
486 th = 1; | 594 |
487 else | |
488 ph = default_pixheight; | |
489 } | |
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); | |
495 | |
496 IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii) = pw; | |
497 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii) = ph; | |
498 #ifdef DEBUG_WIDGETS | 595 #ifdef DEBUG_WIDGETS |
499 debug_widget_instances++; | 596 debug_widget_instances++; |
500 stderr_out ("instantiated "); | 597 stderr_out ("instantiated "); |
501 debug_print (instantiator); | 598 debug_print (instantiator); |
502 stderr_out ("%d widgets instantiated\n", debug_widget_instances); | 599 stderr_out ("%d widgets instantiated\n", debug_widget_instances); |
503 #endif | 600 #endif |
504 } | 601 } |
505 | 602 |
506 static void | 603 /* tree-view geometry - get the height right */ |
507 widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | 604 static void |
508 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | 605 tree_view_query_geometry (Lisp_Object image_instance, |
509 int dest_mask, Lisp_Object domain) | 606 unsigned int* width, unsigned int* height, |
510 { | 607 enum image_instance_geometry disp, Lisp_Object domain) |
511 widget_instantiate_1 (image_instance, instantiator, pointer_fg, | 608 { |
512 pointer_bg, dest_mask, domain, 1, 0, 0); | 609 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
513 } | 610 Lisp_Object items = IMAGE_INSTANCE_WIDGET_ITEMS (ii); |
514 | 611 |
515 /* tree-view generic instantiation - get the height right */ | 612 |
516 static void | 613 if (*width) |
517 tree_view_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | 614 { |
518 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | 615 /* #### what should this be. reconsider when X has tree views. */ |
519 int dest_mask, Lisp_Object domain) | 616 query_string_geometry (IMAGE_INSTANCE_WIDGET_TEXT (ii), |
520 { | 617 IMAGE_INSTANCE_WIDGET_FACE (ii), |
521 Lisp_Object data = Fplist_get (find_keyword_in_vector (instantiator, Q_properties), | 618 width, 0, 0, domain); |
522 Q_items, Qnil); | 619 } |
523 int len; | 620 if (*height) |
524 GET_LIST_LENGTH (data, len); | 621 { |
525 widget_instantiate_1 (image_instance, instantiator, pointer_fg, | 622 int len, h; |
526 pointer_bg, dest_mask, domain, len + 1, 0, 0); | 623 default_face_font_info (domain, 0, 0, &h, 0, 0); |
527 } | 624 GET_LIST_LENGTH (items, len); |
528 | 625 *height = len * h; |
529 static void | 626 } |
530 tab_control_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | 627 } |
531 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | 628 |
532 int dest_mask, Lisp_Object domain) | 629 /* Get the geometry of a tab control. This is based on the number of |
533 { | 630 items and text therin in the tab control. */ |
534 Lisp_Object data = Fplist_get (find_keyword_in_vector (instantiator, Q_properties), | 631 static void |
535 Q_items, Qnil); | 632 tab_control_query_geometry (Lisp_Object image_instance, |
633 unsigned int* width, unsigned int* height, | |
634 enum image_instance_geometry disp, Lisp_Object domain) | |
635 { | |
636 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | |
637 Lisp_Object items = IMAGE_INSTANCE_WIDGET_ITEMS (ii); | |
536 Lisp_Object rest; | 638 Lisp_Object rest; |
537 int len = 0; | 639 unsigned int tw = 0, th = 0; |
538 | 640 |
539 LIST_LOOP (rest, data) | 641 LIST_LOOP (rest, items) |
540 { | 642 { |
541 len += 3; /* some bias */ | 643 unsigned int h, w; |
542 if (STRINGP (XCAR (rest))) | 644 |
543 len += XSTRING_LENGTH (XCAR (rest)); | 645 query_string_geometry (XGUI_ITEM (XCAR (rest))->name, |
544 else if (VECTORP (XCAR (rest))) | 646 IMAGE_INSTANCE_WIDGET_FACE (ii), |
545 { | 647 &w, &h, 0, domain); |
546 Lisp_Object gui = gui_parse_item_keywords (XCAR (rest)); | 648 tw += 2 * WIDGET_BORDER_WIDTH; /* some bias */ |
547 len += XSTRING_LENGTH (XGUI_ITEM (gui)->name); | 649 tw += w; |
548 } | 650 th = max (th, h + 2 * WIDGET_BORDER_HEIGHT); |
549 } | 651 } |
550 | 652 |
551 widget_instantiate_1 (image_instance, instantiator, pointer_fg, | 653 /* Fixup returned values depending on orientation. */ |
552 pointer_bg, dest_mask, domain, 0, 0, len); | 654 if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii)) |
553 } | 655 { |
554 | 656 if (height) *height = tw; |
555 /* Instantiate a static control */ | 657 if (width) *width = th; |
556 static void | 658 } |
557 static_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | 659 else |
558 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | 660 { |
559 int dest_mask, Lisp_Object domain) | 661 if (height) *height = th; |
560 { | 662 if (width) *width = tw; |
561 widget_instantiate_1 (image_instance, instantiator, pointer_fg, | 663 } |
562 pointer_bg, dest_mask, domain, 0, 4, 0); | |
563 } | 664 } |
564 | 665 |
565 | 666 |
566 /***************************************************************************** | 667 /***************************************************************************** |
567 * widget layout * | 668 * widget layout * |
687 | 788 |
688 /* flip through the items to work out how much stuff we have to display */ | 789 /* flip through the items to work out how much stuff we have to display */ |
689 LIST_LOOP (rest, items) | 790 LIST_LOOP (rest, items) |
690 { | 791 { |
691 Lisp_Object glyph = XCAR (rest); | 792 Lisp_Object glyph = XCAR (rest); |
692 int gheight = glyph_height (glyph, Qnil, DEFAULT_INDEX, domain); | 793 int gheight = glyph_height (glyph, domain); |
693 int gwidth = glyph_width (glyph, Qnil, DEFAULT_INDEX, domain); | 794 int gwidth = glyph_width (glyph, domain); |
694 nitems ++; | 795 nitems ++; |
695 if (EQ (orient, Qhorizontal)) | 796 if (EQ (orient, Qhorizontal)) |
696 { | 797 { |
697 maxph = max (maxph, gheight); | 798 maxph = max (maxph, gheight); |
698 maxpw += gwidth; | 799 maxpw += gwidth; |
736 | 837 |
737 children = Fcons (bglyph, children); | 838 children = Fcons (bglyph, children); |
738 XIMAGE_INSTANCE_XOFFSET (bglyph) = 10; /* Really, what should this be? */ | 839 XIMAGE_INSTANCE_XOFFSET (bglyph) = 10; /* Really, what should this be? */ |
739 XIMAGE_INSTANCE_YOFFSET (bglyph) = 0; | 840 XIMAGE_INSTANCE_YOFFSET (bglyph) = 0; |
740 | 841 |
741 ph_adjust = (glyph_height (border, Qnil, DEFAULT_INDEX, domain) / 2); | 842 ph_adjust = (glyph_height (border, domain) / 2); |
742 IMAGE_INSTANCE_LAYOUT_BORDER (ii) = make_int (ph_adjust); | 843 IMAGE_INSTANCE_LAYOUT_BORDER (ii) = make_int (ph_adjust); |
743 } | 844 } |
744 | 845 |
745 /* Work out vertical spacings. */ | 846 /* Work out vertical spacings. */ |
746 if (!ph) | 847 if (!ph) |
766 LIST_LOOP (rest, items) | 867 LIST_LOOP (rest, items) |
767 { | 868 { |
768 /* make sure the image is instantiated */ | 869 /* make sure the image is instantiated */ |
769 Lisp_Object glyph = XCAR (rest); | 870 Lisp_Object glyph = XCAR (rest); |
770 Lisp_Object gii = glyph_image_instance (glyph, domain, ERROR_ME, 1); | 871 Lisp_Object gii = glyph_image_instance (glyph, domain, ERROR_ME, 1); |
771 int gwidth = glyph_width (glyph, Qnil, DEFAULT_INDEX, domain); | 872 int gwidth = glyph_width (glyph, domain); |
772 int gheight = glyph_height (glyph, Qnil, DEFAULT_INDEX, domain); | 873 int gheight = glyph_height (glyph, domain); |
773 | 874 |
774 children = Fcons (gii, children); | 875 children = Fcons (gii, children); |
775 | 876 |
776 if (EQ (orient, Qhorizontal)) | 877 if (EQ (orient, Qhorizontal)) |
777 { | 878 { |
860 | 961 |
861 /* we only do this for properties */ | 962 /* we only do this for properties */ |
862 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT_NO_SYM (widget, "widget"); | 963 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT_NO_SYM (widget, "widget"); |
863 IIFORMAT_HAS_METHOD (widget, property); | 964 IIFORMAT_HAS_METHOD (widget, property); |
864 IIFORMAT_HAS_METHOD (widget, set_property); | 965 IIFORMAT_HAS_METHOD (widget, set_property); |
966 IIFORMAT_HAS_METHOD (widget, query_geometry); | |
967 IIFORMAT_HAS_METHOD (widget, layout); | |
865 | 968 |
866 /* widget image-instantiator types - buttons */ | 969 /* widget image-instantiator types - buttons */ |
867 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (button, "button"); | 970 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (button, "button"); |
868 IIFORMAT_HAS_SHARED_METHOD (button, validate, widget); | 971 IIFORMAT_HAS_SHARED_METHOD (button, validate, widget); |
869 IIFORMAT_HAS_SHARED_METHOD (button, possible_dest_types, widget); | 972 IIFORMAT_HAS_SHARED_METHOD (button, possible_dest_types, widget); |
915 | 1018 |
916 /* tree view */ | 1019 /* tree view */ |
917 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (tree_view, "tree-view"); | 1020 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (tree_view, "tree-view"); |
918 IIFORMAT_HAS_SHARED_METHOD (tree_view, validate, combo_box); | 1021 IIFORMAT_HAS_SHARED_METHOD (tree_view, validate, combo_box); |
919 IIFORMAT_HAS_SHARED_METHOD (tree_view, possible_dest_types, widget); | 1022 IIFORMAT_HAS_SHARED_METHOD (tree_view, possible_dest_types, widget); |
920 IIFORMAT_HAS_METHOD (tree_view, instantiate); | 1023 IIFORMAT_HAS_SHARED_METHOD (tree_view, instantiate, widget); |
1024 IIFORMAT_HAS_METHOD (tree_view, query_geometry); | |
921 VALID_WIDGET_KEYWORDS (tree_view); | 1025 VALID_WIDGET_KEYWORDS (tree_view); |
922 VALID_GUI_KEYWORDS (tree_view); | 1026 VALID_GUI_KEYWORDS (tree_view); |
923 IIFORMAT_VALID_KEYWORD (tree_view, Q_properties, check_valid_item_list); | 1027 IIFORMAT_VALID_KEYWORD (tree_view, Q_properties, check_valid_item_list); |
924 | 1028 |
925 /* tab control */ | 1029 /* tab control */ |
926 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (tab_control, "tab-control"); | 1030 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (tab_control, "tab-control"); |
927 IIFORMAT_HAS_SHARED_METHOD (tab_control, validate, combo_box); | 1031 IIFORMAT_HAS_SHARED_METHOD (tab_control, validate, combo_box); |
928 IIFORMAT_HAS_SHARED_METHOD (tab_control, possible_dest_types, widget); | 1032 IIFORMAT_HAS_SHARED_METHOD (tab_control, possible_dest_types, widget); |
929 IIFORMAT_HAS_METHOD (tab_control, instantiate); | 1033 IIFORMAT_HAS_SHARED_METHOD (tab_control, instantiate, widget); |
1034 IIFORMAT_HAS_METHOD (tab_control, query_geometry); | |
930 VALID_WIDGET_KEYWORDS (tab_control); | 1035 VALID_WIDGET_KEYWORDS (tab_control); |
931 VALID_GUI_KEYWORDS (tab_control); | 1036 VALID_GUI_KEYWORDS (tab_control); |
1037 IIFORMAT_VALID_KEYWORD (tab_control, Q_orientation, check_valid_tab_orientation); | |
932 IIFORMAT_VALID_KEYWORD (tab_control, Q_properties, check_valid_item_list); | 1038 IIFORMAT_VALID_KEYWORD (tab_control, Q_properties, check_valid_item_list); |
933 | 1039 |
934 /* labels */ | 1040 /* labels */ |
935 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (label, "label"); | 1041 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (label, "label"); |
936 IIFORMAT_HAS_SHARED_METHOD (label, possible_dest_types, widget); | 1042 IIFORMAT_HAS_SHARED_METHOD (label, possible_dest_types, widget); |
937 IIFORMAT_HAS_SHARED_METHOD (label, instantiate, static); | 1043 IIFORMAT_HAS_SHARED_METHOD (label, instantiate, widget); |
938 VALID_WIDGET_KEYWORDS (label); | 1044 VALID_WIDGET_KEYWORDS (label); |
939 IIFORMAT_VALID_KEYWORD (label, Q_descriptor, check_valid_string); | 1045 IIFORMAT_VALID_KEYWORD (label, Q_descriptor, check_valid_string); |
940 | 1046 |
941 /* layout */ | 1047 /* layout */ |
942 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (layout, "layout"); | 1048 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (layout, "layout"); |