1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
33 #include "gtkmarshalers.h"
35 #include "gtkspinbutton.h"
37 #include "gtkwidget.h"
38 #include "gtkthemes.h"
39 #include "gtkiconfactory.h"
40 #include "gtksettings.h" /* _gtk_settings_parse_convert() */
42 #define LIGHTNESS_MULT 1.3
43 #define DARKNESS_MULT 0.7
45 /* --- typedefs & structures --- */
52 /* --- prototypes --- */
53 static void gtk_style_init (GtkStyle *style);
54 static void gtk_style_class_init (GtkStyleClass *klass);
55 static void gtk_style_finalize (GObject *object);
56 static void gtk_style_realize (GtkStyle *style,
57 GdkColormap *colormap);
58 static void gtk_style_real_realize (GtkStyle *style);
59 static void gtk_style_real_unrealize (GtkStyle *style);
60 static void gtk_style_real_copy (GtkStyle *style,
62 static void gtk_style_real_set_background (GtkStyle *style,
64 GtkStateType state_type);
65 static GtkStyle *gtk_style_real_clone (GtkStyle *style);
66 static void gtk_style_real_init_from_rc (GtkStyle *style,
67 GtkRcStyle *rc_style);
68 static GdkPixbuf *gtk_default_render_icon (GtkStyle *style,
69 const GtkIconSource *source,
70 GtkTextDirection direction,
75 static void gtk_default_draw_hline (GtkStyle *style,
77 GtkStateType state_type,
84 static void gtk_default_draw_vline (GtkStyle *style,
86 GtkStateType state_type,
93 static void gtk_default_draw_shadow (GtkStyle *style,
95 GtkStateType state_type,
96 GtkShadowType shadow_type,
104 static void gtk_default_draw_polygon (GtkStyle *style,
106 GtkStateType state_type,
107 GtkShadowType shadow_type,
114 static void gtk_default_draw_arrow (GtkStyle *style,
116 GtkStateType state_type,
117 GtkShadowType shadow_type,
121 GtkArrowType arrow_type,
127 static void gtk_default_draw_diamond (GtkStyle *style,
129 GtkStateType state_type,
130 GtkShadowType shadow_type,
138 static void gtk_default_draw_string (GtkStyle *style,
140 GtkStateType state_type,
146 const gchar *string);
147 static void gtk_default_draw_box (GtkStyle *style,
149 GtkStateType state_type,
150 GtkShadowType shadow_type,
158 static void gtk_default_draw_flat_box (GtkStyle *style,
160 GtkStateType state_type,
161 GtkShadowType shadow_type,
169 static void gtk_default_draw_check (GtkStyle *style,
171 GtkStateType state_type,
172 GtkShadowType shadow_type,
180 static void gtk_default_draw_option (GtkStyle *style,
182 GtkStateType state_type,
183 GtkShadowType shadow_type,
191 static void gtk_default_draw_tab (GtkStyle *style,
193 GtkStateType state_type,
194 GtkShadowType shadow_type,
202 static void gtk_default_draw_shadow_gap (GtkStyle *style,
204 GtkStateType state_type,
205 GtkShadowType shadow_type,
213 GtkPositionType gap_side,
216 static void gtk_default_draw_box_gap (GtkStyle *style,
218 GtkStateType state_type,
219 GtkShadowType shadow_type,
227 GtkPositionType gap_side,
230 static void gtk_default_draw_extension (GtkStyle *style,
232 GtkStateType state_type,
233 GtkShadowType shadow_type,
241 GtkPositionType gap_side);
242 static void gtk_default_draw_focus (GtkStyle *style,
244 GtkStateType state_type,
252 static void gtk_default_draw_slider (GtkStyle *style,
254 GtkStateType state_type,
255 GtkShadowType shadow_type,
263 GtkOrientation orientation);
264 static void gtk_default_draw_handle (GtkStyle *style,
266 GtkStateType state_type,
267 GtkShadowType shadow_type,
275 GtkOrientation orientation);
276 static void gtk_default_draw_expander (GtkStyle *style,
278 GtkStateType state_type,
284 GtkExpanderStyle expander_style);
285 static void gtk_default_draw_layout (GtkStyle *style,
287 GtkStateType state_type,
294 PangoLayout *layout);
295 static void gtk_default_draw_resize_grip (GtkStyle *style,
297 GtkStateType state_type,
307 static void gtk_style_shade (GdkColor *a,
310 static void rgb_to_hls (gdouble *r,
313 static void hls_to_rgb (gdouble *h,
317 static void style_unrealize_cursor_gcs (GtkStyle *style);
319 static GdkFont *gtk_style_get_font_internal (GtkStyle *style);
322 * Data for default check and radio buttons
325 static const GtkRequisition default_option_indicator_size = { 7, 13 };
326 static const GtkBorder default_option_indicator_spacing = { 7, 5, 2, 2 };
328 #define INDICATOR_PART_SIZE 13
338 CHECK_INCONSISTENT_TEXT,
345 RADIO_INCONSISTENT_AA,
346 RADIO_INCONSISTENT_TEXT
350 * Extracted from check-13.png, width=13, height=13
352 static const guchar check_black_bits[] = {
353 0x00,0x00,0xfe,0x0f,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,
354 0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00};
355 static const guchar check_dark_bits[] = {
356 0xff,0x1f,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,
357 0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00};
358 static const guchar check_mid_bits[] = {
359 0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,
360 0x08,0x00,0x08,0x00,0x08,0x00,0x08,0xfc,0x0f,0x00,0x00,0x00,0x00};
361 static const guchar check_light_bits[] = {
362 0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,
363 0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0xfe,0x1f,0x00,0x00};
364 static const guchar check_text_bits[] = {
365 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x03,0x80,0x01,0x80,0x00,0x58,
366 0x00,0x60,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
367 static const guchar check_aa_bits[] = {
368 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x58,0x00,0xa0,
369 0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
370 static const guchar check_base_bits[] = {
371 0x00,0x00,0x00,0x00,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc,
372 0x07,0xfc,0x07,0xfc,0x07,0xfc,0x07,0x00,0x00,0x00,0x00,0x00,0x00};
375 * Extracted from check-13-inconsistent.png, width=13, height=13
377 static const guchar check_inconsistent_text_bits[] = {
378 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x03,0xf8,
379 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
382 * check_inconsistent_aa_bits is currently not used, since it is all zeros.
384 static const guchar check_inconsistent_aa_bits[] = {
385 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
386 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
390 * Extracted from radio-13.png, width=13, height=13
392 static const guchar radio_black_bits[] = {
393 0x00,0x00,0xf0,0x01,0x0c,0x02,0x04,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,
394 0x00,0x02,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x08};
395 static const guchar radio_dark_bits[] = {
396 0xf0,0x00,0x0c,0x02,0x02,0x04,0x02,0x04,0x01,0x08,0x01,0x08,0x01,0x08,0x01,
397 0x08,0x00,0x08,0x02,0x04,0x0c,0x06,0xf0,0x01,0x00,0x00,0x00,0x00};
398 static const guchar radio_mid_bits[] = {
399 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
400 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
401 static const guchar radio_light_bits[] = {
402 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,
403 0x10,0x00,0x10,0x00,0x08,0x00,0x08,0x00,0x06,0xe0,0x01,0x00,0x00};
404 static const guchar radio_text_bits[] = {
405 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0xf0,0x01,0xf0,0x01,0xf0,
406 0x01,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
409 * radio_aa_bits is currently not used, since it is all zeros.
411 static const guchar radio_aa_bits[] = {
412 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
413 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
415 static const guchar radio_base_bits[] = {
416 0x00,0x00,0x00,0x00,0xf0,0x01,0xf8,0x03,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc,
417 0x07,0xfc,0x07,0xf8,0x03,0xf0,0x01,0x00,0x00,0x00,0x00,0x00,0x00};
420 * Extracted from radio-13.png, width=13, height=13
422 static const guchar radio_inconsistent_text_bits[] = {
423 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x03,0x00,
424 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
425 static const guchar radio_inconsistent_aa_bits[] = {
426 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x03,0x00,0x00,0xf8,
427 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
431 GList *bmap_list; /* list of GdkBitmap */
432 } indicator_parts[] = {
433 { check_aa_bits, NULL },
434 { check_base_bits, NULL },
435 { check_black_bits, NULL },
436 { check_dark_bits, NULL },
437 { check_light_bits, NULL },
438 { check_mid_bits, NULL },
439 { check_text_bits, NULL },
440 { check_inconsistent_text_bits, NULL },
441 { radio_base_bits, NULL },
442 { radio_black_bits, NULL },
443 { radio_dark_bits, NULL },
444 { radio_light_bits, NULL },
445 { radio_mid_bits, NULL },
446 { radio_text_bits, NULL },
447 { radio_inconsistent_aa_bits, NULL },
448 { radio_inconsistent_text_bits, NULL },
450 #define GTK_GRAY 0xdcdc, 0xdada, 0xd5d5
451 #define GTK_DARK_GRAY 0xc4c4, 0xc2c2, 0xbdbd
452 #define GTK_LIGHT_GRAY 0xeeee, 0xebeb, 0xe7e7
453 #define GTK_WHITE 0xffff, 0xffff, 0xffff
454 #define GTK_BLUE 0x4b4b, 0x6969, 0x8383
455 #define GTK_VERY_DARK_GRAY 0x9c9c, 0x9a9a, 0x9494
456 #define GTK_BLACK 0x0000, 0x0000, 0x0000
457 #define GTK_WEAK_GRAY 0x7530, 0x7530, 0x7530
459 /* --- variables --- */
460 static const GdkColor gtk_default_normal_fg = { 0, GTK_BLACK };
461 static const GdkColor gtk_default_active_fg = { 0, GTK_BLACK };
462 static const GdkColor gtk_default_prelight_fg = { 0, GTK_BLACK };
463 static const GdkColor gtk_default_selected_fg = { 0, GTK_WHITE };
464 static const GdkColor gtk_default_insensitive_fg = { 0, GTK_WEAK_GRAY };
466 static const GdkColor gtk_default_normal_bg = { 0, GTK_GRAY };
467 static const GdkColor gtk_default_active_bg = { 0, GTK_DARK_GRAY };
468 static const GdkColor gtk_default_prelight_bg = { 0, GTK_LIGHT_GRAY };
469 static const GdkColor gtk_default_selected_bg = { 0, GTK_BLUE };
470 static const GdkColor gtk_default_insensitive_bg = { 0, GTK_GRAY };
471 static const GdkColor gtk_default_selected_base = { 0, GTK_BLUE };
472 static const GdkColor gtk_default_active_base = { 0, GTK_VERY_DARK_GRAY };
474 static gpointer parent_class = NULL;
476 /* --- signals --- */
477 static guint realize_signal = 0;
478 static guint unrealize_signal = 0;
480 /* --- functions --- */
482 gtk_style_get_type (void)
484 static GType style_type = 0;
488 static const GTypeInfo style_info =
490 sizeof (GtkStyleClass),
491 (GBaseInitFunc) NULL,
492 (GBaseFinalizeFunc) NULL,
493 (GClassInitFunc) gtk_style_class_init,
494 NULL, /* class_finalize */
495 NULL, /* class_data */
498 (GInstanceInitFunc) gtk_style_init,
501 style_type = g_type_register_static (G_TYPE_OBJECT, "GtkStyle",
509 * _gtk_style_init_for_settings:
510 * @style: a #GtkStyle
511 * @settings: a #GtkSettings
513 * Initializes the font description in @style according to the default
514 * font name of @settings. This is called for gtk_style_new() with
515 * the settings for the default screen (if any); if we are creating
516 * a style for a particular screen, we then call it again in a
517 * location where we know the correct settings.
518 * The reason for this is that gtk_rc_style_create_style() doesn't
519 * take the screen for an argument.
522 _gtk_style_init_for_settings (GtkStyle *style,
523 GtkSettings *settings)
525 const gchar *font_name = _gtk_rc_context_get_default_font_name (settings);
527 if (style->font_desc)
528 pango_font_description_free (style->font_desc);
530 style->font_desc = pango_font_description_from_string (font_name);
532 if (!pango_font_description_get_family (style->font_desc))
534 g_warning ("Default font does not have a family set");
535 pango_font_description_set_family (style->font_desc, "Sans");
537 if (pango_font_description_get_size (style->font_desc) <= 0)
539 g_warning ("Default font does not have a positive size");
540 pango_font_description_set_size (style->font_desc, 10 * PANGO_SCALE);
545 gtk_style_init (GtkStyle *style)
549 GtkSettings *settings = gtk_settings_get_default ();
552 _gtk_style_init_for_settings (style, settings);
554 style->font_desc = pango_font_description_from_string ("Sans 10");
556 style->attach_count = 0;
557 style->colormap = NULL;
560 style->black.red = 0;
561 style->black.green = 0;
562 style->black.blue = 0;
564 style->white.red = 65535;
565 style->white.green = 65535;
566 style->white.blue = 65535;
568 style->black_gc = NULL;
569 style->white_gc = NULL;
571 style->fg[GTK_STATE_NORMAL] = gtk_default_normal_fg;
572 style->fg[GTK_STATE_ACTIVE] = gtk_default_active_fg;
573 style->fg[GTK_STATE_PRELIGHT] = gtk_default_prelight_fg;
574 style->fg[GTK_STATE_SELECTED] = gtk_default_selected_fg;
575 style->fg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
577 style->bg[GTK_STATE_NORMAL] = gtk_default_normal_bg;
578 style->bg[GTK_STATE_ACTIVE] = gtk_default_active_bg;
579 style->bg[GTK_STATE_PRELIGHT] = gtk_default_prelight_bg;
580 style->bg[GTK_STATE_SELECTED] = gtk_default_selected_bg;
581 style->bg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_bg;
583 for (i = 0; i < 4; i++)
585 style->text[i] = style->fg[i];
586 style->base[i] = style->white;
589 style->base[GTK_STATE_SELECTED] = gtk_default_selected_base;
590 style->text[GTK_STATE_SELECTED] = style->white;
591 style->base[GTK_STATE_ACTIVE] = gtk_default_active_base;
592 style->text[GTK_STATE_ACTIVE] = style->white;
593 style->base[GTK_STATE_INSENSITIVE] = gtk_default_prelight_bg;
594 style->text[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
596 for (i = 0; i < 5; i++)
597 style->bg_pixmap[i] = NULL;
599 style->rc_style = NULL;
601 for (i = 0; i < 5; i++)
603 style->fg_gc[i] = NULL;
604 style->bg_gc[i] = NULL;
605 style->light_gc[i] = NULL;
606 style->dark_gc[i] = NULL;
607 style->mid_gc[i] = NULL;
608 style->text_gc[i] = NULL;
609 style->base_gc[i] = NULL;
610 style->text_aa_gc[i] = NULL;
613 style->xthickness = 2;
614 style->ythickness = 2;
616 style->property_cache = NULL;
620 gtk_style_class_init (GtkStyleClass *klass)
622 GObjectClass *object_class = G_OBJECT_CLASS (klass);
624 parent_class = g_type_class_peek_parent (klass);
626 object_class->finalize = gtk_style_finalize;
628 klass->clone = gtk_style_real_clone;
629 klass->copy = gtk_style_real_copy;
630 klass->init_from_rc = gtk_style_real_init_from_rc;
631 klass->realize = gtk_style_real_realize;
632 klass->unrealize = gtk_style_real_unrealize;
633 klass->set_background = gtk_style_real_set_background;
634 klass->render_icon = gtk_default_render_icon;
636 klass->draw_hline = gtk_default_draw_hline;
637 klass->draw_vline = gtk_default_draw_vline;
638 klass->draw_shadow = gtk_default_draw_shadow;
639 klass->draw_polygon = gtk_default_draw_polygon;
640 klass->draw_arrow = gtk_default_draw_arrow;
641 klass->draw_diamond = gtk_default_draw_diamond;
642 klass->draw_string = gtk_default_draw_string;
643 klass->draw_box = gtk_default_draw_box;
644 klass->draw_flat_box = gtk_default_draw_flat_box;
645 klass->draw_check = gtk_default_draw_check;
646 klass->draw_option = gtk_default_draw_option;
647 klass->draw_tab = gtk_default_draw_tab;
648 klass->draw_shadow_gap = gtk_default_draw_shadow_gap;
649 klass->draw_box_gap = gtk_default_draw_box_gap;
650 klass->draw_extension = gtk_default_draw_extension;
651 klass->draw_focus = gtk_default_draw_focus;
652 klass->draw_slider = gtk_default_draw_slider;
653 klass->draw_handle = gtk_default_draw_handle;
654 klass->draw_expander = gtk_default_draw_expander;
655 klass->draw_layout = gtk_default_draw_layout;
656 klass->draw_resize_grip = gtk_default_draw_resize_grip;
661 * @style: the object which received the signal
663 * Emitted when the style has been initialized for a particular
664 * colormap and depth. Connecting to this signal is probably seldom
665 * useful since most of the time applications and widgets only
666 * deal with styles that have been already realized.
670 realize_signal = g_signal_new ("realize",
671 G_TYPE_FROM_CLASS (object_class),
673 G_STRUCT_OFFSET (GtkStyleClass, realize),
675 _gtk_marshal_VOID__VOID,
678 * GtkStyle::unrealize:
679 * @style: the object which received the signal
681 * Emitted when the aspects of the style specific to a particular colormap
682 * and depth are being cleaned up. A connection to this signal can be useful
683 * if a widget wants to cache objects like a #GdkGC as object data on #GtkStyle.
684 * This signal provides a convenient place to free such cached objects.
688 unrealize_signal = g_signal_new ("unrealize",
689 G_TYPE_FROM_CLASS (object_class),
691 G_STRUCT_OFFSET (GtkStyleClass, unrealize),
693 _gtk_marshal_VOID__VOID,
698 clear_property_cache (GtkStyle *style)
700 if (style->property_cache)
704 for (i = 0; i < style->property_cache->len; i++)
706 PropertyValue *node = &g_array_index (style->property_cache, PropertyValue, i);
708 g_param_spec_unref (node->pspec);
709 g_value_unset (&node->value);
711 g_array_free (style->property_cache, TRUE);
712 style->property_cache = NULL;
717 gtk_style_finalize (GObject *object)
719 GtkStyle *style = GTK_STYLE (object);
721 g_return_if_fail (style->attach_count == 0);
723 clear_property_cache (style);
725 /* All the styles in the list have the same
726 * style->styles pointer. If we delete the
727 * *first* style from the list, we need to update
728 * the style->styles pointers from all the styles.
729 * Otherwise we simply remove the node from
734 if (style->styles->data != style)
735 g_slist_remove (style->styles, style);
738 GSList *tmp_list = style->styles->next;
742 GTK_STYLE (tmp_list->data)->styles = style->styles->next;
743 tmp_list = tmp_list->next;
745 g_slist_free_1 (style->styles);
749 if (style->icon_factories)
751 GSList *tmp_list = style->icon_factories;
755 g_object_unref (tmp_list->data);
756 tmp_list = tmp_list->next;
759 g_slist_free (style->icon_factories);
762 pango_font_description_free (style->font_desc);
764 if (style->private_font)
765 gdk_font_unref (style->private_font);
767 if (style->private_font_desc)
768 pango_font_description_free (style->private_font_desc);
771 gtk_rc_style_unref (style->rc_style);
773 G_OBJECT_CLASS (parent_class)->finalize (object);
778 gtk_style_copy (GtkStyle *style)
782 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
784 new_style = GTK_STYLE_GET_CLASS (style)->clone (style);
785 GTK_STYLE_GET_CLASS (style)->copy (new_style, style);
791 gtk_style_duplicate (GtkStyle *style)
795 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
797 new_style = gtk_style_copy (style);
799 /* All the styles in the list have the same
800 * style->styles pointer. When we insert a new
801 * style, we append it to the list to avoid having
802 * to update the existing ones.
804 style->styles = g_slist_append (style->styles, new_style);
805 new_style->styles = style->styles;
812 * @returns: a new #GtkStyle.
814 * Creates a new #GtkStyle.
821 style = g_object_new (GTK_TYPE_STYLE, NULL);
828 * @style: a #GtkStyle.
829 * @window: a #GdkWindow.
830 * @returns: Either @style, or a newly-created #GtkStyle.
831 * If the style is newly created, the style parameter
832 * will be dereferenced, and the new style will have
833 * a reference count belonging to the caller.
835 * Attaches a style to a window; this process allocates the
836 * colors and creates the GC's for the style - it specializes
837 * it to a particular visual and colormap. The process may
838 * involve the creation of a new style if the style has already
839 * been attached to a window with a different style and colormap.
842 gtk_style_attach (GtkStyle *style,
846 GtkStyle *new_style = NULL;
847 GdkColormap *colormap;
849 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
850 g_return_val_if_fail (window != NULL, NULL);
852 colormap = gdk_drawable_get_colormap (window);
855 style->styles = g_slist_append (NULL, style);
857 styles = style->styles;
860 new_style = styles->data;
862 if (new_style->colormap == colormap)
866 styles = styles->next;
871 styles = style->styles;
875 new_style = styles->data;
877 if (new_style->attach_count == 0)
879 gtk_style_realize (new_style, colormap);
884 styles = styles->next;
890 new_style = gtk_style_duplicate (style);
891 if (gdk_colormap_get_screen (style->colormap) != gdk_colormap_get_screen (colormap) &&
892 new_style->private_font)
894 gdk_font_unref (new_style->private_font);
895 new_style->private_font = NULL;
897 gtk_style_realize (new_style, colormap);
900 /* A style gets a refcount from being attached */
901 if (new_style->attach_count == 0)
902 g_object_ref (new_style);
904 /* Another refcount belongs to the parent */
905 if (style != new_style)
907 g_object_unref (style);
908 g_object_ref (new_style);
911 new_style->attach_count++;
917 gtk_style_detach (GtkStyle *style)
919 g_return_if_fail (GTK_IS_STYLE (style));
921 style->attach_count -= 1;
922 if (style->attach_count == 0)
924 g_signal_emit (style, unrealize_signal, 0);
926 g_object_unref (style->colormap);
927 style->colormap = NULL;
929 if (style->private_font_desc)
931 if (style->private_font)
933 gdk_font_unref (style->private_font);
934 style->private_font = NULL;
937 pango_font_description_free (style->private_font_desc);
938 style->private_font_desc = NULL;
941 g_object_unref (style);
947 * @style: a #GtkStyle.
950 * Deprecated equivalent of g_object_ref().
953 gtk_style_ref (GtkStyle *style)
955 return (GtkStyle *) g_object_ref (style);
960 * @style: a #GtkStyle.
962 * Deprecated equivalent of g_object_unref().
965 gtk_style_unref (GtkStyle *style)
967 g_object_unref (style);
971 gtk_style_realize (GtkStyle *style,
972 GdkColormap *colormap)
974 g_return_if_fail (GTK_IS_STYLE (style));
975 g_return_if_fail (GDK_IS_COLORMAP (colormap));
977 style->colormap = g_object_ref (colormap);
978 style->depth = gdk_colormap_get_visual (colormap)->depth;
980 g_signal_emit (style, realize_signal, 0);
984 gtk_style_lookup_icon_set (GtkStyle *style,
985 const char *stock_id)
989 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
990 g_return_val_if_fail (stock_id != NULL, NULL);
992 iter = style->icon_factories;
995 GtkIconSet *icon_set = gtk_icon_factory_lookup (GTK_ICON_FACTORY (iter->data),
1000 iter = g_slist_next (iter);
1003 return gtk_icon_factory_lookup_default (stock_id);
1008 * @style: a #GtkStyle
1009 * @window: a #GdkWindow
1010 * @state_type: a state
1011 * @x1: the starting x coordinate
1012 * @x2: the ending x coordinate
1013 * @y: the y coordinate
1015 * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @window
1016 * using the given style and state.
1018 * Deprecated: Use gtk_paint_hline() instead.
1021 gtk_draw_hline (GtkStyle *style,
1023 GtkStateType state_type,
1028 g_return_if_fail (GTK_IS_STYLE (style));
1029 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
1031 GTK_STYLE_GET_CLASS (style)->draw_hline (style, window, state_type, NULL, NULL, NULL, x1, x2, y);
1037 * @style: a #GtkStyle
1038 * @window: a #GdkWindow
1039 * @state_type: a state
1040 * @y1_: the starting y coordinate
1041 * @y2_: the ending y coordinate
1042 * @x: the x coordinate
1044 * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @window
1045 * using the given style and state.
1047 * Deprecated: Use gtk_paint_vline() instead.
1050 gtk_draw_vline (GtkStyle *style,
1052 GtkStateType state_type,
1057 g_return_if_fail (GTK_IS_STYLE (style));
1058 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
1060 GTK_STYLE_GET_CLASS (style)->draw_vline (style, window, state_type, NULL, NULL, NULL, y1_, y2_, x);
1065 * @style: a #GtkStyle
1066 * @window: a #GdkWindow
1067 * @state_type: a state
1068 * @shadow_type: type of shadow to draw
1069 * @x: x origin of the rectangle
1070 * @y: y origin of the rectangle
1071 * @width: width of the rectangle
1072 * @height: width of the rectangle
1074 * Draws a shadow around the given rectangle in @window
1075 * using the given style and state and shadow type.
1077 * Deprecated: Use gtk_paint_shadow() instead.
1080 gtk_draw_shadow (GtkStyle *style,
1082 GtkStateType state_type,
1083 GtkShadowType shadow_type,
1089 g_return_if_fail (GTK_IS_STYLE (style));
1090 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
1092 GTK_STYLE_GET_CLASS (style)->draw_shadow (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1097 * @style: a #GtkStyle
1098 * @window: a #GdkWindow
1099 * @state_type: a state
1100 * @shadow_type: type of shadow to draw
1101 * @points: an array of #GdkPoint<!-- -->s
1102 * @npoints: length of @points
1103 * @fill: %TRUE if the polygon should be filled
1105 * Draws a polygon on @window with the given parameters.
1107 * Deprecated: Use gtk_paint_polygon() instead.
1110 gtk_draw_polygon (GtkStyle *style,
1112 GtkStateType state_type,
1113 GtkShadowType shadow_type,
1118 g_return_if_fail (GTK_IS_STYLE (style));
1119 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_polygon != NULL);
1121 GTK_STYLE_GET_CLASS (style)->draw_polygon (style, window, state_type, shadow_type, NULL, NULL, NULL, points, npoints, fill);
1126 * @style: a #GtkStyle
1127 * @window: a #GdkWindow
1128 * @state_type: a state
1129 * @shadow_type: the type of shadow to draw
1130 * @arrow_type: the type of arrow to draw
1131 * @fill: %TRUE if the arrow tip should be filled
1132 * @x: x origin of the rectangle to draw the arrow in
1133 * @y: y origin of the rectangle to draw the arrow in
1134 * @width: width of the rectangle to draw the arrow in
1135 * @height: height of the rectangle to draw the arrow in
1137 * Draws an arrow in the given rectangle on @window using the given
1138 * parameters. @arrow_type determines the direction of the arrow.
1140 * Deprecated: Use gtk_paint_arrow() instead.
1143 gtk_draw_arrow (GtkStyle *style,
1145 GtkStateType state_type,
1146 GtkShadowType shadow_type,
1147 GtkArrowType arrow_type,
1154 g_return_if_fail (GTK_IS_STYLE (style));
1155 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
1157 GTK_STYLE_GET_CLASS (style)->draw_arrow (style, window, state_type, shadow_type, NULL, NULL, NULL, arrow_type, fill, x, y, width, height);
1162 * @style: a #GtkStyle
1163 * @window: a #GdkWindow
1164 * @state_type: a state
1165 * @shadow_type: the type of shadow to draw
1166 * @x: x origin of the rectangle to draw the diamond in
1167 * @y: y origin of the rectangle to draw the diamond in
1168 * @width: width of the rectangle to draw the diamond in
1169 * @height: height of the rectangle to draw the diamond in
1171 * Draws a diamond in the given rectangle on @window using the given
1174 * Deprecated: Use gtk_paint_diamond() instead.
1177 gtk_draw_diamond (GtkStyle *style,
1179 GtkStateType state_type,
1180 GtkShadowType shadow_type,
1186 g_return_if_fail (GTK_IS_STYLE (style));
1187 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
1189 GTK_STYLE_GET_CLASS (style)->draw_diamond (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1194 * @style: a #GtkStyle
1195 * @window: a #GdkWindow
1196 * @state_type: a state
1199 * @string: the string to draw
1201 * Draws a text string on @window with the given parameters.
1203 * Deprecated: Use gtk_paint_layout() instead.
1206 gtk_draw_string (GtkStyle *style,
1208 GtkStateType state_type,
1211 const gchar *string)
1213 g_return_if_fail (GTK_IS_STYLE (style));
1214 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_string != NULL);
1216 GTK_STYLE_GET_CLASS (style)->draw_string (style, window, state_type, NULL, NULL, NULL, x, y, string);
1221 * @style: a #GtkStyle
1222 * @window: a #GdkWindow
1223 * @state_type: a state
1224 * @shadow_type: the type of shadow to draw
1225 * @x: x origin of the box
1226 * @y: y origin of the box
1227 * @width: the width of the box
1228 * @height: the height of the box
1230 * Draws a box on @window with the given parameters.
1232 * Deprecated: Use gtk_paint_box() instead.
1235 gtk_draw_box (GtkStyle *style,
1237 GtkStateType state_type,
1238 GtkShadowType shadow_type,
1244 g_return_if_fail (GTK_IS_STYLE (style));
1245 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
1247 GTK_STYLE_GET_CLASS (style)->draw_box (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1251 * gtk_draw_flat_box:
1252 * @style: a #GtkStyle
1253 * @window: a #GdkWindow
1254 * @state_type: a state
1255 * @shadow_type: the type of shadow to draw
1256 * @x: x origin of the box
1257 * @y: y origin of the box
1258 * @width: the width of the box
1259 * @height: the height of the box
1261 * Draws a flat box on @window with the given parameters.
1263 * Deprecated: Use gtk_paint_flat_box() instead.
1266 gtk_draw_flat_box (GtkStyle *style,
1268 GtkStateType state_type,
1269 GtkShadowType shadow_type,
1275 g_return_if_fail (GTK_IS_STYLE (style));
1276 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
1278 GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1283 * @style: a #GtkStyle
1284 * @window: a #GdkWindow
1285 * @state_type: a state
1286 * @shadow_type: the type of shadow to draw
1287 * @x: x origin of the rectangle to draw the check in
1288 * @y: y origin of the rectangle to draw the check in
1289 * @width: the width of the rectangle to draw the check in
1290 * @height: the height of the rectangle to draw the check in
1292 * Draws a check button indicator in the given rectangle on @window with
1293 * the given parameters.
1295 * Deprecated: Use gtk_paint_check() instead.
1298 gtk_draw_check (GtkStyle *style,
1300 GtkStateType state_type,
1301 GtkShadowType shadow_type,
1307 g_return_if_fail (GTK_IS_STYLE (style));
1308 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
1310 GTK_STYLE_GET_CLASS (style)->draw_check (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1315 * @style: a #GtkStyle
1316 * @window: a #GdkWindow
1317 * @state_type: a state
1318 * @shadow_type: the type of shadow to draw
1319 * @x: x origin of the rectangle to draw the option in
1320 * @y: y origin of the rectangle to draw the option in
1321 * @width: the width of the rectangle to draw the option in
1322 * @height: the height of the rectangle to draw the option in
1324 * Draws a radio button indicator in the given rectangle on @window with
1325 * the given parameters.
1327 * Deprecated: Use gtk_paint_option() instead.
1330 gtk_draw_option (GtkStyle *style,
1332 GtkStateType state_type,
1333 GtkShadowType shadow_type,
1339 g_return_if_fail (GTK_IS_STYLE (style));
1340 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
1342 GTK_STYLE_GET_CLASS (style)->draw_option (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1347 * @style: a #GtkStyle
1348 * @window: a #GdkWindow
1349 * @state_type: a state
1350 * @shadow_type: the type of shadow to draw
1351 * @x: x origin of the rectangle to draw the tab in
1352 * @y: y origin of the rectangle to draw the tab in
1353 * @width: the width of the rectangle to draw the tab in
1354 * @height: the height of the rectangle to draw the tab in
1356 * Draws an option menu tab (i.e. the up and down pointing arrows)
1357 * in the given rectangle on @window using the given parameters.
1359 * Deprecated: Use gtk_paint_tab() instead.
1362 gtk_draw_tab (GtkStyle *style,
1364 GtkStateType state_type,
1365 GtkShadowType shadow_type,
1371 g_return_if_fail (GTK_IS_STYLE (style));
1372 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
1374 GTK_STYLE_GET_CLASS (style)->draw_tab (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1378 * gtk_draw_shadow_gap:
1379 * @style: a #GtkStyle
1380 * @window: a #GdkWindow
1381 * @state_type: a state
1382 * @shadow_type: type of shadow to draw
1383 * @x: x origin of the rectangle
1384 * @y: y origin of the rectangle
1385 * @width: width of the rectangle
1386 * @height: width of the rectangle
1387 * @gap_side: side in which to leave the gap
1388 * @gap_x: starting position of the gap
1389 * @gap_width: width of the gap
1391 * Draws a shadow around the given rectangle in @window
1392 * using the given style and state and shadow type, leaving a
1395 * Deprecated: Use gtk_paint_shadow_gap() instead.
1398 gtk_draw_shadow_gap (GtkStyle *style,
1400 GtkStateType state_type,
1401 GtkShadowType shadow_type,
1406 GtkPositionType gap_side,
1410 g_return_if_fail (GTK_IS_STYLE (style));
1411 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
1413 GTK_STYLE_GET_CLASS (style)->draw_shadow_gap (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, gap_side, gap_x, gap_width);
1418 * @style: a #GtkStyle
1419 * @window: a #GdkWindow
1420 * @state_type: a state
1421 * @shadow_type: type of shadow to draw
1422 * @x: x origin of the rectangle
1423 * @y: y origin of the rectangle
1424 * @width: width of the rectangle
1425 * @height: width of the rectangle
1426 * @gap_side: side in which to leave the gap
1427 * @gap_x: starting position of the gap
1428 * @gap_width: width of the gap
1430 * Draws a box in @window using the given style and state and shadow type,
1431 * leaving a gap in one side.
1433 * Deprecated: Use gtk_paint_box_gap() instead.
1436 gtk_draw_box_gap (GtkStyle *style,
1438 GtkStateType state_type,
1439 GtkShadowType shadow_type,
1444 GtkPositionType gap_side,
1448 g_return_if_fail (GTK_IS_STYLE (style));
1449 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
1451 GTK_STYLE_GET_CLASS (style)->draw_box_gap (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, gap_side, gap_x, gap_width);
1455 * gtk_draw_extension:
1456 * @style: a #GtkStyle
1457 * @window: a #GdkWindow
1458 * @state_type: a state
1459 * @shadow_type: type of shadow to draw
1460 * @x: x origin of the extension
1461 * @y: y origin of the extension
1462 * @width: width of the extension
1463 * @height: width of the extension
1464 * @gap_side: the side on to which the extension is attached
1466 * Draws an extension, i.e. a notebook tab.
1468 * Deprecated: Use gtk_paint_extension() instead.
1471 gtk_draw_extension (GtkStyle *style,
1473 GtkStateType state_type,
1474 GtkShadowType shadow_type,
1479 GtkPositionType gap_side)
1481 g_return_if_fail (GTK_IS_STYLE (style));
1482 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
1484 GTK_STYLE_GET_CLASS (style)->draw_extension (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, gap_side);
1489 * @style: a #GtkStyle
1490 * @window: a #GdkWindow
1491 * @x: the x origin of the rectangle around which to draw a focus indicator
1492 * @y: the y origin of the rectangle around which to draw a focus indicator
1493 * @width: the width of the rectangle around which to draw a focus indicator
1494 * @height: the height of the rectangle around which to draw a focus indicator
1496 * Draws a focus indicator around the given rectangle on @window using the
1499 * Deprecated: Use gtk_paint_focus() instead.
1502 gtk_draw_focus (GtkStyle *style,
1509 g_return_if_fail (GTK_IS_STYLE (style));
1510 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
1512 GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, GTK_STATE_NORMAL, NULL, NULL, NULL, x, y, width, height);
1516 gtk_draw_slider (GtkStyle *style,
1518 GtkStateType state_type,
1519 GtkShadowType shadow_type,
1524 GtkOrientation orientation)
1526 g_return_if_fail (GTK_IS_STYLE (style));
1527 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
1529 GTK_STYLE_GET_CLASS (style)->draw_slider (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, orientation);
1534 * @style: a #GtkStyle
1535 * @window: a #GdkWindow
1536 * @state_type: a state
1537 * @shadow_type: type of shadow to draw
1538 * @x: x origin of the handle
1539 * @y: y origin of the handle
1540 * @width: with of the handle
1541 * @height: height of the handle
1542 * @orientation: the orientation of the handle
1544 * Draws a handle as used in #GtkHandleBox and #GtkPaned.
1546 * Deprecated: Use gtk_paint_handle() instead.
1549 gtk_draw_handle (GtkStyle *style,
1551 GtkStateType state_type,
1552 GtkShadowType shadow_type,
1557 GtkOrientation orientation)
1559 g_return_if_fail (GTK_IS_STYLE (style));
1560 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
1562 GTK_STYLE_GET_CLASS (style)->draw_handle (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, orientation);
1566 * gtk_draw_expander:
1567 * @style: a #GtkStyle
1568 * @window: a #GdkWindow
1569 * @state_type: a state
1570 * @x: the x position to draw the expander at
1571 * @y: the y position to draw the expander at
1572 * @expander_style: the style to draw the expander in
1574 * Draws an expander as used in #GtkTreeView.
1576 * Deprecated: Use gtk_paint_expander() instead.
1579 gtk_draw_expander (GtkStyle *style,
1581 GtkStateType state_type,
1584 GtkExpanderStyle expander_style)
1586 g_return_if_fail (GTK_IS_STYLE (style));
1587 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
1589 GTK_STYLE_GET_CLASS (style)->draw_expander (style, window, state_type,
1591 x, y, expander_style);
1595 gtk_draw_layout (GtkStyle *style,
1597 GtkStateType state_type,
1601 PangoLayout *layout)
1603 g_return_if_fail (GTK_IS_STYLE (style));
1604 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
1606 GTK_STYLE_GET_CLASS (style)->draw_layout (style, window, state_type, use_text,
1612 * gtk_draw_resize_grip:
1613 * @style: a #GtkStyle
1614 * @window: a #GdkWindow
1615 * @state_type: a state
1616 * @edge: the edge in which to draw the resize grip
1617 * @x: the x origin of the rectangle in which to draw the resize grip
1618 * @y: the y origin of the rectangle in which to draw the resize grip
1619 * @width: the width of the rectangle in which to draw the resize grip
1620 * @height: the height of the rectangle in which to draw the resize grip
1622 * Draws a resize grip in the given rectangle on @window using the given
1625 * Deprecated: Use gtk_paint_resize_grip() instead.
1628 gtk_draw_resize_grip (GtkStyle *style,
1630 GtkStateType state_type,
1637 g_return_if_fail (GTK_IS_STYLE (style));
1638 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
1640 GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, window, state_type,
1643 x, y, width, height);
1648 * gtk_style_set_background:
1649 * @style: a #GtkStyle
1650 * @window: a #GdkWindow
1651 * @state_type: a state
1653 * Sets the background of @window to the background color or pixmap
1654 * specified by @style for the given state.
1657 gtk_style_set_background (GtkStyle *style,
1659 GtkStateType state_type)
1661 g_return_if_fail (GTK_IS_STYLE (style));
1662 g_return_if_fail (window != NULL);
1664 GTK_STYLE_GET_CLASS (style)->set_background (style, window, state_type);
1667 /* Default functions */
1669 gtk_style_real_clone (GtkStyle *style)
1671 return g_object_new (G_OBJECT_TYPE (style), NULL);
1675 gtk_style_real_copy (GtkStyle *style,
1680 for (i = 0; i < 5; i++)
1682 style->fg[i] = src->fg[i];
1683 style->bg[i] = src->bg[i];
1684 style->text[i] = src->text[i];
1685 style->base[i] = src->base[i];
1687 if (style->bg_pixmap[i])
1688 g_object_unref (style->bg_pixmap[i]),
1689 style->bg_pixmap[i] = src->bg_pixmap[i];
1690 if (style->bg_pixmap[i])
1691 g_object_ref (style->bg_pixmap[i]);
1694 if (style->private_font)
1695 gdk_font_unref (style->private_font);
1696 style->private_font = src->private_font;
1697 if (style->private_font)
1698 gdk_font_ref (style->private_font);
1700 if (style->font_desc)
1701 pango_font_description_free (style->font_desc);
1703 style->font_desc = pango_font_description_copy (src->font_desc);
1705 style->font_desc = NULL;
1707 style->xthickness = src->xthickness;
1708 style->ythickness = src->ythickness;
1710 if (style->rc_style)
1711 gtk_rc_style_unref (style->rc_style);
1712 style->rc_style = src->rc_style;
1714 gtk_rc_style_ref (src->rc_style);
1716 /* don't copy, just clear cache */
1717 clear_property_cache (style);
1721 gtk_style_real_init_from_rc (GtkStyle *style,
1722 GtkRcStyle *rc_style)
1726 /* cache _should_ be still empty */
1727 clear_property_cache (style);
1729 if (rc_style->font_desc)
1730 pango_font_description_merge (style->font_desc, rc_style->font_desc, TRUE);
1732 for (i = 0; i < 5; i++)
1734 if (rc_style->color_flags[i] & GTK_RC_FG)
1735 style->fg[i] = rc_style->fg[i];
1736 if (rc_style->color_flags[i] & GTK_RC_BG)
1737 style->bg[i] = rc_style->bg[i];
1738 if (rc_style->color_flags[i] & GTK_RC_TEXT)
1739 style->text[i] = rc_style->text[i];
1740 if (rc_style->color_flags[i] & GTK_RC_BASE)
1741 style->base[i] = rc_style->base[i];
1744 if (rc_style->xthickness >= 0)
1745 style->xthickness = rc_style->xthickness;
1746 if (rc_style->ythickness >= 0)
1747 style->ythickness = rc_style->ythickness;
1749 if (rc_style->icon_factories)
1753 style->icon_factories = g_slist_copy (rc_style->icon_factories);
1755 iter = style->icon_factories;
1756 while (iter != NULL)
1758 g_object_ref (iter->data);
1759 iter = g_slist_next (iter);
1765 style_property_values_cmp (gconstpointer bsearch_node1,
1766 gconstpointer bsearch_node2)
1768 const PropertyValue *val1 = bsearch_node1;
1769 const PropertyValue *val2 = bsearch_node2;
1771 if (val1->widget_type == val2->widget_type)
1772 return val1->pspec < val2->pspec ? -1 : val1->pspec == val2->pspec ? 0 : 1;
1774 return val1->widget_type < val2->widget_type ? -1 : 1;
1778 _gtk_style_peek_property_value (GtkStyle *style,
1781 GtkRcPropertyParser parser)
1783 PropertyValue *pcache, key = { 0, NULL, { 0, } };
1784 const GtkRcProperty *rcprop = NULL;
1787 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1788 g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL);
1789 g_return_val_if_fail (g_type_is_a (pspec->owner_type, GTK_TYPE_WIDGET), NULL);
1790 g_return_val_if_fail (g_type_is_a (widget_type, pspec->owner_type), NULL);
1792 key.widget_type = widget_type;
1795 /* need value cache array */
1796 if (!style->property_cache)
1797 style->property_cache = g_array_new (FALSE, FALSE, sizeof (PropertyValue));
1800 pcache = bsearch (&key,
1801 style->property_cache->data, style->property_cache->len,
1802 sizeof (PropertyValue), style_property_values_cmp);
1804 return &pcache->value;
1808 while (i < style->property_cache->len &&
1809 style_property_values_cmp (&key, &g_array_index (style->property_cache, PropertyValue, i)) >= 0)
1812 g_array_insert_val (style->property_cache, i, key);
1813 pcache = &g_array_index (style->property_cache, PropertyValue, i);
1815 /* cache miss, initialize value type, then set contents */
1816 g_param_spec_ref (pcache->pspec);
1817 g_value_init (&pcache->value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1819 /* value provided by rc style? */
1820 if (style->rc_style)
1822 GQuark prop_quark = g_quark_from_string (pspec->name);
1826 rcprop = _gtk_rc_style_lookup_rc_property (style->rc_style,
1827 g_type_qname (widget_type),
1831 widget_type = g_type_parent (widget_type);
1833 while (g_type_is_a (widget_type, pspec->owner_type));
1836 /* when supplied by rc style, we need to convert */
1837 if (rcprop && !_gtk_settings_parse_convert (parser, &rcprop->value,
1838 pspec, &pcache->value))
1840 gchar *contents = g_strdup_value_contents (&rcprop->value);
1842 g_message ("%s: failed to retrieve property `%s::%s' of type `%s' from rc file value \"%s\" of type `%s'",
1844 g_type_name (pspec->owner_type), pspec->name,
1845 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1847 G_VALUE_TYPE_NAME (&rcprop->value));
1849 rcprop = NULL; /* needs default */
1852 /* not supplied by rc style (or conversion failed), revert to default */
1854 g_param_value_set_default (pspec, &pcache->value);
1856 return &pcache->value;
1860 load_bg_image (GdkColormap *colormap,
1862 const gchar *filename)
1864 if (strcmp (filename, "<parent>") == 0)
1865 return (GdkPixmap*) GDK_PARENT_RELATIVE;
1868 return gdk_pixmap_colormap_create_from_xpm (NULL, colormap, NULL,
1875 gtk_style_real_realize (GtkStyle *style)
1877 GdkGCValues gc_values;
1878 GdkGCValuesMask gc_values_mask;
1882 for (i = 0; i < 5; i++)
1884 gtk_style_shade (&style->bg[i], &style->light[i], LIGHTNESS_MULT);
1885 gtk_style_shade (&style->bg[i], &style->dark[i], DARKNESS_MULT);
1887 style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
1888 style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
1889 style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
1891 style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
1892 style->text_aa[i].green = (style->text[i].green + style->base[i].green) / 2;
1893 style->text_aa[i].blue = (style->text[i].blue + style->base[i].blue) / 2;
1896 style->black.red = 0x0000;
1897 style->black.green = 0x0000;
1898 style->black.blue = 0x0000;
1899 gdk_colormap_alloc_color (style->colormap, &style->black, FALSE, TRUE);
1901 style->white.red = 0xffff;
1902 style->white.green = 0xffff;
1903 style->white.blue = 0xffff;
1904 gdk_colormap_alloc_color (style->colormap, &style->white, FALSE, TRUE);
1906 gc_values_mask = GDK_GC_FOREGROUND | GDK_GC_BACKGROUND;
1908 gc_values.foreground = style->black;
1909 gc_values.background = style->white;
1910 style->black_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1912 gc_values.foreground = style->white;
1913 gc_values.background = style->black;
1914 style->white_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1916 gc_values_mask = GDK_GC_FOREGROUND;
1918 for (i = 0; i < 5; i++)
1920 if (style->rc_style && style->rc_style->bg_pixmap_name[i])
1921 style->bg_pixmap[i] = load_bg_image (style->colormap,
1923 style->rc_style->bg_pixmap_name[i]);
1925 if (!gdk_colormap_alloc_color (style->colormap, &style->fg[i], FALSE, TRUE))
1926 g_warning ("unable to allocate color: ( %d %d %d )",
1927 style->fg[i].red, style->fg[i].green, style->fg[i].blue);
1928 if (!gdk_colormap_alloc_color (style->colormap, &style->bg[i], FALSE, TRUE))
1929 g_warning ("unable to allocate color: ( %d %d %d )",
1930 style->bg[i].red, style->bg[i].green, style->bg[i].blue);
1931 if (!gdk_colormap_alloc_color (style->colormap, &style->light[i], FALSE, TRUE))
1932 g_warning ("unable to allocate color: ( %d %d %d )",
1933 style->light[i].red, style->light[i].green, style->light[i].blue);
1934 if (!gdk_colormap_alloc_color (style->colormap, &style->dark[i], FALSE, TRUE))
1935 g_warning ("unable to allocate color: ( %d %d %d )",
1936 style->dark[i].red, style->dark[i].green, style->dark[i].blue);
1937 if (!gdk_colormap_alloc_color (style->colormap, &style->mid[i], FALSE, TRUE))
1938 g_warning ("unable to allocate color: ( %d %d %d )",
1939 style->mid[i].red, style->mid[i].green, style->mid[i].blue);
1940 if (!gdk_colormap_alloc_color (style->colormap, &style->text[i], FALSE, TRUE))
1941 g_warning ("unable to allocate color: ( %d %d %d )",
1942 style->text[i].red, style->text[i].green, style->text[i].blue);
1943 if (!gdk_colormap_alloc_color (style->colormap, &style->base[i], FALSE, TRUE))
1944 g_warning ("unable to allocate color: ( %d %d %d )",
1945 style->base[i].red, style->base[i].green, style->base[i].blue);
1946 if (!gdk_colormap_alloc_color (style->colormap, &style->text_aa[i], FALSE, TRUE))
1947 g_warning ("unable to allocate color: ( %d %d %d )",
1948 style->text_aa[i].red, style->text_aa[i].green, style->text_aa[i].blue);
1950 gc_values.foreground = style->fg[i];
1951 style->fg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1953 gc_values.foreground = style->bg[i];
1954 style->bg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1956 gc_values.foreground = style->light[i];
1957 style->light_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1959 gc_values.foreground = style->dark[i];
1960 style->dark_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1962 gc_values.foreground = style->mid[i];
1963 style->mid_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1965 gc_values.foreground = style->text[i];
1966 style->text_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1968 gc_values.foreground = style->base[i];
1969 style->base_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1971 gc_values.foreground = style->text_aa[i];
1972 style->text_aa_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1977 gtk_style_real_unrealize (GtkStyle *style)
1981 gtk_gc_release (style->black_gc);
1982 gtk_gc_release (style->white_gc);
1984 for (i = 0; i < 5; i++)
1986 gtk_gc_release (style->fg_gc[i]);
1987 gtk_gc_release (style->bg_gc[i]);
1988 gtk_gc_release (style->light_gc[i]);
1989 gtk_gc_release (style->dark_gc[i]);
1990 gtk_gc_release (style->mid_gc[i]);
1991 gtk_gc_release (style->text_gc[i]);
1992 gtk_gc_release (style->base_gc[i]);
1993 gtk_gc_release (style->text_aa_gc[i]);
1995 if (style->bg_pixmap[i] && style->bg_pixmap[i] != (GdkPixmap*) GDK_PARENT_RELATIVE)
1997 g_object_unref (style->bg_pixmap[i]);
1998 style->bg_pixmap[i] = NULL;
2003 gdk_colormap_free_colors (style->colormap, style->fg, 5);
2004 gdk_colormap_free_colors (style->colormap, style->bg, 5);
2005 gdk_colormap_free_colors (style->colormap, style->light, 5);
2006 gdk_colormap_free_colors (style->colormap, style->dark, 5);
2007 gdk_colormap_free_colors (style->colormap, style->mid, 5);
2008 gdk_colormap_free_colors (style->colormap, style->text, 5);
2009 gdk_colormap_free_colors (style->colormap, style->base, 5);
2010 gdk_colormap_free_colors (style->colormap, style->text_aa, 5);
2012 style_unrealize_cursor_gcs (style);
2016 gtk_style_real_set_background (GtkStyle *style,
2018 GtkStateType state_type)
2021 gint parent_relative;
2023 if (style->bg_pixmap[state_type])
2025 if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
2028 parent_relative = TRUE;
2032 pixmap = style->bg_pixmap[state_type];
2033 parent_relative = FALSE;
2036 gdk_window_set_back_pixmap (window, pixmap, parent_relative);
2039 gdk_window_set_background (window, &style->bg[state_type]);
2043 * gtk_style_render_icon:
2044 * @style: a #GtkStyle
2045 * @source: the #GtkIconSource specifying the icon to render
2046 * @direction: a text direction
2048 * @size: the size to render the icon at. A size of (GtkIconSize)-1
2049 * means render at the size of the source and don't scale.
2050 * @widget: the widget
2051 * @detail: a style detail
2052 * @returns: a newly-created #GdkPixbuf containing the rendered icon
2054 * Renders the icon specified by @source at the given @size
2055 * according to the given parameters and returns the result in a
2059 gtk_style_render_icon (GtkStyle *style,
2060 const GtkIconSource *source,
2061 GtkTextDirection direction,
2065 const gchar *detail)
2069 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
2070 g_return_val_if_fail (GTK_STYLE_GET_CLASS (style)->render_icon != NULL, NULL);
2072 pixbuf = GTK_STYLE_GET_CLASS (style)->render_icon (style, source, direction, state,
2073 size, widget, detail);
2075 g_return_val_if_fail (pixbuf != NULL, NULL);
2080 /* Default functions */
2082 gtk_style_apply_default_background (GtkStyle *style,
2085 GtkStateType state_type,
2092 GdkRectangle new_rect, old_rect;
2098 old_rect.width = width;
2099 old_rect.height = height;
2101 if (!gdk_rectangle_intersect (area, &old_rect, &new_rect))
2108 new_rect.width = width;
2109 new_rect.height = height;
2112 if (!style->bg_pixmap[state_type] ||
2113 GDK_IS_PIXMAP (window) ||
2114 (!set_bg && style->bg_pixmap[state_type] != (GdkPixmap*) GDK_PARENT_RELATIVE))
2116 GdkGC *gc = style->bg_gc[state_type];
2118 if (style->bg_pixmap[state_type])
2120 gdk_gc_set_fill (gc, GDK_TILED);
2121 gdk_gc_set_tile (gc, style->bg_pixmap[state_type]);
2124 gdk_draw_rectangle (window, gc, TRUE,
2125 new_rect.x, new_rect.y, new_rect.width, new_rect.height);
2126 if (style->bg_pixmap[state_type])
2127 gdk_gc_set_fill (gc, GDK_SOLID);
2133 if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
2134 gdk_window_set_back_pixmap (window, NULL, TRUE);
2136 gdk_window_set_back_pixmap (window, style->bg_pixmap[state_type], FALSE);
2139 gdk_window_clear_area (window,
2140 new_rect.x, new_rect.y,
2141 new_rect.width, new_rect.height);
2146 scale_or_ref (GdkPixbuf *src,
2150 if (width == gdk_pixbuf_get_width (src) &&
2151 height == gdk_pixbuf_get_height (src))
2153 return g_object_ref (src);
2157 return gdk_pixbuf_scale_simple (src,
2159 GDK_INTERP_BILINEAR);
2164 gtk_default_render_icon (GtkStyle *style,
2165 const GtkIconSource *source,
2166 GtkTextDirection direction,
2170 const gchar *detail)
2176 GdkPixbuf *base_pixbuf;
2178 GtkSettings *settings;
2180 /* Oddly, style can be NULL in this function, because
2181 * GtkIconSet can be used without a style and if so
2182 * it uses this function.
2185 base_pixbuf = gtk_icon_source_get_pixbuf (source);
2187 g_return_val_if_fail (base_pixbuf != NULL, NULL);
2189 if (widget && gtk_widget_has_screen (widget))
2191 screen = gtk_widget_get_screen (widget);
2192 settings = gtk_settings_get_for_screen (screen);
2194 else if (style && style->colormap)
2196 screen = gdk_colormap_get_screen (style->colormap);
2197 settings = gtk_settings_get_for_screen (screen);
2201 settings = gtk_settings_get_default ();
2202 GTK_NOTE (MULTIHEAD,
2203 g_warning ("Using the default screen for gtk_default_render_icon()"));
2207 if (size != (GtkIconSize) -1 && !gtk_icon_size_lookup_for_settings (settings, size, &width, &height))
2209 g_warning (G_STRLOC ": invalid icon size '%d'", size);
2213 /* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
2216 if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source))
2217 scaled = scale_or_ref (base_pixbuf, width, height);
2219 scaled = g_object_ref (base_pixbuf);
2221 /* If the state was wildcarded, then generate a state. */
2222 if (gtk_icon_source_get_state_wildcarded (source))
2224 if (state == GTK_STATE_INSENSITIVE)
2226 stated = gdk_pixbuf_copy (scaled);
2228 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
2231 g_object_unref (scaled);
2233 else if (state == GTK_STATE_PRELIGHT)
2235 stated = gdk_pixbuf_copy (scaled);
2237 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
2240 g_object_unref (scaled);
2254 sanitize_size (GdkWindow *window,
2258 if ((*width == -1) && (*height == -1))
2259 gdk_drawable_get_size (window, width, height);
2260 else if (*width == -1)
2261 gdk_drawable_get_size (window, width, NULL);
2262 else if (*height == -1)
2263 gdk_drawable_get_size (window, NULL, height);
2267 get_indicator_for_screen (GdkDrawable *drawable,
2271 GdkScreen *screen = gdk_drawable_get_screen (drawable);
2275 tmp_list = indicator_parts[part].bmap_list;
2278 bitmap = tmp_list->data;
2280 if (gdk_drawable_get_screen (bitmap) == screen)
2283 tmp_list = tmp_list->next;
2286 bitmap = gdk_bitmap_create_from_data (drawable,
2287 (gchar *)indicator_parts[part].bits,
2288 INDICATOR_PART_SIZE, INDICATOR_PART_SIZE);
2289 indicator_parts[part].bmap_list = g_list_prepend (indicator_parts[part].bmap_list, bitmap);
2295 draw_part (GdkDrawable *drawable,
2303 gdk_gc_set_clip_rectangle (gc, area);
2305 gdk_gc_set_ts_origin (gc, x, y);
2306 gdk_gc_set_stipple (gc, get_indicator_for_screen (drawable, part));
2307 gdk_gc_set_fill (gc, GDK_STIPPLED);
2309 gdk_draw_rectangle (drawable, gc, TRUE, x, y, INDICATOR_PART_SIZE, INDICATOR_PART_SIZE);
2311 gdk_gc_set_fill (gc, GDK_SOLID);
2314 gdk_gc_set_clip_rectangle (gc, NULL);
2318 gtk_default_draw_hline (GtkStyle *style,
2320 GtkStateType state_type,
2323 const gchar *detail,
2328 gint thickness_light;
2329 gint thickness_dark;
2332 g_return_if_fail (GTK_IS_STYLE (style));
2333 g_return_if_fail (window != NULL);
2335 thickness_light = style->ythickness / 2;
2336 thickness_dark = style->ythickness - thickness_light;
2340 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2341 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2344 if (detail && !strcmp (detail, "label"))
2346 if (state_type == GTK_STATE_INSENSITIVE)
2347 gdk_draw_line (window, style->white_gc, x1 + 1, y + 1, x2 + 1, y + 1);
2348 gdk_draw_line (window, style->fg_gc[state_type], x1, y, x2, y);
2352 for (i = 0; i < thickness_dark; i++)
2354 gdk_draw_line (window, style->dark_gc[state_type], x1, y + i, x2 - i - 1, y + i);
2355 gdk_draw_line (window, style->light_gc[state_type], x2 - i, y + i, x2, y + i);
2358 y += thickness_dark;
2359 for (i = 0; i < thickness_light; i++)
2361 gdk_draw_line (window, style->dark_gc[state_type], x1, y + i, x1 + thickness_light - i - 1, y + i);
2362 gdk_draw_line (window, style->light_gc[state_type], x1 + thickness_light - i, y + i, x2, y + i);
2368 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2369 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2375 gtk_default_draw_vline (GtkStyle *style,
2377 GtkStateType state_type,
2380 const gchar *detail,
2385 gint thickness_light;
2386 gint thickness_dark;
2389 g_return_if_fail (GTK_IS_STYLE (style));
2390 g_return_if_fail (window != NULL);
2392 thickness_light = style->xthickness / 2;
2393 thickness_dark = style->xthickness - thickness_light;
2397 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2398 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2400 for (i = 0; i < thickness_dark; i++)
2402 gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i, y2 - i - 1);
2403 gdk_draw_line (window, style->light_gc[state_type], x + i, y2 - i, x + i, y2);
2406 x += thickness_dark;
2407 for (i = 0; i < thickness_light; i++)
2409 gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i, y1 + thickness_light - i - 1);
2410 gdk_draw_line (window, style->light_gc[state_type], x + i, y1 + thickness_light - i, x + i, y2);
2414 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2415 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2420 draw_thin_shadow (GtkStyle *style,
2431 sanitize_size (window, &width, &height);
2433 gc1 = style->light_gc[state];
2434 gc2 = style->dark_gc[state];
2438 gdk_gc_set_clip_rectangle (gc1, area);
2439 gdk_gc_set_clip_rectangle (gc2, area);
2442 gdk_draw_line (window, gc1,
2443 x, y + height - 1, x + width - 1, y + height - 1);
2444 gdk_draw_line (window, gc1,
2445 x + width - 1, y, x + width - 1, y + height - 1);
2447 gdk_draw_line (window, gc2,
2448 x, y, x + width - 2, y);
2449 gdk_draw_line (window, gc2,
2450 x, y, x, y + height - 2);
2454 gdk_gc_set_clip_rectangle (gc1, NULL);
2455 gdk_gc_set_clip_rectangle (gc2, NULL);
2460 draw_spinbutton_shadow (GtkStyle *style,
2463 GtkTextDirection direction,
2470 sanitize_size (window, &width, &height);
2474 gdk_gc_set_clip_rectangle (style->black_gc, area);
2475 gdk_gc_set_clip_rectangle (style->bg_gc[state], area);
2476 gdk_gc_set_clip_rectangle (style->dark_gc[state], area);
2477 gdk_gc_set_clip_rectangle (style->light_gc[state], area);
2480 if (direction == GTK_TEXT_DIR_LTR)
2482 gdk_draw_line (window, style->dark_gc[state],
2483 x, y, x + width - 1, y);
2484 gdk_draw_line (window, style->black_gc,
2485 x, y + 1, x + width - 2, y + 1);
2486 gdk_draw_line (window, style->black_gc,
2487 x + width - 2, y + 2, x + width - 2, y + height - 3);
2488 gdk_draw_line (window, style->light_gc[state],
2489 x + width - 1, y + 1, x + width - 1, y + height - 2);
2490 gdk_draw_line (window, style->light_gc[state],
2491 x, y + height - 1, x + width - 1, y + height - 1);
2492 gdk_draw_line (window, style->bg_gc[state],
2493 x, y + height - 2, x + width - 2, y + height - 2);
2494 gdk_draw_line (window, style->black_gc,
2495 x, y + 2, x, y + height - 3);
2499 gdk_draw_line (window, style->dark_gc[state],
2500 x, y, x + width - 1, y);
2501 gdk_draw_line (window, style->dark_gc[state],
2502 x, y + 1, x, y + height - 1);
2503 gdk_draw_line (window, style->black_gc,
2504 x + 1, y + 1, x + width - 1, y + 1);
2505 gdk_draw_line (window, style->black_gc,
2506 x + 1, y + 2, x + 1, y + height - 2);
2507 gdk_draw_line (window, style->black_gc,
2508 x + width - 1, y + 2, x + width - 1, y + height - 3);
2509 gdk_draw_line (window, style->light_gc[state],
2510 x + 1, y + height - 1, x + width - 1, y + height - 1);
2511 gdk_draw_line (window, style->bg_gc[state],
2512 x + 2, y + height - 2, x + width - 1, y + height - 2);
2517 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
2518 gdk_gc_set_clip_rectangle (style->bg_gc[state], NULL);
2519 gdk_gc_set_clip_rectangle (style->dark_gc[state], NULL);
2520 gdk_gc_set_clip_rectangle (style->light_gc[state], NULL);
2525 draw_menu_shadow (GtkStyle *style,
2534 if (style->ythickness > 0)
2536 if (style->ythickness > 1)
2538 gdk_draw_line (window, style->dark_gc[state],
2539 x + 1, y + height - 2, x + width - 2, y + height - 2);
2540 gdk_draw_line (window, style->black_gc,
2541 x, y + height - 1, x + width - 1, y + height - 1);
2545 gdk_draw_line (window, style->dark_gc[state],
2546 x + 1, y + height - 1, x + width - 1, y + height - 1);
2550 if (style->xthickness > 0)
2552 if (style->xthickness > 1)
2554 gdk_draw_line (window, style->dark_gc[state],
2555 x + width - 2, y + 1, x + width - 2, y + height - 2);
2557 gdk_draw_line (window, style->black_gc,
2558 x + width - 1, y, x + width - 1, y + height - 1);
2562 gdk_draw_line (window, style->dark_gc[state],
2563 x + width - 1, y + 1, x + width - 1, y + height - 1);
2567 /* Light around top and left */
2569 if (style->ythickness > 0)
2570 gdk_draw_line (window, style->black_gc,
2571 x, y, x + width - 2, y);
2572 if (style->xthickness > 0)
2573 gdk_draw_line (window, style->black_gc,
2574 x, y, x, y + height - 2);
2576 if (style->ythickness > 1)
2577 gdk_draw_line (window, style->light_gc[state],
2578 x + 1, y + 1, x + width - 3, y + 1);
2579 if (style->xthickness > 1)
2580 gdk_draw_line (window, style->light_gc[state],
2581 x + 1, y + 1, x + 1, y + height - 3);
2584 static GtkTextDirection
2585 get_direction (GtkWidget *widget)
2587 GtkTextDirection dir;
2590 dir = gtk_widget_get_direction (widget);
2592 dir = GTK_TEXT_DIR_LTR;
2599 gtk_default_draw_shadow (GtkStyle *style,
2601 GtkStateType state_type,
2602 GtkShadowType shadow_type,
2605 const gchar *detail,
2613 gint thickness_light;
2614 gint thickness_dark;
2617 g_return_if_fail (GTK_IS_STYLE (style));
2618 g_return_if_fail (window != NULL);
2620 if (shadow_type == GTK_SHADOW_IN)
2622 if (detail && (strcmp (detail, "buttondefault") == 0))
2624 sanitize_size (window, &width, &height);
2626 gdk_draw_rectangle (window, style->black_gc, FALSE,
2627 x, y, width - 1, height - 1);
2631 if (detail && strcmp (detail, "trough") == 0)
2633 draw_thin_shadow (style, window, state_type, area,
2634 x, y, width, height);
2637 if (widget && GTK_IS_SPIN_BUTTON (widget) &&
2638 detail && strcmp (detail, "spinbutton") == 0)
2640 draw_spinbutton_shadow (style, window, state_type,
2641 get_direction (widget), area, x, y, width, height);
2647 if (shadow_type == GTK_SHADOW_OUT && detail && strcmp (detail, "menu") == 0)
2649 draw_menu_shadow (style, window, state_type, area, x, y, width, height);
2653 sanitize_size (window, &width, &height);
2655 switch (shadow_type)
2657 case GTK_SHADOW_NONE:
2660 case GTK_SHADOW_ETCHED_IN:
2661 gc1 = style->light_gc[state_type];
2662 gc2 = style->dark_gc[state_type];
2664 case GTK_SHADOW_OUT:
2665 case GTK_SHADOW_ETCHED_OUT:
2666 gc1 = style->dark_gc[state_type];
2667 gc2 = style->light_gc[state_type];
2673 gdk_gc_set_clip_rectangle (gc1, area);
2674 gdk_gc_set_clip_rectangle (gc2, area);
2675 if (shadow_type == GTK_SHADOW_IN ||
2676 shadow_type == GTK_SHADOW_OUT)
2678 gdk_gc_set_clip_rectangle (style->black_gc, area);
2679 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
2683 switch (shadow_type)
2685 case GTK_SHADOW_NONE:
2689 /* Light around right and bottom edge */
2691 if (style->ythickness > 0)
2692 gdk_draw_line (window, gc1,
2693 x, y + height - 1, x + width - 1, y + height - 1);
2694 if (style->xthickness > 0)
2695 gdk_draw_line (window, gc1,
2696 x + width - 1, y, x + width - 1, y + height - 1);
2698 if (style->ythickness > 1)
2699 gdk_draw_line (window, style->bg_gc[state_type],
2700 x + 1, y + height - 2, x + width - 2, y + height - 2);
2701 if (style->xthickness > 1)
2702 gdk_draw_line (window, style->bg_gc[state_type],
2703 x + width - 2, y + 1, x + width - 2, y + height - 2);
2705 /* Dark around left and top */
2707 if (style->ythickness > 1)
2708 gdk_draw_line (window, style->black_gc,
2709 x + 1, y + 1, x + width - 2, y + 1);
2710 if (style->xthickness > 1)
2711 gdk_draw_line (window, style->black_gc,
2712 x + 1, y + 1, x + 1, y + height - 2);
2714 if (style->ythickness > 0)
2715 gdk_draw_line (window, gc2,
2716 x, y, x + width - 1, y);
2717 if (style->xthickness > 0)
2718 gdk_draw_line (window, gc2,
2719 x, y, x, y + height - 1);
2722 case GTK_SHADOW_OUT:
2723 /* Dark around right and bottom edge */
2725 if (style->ythickness > 0)
2727 if (style->ythickness > 1)
2729 gdk_draw_line (window, gc1,
2730 x + 1, y + height - 2, x + width - 2, y + height - 2);
2731 gdk_draw_line (window, style->black_gc,
2732 x, y + height - 1, x + width - 1, y + height - 1);
2736 gdk_draw_line (window, gc1,
2737 x + 1, y + height - 1, x + width - 1, y + height - 1);
2741 if (style->xthickness > 0)
2743 if (style->xthickness > 1)
2745 gdk_draw_line (window, gc1,
2746 x + width - 2, y + 1, x + width - 2, y + height - 2);
2748 gdk_draw_line (window, style->black_gc,
2749 x + width - 1, y, x + width - 1, y + height - 1);
2753 gdk_draw_line (window, gc1,
2754 x + width - 1, y + 1, x + width - 1, y + height - 1);
2758 /* Light around top and left */
2760 if (style->ythickness > 0)
2761 gdk_draw_line (window, gc2,
2762 x, y, x + width - 2, y);
2763 if (style->xthickness > 0)
2764 gdk_draw_line (window, gc2,
2765 x, y, x, y + height - 2);
2767 if (style->ythickness > 1)
2768 gdk_draw_line (window, style->bg_gc[state_type],
2769 x + 1, y + 1, x + width - 3, y + 1);
2770 if (style->xthickness > 1)
2771 gdk_draw_line (window, style->bg_gc[state_type],
2772 x + 1, y + 1, x + 1, y + height - 3);
2775 case GTK_SHADOW_ETCHED_IN:
2776 case GTK_SHADOW_ETCHED_OUT:
2777 if (style->xthickness > 0)
2779 if (style->xthickness > 1)
2781 thickness_light = 1;
2784 for (i = 0; i < thickness_dark; i++)
2786 gdk_draw_line (window, gc1,
2790 y + height - i - 1);
2791 gdk_draw_line (window, gc2,
2795 y + height - i - 2);
2798 for (i = 0; i < thickness_light; i++)
2800 gdk_draw_line (window, gc1,
2801 x + thickness_dark + i,
2802 y + thickness_dark + i,
2803 x + thickness_dark + i,
2804 y + height - thickness_dark - i - 1);
2805 gdk_draw_line (window, gc2,
2806 x + width - thickness_light - i - 1,
2807 y + thickness_dark + i,
2808 x + width - thickness_light - i - 1,
2809 y + height - thickness_light - 1);
2814 gdk_draw_line (window,
2815 style->dark_gc[state_type],
2816 x, y, x, y + height);
2817 gdk_draw_line (window,
2818 style->dark_gc[state_type],
2819 x + width, y, x + width, y + height);
2823 if (style->ythickness > 0)
2825 if (style->ythickness > 1)
2827 thickness_light = 1;
2830 for (i = 0; i < thickness_dark; i++)
2832 gdk_draw_line (window, gc1,
2836 y + height - i - 1);
2838 gdk_draw_line (window, gc2,
2845 for (i = 0; i < thickness_light; i++)
2847 gdk_draw_line (window, gc1,
2848 x + thickness_dark + i,
2849 y + thickness_dark + i,
2850 x + width - thickness_dark - i - 2,
2851 y + thickness_dark + i);
2853 gdk_draw_line (window, gc2,
2854 x + thickness_dark + i,
2855 y + height - thickness_light - i - 1,
2856 x + width - thickness_light - 1,
2857 y + height - thickness_light - i - 1);
2862 gdk_draw_line (window,
2863 style->dark_gc[state_type],
2864 x, y, x + width, y);
2865 gdk_draw_line (window,
2866 style->dark_gc[state_type],
2867 x, y + height, x + width, y + height);
2874 if (shadow_type == GTK_SHADOW_IN &&
2875 widget && GTK_IS_SPIN_BUTTON (widget) &&
2876 detail && strcmp (detail, "entry") == 0)
2878 if (get_direction (widget) == GTK_TEXT_DIR_LTR)
2880 gdk_draw_line (window,
2881 style->base_gc[state_type],
2882 x + width - 1, y + 2,
2883 x + width - 1, y + height - 3);
2884 gdk_draw_line (window,
2885 style->base_gc[state_type],
2886 x + width - 2, y + 2,
2887 x + width - 2, y + height - 3);
2888 gdk_draw_point (window,
2890 x + width - 1, y + 1);
2891 gdk_draw_point (window,
2892 style->bg_gc[state_type],
2893 x + width - 1, y + height - 2);
2897 gdk_draw_line (window,
2898 style->base_gc[state_type],
2901 gdk_draw_line (window,
2902 style->base_gc[state_type],
2904 x + 1, y + height - 3);
2905 gdk_draw_point (window,
2908 gdk_draw_line (window,
2909 style->bg_gc[state_type],
2911 x + 1, y + height - 2);
2912 gdk_draw_point (window,
2913 style->light_gc[state_type],
2921 gdk_gc_set_clip_rectangle (gc1, NULL);
2922 gdk_gc_set_clip_rectangle (gc2, NULL);
2923 if (shadow_type == GTK_SHADOW_IN ||
2924 shadow_type == GTK_SHADOW_OUT)
2926 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
2927 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
2933 gtk_default_draw_polygon (GtkStyle *style,
2935 GtkStateType state_type,
2936 GtkShadowType shadow_type,
2939 const gchar *detail,
2944 static const gdouble pi_over_4 = G_PI_4;
2945 static const gdouble pi_3_over_4 = G_PI_4 * 3;
2955 g_return_if_fail (GTK_IS_STYLE (style));
2956 g_return_if_fail (window != NULL);
2957 g_return_if_fail (points != NULL);
2959 switch (shadow_type)
2962 gc1 = style->bg_gc[state_type];
2963 gc2 = style->dark_gc[state_type];
2964 gc3 = style->light_gc[state_type];
2965 gc4 = style->black_gc;
2967 case GTK_SHADOW_ETCHED_IN:
2968 gc1 = style->light_gc[state_type];
2969 gc2 = style->dark_gc[state_type];
2970 gc3 = style->dark_gc[state_type];
2971 gc4 = style->light_gc[state_type];
2973 case GTK_SHADOW_OUT:
2974 gc1 = style->dark_gc[state_type];
2975 gc2 = style->light_gc[state_type];
2976 gc3 = style->black_gc;
2977 gc4 = style->bg_gc[state_type];
2979 case GTK_SHADOW_ETCHED_OUT:
2980 gc1 = style->dark_gc[state_type];
2981 gc2 = style->light_gc[state_type];
2982 gc3 = style->light_gc[state_type];
2983 gc4 = style->dark_gc[state_type];
2991 gdk_gc_set_clip_rectangle (gc1, area);
2992 gdk_gc_set_clip_rectangle (gc2, area);
2993 gdk_gc_set_clip_rectangle (gc3, area);
2994 gdk_gc_set_clip_rectangle (gc4, area);
2998 gdk_draw_polygon (window, style->bg_gc[state_type], TRUE, points, npoints);
3002 for (i = 0; i < npoints; i++)
3004 if ((points[i].x == points[i+1].x) &&
3005 (points[i].y == points[i+1].y))
3011 angle = atan2 (points[i+1].y - points[i].y,
3012 points[i+1].x - points[i].x);
3015 if ((angle > -pi_3_over_4) && (angle < pi_over_4))
3017 if (angle > -pi_over_4)
3028 gdk_draw_line (window, gc1,
3029 points[i].x-xadjust, points[i].y-yadjust,
3030 points[i+1].x-xadjust, points[i+1].y-yadjust);
3031 gdk_draw_line (window, gc3,
3032 points[i].x, points[i].y,
3033 points[i+1].x, points[i+1].y);
3037 if ((angle < -pi_3_over_4) || (angle > pi_3_over_4))
3048 gdk_draw_line (window, gc4,
3049 points[i].x+xadjust, points[i].y+yadjust,
3050 points[i+1].x+xadjust, points[i+1].y+yadjust);
3051 gdk_draw_line (window, gc2,
3052 points[i].x, points[i].y,
3053 points[i+1].x, points[i+1].y);
3059 gdk_gc_set_clip_rectangle (gc1, NULL);
3060 gdk_gc_set_clip_rectangle (gc2, NULL);
3061 gdk_gc_set_clip_rectangle (gc3, NULL);
3062 gdk_gc_set_clip_rectangle (gc4, NULL);
3067 draw_arrow (GdkWindow *window,
3070 GtkArrowType arrow_type,
3079 gdk_gc_set_clip_rectangle (gc, area);
3081 if (arrow_type == GTK_ARROW_DOWN)
3083 for (i = 0, j = 0; i < height; i++, j++)
3084 gdk_draw_line (window, gc, x + j, y + i, x + width - j - 1, y + i);
3086 else if (arrow_type == GTK_ARROW_UP)
3088 for (i = height - 1, j = 0; i >= 0; i--, j++)
3089 gdk_draw_line (window, gc, x + j, y + i, x + width - j - 1, y + i);
3091 else if (arrow_type == GTK_ARROW_LEFT)
3093 for (i = width - 1, j = 0; i >= 0; i--, j++)
3094 gdk_draw_line (window, gc, x + i, y + j, x + i, y + height - j - 1);
3096 else if (arrow_type == GTK_ARROW_RIGHT)
3098 for (i = 0, j = 0; i < width; i++, j++)
3099 gdk_draw_line (window, gc, x + i, y + j, x + i, y + height - j - 1);
3103 gdk_gc_set_clip_rectangle (gc, NULL);
3107 calculate_arrow_geometry (GtkArrowType arrow_type,
3119 case GTK_ARROW_DOWN:
3129 if (arrow_type == GTK_ARROW_DOWN)
3131 if (*height % 2 == 1 || h % 2 == 0)
3136 if (*height % 2 == 0 || h % 2 == 0)
3141 case GTK_ARROW_RIGHT:
3142 case GTK_ARROW_LEFT:
3152 if (arrow_type == GTK_ARROW_RIGHT)
3154 if (*width % 2 == 1 || w % 2 == 0)
3159 if (*width % 2 == 0 || w % 2 == 0)
3165 /* should not be reached */
3169 *x += (*width - w) / 2;
3170 *y += (*height - h) / 2;
3176 gtk_default_draw_arrow (GtkStyle *style,
3179 GtkShadowType shadow,
3182 const gchar *detail,
3183 GtkArrowType arrow_type,
3190 gint original_width, original_x;
3192 sanitize_size (window, &width, &height);
3194 original_width = width;
3197 calculate_arrow_geometry (arrow_type, &x, &y, &width, &height);
3199 if (detail && strcmp (detail, "menu_scroll_arrow_up") == 0)
3202 if (state == GTK_STATE_INSENSITIVE)
3203 draw_arrow (window, style->white_gc, area, arrow_type,
3204 x + 1, y + 1, width, height);
3205 draw_arrow (window, style->fg_gc[state], area, arrow_type,
3206 x, y, width, height);
3210 gtk_default_draw_diamond (GtkStyle *style,
3212 GtkStateType state_type,
3213 GtkShadowType shadow_type,
3216 const gchar *detail,
3224 GdkGC *outer_nw = NULL;
3225 GdkGC *outer_ne = NULL;
3226 GdkGC *outer_sw = NULL;
3227 GdkGC *outer_se = NULL;
3228 GdkGC *middle_nw = NULL;
3229 GdkGC *middle_ne = NULL;
3230 GdkGC *middle_sw = NULL;
3231 GdkGC *middle_se = NULL;
3232 GdkGC *inner_nw = NULL;
3233 GdkGC *inner_ne = NULL;
3234 GdkGC *inner_sw = NULL;
3235 GdkGC *inner_se = NULL;
3237 g_return_if_fail (GTK_IS_STYLE (style));
3238 g_return_if_fail (window != NULL);
3240 sanitize_size (window, &width, &height);
3242 half_width = width / 2;
3243 half_height = height / 2;
3247 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
3248 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
3249 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
3250 gdk_gc_set_clip_rectangle (style->black_gc, area);
3253 switch (shadow_type)
3256 inner_sw = inner_se = style->bg_gc[state_type];
3257 middle_sw = middle_se = style->light_gc[state_type];
3258 outer_sw = outer_se = style->light_gc[state_type];
3259 inner_nw = inner_ne = style->black_gc;
3260 middle_nw = middle_ne = style->dark_gc[state_type];
3261 outer_nw = outer_ne = style->dark_gc[state_type];
3264 case GTK_SHADOW_OUT:
3265 inner_sw = inner_se = style->dark_gc[state_type];
3266 middle_sw = middle_se = style->dark_gc[state_type];
3267 outer_sw = outer_se = style->black_gc;
3268 inner_nw = inner_ne = style->bg_gc[state_type];
3269 middle_nw = middle_ne = style->light_gc[state_type];
3270 outer_nw = outer_ne = style->light_gc[state_type];
3273 case GTK_SHADOW_ETCHED_IN:
3274 inner_sw = inner_se = style->bg_gc[state_type];
3275 middle_sw = middle_se = style->dark_gc[state_type];
3276 outer_sw = outer_se = style->light_gc[state_type];
3277 inner_nw = inner_ne = style->bg_gc[state_type];
3278 middle_nw = middle_ne = style->light_gc[state_type];
3279 outer_nw = outer_ne = style->dark_gc[state_type];
3282 case GTK_SHADOW_ETCHED_OUT:
3283 inner_sw = inner_se = style->bg_gc[state_type];
3284 middle_sw = middle_se = style->light_gc[state_type];
3285 outer_sw = outer_se = style->dark_gc[state_type];
3286 inner_nw = inner_ne = style->bg_gc[state_type];
3287 middle_nw = middle_ne = style->dark_gc[state_type];
3288 outer_nw = outer_ne = style->light_gc[state_type];
3298 gdk_draw_line (window, inner_sw,
3299 x + 2, y + half_height,
3300 x + half_width, y + height - 2);
3301 gdk_draw_line (window, inner_se,
3302 x + half_width, y + height - 2,
3303 x + width - 2, y + half_height);
3304 gdk_draw_line (window, middle_sw,
3305 x + 1, y + half_height,
3306 x + half_width, y + height - 1);
3307 gdk_draw_line (window, middle_se,
3308 x + half_width, y + height - 1,
3309 x + width - 1, y + half_height);
3310 gdk_draw_line (window, outer_sw,
3312 x + half_width, y + height);
3313 gdk_draw_line (window, outer_se,
3314 x + half_width, y + height,
3315 x + width, y + half_height);
3317 gdk_draw_line (window, inner_nw,
3318 x + 2, y + half_height,
3319 x + half_width, y + 2);
3320 gdk_draw_line (window, inner_ne,
3321 x + half_width, y + 2,
3322 x + width - 2, y + half_height);
3323 gdk_draw_line (window, middle_nw,
3324 x + 1, y + half_height,
3325 x + half_width, y + 1);
3326 gdk_draw_line (window, middle_ne,
3327 x + half_width, y + 1,
3328 x + width - 1, y + half_height);
3329 gdk_draw_line (window, outer_nw,
3332 gdk_draw_line (window, outer_ne,
3334 x + width, y + half_height);
3339 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
3340 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
3341 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
3342 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
3347 gtk_default_draw_string (GtkStyle *style,
3349 GtkStateType state_type,
3352 const gchar *detail,
3355 const gchar *string)
3357 GdkDisplay *display;
3359 g_return_if_fail (GTK_IS_STYLE (style));
3360 g_return_if_fail (window != NULL);
3362 display = gdk_drawable_get_display (window);
3366 gdk_gc_set_clip_rectangle (style->white_gc, area);
3367 gdk_gc_set_clip_rectangle (style->fg_gc[state_type], area);
3370 if (state_type == GTK_STATE_INSENSITIVE)
3371 gdk_draw_string (window,
3372 gtk_style_get_font_internal (style),
3373 style->white_gc, x + 1, y + 1, string);
3375 gdk_draw_string (window,
3376 gtk_style_get_font_internal (style),
3377 style->fg_gc[state_type], x, y, string);
3381 gdk_gc_set_clip_rectangle (style->white_gc, NULL);
3382 gdk_gc_set_clip_rectangle (style->fg_gc[state_type], NULL);
3387 option_menu_get_props (GtkWidget *widget,
3388 GtkRequisition *indicator_size,
3389 GtkBorder *indicator_spacing)
3391 GtkRequisition *tmp_size = NULL;
3392 GtkBorder *tmp_spacing = NULL;
3395 gtk_widget_style_get (widget,
3396 "indicator_size", &tmp_size,
3397 "indicator_spacing", &tmp_spacing,
3402 *indicator_size = *tmp_size;
3406 *indicator_size = default_option_indicator_size;
3410 *indicator_spacing = *tmp_spacing;
3411 g_free (tmp_spacing);
3414 *indicator_spacing = default_option_indicator_spacing;
3418 gtk_default_draw_box (GtkStyle *style,
3420 GtkStateType state_type,
3421 GtkShadowType shadow_type,
3424 const gchar *detail,
3430 gboolean is_spinbutton_box = FALSE;
3432 g_return_if_fail (GTK_IS_STYLE (style));
3433 g_return_if_fail (window != NULL);
3435 sanitize_size (window, &width, &height);
3437 if (widget && GTK_IS_SPIN_BUTTON (widget) && detail)
3439 if (strcmp (detail, "spinbutton_up") == 0)
3445 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
3450 is_spinbutton_box = TRUE;
3452 else if (strcmp (detail, "spinbutton_down") == 0)
3457 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
3462 is_spinbutton_box = TRUE;
3466 if (!style->bg_pixmap[state_type] ||
3467 GDK_IS_PIXMAP (window))
3469 GdkGC *gc = style->bg_gc[state_type];
3471 if (state_type == GTK_STATE_SELECTED && detail && strcmp (detail, "paned") == 0)
3473 if (widget && !GTK_WIDGET_HAS_FOCUS (widget))
3474 gc = style->base_gc[GTK_STATE_ACTIVE];
3478 gdk_gc_set_clip_rectangle (gc, area);
3480 gdk_draw_rectangle (window, gc, TRUE,
3481 x, y, width, height);
3483 gdk_gc_set_clip_rectangle (gc, NULL);
3486 gtk_style_apply_default_background (style, window,
3487 widget && !GTK_WIDGET_NO_WINDOW (widget),
3488 state_type, area, x, y, width, height);
3490 if (is_spinbutton_box)
3495 lower_gc = style->dark_gc[state_type];
3496 if (shadow_type == GTK_SHADOW_OUT)
3497 upper_gc = style->light_gc[state_type];
3499 upper_gc = style->dark_gc[state_type];
3503 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
3504 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
3507 gdk_draw_line (window, upper_gc, x, y, x + width - 1, y);
3508 gdk_draw_line (window, lower_gc, x, y + height - 1, x + width - 1, y + height - 1);
3512 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
3513 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
3518 gtk_paint_shadow (style, window, state_type, shadow_type, area, widget, detail,
3519 x, y, width, height);
3521 if (detail && strcmp (detail, "optionmenu") == 0)
3523 GtkRequisition indicator_size;
3524 GtkBorder indicator_spacing;
3527 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
3529 sanitize_size (window, &width, &height);
3531 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
3532 vline_x = x + indicator_size.width + indicator_spacing.left + indicator_spacing.right;
3534 vline_x = x + width - (indicator_size.width + indicator_spacing.left + indicator_spacing.right) - style->xthickness;
3536 gtk_paint_vline (style, window, state_type, area, widget,
3538 y + style->ythickness + 1,
3539 y + height - style->ythickness - 3,
3545 get_darkened_gc (GdkWindow *window,
3549 GdkColor src = *color;
3550 GdkColor shaded = *color;
3553 gc = gdk_gc_new (window);
3555 while (darken_count)
3557 gtk_style_shade (&src, &shaded, 0.93);
3562 gdk_gc_set_rgb_fg_color (gc, &shaded);
3568 gtk_default_draw_flat_box (GtkStyle *style,
3570 GtkStateType state_type,
3571 GtkShadowType shadow_type,
3574 const gchar *detail,
3581 GdkGC *freeme = NULL;
3583 g_return_if_fail (GTK_IS_STYLE (style));
3584 g_return_if_fail (window != NULL);
3586 sanitize_size (window, &width, &height);
3590 if (state_type == GTK_STATE_SELECTED)
3592 if (!strcmp ("text", detail))
3593 gc1 = style->bg_gc[GTK_STATE_SELECTED];
3594 else if (!strncmp ("cell_even", detail, strlen ("cell_even")) ||
3595 !strncmp ("cell_odd", detail, strlen ("cell_odd")))
3597 /* This has to be really broken; alex made me do it. -jrb */
3598 if (GTK_WIDGET_HAS_FOCUS (widget))
3599 gc1 = style->base_gc[state_type];
3601 gc1 = style->base_gc[GTK_STATE_ACTIVE];
3605 gc1 = style->bg_gc[state_type];
3610 if (!strcmp ("viewportbin", detail))
3611 gc1 = style->bg_gc[GTK_STATE_NORMAL];
3612 else if (!strcmp ("entry_bg", detail))
3613 gc1 = style->base_gc[state_type];
3615 /* For trees: even rows are base color, odd rows are a shade of
3616 * the base color, the sort column is a shade of the original color
3620 else if (!strcmp ("cell_even", detail) ||
3621 !strcmp ("cell_odd", detail) ||
3622 !strcmp ("cell_even_ruled", detail))
3624 GdkColor *color = NULL;
3626 gtk_widget_style_get (widget,
3627 "even_row_color", &color,
3632 freeme = get_darkened_gc (window, color, 0);
3635 gdk_color_free (color);
3638 gc1 = style->base_gc[state_type];
3640 else if (!strcmp ("cell_odd_ruled", detail))
3644 gtk_widget_style_get (widget,
3645 "odd_row_color", &color,
3650 freeme = get_darkened_gc (window, color, 0);
3653 gdk_color_free (color);
3657 gtk_widget_style_get (widget,
3658 "even_row_color", &color,
3663 freeme = get_darkened_gc (window, color, 1);
3664 gdk_color_free (color);
3667 freeme = get_darkened_gc (window, &style->base[state_type], 1);
3671 else if (!strcmp ("cell_even_sorted", detail) ||
3672 !strcmp ("cell_odd_sorted", detail) ||
3673 !strcmp ("cell_even_ruled_sorted", detail))
3675 GdkColor *color = NULL;
3677 if (!strcmp ("cell_odd_sorted", detail))
3678 gtk_widget_style_get (widget,
3679 "odd_row_color", &color,
3682 gtk_widget_style_get (widget,
3683 "even_row_color", &color,
3688 freeme = get_darkened_gc (window, color, 1);
3691 gdk_color_free (color);
3695 freeme = get_darkened_gc (window, &style->base[state_type], 1);
3699 else if (!strcmp ("cell_odd_ruled_sorted", detail))
3701 GdkColor *color = NULL;
3703 gtk_widget_style_get (widget,
3704 "odd_row_color", &color,
3709 freeme = get_darkened_gc (window, color, 1);
3712 gdk_color_free (color);
3716 gtk_widget_style_get (widget,
3717 "even_row_color", &color,
3722 freeme = get_darkened_gc (window, color, 2);
3723 gdk_color_free (color);
3726 freeme = get_darkened_gc (window, &style->base[state_type], 2);
3731 gc1 = style->bg_gc[state_type];
3735 gc1 = style->bg_gc[state_type];
3737 if (!style->bg_pixmap[state_type] || gc1 != style->bg_gc[state_type] ||
3738 GDK_IS_PIXMAP (window))
3741 gdk_gc_set_clip_rectangle (gc1, area);
3743 gdk_draw_rectangle (window, gc1, TRUE,
3744 x, y, width, height);
3746 if (detail && !strcmp ("tooltip", detail))
3747 gdk_draw_rectangle (window, style->black_gc, FALSE,
3748 x, y, width - 1, height - 1);
3751 gdk_gc_set_clip_rectangle (gc1, NULL);
3754 gtk_style_apply_default_background (style, window,
3755 widget && !GTK_WIDGET_NO_WINDOW (widget),
3756 state_type, area, x, y, width, height);
3760 g_object_unref (freeme);
3764 create_aa_gc (GdkWindow *window, GtkStyle *style, GtkStateType state_type)
3767 GdkGC *gc = gdk_gc_new (window);
3769 aa_color.red = (style->fg[state_type].red + style->bg[state_type].red) / 2;
3770 aa_color.green = (style->fg[state_type].green + style->bg[state_type].green) / 2;
3771 aa_color.blue = (style->fg[state_type].blue + style->bg[state_type].blue) / 2;
3773 gdk_gc_set_rgb_fg_color (gc, &aa_color);
3779 gtk_default_draw_check (GtkStyle *style,
3781 GtkStateType state_type,
3782 GtkShadowType shadow_type,
3785 const gchar *detail,
3791 if (detail && strcmp (detail, "cellcheck") == 0)
3794 gdk_gc_set_clip_rectangle (widget->style->base_gc[state_type], area);
3795 gdk_draw_rectangle (window,
3796 widget->style->base_gc[state_type],
3802 gdk_gc_set_clip_rectangle (widget->style->base_gc[state_type], NULL);
3803 gdk_gc_set_clip_rectangle (widget->style->text_gc[state_type], area);
3805 gdk_draw_rectangle (window,
3806 widget->style->text_gc[state_type],
3811 gdk_gc_set_clip_rectangle (widget->style->text_gc[state_type], NULL);
3813 x -= (1 + INDICATOR_PART_SIZE - width) / 2;
3814 y -= (((1 + INDICATOR_PART_SIZE - height) / 2) - 1);
3815 if (shadow_type == GTK_SHADOW_IN)
3817 draw_part (window, style->text_gc[state_type], area, x, y, CHECK_TEXT);
3818 draw_part (window, style->text_aa_gc[state_type], area, x, y, CHECK_AA);
3820 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
3822 draw_part (window, style->text_gc[state_type], area, x, y, CHECK_INCONSISTENT_TEXT);
3827 GdkGC *free_me = NULL;
3833 x -= (1 + INDICATOR_PART_SIZE - width) / 2;
3834 y -= (1 + INDICATOR_PART_SIZE - height) / 2;
3836 if (detail && strcmp (detail, "check") == 0) /* Menu item */
3838 text_gc = style->fg_gc[state_type];
3839 base_gc = style->bg_gc[state_type];
3840 aa_gc = free_me = create_aa_gc (window, style, state_type);
3844 if (state_type == GTK_STATE_ACTIVE)
3846 text_gc = style->fg_gc[state_type];
3847 base_gc = style->bg_gc[state_type];
3848 aa_gc = free_me = create_aa_gc (window, style, state_type);
3852 text_gc = style->text_gc[state_type];
3853 base_gc = style->base_gc[state_type];
3854 aa_gc = style->text_aa_gc[state_type];
3857 draw_part (window, base_gc, area, x, y, CHECK_BASE);
3858 draw_part (window, style->black_gc, area, x, y, CHECK_BLACK);
3859 draw_part (window, style->dark_gc[state_type], area, x, y, CHECK_DARK);
3860 draw_part (window, style->mid_gc[state_type], area, x, y, CHECK_MID);
3861 draw_part (window, style->light_gc[state_type], area, x, y, CHECK_LIGHT);
3864 if (shadow_type == GTK_SHADOW_IN)
3866 draw_part (window, text_gc, area, x, y, CHECK_TEXT);
3867 draw_part (window, aa_gc, area, x, y, CHECK_AA);
3869 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
3871 draw_part (window, text_gc, area, x, y, CHECK_INCONSISTENT_TEXT);
3875 g_object_unref (free_me);
3880 gtk_default_draw_option (GtkStyle *style,
3882 GtkStateType state_type,
3883 GtkShadowType shadow_type,
3886 const gchar *detail,
3892 if (detail && strcmp (detail, "cellradio") == 0)
3895 gdk_gc_set_clip_rectangle (widget->style->fg_gc[state_type], area);
3896 gdk_draw_arc (window,
3897 widget->style->fg_gc[state_type],
3904 if (shadow_type == GTK_SHADOW_IN)
3906 gdk_draw_arc (window,
3907 widget->style->fg_gc[state_type],
3915 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
3917 draw_part (window, widget->style->fg_gc[state_type],
3918 area, x, y, CHECK_INCONSISTENT_TEXT);
3921 gdk_gc_set_clip_rectangle (widget->style->fg_gc[state_type], NULL);
3925 GdkGC *free_me = NULL;
3931 x -= (1 + INDICATOR_PART_SIZE - width) / 2;
3932 y -= (1 + INDICATOR_PART_SIZE - height) / 2;
3934 if (detail && strcmp (detail, "option") == 0) /* Menu item */
3936 text_gc = style->fg_gc[state_type];
3937 base_gc = style->bg_gc[state_type];
3938 aa_gc = free_me = create_aa_gc (window, style, state_type);
3942 if (state_type == GTK_STATE_ACTIVE)
3944 text_gc = style->fg_gc[state_type];
3945 base_gc = style->bg_gc[state_type];
3946 aa_gc = free_me = create_aa_gc (window, style, state_type);
3950 text_gc = style->text_gc[state_type];
3951 base_gc = style->base_gc[state_type];
3952 aa_gc = style->text_aa_gc[state_type];
3955 draw_part (window, base_gc, area, x, y, RADIO_BASE);
3956 draw_part (window, style->black_gc, area, x, y, RADIO_BLACK);
3957 draw_part (window, style->dark_gc[state_type], area, x, y, RADIO_DARK);
3958 draw_part (window, style->mid_gc[state_type], area, x, y, RADIO_MID);
3959 draw_part (window, style->light_gc[state_type], area, x, y, RADIO_LIGHT);
3962 if (shadow_type == GTK_SHADOW_IN)
3964 draw_part (window, text_gc, area, x, y, RADIO_TEXT);
3966 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
3968 if (detail && strcmp (detail, "option") == 0) /* Menu item */
3970 draw_part (window, text_gc, area, x, y, CHECK_INCONSISTENT_TEXT);
3974 draw_part (window, text_gc, area, x, y, RADIO_INCONSISTENT_TEXT);
3975 draw_part (window, aa_gc, area, x, y, RADIO_INCONSISTENT_AA);
3980 g_object_unref (free_me);
3985 gtk_default_draw_tab (GtkStyle *style,
3987 GtkStateType state_type,
3988 GtkShadowType shadow_type,
3991 const gchar *detail,
3997 #define ARROW_SPACE 4
3999 GtkRequisition indicator_size;
4000 GtkBorder indicator_spacing;
4003 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
4005 indicator_size.width += (indicator_size.width % 2) - 1;
4006 arrow_height = indicator_size.width / 2 + 1;
4008 x += (width - indicator_size.width) / 2;
4009 y += (height - (2 * arrow_height + ARROW_SPACE)) / 2;
4011 if (state_type == GTK_STATE_INSENSITIVE)
4013 draw_arrow (window, style->white_gc, area,
4014 GTK_ARROW_UP, x + 1, y + 1,
4015 indicator_size.width, arrow_height);
4017 draw_arrow (window, style->white_gc, area,
4018 GTK_ARROW_DOWN, x + 1, y + arrow_height + ARROW_SPACE + 1,
4019 indicator_size.width, arrow_height);
4022 draw_arrow (window, style->fg_gc[state_type], area,
4024 indicator_size.width, arrow_height);
4027 draw_arrow (window, style->fg_gc[state_type], area,
4028 GTK_ARROW_DOWN, x, y + arrow_height + ARROW_SPACE,
4029 indicator_size.width, arrow_height);
4033 gtk_default_draw_shadow_gap (GtkStyle *style,
4035 GtkStateType state_type,
4036 GtkShadowType shadow_type,
4039 const gchar *detail,
4044 GtkPositionType gap_side,
4053 g_return_if_fail (GTK_IS_STYLE (style));
4054 g_return_if_fail (window != NULL);
4056 sanitize_size (window, &width, &height);
4058 switch (shadow_type)
4060 case GTK_SHADOW_NONE:
4063 gc1 = style->dark_gc[state_type];
4064 gc2 = style->black_gc;
4065 gc3 = style->bg_gc[state_type];
4066 gc4 = style->light_gc[state_type];
4068 case GTK_SHADOW_ETCHED_IN:
4069 gc1 = style->dark_gc[state_type];
4070 gc2 = style->light_gc[state_type];
4071 gc3 = style->dark_gc[state_type];
4072 gc4 = style->light_gc[state_type];
4074 case GTK_SHADOW_OUT:
4075 gc1 = style->light_gc[state_type];
4076 gc2 = style->bg_gc[state_type];
4077 gc3 = style->dark_gc[state_type];
4078 gc4 = style->black_gc;
4080 case GTK_SHADOW_ETCHED_OUT:
4081 gc1 = style->light_gc[state_type];
4082 gc2 = style->dark_gc[state_type];
4083 gc3 = style->light_gc[state_type];
4084 gc4 = style->dark_gc[state_type];
4089 gdk_gc_set_clip_rectangle (gc1, area);
4090 gdk_gc_set_clip_rectangle (gc2, area);
4091 gdk_gc_set_clip_rectangle (gc3, area);
4092 gdk_gc_set_clip_rectangle (gc4, area);
4095 switch (shadow_type)
4097 case GTK_SHADOW_NONE:
4099 case GTK_SHADOW_OUT:
4100 case GTK_SHADOW_ETCHED_IN:
4101 case GTK_SHADOW_ETCHED_OUT:
4105 gdk_draw_line (window, gc1,
4106 x, y, x, y + height - 1);
4107 gdk_draw_line (window, gc2,
4108 x + 1, y, x + 1, y + height - 2);
4110 gdk_draw_line (window, gc3,
4111 x + 1, y + height - 2, x + width - 2, y + height - 2);
4112 gdk_draw_line (window, gc3,
4113 x + width - 2, y, x + width - 2, y + height - 2);
4114 gdk_draw_line (window, gc4,
4115 x, y + height - 1, x + width - 1, y + height - 1);
4116 gdk_draw_line (window, gc4,
4117 x + width - 1, y, x + width - 1, y + height - 1);
4120 gdk_draw_line (window, gc1,
4121 x, y, x + gap_x - 1, y);
4122 gdk_draw_line (window, gc2,
4123 x + 1, y + 1, x + gap_x - 1, y + 1);
4124 gdk_draw_line (window, gc2,
4125 x + gap_x, y, x + gap_x, y);
4127 if ((width - (gap_x + gap_width)) > 0)
4129 gdk_draw_line (window, gc1,
4130 x + gap_x + gap_width, y, x + width - 2, y);
4131 gdk_draw_line (window, gc2,
4132 x + gap_x + gap_width, y + 1, x + width - 3, y + 1);
4133 gdk_draw_line (window, gc2,
4134 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
4137 case GTK_POS_BOTTOM:
4138 gdk_draw_line (window, gc1,
4139 x, y, x + width - 1, y);
4140 gdk_draw_line (window, gc1,
4141 x, y, x, y + height - 1);
4142 gdk_draw_line (window, gc2,
4143 x + 1, y + 1, x + width - 2, y + 1);
4144 gdk_draw_line (window, gc2,
4145 x + 1, y + 1, x + 1, y + height - 1);
4147 gdk_draw_line (window, gc3,
4148 x + width - 2, y + 1, x + width - 2, y + height - 1);
4149 gdk_draw_line (window, gc4,
4150 x + width - 1, y, x + width - 1, y + height - 1);
4153 gdk_draw_line (window, gc4,
4154 x, y + height - 1, x + gap_x - 1, y + height - 1);
4155 gdk_draw_line (window, gc3,
4156 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
4157 gdk_draw_line (window, gc3,
4158 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
4160 if ((width - (gap_x + gap_width)) > 0)
4162 gdk_draw_line (window, gc4,
4163 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
4164 gdk_draw_line (window, gc3,
4165 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
4166 gdk_draw_line (window, gc3,
4167 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
4171 gdk_draw_line (window, gc1,
4172 x, y, x + width - 1, y);
4173 gdk_draw_line (window, gc2,
4174 x, y + 1, x + width - 2, y + 1);
4176 gdk_draw_line (window, gc3,
4177 x, y + height - 2, x + width - 2, y + height - 2);
4178 gdk_draw_line (window, gc3,
4179 x + width - 2, y + 1, x + width - 2, y + height - 2);
4180 gdk_draw_line (window, gc4,
4181 x, y + height - 1, x + width - 1, y + height - 1);
4182 gdk_draw_line (window, gc4,
4183 x + width - 1, y, x + width - 1, y + height - 1);
4186 gdk_draw_line (window, gc1,
4187 x, y, x, y + gap_x - 1);
4188 gdk_draw_line (window, gc2,
4189 x + 1, y + 1, x + 1, y + gap_x - 1);
4190 gdk_draw_line (window, gc2,
4191 x, y + gap_x, x, y + gap_x);
4193 if ((width - (gap_x + gap_width)) > 0)
4195 gdk_draw_line (window, gc1,
4196 x, y + gap_x + gap_width, x, y + height - 2);
4197 gdk_draw_line (window, gc2,
4198 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
4199 gdk_draw_line (window, gc2,
4200 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
4204 gdk_draw_line (window, gc1,
4205 x, y, x + width - 1, y);
4206 gdk_draw_line (window, gc1,
4207 x, y, x, y + height - 1);
4208 gdk_draw_line (window, gc2,
4209 x + 1, y + 1, x + width - 1, y + 1);
4210 gdk_draw_line (window, gc2,
4211 x + 1, y + 1, x + 1, y + height - 2);
4213 gdk_draw_line (window, gc3,
4214 x + 1, y + height - 2, x + width - 1, y + height - 2);
4215 gdk_draw_line (window, gc4,
4216 x, y + height - 1, x + width - 1, y + height - 1);
4219 gdk_draw_line (window, gc4,
4220 x + width - 1, y, x + width - 1, y + gap_x - 1);
4221 gdk_draw_line (window, gc3,
4222 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
4223 gdk_draw_line (window, gc3,
4224 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
4226 if ((width - (gap_x + gap_width)) > 0)
4228 gdk_draw_line (window, gc4,
4229 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
4230 gdk_draw_line (window, gc3,
4231 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
4232 gdk_draw_line (window, gc3,
4233 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
4241 gdk_gc_set_clip_rectangle (gc1, NULL);
4242 gdk_gc_set_clip_rectangle (gc2, NULL);
4243 gdk_gc_set_clip_rectangle (gc3, NULL);
4244 gdk_gc_set_clip_rectangle (gc4, NULL);
4249 gtk_default_draw_box_gap (GtkStyle *style,
4251 GtkStateType state_type,
4252 GtkShadowType shadow_type,
4255 const gchar *detail,
4260 GtkPositionType gap_side,
4269 g_return_if_fail (GTK_IS_STYLE (style));
4270 g_return_if_fail (window != NULL);
4272 gtk_style_apply_default_background (style, window,
4273 widget && !GTK_WIDGET_NO_WINDOW (widget),
4274 state_type, area, x, y, width, height);
4276 sanitize_size (window, &width, &height);
4278 switch (shadow_type)
4280 case GTK_SHADOW_NONE:
4283 gc1 = style->dark_gc[state_type];
4284 gc2 = style->black_gc;
4285 gc3 = style->bg_gc[state_type];
4286 gc4 = style->light_gc[state_type];
4288 case GTK_SHADOW_ETCHED_IN:
4289 gc1 = style->dark_gc[state_type];
4290 gc2 = style->light_gc[state_type];
4291 gc3 = style->dark_gc[state_type];
4292 gc4 = style->light_gc[state_type];
4294 case GTK_SHADOW_OUT:
4295 gc1 = style->light_gc[state_type];
4296 gc2 = style->bg_gc[state_type];
4297 gc3 = style->dark_gc[state_type];
4298 gc4 = style->black_gc;
4300 case GTK_SHADOW_ETCHED_OUT:
4301 gc1 = style->light_gc[state_type];
4302 gc2 = style->dark_gc[state_type];
4303 gc3 = style->light_gc[state_type];
4304 gc4 = style->dark_gc[state_type];
4310 gdk_gc_set_clip_rectangle (gc1, area);
4311 gdk_gc_set_clip_rectangle (gc2, area);
4312 gdk_gc_set_clip_rectangle (gc3, area);
4313 gdk_gc_set_clip_rectangle (gc4, area);
4316 switch (shadow_type)
4318 case GTK_SHADOW_NONE:
4320 case GTK_SHADOW_OUT:
4321 case GTK_SHADOW_ETCHED_IN:
4322 case GTK_SHADOW_ETCHED_OUT:
4326 gdk_draw_line (window, gc1,
4327 x, y, x, y + height - 1);
4328 gdk_draw_line (window, gc2,
4329 x + 1, y, x + 1, y + height - 2);
4331 gdk_draw_line (window, gc3,
4332 x + 1, y + height - 2, x + width - 2, y + height - 2);
4333 gdk_draw_line (window, gc3,
4334 x + width - 2, y, x + width - 2, y + height - 2);
4335 gdk_draw_line (window, gc4,
4336 x, y + height - 1, x + width - 1, y + height - 1);
4337 gdk_draw_line (window, gc4,
4338 x + width - 1, y, x + width - 1, y + height - 1);
4341 gdk_draw_line (window, gc1,
4342 x, y, x + gap_x - 1, y);
4343 gdk_draw_line (window, gc2,
4344 x + 1, y + 1, x + gap_x - 1, y + 1);
4345 gdk_draw_line (window, gc2,
4346 x + gap_x, y, x + gap_x, y);
4348 if ((width - (gap_x + gap_width)) > 0)
4350 gdk_draw_line (window, gc1,
4351 x + gap_x + gap_width, y, x + width - 2, y);
4352 gdk_draw_line (window, gc2,
4353 x + gap_x + gap_width, y + 1, x + width - 2, y + 1);
4354 gdk_draw_line (window, gc2,
4355 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
4358 case GTK_POS_BOTTOM:
4359 gdk_draw_line (window, gc1,
4360 x, y, x + width - 1, y);
4361 gdk_draw_line (window, gc1,
4362 x, y, x, y + height - 1);
4363 gdk_draw_line (window, gc2,
4364 x + 1, y + 1, x + width - 2, y + 1);
4365 gdk_draw_line (window, gc2,
4366 x + 1, y + 1, x + 1, y + height - 1);
4368 gdk_draw_line (window, gc3,
4369 x + width - 2, y + 1, x + width - 2, y + height - 1);
4370 gdk_draw_line (window, gc4,
4371 x + width - 1, y, x + width - 1, y + height - 1);
4374 gdk_draw_line (window, gc4,
4375 x, y + height - 1, x + gap_x - 1, y + height - 1);
4376 gdk_draw_line (window, gc3,
4377 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
4378 gdk_draw_line (window, gc3,
4379 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
4381 if ((width - (gap_x + gap_width)) > 0)
4383 gdk_draw_line (window, gc4,
4384 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
4385 gdk_draw_line (window, gc3,
4386 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
4387 gdk_draw_line (window, gc3,
4388 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
4392 gdk_draw_line (window, gc1,
4393 x, y, x + width - 1, y);
4394 gdk_draw_line (window, gc2,
4395 x, y + 1, x + width - 2, y + 1);
4397 gdk_draw_line (window, gc3,
4398 x, y + height - 2, x + width - 2, y + height - 2);
4399 gdk_draw_line (window, gc3,
4400 x + width - 2, y + 1, x + width - 2, y + height - 2);
4401 gdk_draw_line (window, gc4,
4402 x, y + height - 1, x + width - 1, y + height - 1);
4403 gdk_draw_line (window, gc4,
4404 x + width - 1, y, x + width - 1, y + height - 1);
4407 gdk_draw_line (window, gc1,
4408 x, y, x, y + gap_x - 1);
4409 gdk_draw_line (window, gc2,
4410 x + 1, y + 1, x + 1, y + gap_x - 1);
4411 gdk_draw_line (window, gc2,
4412 x, y + gap_x, x, y + gap_x);
4414 if ((width - (gap_x + gap_width)) > 0)
4416 gdk_draw_line (window, gc1,
4417 x, y + gap_x + gap_width, x, y + height - 2);
4418 gdk_draw_line (window, gc2,
4419 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
4420 gdk_draw_line (window, gc2,
4421 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
4425 gdk_draw_line (window, gc1,
4426 x, y, x + width - 1, y);
4427 gdk_draw_line (window, gc1,
4428 x, y, x, y + height - 1);
4429 gdk_draw_line (window, gc2,
4430 x + 1, y + 1, x + width - 1, y + 1);
4431 gdk_draw_line (window, gc2,
4432 x + 1, y + 1, x + 1, y + height - 2);
4434 gdk_draw_line (window, gc3,
4435 x + 1, y + height - 2, x + width - 1, y + height - 2);
4436 gdk_draw_line (window, gc4,
4437 x, y + height - 1, x + width - 1, y + height - 1);
4440 gdk_draw_line (window, gc4,
4441 x + width - 1, y, x + width - 1, y + gap_x - 1);
4442 gdk_draw_line (window, gc3,
4443 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
4444 gdk_draw_line (window, gc3,
4445 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
4447 if ((width - (gap_x + gap_width)) > 0)
4449 gdk_draw_line (window, gc4,
4450 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
4451 gdk_draw_line (window, gc3,
4452 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
4453 gdk_draw_line (window, gc3,
4454 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
4462 gdk_gc_set_clip_rectangle (gc1, NULL);
4463 gdk_gc_set_clip_rectangle (gc2, NULL);
4464 gdk_gc_set_clip_rectangle (gc3, NULL);
4465 gdk_gc_set_clip_rectangle (gc4, NULL);
4470 gtk_default_draw_extension (GtkStyle *style,
4472 GtkStateType state_type,
4473 GtkShadowType shadow_type,
4476 const gchar *detail,
4481 GtkPositionType gap_side)
4488 g_return_if_fail (GTK_IS_STYLE (style));
4489 g_return_if_fail (window != NULL);
4491 gtk_style_apply_default_background (style, window,
4492 widget && !GTK_WIDGET_NO_WINDOW (widget),
4493 GTK_STATE_NORMAL, area, x, y, width, height);
4495 sanitize_size (window, &width, &height);
4497 switch (shadow_type)
4499 case GTK_SHADOW_NONE:
4502 gc1 = style->dark_gc[state_type];
4503 gc2 = style->black_gc;
4504 gc3 = style->bg_gc[state_type];
4505 gc4 = style->light_gc[state_type];
4507 case GTK_SHADOW_ETCHED_IN:
4508 gc1 = style->dark_gc[state_type];
4509 gc2 = style->light_gc[state_type];
4510 gc3 = style->dark_gc[state_type];
4511 gc4 = style->light_gc[state_type];
4513 case GTK_SHADOW_OUT:
4514 gc1 = style->light_gc[state_type];
4515 gc2 = style->bg_gc[state_type];
4516 gc3 = style->dark_gc[state_type];
4517 gc4 = style->black_gc;
4519 case GTK_SHADOW_ETCHED_OUT:
4520 gc1 = style->light_gc[state_type];
4521 gc2 = style->dark_gc[state_type];
4522 gc3 = style->light_gc[state_type];
4523 gc4 = style->dark_gc[state_type];
4529 gdk_gc_set_clip_rectangle (gc1, area);
4530 gdk_gc_set_clip_rectangle (gc2, area);
4531 gdk_gc_set_clip_rectangle (gc3, area);
4532 gdk_gc_set_clip_rectangle (gc4, area);
4535 switch (shadow_type)
4537 case GTK_SHADOW_NONE:
4539 case GTK_SHADOW_OUT:
4540 case GTK_SHADOW_ETCHED_IN:
4541 case GTK_SHADOW_ETCHED_OUT:
4545 gtk_style_apply_default_background (style, window,
4546 widget && !GTK_WIDGET_NO_WINDOW (widget),
4548 x + style->xthickness,
4550 width - (2 * style->xthickness),
4551 height - (style->ythickness));
4552 gdk_draw_line (window, gc1,
4553 x, y, x, y + height - 2);
4554 gdk_draw_line (window, gc2,
4555 x + 1, y, x + 1, y + height - 2);
4557 gdk_draw_line (window, gc3,
4558 x + 2, y + height - 2, x + width - 2, y + height - 2);
4559 gdk_draw_line (window, gc3,
4560 x + width - 2, y, x + width - 2, y + height - 2);
4561 gdk_draw_line (window, gc4,
4562 x + 1, y + height - 1, x + width - 2, y + height - 1);
4563 gdk_draw_line (window, gc4,
4564 x + width - 1, y, x + width - 1, y + height - 2);
4566 case GTK_POS_BOTTOM:
4567 gtk_style_apply_default_background (style, window,
4568 widget && !GTK_WIDGET_NO_WINDOW (widget),
4570 x + style->xthickness,
4571 y + style->ythickness,
4572 width - (2 * style->xthickness),
4573 height - (style->ythickness));
4574 gdk_draw_line (window, gc1,
4575 x + 1, y, x + width - 2, y);
4576 gdk_draw_line (window, gc1,
4577 x, y + 1, x, y + height - 1);
4578 gdk_draw_line (window, gc2,
4579 x + 1, y + 1, x + width - 2, y + 1);
4580 gdk_draw_line (window, gc2,
4581 x + 1, y + 1, x + 1, y + height - 1);
4583 gdk_draw_line (window, gc3,
4584 x + width - 2, y + 2, x + width - 2, y + height - 1);
4585 gdk_draw_line (window, gc4,
4586 x + width - 1, y + 1, x + width - 1, y + height - 1);
4589 gtk_style_apply_default_background (style, window,
4590 widget && !GTK_WIDGET_NO_WINDOW (widget),
4593 y + style->ythickness,
4594 width - (style->xthickness),
4595 height - (2 * style->ythickness));
4596 gdk_draw_line (window, gc1,
4597 x, y, x + width - 2, y);
4598 gdk_draw_line (window, gc2,
4599 x + 1, y + 1, x + width - 2, y + 1);
4601 gdk_draw_line (window, gc3,
4602 x, y + height - 2, x + width - 2, y + height - 2);
4603 gdk_draw_line (window, gc3,
4604 x + width - 2, y + 2, x + width - 2, y + height - 2);
4605 gdk_draw_line (window, gc4,
4606 x, y + height - 1, x + width - 2, y + height - 1);
4607 gdk_draw_line (window, gc4,
4608 x + width - 1, y + 1, x + width - 1, y + height - 2);
4611 gtk_style_apply_default_background (style, window,
4612 widget && !GTK_WIDGET_NO_WINDOW (widget),
4614 x + style->xthickness,
4615 y + style->ythickness,
4616 width - (style->xthickness),
4617 height - (2 * style->ythickness));
4618 gdk_draw_line (window, gc1,
4619 x + 1, y, x + width - 1, y);
4620 gdk_draw_line (window, gc1,
4621 x, y + 1, x, y + height - 2);
4622 gdk_draw_line (window, gc2,
4623 x + 1, y + 1, x + width - 1, y + 1);
4624 gdk_draw_line (window, gc2,
4625 x + 1, y + 1, x + 1, y + height - 2);
4627 gdk_draw_line (window, gc3,
4628 x + 2, y + height - 2, x + width - 1, y + height - 2);
4629 gdk_draw_line (window, gc4,
4630 x + 1, y + height - 1, x + width - 1, y + height - 1);
4637 gdk_gc_set_clip_rectangle (gc1, NULL);
4638 gdk_gc_set_clip_rectangle (gc2, NULL);
4639 gdk_gc_set_clip_rectangle (gc3, NULL);
4640 gdk_gc_set_clip_rectangle (gc4, NULL);
4645 gtk_default_draw_focus (GtkStyle *style,
4647 GtkStateType state_type,
4650 const gchar *detail,
4658 gboolean free_dash_list = FALSE;
4659 gint line_width = 1;
4660 gint8 *dash_list = "\1\1";
4665 gtk_widget_style_get (widget,
4666 "focus-line-width", &line_width,
4667 "focus-line-pattern", (gchar *)&dash_list,
4670 free_dash_list = TRUE;
4673 sanitize_size (window, &width, &height);
4675 if (detail && !strcmp (detail, "colorwheel_light"))
4676 gc = style->black_gc;
4677 else if (detail && !strcmp (detail, "colorwheel_dark"))
4678 gc = style->white_gc;
4680 gc = style->fg_gc[state_type];
4682 gdk_gc_set_line_attributes (gc, line_width,
4683 dash_list[0] ? GDK_LINE_ON_OFF_DASH : GDK_LINE_SOLID,
4684 GDK_CAP_BUTT, GDK_JOIN_MITER);
4687 gdk_gc_set_clip_rectangle (gc, area);
4689 if (detail && !strcmp (detail, "add-mode"))
4695 free_dash_list = FALSE;
4698 points[0].x = x + line_width / 2;
4699 points[0].y = y + line_width / 2;
4700 points[1].x = x + width - line_width + line_width / 2;
4701 points[1].y = y + line_width / 2;
4702 points[2].x = x + width - line_width + line_width / 2;
4703 points[2].y = y + height - line_width + line_width / 2;
4704 points[3].x = x + line_width / 2;
4705 points[3].y = y + height - line_width + line_width / 2;
4706 points[4] = points[0];
4710 gdk_draw_lines (window, gc, points, 5);
4714 /* We go through all the pain below because the X rasterization
4715 * rules don't really work right for dashed lines if you
4716 * want continuity in segments that go between top/right
4717 * and left/bottom. For instance, a top left corner
4718 * with a 1-1 dash is drawn as:
4725 * This is because pixels on the top and left boundaries
4726 * of polygons are drawn, but not on the bottom and right.
4727 * So, if you have a line going up that turns the corner
4728 * and goes right, there is a one pixel shift in the pattern.
4730 * So, to fix this, we drawn the top and right in one call,
4731 * then the left and bottom in another call, fixing up
4732 * the dash offset for the second call ourselves to get
4733 * continuity at the upper left.
4735 * It's not perfect since we really should have a join at
4736 * the upper left and lower right instead of two intersecting
4737 * lines but that's only really apparent for no-dashes,
4738 * which (for this reason) are done as one polygon and
4739 * don't to through this code path.
4742 dash_len = strlen (dash_list);
4745 gdk_gc_set_dashes (gc, 0, dash_list, dash_len);
4747 gdk_draw_lines (window, gc, points, 3);
4749 /* We draw this line one farther over than it is "supposed" to
4750 * because of another rasterization problem ... if two 1 pixel
4751 * unjoined lines meet at the lower right, there will be a missing
4758 gint dash_pixels = 0;
4761 /* Adjust the dash offset for the bottom and left so we
4762 * match up at the upper left.
4764 for (i = 0; i < dash_len; i++)
4765 dash_pixels += dash_list[i];
4767 if (dash_len % 2 == 1)
4770 gdk_gc_set_dashes (gc, dash_pixels - (width + height - 2 * line_width) % dash_pixels, dash_list, dash_len);
4773 gdk_draw_lines (window, gc, points + 2, 3);
4776 gdk_gc_set_line_attributes (gc, 0, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
4779 gdk_gc_set_clip_rectangle (gc, NULL);
4786 gtk_default_draw_slider (GtkStyle *style,
4788 GtkStateType state_type,
4789 GtkShadowType shadow_type,
4792 const gchar *detail,
4797 GtkOrientation orientation)
4799 g_return_if_fail (GTK_IS_STYLE (style));
4800 g_return_if_fail (window != NULL);
4802 sanitize_size (window, &width, &height);
4804 gtk_paint_box (style, window, state_type, shadow_type,
4805 area, widget, detail, x, y, width, height);
4808 (strcmp ("hscale", detail) == 0 ||
4809 strcmp ("vscale", detail) == 0))
4811 if (orientation == GTK_ORIENTATION_HORIZONTAL)
4812 gtk_paint_vline (style, window, state_type, area, widget, detail,
4813 y + style->ythickness,
4814 y + height - style->ythickness - 1, x + width / 2);
4816 gtk_paint_hline (style, window, state_type, area, widget, detail,
4817 x + style->xthickness,
4818 x + width - style->xthickness - 1, y + height / 2);
4823 draw_dot (GdkWindow *window,
4831 size = CLAMP (size, 2, 3);
4835 gdk_draw_point (window, light_gc, x, y);
4836 gdk_draw_point (window, light_gc, x+1, y+1);
4840 gdk_draw_point (window, light_gc, x, y);
4841 gdk_draw_point (window, light_gc, x+1, y);
4842 gdk_draw_point (window, light_gc, x, y+1);
4843 gdk_draw_point (window, dark_gc, x+1, y+2);
4844 gdk_draw_point (window, dark_gc, x+2, y+1);
4845 gdk_draw_point (window, dark_gc, x+2, y+2);
4850 gtk_default_draw_handle (GtkStyle *style,
4852 GtkStateType state_type,
4853 GtkShadowType shadow_type,
4856 const gchar *detail,
4861 GtkOrientation orientation)
4864 gint xthick, ythick;
4865 GdkGC *light_gc, *dark_gc;
4866 GdkGC *free_me = NULL;
4871 g_return_if_fail (GTK_IS_STYLE (style));
4872 g_return_if_fail (window != NULL);
4874 sanitize_size (window, &width, &height);
4876 gtk_paint_box (style, window, state_type, shadow_type, area, widget,
4877 detail, x, y, width, height);
4880 if (detail && !strcmp (detail, "paned"))
4882 /* we want to ignore the shadow border in paned widgets */
4886 if (state_type == GTK_STATE_SELECTED && widget && !GTK_WIDGET_HAS_FOCUS (widget))
4888 GdkColor unfocused_light;
4890 gtk_style_shade (&style->base[GTK_STATE_ACTIVE], &unfocused_light,
4893 light_gc = free_me = gdk_gc_new (window);
4894 gdk_gc_set_rgb_fg_color (light_gc, &unfocused_light);
4897 light_gc = style->light_gc[state_type];
4899 dark_gc = style->black_gc;
4903 xthick = style->xthickness;
4904 ythick = style->ythickness;
4906 light_gc = style->light_gc[state_type];
4907 dark_gc = style->dark_gc[state_type];
4910 rect.x = x + xthick;
4911 rect.y = y + ythick;
4912 rect.width = width - (xthick * 2);
4913 rect.height = height - (ythick * 2);
4916 intersect = gdk_rectangle_intersect (area, &rect, &dest);
4926 gdk_gc_set_clip_rectangle (light_gc, &dest);
4927 gdk_gc_set_clip_rectangle (dark_gc, &dest);
4929 if (detail && !strcmp (detail, "paned"))
4931 if (orientation == GTK_ORIENTATION_HORIZONTAL)
4932 for (xx = x + width/2 - 15; xx <= x + width/2 + 15; xx += 5)
4933 draw_dot (window, light_gc, dark_gc, xx, y + height/2 - 1, 3);
4935 for (yy = y + height/2 - 15; yy <= y + height/2 + 15; yy += 5)
4936 draw_dot (window, light_gc, dark_gc, x + width/2 - 1, yy, 3);
4940 for (yy = y + ythick; yy < (y + height - ythick); yy += 3)
4941 for (xx = x + xthick; xx < (x + width - xthick); xx += 6)
4943 draw_dot (window, light_gc, dark_gc, xx, yy, 2);
4944 draw_dot (window, light_gc, dark_gc, xx + 3, yy + 1, 2);
4948 gdk_gc_set_clip_rectangle (light_gc, NULL);
4949 gdk_gc_set_clip_rectangle (dark_gc, NULL);
4953 g_object_unref (free_me);
4957 create_expander_affine (gdouble affine[6],
4967 width = expander_size / 4.0;
4968 height = expander_size / 2.0;
4985 s = sin (degrees * G_PI / 180.0);
4986 c = cos (degrees * G_PI / 180.0);
4994 affine[4] = -width * c - height * -s + x;
4995 affine[5] = -width * s - height * c + y;
4999 apply_affine_on_point (double affine[6], GdkPoint *point)
5003 x = point->x * affine[0] + point->y * affine[2] + affine[4];
5004 y = point->x * affine[1] + point->y * affine[3] + affine[5];
5006 point->x = floor (x);
5007 point->y = floor (y);
5011 gtk_style_draw_polygon_with_gc (GdkWindow *window, GdkGC *gc, gint line_width,
5012 gboolean do_fill, GdkPoint *points, gint n_points)
5014 gdk_gc_set_line_attributes (gc, line_width,
5016 GDK_CAP_BUTT, GDK_JOIN_MITER);
5018 gdk_draw_polygon (window, gc, do_fill, points, n_points);
5019 gdk_gc_set_line_attributes (gc, 0, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
5023 gtk_default_draw_expander (GtkStyle *style,
5025 GtkStateType state_type,
5028 const gchar *detail,
5031 GtkExpanderStyle expander_style)
5040 gtk_widget_style_get (widget,
5041 "expander-size", &expander_size,
5043 line_width = MAX (1, expander_size/9);
5047 gdk_gc_set_clip_rectangle (style->fg_gc[GTK_STATE_NORMAL], area);
5048 gdk_gc_set_clip_rectangle (style->base_gc[GTK_STATE_NORMAL], area);
5051 /* a rough estimate of how much the joins of the triangle will overshoot.
5052 * 2.4 ~ 1 / tan (45 / 2)
5054 o = ceil (2.4 * line_width / 2.0);
5055 points[0].x = line_width / 2;
5057 points[1].x = expander_size / 2 + line_width / 2 - o;
5058 points[1].y = expander_size / 2;
5059 points[2].x = line_width / 2;
5060 points[2].y = expander_size - o;
5062 switch (expander_style)
5064 case GTK_EXPANDER_COLLAPSED:
5065 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 180 : 0;
5067 case GTK_EXPANDER_SEMI_COLLAPSED:
5068 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 150 : 30;
5070 case GTK_EXPANDER_SEMI_EXPANDED:
5071 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 120 : 60;
5073 case GTK_EXPANDER_EXPANDED:
5077 g_assert_not_reached ();
5080 create_expander_affine (affine, degrees, expander_size, x, y);
5082 for (i = 0; i < 3; i++)
5083 apply_affine_on_point (affine, &points[i]);
5085 if (state_type == GTK_STATE_PRELIGHT)
5087 gtk_style_draw_polygon_with_gc (window, style->fg_gc[GTK_STATE_PRELIGHT],
5088 1, TRUE, points, 3);
5090 else if (state_type == GTK_STATE_ACTIVE)
5092 gtk_style_draw_polygon_with_gc (window, style->light_gc[GTK_STATE_ACTIVE],
5093 1, TRUE, points, 3);
5094 gtk_style_draw_polygon_with_gc (window, style->fg_gc[GTK_STATE_NORMAL],
5095 line_width, FALSE, points, 3);
5099 gtk_style_draw_polygon_with_gc (window, style->base_gc[GTK_STATE_NORMAL],
5100 1, TRUE, points, 3);
5101 gtk_style_draw_polygon_with_gc (window, style->fg_gc[GTK_STATE_NORMAL],
5102 line_width, FALSE, points, 3);
5106 gdk_gc_set_clip_rectangle (style->fg_gc[GTK_STATE_NORMAL], NULL);
5107 gdk_gc_set_clip_rectangle (style->base_gc[GTK_STATE_NORMAL], NULL);
5111 typedef struct _ByteRange ByteRange;
5120 range_new (guint start,
5123 ByteRange *br = g_new (ByteRange, 1);
5132 get_insensitive_layout (GdkDrawable *drawable,
5133 PangoLayout *layout)
5135 GSList *embossed_ranges = NULL;
5136 GSList *stippled_ranges = NULL;
5137 PangoLayoutIter *iter;
5138 GSList *tmp_list = NULL;
5139 PangoLayout *new_layout;
5140 PangoAttrList *attrs;
5141 GdkBitmap *stipple = NULL;
5143 iter = pango_layout_get_iter (layout);
5147 PangoLayoutRun *run;
5148 PangoAttribute *attr;
5149 gboolean need_stipple = FALSE;
5152 run = pango_layout_iter_get_run (iter);
5156 tmp_list = run->item->analysis.extra_attrs;
5158 while (tmp_list != NULL)
5160 attr = tmp_list->data;
5161 switch (attr->klass->type)
5163 case PANGO_ATTR_FOREGROUND:
5164 case PANGO_ATTR_BACKGROUND:
5165 need_stipple = TRUE;
5175 tmp_list = g_slist_next (tmp_list);
5178 br = range_new (run->item->offset, run->item->offset + run->item->length);
5181 stippled_ranges = g_slist_prepend (stippled_ranges, br);
5183 embossed_ranges = g_slist_prepend (embossed_ranges, br);
5186 while (pango_layout_iter_next_run (iter));
5188 pango_layout_iter_free (iter);
5190 new_layout = pango_layout_copy (layout);
5192 attrs = pango_layout_get_attributes (new_layout);
5196 /* Create attr list if there wasn't one */
5197 attrs = pango_attr_list_new ();
5198 pango_layout_set_attributes (new_layout, attrs);
5199 pango_attr_list_unref (attrs);
5202 tmp_list = embossed_ranges;
5203 while (tmp_list != NULL)
5205 PangoAttribute *attr;
5206 ByteRange *br = tmp_list->data;
5208 attr = gdk_pango_attr_embossed_new (TRUE);
5210 attr->start_index = br->start;
5211 attr->end_index = br->end;
5213 pango_attr_list_change (attrs, attr);
5217 tmp_list = g_slist_next (tmp_list);
5220 g_slist_free (embossed_ranges);
5222 tmp_list = stippled_ranges;
5223 while (tmp_list != NULL)
5225 PangoAttribute *attr;
5226 ByteRange *br = tmp_list->data;
5228 if (stipple == NULL)
5230 #define gray50_width 2
5231 #define gray50_height 2
5232 static const char gray50_bits[] = {
5236 stipple = gdk_bitmap_create_from_data (drawable,
5237 gray50_bits, gray50_width,
5241 attr = gdk_pango_attr_stipple_new (stipple);
5243 attr->start_index = br->start;
5244 attr->end_index = br->end;
5246 pango_attr_list_change (attrs, attr);
5250 tmp_list = g_slist_next (tmp_list);
5253 g_slist_free (stippled_ranges);
5256 g_object_unref (stipple);
5262 gtk_default_draw_layout (GtkStyle *style,
5264 GtkStateType state_type,
5268 const gchar *detail,
5271 PangoLayout *layout)
5275 g_return_if_fail (GTK_IS_STYLE (style));
5276 g_return_if_fail (window != NULL);
5278 gc = use_text ? style->text_gc[state_type] : style->fg_gc[state_type];
5281 gdk_gc_set_clip_rectangle (gc, area);
5283 if (state_type == GTK_STATE_INSENSITIVE)
5287 ins = get_insensitive_layout (window, layout);
5289 gdk_draw_layout (window, gc, x, y, ins);
5291 g_object_unref (ins);
5295 gdk_draw_layout (window, gc, x, y, layout);
5299 gdk_gc_set_clip_rectangle (gc, NULL);
5303 gtk_default_draw_resize_grip (GtkStyle *style,
5305 GtkStateType state_type,
5308 const gchar *detail,
5318 g_return_if_fail (GTK_IS_STYLE (style));
5319 g_return_if_fail (window != NULL);
5323 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
5324 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
5325 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
5331 case GDK_WINDOW_EDGE_NORTH_WEST:
5332 /* make it square */
5335 else if (height < width)
5339 case GDK_WINDOW_EDGE_NORTH:
5343 case GDK_WINDOW_EDGE_NORTH_EAST:
5344 /* make it square, aligning to top right */
5347 else if (height < width)
5349 x += (width - height);
5354 case GDK_WINDOW_EDGE_WEST:
5358 case GDK_WINDOW_EDGE_EAST:
5359 /* aligning to right */
5362 x += (width - height);
5366 case GDK_WINDOW_EDGE_SOUTH_WEST:
5367 /* make it square, aligning to bottom left */
5370 y += (height - width);
5373 else if (height < width)
5377 case GDK_WINDOW_EDGE_SOUTH:
5378 /* align to bottom */
5381 y += (height - width);
5385 case GDK_WINDOW_EDGE_SOUTH_EAST:
5386 /* make it square, aligning to bottom right */
5389 y += (height - width);
5392 else if (height < width)
5394 x += (width - height);
5400 g_assert_not_reached ();
5402 /* Clear background */
5404 for (i = 0; i < 4; i++)
5408 points[j].x = (i == 0 || i == 3) ? x : x + width;
5409 points[j].y = (i < 2) ? y : y + height;
5414 gdk_draw_polygon (window, style->bg_gc[state_type], TRUE,
5415 points, skip < 0 ? 4 : 3);
5419 case GDK_WINDOW_EDGE_WEST:
5420 case GDK_WINDOW_EDGE_EAST:
5426 while (xi < x + width)
5428 gdk_draw_line (window,
5429 style->light_gc[state_type],
5434 gdk_draw_line (window,
5435 style->dark_gc[state_type],
5443 case GDK_WINDOW_EDGE_NORTH:
5444 case GDK_WINDOW_EDGE_SOUTH:
5450 while (yi < y + height)
5452 gdk_draw_line (window,
5453 style->light_gc[state_type],
5458 gdk_draw_line (window,
5459 style->dark_gc[state_type],
5467 case GDK_WINDOW_EDGE_NORTH_WEST:
5476 gdk_draw_line (window,
5477 style->dark_gc[state_type],
5484 gdk_draw_line (window,
5485 style->dark_gc[state_type],
5492 gdk_draw_line (window,
5493 style->light_gc[state_type],
5503 case GDK_WINDOW_EDGE_NORTH_EAST:
5510 while (xi < (x + width - 3))
5512 gdk_draw_line (window,
5513 style->light_gc[state_type],
5520 gdk_draw_line (window,
5521 style->dark_gc[state_type],
5528 gdk_draw_line (window,
5529 style->dark_gc[state_type],
5538 case GDK_WINDOW_EDGE_SOUTH_WEST:
5547 gdk_draw_line (window,
5548 style->dark_gc[state_type],
5555 gdk_draw_line (window,
5556 style->dark_gc[state_type],
5563 gdk_draw_line (window,
5564 style->light_gc[state_type],
5574 case GDK_WINDOW_EDGE_SOUTH_EAST:
5581 while (xi < (x + width - 3))
5583 gdk_draw_line (window,
5584 style->light_gc[state_type],
5591 gdk_draw_line (window,
5592 style->dark_gc[state_type],
5599 gdk_draw_line (window,
5600 style->dark_gc[state_type],
5610 g_assert_not_reached ();
5616 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
5617 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
5618 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
5623 gtk_style_shade (GdkColor *a,
5631 red = (gdouble) a->red / 65535.0;
5632 green = (gdouble) a->green / 65535.0;
5633 blue = (gdouble) a->blue / 65535.0;
5635 rgb_to_hls (&red, &green, &blue);
5640 else if (green < 0.0)
5646 else if (blue < 0.0)
5649 hls_to_rgb (&red, &green, &blue);
5651 b->red = red * 65535.0;
5652 b->green = green * 65535.0;
5653 b->blue = blue * 65535.0;
5657 rgb_to_hls (gdouble *r,
5698 l = (max + min) / 2;
5705 s = (max - min) / (max + min);
5707 s = (max - min) / (2 - max - min);
5711 h = (green - blue) / delta;
5712 else if (green == max)
5713 h = 2 + (blue - red) / delta;
5714 else if (blue == max)
5715 h = 4 + (red - green) / delta;
5728 hls_to_rgb (gdouble *h,
5741 if (lightness <= 0.5)
5742 m2 = lightness * (1 + saturation);
5744 m2 = lightness + saturation - lightness * saturation;
5745 m1 = 2 * lightness - m2;
5747 if (saturation == 0)
5762 r = m1 + (m2 - m1) * hue / 60;
5766 r = m1 + (m2 - m1) * (240 - hue) / 60;
5777 g = m1 + (m2 - m1) * hue / 60;
5781 g = m1 + (m2 - m1) * (240 - hue) / 60;
5792 b = m1 + (m2 - m1) * hue / 60;
5796 b = m1 + (m2 - m1) * (240 - hue) / 60;
5809 * @style: a #GtkStyle
5810 * @window: a #GdkWindow
5811 * @state_type: a state
5812 * @area: rectangle to which the output is clipped
5813 * @widget: the widget
5814 * @detail: a style detail
5815 * @x1: the starting x coordinate
5816 * @x2: the ending x coordinate
5817 * @y: the y coordinate
5819 * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @window
5820 * using the given style and state.
5823 gtk_paint_hline (GtkStyle *style,
5825 GtkStateType state_type,
5828 const gchar *detail,
5833 g_return_if_fail (GTK_IS_STYLE (style));
5834 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
5836 GTK_STYLE_GET_CLASS (style)->draw_hline (style, window, state_type, area, widget, detail, x1, x2, y);
5841 * @style: a #GtkStyle
5842 * @window: a #GdkWindow
5843 * @state_type: a state
5844 * @area: rectangle to which the output is clipped
5845 * @widget: the widget
5846 * @detail: a style detail
5847 * @y1_: the starting y coordinate
5848 * @y2_: the ending y coordinate
5849 * @x: the x coordinate
5851 * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @window
5852 * using the given style and state.
5855 gtk_paint_vline (GtkStyle *style,
5857 GtkStateType state_type,
5860 const gchar *detail,
5865 g_return_if_fail (GTK_IS_STYLE (style));
5866 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
5868 GTK_STYLE_GET_CLASS (style)->draw_vline (style, window, state_type, area, widget, detail, y1_, y2_, x);
5873 * @style: a #GtkStyle
5874 * @window: a #GdkWindow
5875 * @state_type: a state
5876 * @shadow_type: type of shadow to draw
5877 * @area: clip rectangle
5878 * @widget: the widget
5879 * @detail: a style detail
5880 * @x: x origin of the rectangle
5881 * @y: y origin of the rectangle
5882 * @width: width of the rectangle
5883 * @height: width of the rectangle
5885 * Draws a shadow around the given rectangle in @window
5886 * using the given style and state and shadow type.
5889 gtk_paint_shadow (GtkStyle *style,
5891 GtkStateType state_type,
5892 GtkShadowType shadow_type,
5895 const gchar *detail,
5901 g_return_if_fail (GTK_IS_STYLE (style));
5902 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
5904 GTK_STYLE_GET_CLASS (style)->draw_shadow (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
5908 * gtk_paint_polygon:
5909 * @style: a #GtkStyle
5910 * @window: a #GdkWindow
5911 * @state_type: a state
5912 * @shadow_type: type of shadow to draw
5913 * @area: clip rectangle
5914 * @widget: the widget
5915 * @detail: a style detail
5916 * @points: an array of #GdkPoint<!-- -->s
5917 * @npoints: length of @points
5918 * @fill: %TRUE if the polygon should be filled
5920 * Draws a polygon on @window with the given parameters.
5923 gtk_paint_polygon (GtkStyle *style,
5925 GtkStateType state_type,
5926 GtkShadowType shadow_type,
5929 const gchar *detail,
5934 g_return_if_fail (GTK_IS_STYLE (style));
5935 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_polygon != NULL);
5937 GTK_STYLE_GET_CLASS (style)->draw_polygon (style, window, state_type, shadow_type, area, widget, detail, points, npoints, fill);
5942 * @style: a #GtkStyle
5943 * @window: a #GdkWindow
5944 * @state_type: a state
5945 * @shadow_type: the type of shadow to draw
5946 * @area: clip rectangle
5947 * @widget: the widget
5948 * @detail: a style detail
5949 * @arrow_type: the type of arrow to draw
5950 * @fill: %TRUE if the arrow tip should be filled
5951 * @x: x origin of the rectangle to draw the arrow in
5952 * @y: y origin of the rectangle to draw the arrow in
5953 * @width: width of the rectangle to draw the arrow in
5954 * @height: height of the rectangle to draw the arrow in
5956 * Draws an arrow in the given rectangle on @window using the given
5957 * parameters. @arrow_type determines the direction of the arrow.
5960 gtk_paint_arrow (GtkStyle *style,
5962 GtkStateType state_type,
5963 GtkShadowType shadow_type,
5966 const gchar *detail,
5967 GtkArrowType arrow_type,
5974 g_return_if_fail (GTK_IS_STYLE (style));
5975 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
5977 GTK_STYLE_GET_CLASS (style)->draw_arrow (style, window, state_type, shadow_type, area, widget, detail, arrow_type, fill, x, y, width, height);
5981 * gtk_paint_diamond:
5982 * @style: a #GtkStyle
5983 * @window: a #GdkWindow
5984 * @state_type: a state
5985 * @shadow_type: the type of shadow to draw
5986 * @area: clip rectangle
5987 * @widget: the widget
5988 * @detail: a style detail
5989 * @x: x origin of the rectangle to draw the diamond in
5990 * @y: y origin of the rectangle to draw the diamond in
5991 * @width: width of the rectangle to draw the diamond in
5992 * @height: height of the rectangle to draw the diamond in
5994 * Draws a diamond in the given rectangle on @window using the given
5998 gtk_paint_diamond (GtkStyle *style,
6000 GtkStateType state_type,
6001 GtkShadowType shadow_type,
6004 const gchar *detail,
6010 g_return_if_fail (GTK_IS_STYLE (style));
6011 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
6013 GTK_STYLE_GET_CLASS (style)->draw_diamond (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
6018 * @style: a #GtkStyle
6019 * @window: a #GdkWindow
6020 * @state_type: a state
6021 * @area: clip rectangle
6022 * @widget: the widget
6023 * @detail: a style detail
6026 * @string: the string to draw
6028 * Draws a text string on @window with the given parameters.
6030 * Deprecated: Use gtk_paint_layout() instead.
6033 gtk_paint_string (GtkStyle *style,
6035 GtkStateType state_type,
6038 const gchar *detail,
6041 const gchar *string)
6043 g_return_if_fail (GTK_IS_STYLE (style));
6044 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_string != NULL);
6046 GTK_STYLE_GET_CLASS (style)->draw_string (style, window, state_type, area, widget, detail, x, y, string);
6051 * @style: a #GtkStyle
6052 * @window: a #GdkWindow
6053 * @state_type: a state
6054 * @shadow_type: the type of shadow to draw
6055 * @area: clip rectangle
6056 * @widget: the widget
6057 * @detail: a style detail
6058 * @x: x origin of the box
6059 * @y: y origin of the box
6060 * @width: the width of the box
6061 * @height: the height of the box
6063 * Draws a box on @window with the given parameters.
6066 gtk_paint_box (GtkStyle *style,
6068 GtkStateType state_type,
6069 GtkShadowType shadow_type,
6072 const gchar *detail,
6078 g_return_if_fail (GTK_IS_STYLE (style));
6079 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
6081 GTK_STYLE_GET_CLASS (style)->draw_box (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
6085 * gtk_paint_flat_box:
6086 * @style: a #GtkStyle
6087 * @window: a #GdkWindow
6088 * @state_type: a state
6089 * @shadow_type: the type of shadow to draw
6090 * @area: clip rectangle
6091 * @widget: the widget
6092 * @detail: a style detail
6093 * @x: x origin of the box
6094 * @y: y origin of the box
6095 * @width: the width of the box
6096 * @height: the height of the box
6098 * Draws a flat box on @window with the given parameters.
6101 gtk_paint_flat_box (GtkStyle *style,
6103 GtkStateType state_type,
6104 GtkShadowType shadow_type,
6107 const gchar *detail,
6113 g_return_if_fail (GTK_IS_STYLE (style));
6114 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
6116 GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
6121 * @style: a #GtkStyle
6122 * @window: a #GdkWindow
6123 * @state_type: a state
6124 * @shadow_type: the type of shadow to draw
6125 * @area: clip rectangle
6126 * @widget: the widget
6127 * @detail: a style detail
6128 * @x: x origin of the rectangle to draw the check in
6129 * @y: y origin of the rectangle to draw the check in
6130 * @width: the width of the rectangle to draw the check in
6131 * @height: the height of the rectangle to draw the check in
6133 * Draws a check button indicator in the given rectangle on @window with
6134 * the given parameters.
6137 gtk_paint_check (GtkStyle *style,
6139 GtkStateType state_type,
6140 GtkShadowType shadow_type,
6143 const gchar *detail,
6149 g_return_if_fail (GTK_IS_STYLE (style));
6150 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
6152 GTK_STYLE_GET_CLASS (style)->draw_check (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
6157 * @style: a #GtkStyle
6158 * @window: a #GdkWindow
6159 * @state_type: a state
6160 * @shadow_type: the type of shadow to draw
6161 * @area: clip rectangle
6162 * @widget: the widget
6163 * @detail: a style detail
6164 * @x: x origin of the rectangle to draw the option in
6165 * @y: y origin of the rectangle to draw the option in
6166 * @width: the width of the rectangle to draw the option in
6167 * @height: the height of the rectangle to draw the option in
6169 * Draws a radio button indicator in the given rectangle on @window with
6170 * the given parameters.
6173 gtk_paint_option (GtkStyle *style,
6175 GtkStateType state_type,
6176 GtkShadowType shadow_type,
6179 const gchar *detail,
6185 g_return_if_fail (GTK_IS_STYLE (style));
6186 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
6188 GTK_STYLE_GET_CLASS (style)->draw_option (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
6193 * @style: a #GtkStyle
6194 * @window: a #GdkWindow
6195 * @state_type: a state
6196 * @shadow_type: the type of shadow to draw
6197 * @area: clip rectangle
6198 * @widget: the widget
6199 * @detail: a style detail
6200 * @x: x origin of the rectangle to draw the tab in
6201 * @y: y origin of the rectangle to draw the tab in
6202 * @width: the width of the rectangle to draw the tab in
6203 * @height: the height of the rectangle to draw the tab in
6205 * Draws an option menu tab (i.e. the up and down pointing arrows)
6206 * in the given rectangle on @window using the given parameters.
6209 gtk_paint_tab (GtkStyle *style,
6211 GtkStateType state_type,
6212 GtkShadowType shadow_type,
6215 const gchar *detail,
6221 g_return_if_fail (GTK_IS_STYLE (style));
6222 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
6224 GTK_STYLE_GET_CLASS (style)->draw_tab (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
6228 * gtk_paint_shadow_gap:
6229 * @style: a #GtkStyle
6230 * @window: a #GdkWindow
6231 * @state_type: a state
6232 * @shadow_type: type of shadow to draw
6233 * @area: clip rectangle
6234 * @widget: the widget
6235 * @detail: a style detail
6236 * @x: x origin of the rectangle
6237 * @y: y origin of the rectangle
6238 * @width: width of the rectangle
6239 * @height: width of the rectangle
6240 * @gap_side: side in which to leave the gap
6241 * @gap_x: starting position of the gap
6242 * @gap_width: width of the gap
6244 * Draws a shadow around the given rectangle in @window
6245 * using the given style and state and shadow type, leaving a
6249 gtk_paint_shadow_gap (GtkStyle *style,
6251 GtkStateType state_type,
6252 GtkShadowType shadow_type,
6260 GtkPositionType gap_side,
6264 g_return_if_fail (GTK_IS_STYLE (style));
6265 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
6267 GTK_STYLE_GET_CLASS (style)->draw_shadow_gap (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, gap_side, gap_x, gap_width);
6272 * gtk_paint_box_gap:
6273 * @style: a #GtkStyle
6274 * @window: a #GdkWindow
6275 * @state_type: a state
6276 * @shadow_type: type of shadow to draw
6277 * @area: clip rectangle
6278 * @widget: the widget
6279 * @detail: a style detail
6280 * @x: x origin of the rectangle
6281 * @y: y origin of the rectangle
6282 * @width: width of the rectangle
6283 * @height: width of the rectangle
6284 * @gap_side: side in which to leave the gap
6285 * @gap_x: starting position of the gap
6286 * @gap_width: width of the gap
6288 * Draws a box in @window using the given style and state and shadow type,
6289 * leaving a gap in one side.
6292 gtk_paint_box_gap (GtkStyle *style,
6294 GtkStateType state_type,
6295 GtkShadowType shadow_type,
6303 GtkPositionType gap_side,
6307 g_return_if_fail (GTK_IS_STYLE (style));
6308 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
6310 GTK_STYLE_GET_CLASS (style)->draw_box_gap (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, gap_side, gap_x, gap_width);
6314 * gtk_paint_extension:
6315 * @style: a #GtkStyle
6316 * @window: a #GdkWindow
6317 * @state_type: a state
6318 * @shadow_type: type of shadow to draw
6319 * @area: clip rectangle
6320 * @widget: the widget
6321 * @detail: a style detail
6322 * @x: x origin of the extension
6323 * @y: y origin of the extension
6324 * @width: width of the extension
6325 * @height: width of the extension
6326 * @gap_side: the side on to which the extension is attached
6328 * Draws an extension, i.e. a notebook tab.
6331 gtk_paint_extension (GtkStyle *style,
6333 GtkStateType state_type,
6334 GtkShadowType shadow_type,
6342 GtkPositionType gap_side)
6344 g_return_if_fail (GTK_IS_STYLE (style));
6345 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
6347 GTK_STYLE_GET_CLASS (style)->draw_extension (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, gap_side);
6352 * @style: a #GtkStyle
6353 * @window: a #GdkWindow
6354 * @state_type: a state
6355 * @area: clip rectangle
6356 * @widget: the widget
6357 * @detail: a style detail
6358 * @x: the x origin of the rectangle around which to draw a focus indicator
6359 * @y: the y origin of the rectangle around which to draw a focus indicator
6360 * @width: the width of the rectangle around which to draw a focus indicator
6361 * @height: the height of the rectangle around which to draw a focus indicator
6363 * Draws a focus indicator around the given rectangle on @window using the
6367 gtk_paint_focus (GtkStyle *style,
6369 GtkStateType state_type,
6372 const gchar *detail,
6378 g_return_if_fail (GTK_IS_STYLE (style));
6379 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
6381 GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, state_type, area, widget, detail, x, y, width, height);
6385 gtk_paint_slider (GtkStyle *style,
6387 GtkStateType state_type,
6388 GtkShadowType shadow_type,
6391 const gchar *detail,
6396 GtkOrientation orientation)
6398 g_return_if_fail (GTK_IS_STYLE (style));
6399 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
6401 GTK_STYLE_GET_CLASS (style)->draw_slider (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, orientation);
6406 * @style: a #GtkStyle
6407 * @window: a #GdkWindow
6408 * @state_type: a state
6409 * @shadow_type: type of shadow to draw
6410 * @area: clip rectangle
6411 * @widget: the widget
6412 * @detail: a style detail
6413 * @x: x origin of the handle
6414 * @y: y origin of the handle
6415 * @width: with of the handle
6416 * @height: height of the handle
6417 * @orientation: the orientation of the handle
6419 * Draws a handle as used in #GtkHandleBox and #GtkPaned.
6422 gtk_paint_handle (GtkStyle *style,
6424 GtkStateType state_type,
6425 GtkShadowType shadow_type,
6428 const gchar *detail,
6433 GtkOrientation orientation)
6435 g_return_if_fail (GTK_IS_STYLE (style));
6436 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
6438 GTK_STYLE_GET_CLASS (style)->draw_handle (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, orientation);
6442 * gtk_paint_expander:
6443 * @style: a #GtkStyle
6444 * @window: a #GdkWindow
6445 * @state_type: a state
6446 * @area: clip rectangle
6447 * @widget: the widget
6448 * @detail: a style detail
6449 * @x: the x position to draw the expander at
6450 * @y: the y position to draw the expander at
6451 * @expander_style: the style to draw the expander in
6453 * Draws an expander as used in #GtkTreeView.
6456 gtk_paint_expander (GtkStyle *style,
6458 GtkStateType state_type,
6461 const gchar *detail,
6464 GtkExpanderStyle expander_style)
6466 g_return_if_fail (GTK_IS_STYLE (style));
6467 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
6469 GTK_STYLE_GET_CLASS (style)->draw_expander (style, window, state_type, area,
6470 widget, detail, x, y, expander_style);
6474 gtk_paint_layout (GtkStyle *style,
6476 GtkStateType state_type,
6480 const gchar *detail,
6483 PangoLayout *layout)
6485 g_return_if_fail (GTK_IS_STYLE (style));
6486 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
6488 GTK_STYLE_GET_CLASS (style)->draw_layout (style, window, state_type, use_text, area,
6489 widget, detail, x, y, layout);
6493 * gtk_paint_resize_grip:
6494 * @style: a #GtkStyle
6495 * @window: a #GdkWindow
6496 * @state_type: a state
6497 * @area: clip rectangle
6498 * @widget: the widget
6499 * @detail: a style detail
6500 * @edge: the edge in which to draw the resize grip
6501 * @x: the x origin of the rectangle in which to draw the resize grip
6502 * @y: the y origin of the rectangle in which to draw the resize grip
6503 * @width: the width of the rectangle in which to draw the resize grip
6504 * @height: the height of the rectangle in which to draw the resize grip
6506 * Draws a resize grip in the given rectangle on @window using the given
6510 gtk_paint_resize_grip (GtkStyle *style,
6512 GtkStateType state_type,
6515 const gchar *detail,
6523 g_return_if_fail (GTK_IS_STYLE (style));
6524 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
6526 GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, window, state_type,
6527 area, widget, detail,
6528 edge, x, y, width, height);
6533 * @border_: a #GtkBorder.
6534 * @returns: a copy of @border_.
6536 * Copies a #GtkBorder structure.
6539 gtk_border_copy (const GtkBorder *border)
6541 return (GtkBorder *)g_memdup (border, sizeof (GtkBorder));
6546 * @border_: a #GtkBorder.
6548 * Frees a #GtkBorder structure.
6551 gtk_border_free (GtkBorder *border)
6557 gtk_border_get_type (void)
6559 static GType our_type = 0;
6562 our_type = g_boxed_type_register_static ("GtkBorder",
6563 (GBoxedCopyFunc) gtk_border_copy,
6564 (GBoxedFreeFunc) gtk_border_free);
6570 gtk_style_get_font_internal (GtkStyle *style)
6572 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
6574 if (style->private_font && style->private_font_desc)
6576 if (!style->font_desc ||
6577 !pango_font_description_equal (style->private_font_desc, style->font_desc))
6579 gdk_font_unref (style->private_font);
6580 style->private_font = NULL;
6582 if (style->private_font_desc)
6584 pango_font_description_free (style->private_font_desc);
6585 style->private_font_desc = NULL;
6590 if (!style->private_font)
6592 GdkDisplay *display;
6594 if (style->colormap)
6596 display = gdk_screen_get_display (gdk_colormap_get_screen (style->colormap));
6600 display = gdk_display_get_default ();
6601 GTK_NOTE (MULTIHEAD,
6602 g_warning ("gtk_style_get_font() should not be called on an unattached style"));
6605 if (style->font_desc)
6607 style->private_font = gdk_font_from_description_for_display (display, style->font_desc);
6608 style->private_font_desc = pango_font_description_copy (style->font_desc);
6611 if (!style->private_font)
6612 style->private_font = gdk_font_load_for_display (display, "fixed");
6614 if (!style->private_font)
6615 g_error ("Unable to load \"fixed\" font");
6618 return style->private_font;
6622 * gtk_style_get_font:
6623 * @style: a #GtkStyle
6625 * Gets the #GdkFont to use for the given style. This is
6626 * meant only as a replacement for direct access to @style->font
6627 * and should not be used in new code. New code should
6628 * use @style->font_desc instead.
6630 * Return value: the #GdkFont for the style. This font is owned
6631 * by the style; if you want to keep around a copy, you must
6632 * call gdk_font_ref().
6635 gtk_style_get_font (GtkStyle *style)
6637 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
6639 return gtk_style_get_font_internal (style);
6643 * gtk_style_set_font:
6644 * @style: a #GtkStyle.
6645 * @font: a #GdkFont, or %NULL to use the #GdkFont corresponding
6646 * to style->font_desc.
6648 * Sets the #GdkFont to use for a given style. This is
6649 * meant only as a replacement for direct access to style->font
6650 * and should not be used in new code. New code should
6651 * use style->font_desc instead.
6654 gtk_style_set_font (GtkStyle *style,
6659 g_return_if_fail (GTK_IS_STYLE (style));
6661 old_font = style->private_font;
6663 style->private_font = font;
6665 gdk_font_ref (font);
6668 gdk_font_unref (old_font);
6670 if (style->private_font_desc)
6672 pango_font_description_free (style->private_font_desc);
6673 style->private_font_desc = NULL;
6677 typedef struct _CursorInfo CursorInfo;
6683 GdkGC *secondary_gc;
6687 style_unrealize_cursor_gcs (GtkStyle *style)
6691 cursor_info = g_object_get_data (G_OBJECT (style), "gtk-style-cursor-info");
6694 if (cursor_info->primary_gc)
6695 gtk_gc_release (cursor_info->primary_gc);
6697 if (cursor_info->secondary_gc)
6698 gtk_gc_release (cursor_info->secondary_gc);
6700 g_free (cursor_info);
6701 g_object_set_data (G_OBJECT (style), "gtk-style-cursor-info", NULL);
6706 make_cursor_gc (GtkWidget *widget,
6707 const gchar *property_name,
6708 const GdkColor *fallback)
6710 GdkGCValues gc_values;
6711 GdkGCValuesMask gc_values_mask;
6712 GdkColor *cursor_color;
6714 gtk_widget_style_get (widget, property_name, &cursor_color, NULL);
6716 gc_values_mask = GDK_GC_FOREGROUND;
6719 gc_values.foreground = *cursor_color;
6720 gdk_color_free (cursor_color);
6723 gc_values.foreground = *fallback;
6725 gdk_rgb_find_color (widget->style->colormap, &gc_values.foreground);
6726 return gtk_gc_get (widget->style->depth, widget->style->colormap, &gc_values, gc_values_mask);
6730 get_insertion_cursor_gc (GtkWidget *widget,
6731 gboolean is_primary)
6733 CursorInfo *cursor_info;
6735 cursor_info = g_object_get_data (G_OBJECT (widget->style), "gtk-style-cursor-info");
6738 cursor_info = g_new (CursorInfo, 1);
6739 g_object_set_data (G_OBJECT (widget->style), "gtk-style-cursor-info", cursor_info);
6740 cursor_info->primary_gc = NULL;
6741 cursor_info->secondary_gc = NULL;
6742 cursor_info->for_type = G_TYPE_INVALID;
6745 /* We have to keep track of the type because gtk_widget_style_get()
6746 * can return different results when called on the same property and
6747 * same style but for different widgets. :-(. That is,
6748 * GtkEntry::cursor-color = "red" in a style will modify the cursor
6749 * color for entries but not for text view.
6751 if (cursor_info->for_type != G_OBJECT_TYPE (widget))
6753 cursor_info->for_type = G_OBJECT_TYPE (widget);
6754 if (cursor_info->primary_gc)
6756 gtk_gc_release (cursor_info->primary_gc);
6757 cursor_info->primary_gc = NULL;
6759 if (cursor_info->secondary_gc)
6761 gtk_gc_release (cursor_info->secondary_gc);
6762 cursor_info->secondary_gc = NULL;
6768 if (!cursor_info->primary_gc)
6769 cursor_info->primary_gc = make_cursor_gc (widget,
6771 &widget->style->black);
6773 return cursor_info->primary_gc;
6777 static const GdkColor gray = { 0, 0x8888, 0x8888, 0x8888 };
6779 if (!cursor_info->secondary_gc)
6780 cursor_info->secondary_gc = make_cursor_gc (widget,
6781 "secondary-cursor-color",
6784 return cursor_info->secondary_gc;
6789 draw_insertion_cursor (GtkWidget *widget,
6790 GdkDrawable *drawable,
6792 GdkRectangle *location,
6793 GtkTextDirection direction,
6794 gboolean draw_arrow)
6800 gfloat cursor_aspect_ratio;
6803 g_return_if_fail (direction != GTK_TEXT_DIR_NONE);
6805 gtk_widget_style_get (widget, "cursor-aspect-ratio", &cursor_aspect_ratio, NULL);
6807 stem_width = location->height * cursor_aspect_ratio + 1;
6808 arrow_width = stem_width + 1;
6810 /* put (stem_width % 2) on the proper side of the cursor */
6811 if (direction == GTK_TEXT_DIR_LTR)
6812 offset = stem_width / 2;
6814 offset = stem_width - stem_width / 2;
6816 for (i = 0; i < stem_width; i++)
6817 gdk_draw_line (drawable, gc,
6818 location->x + i - offset, location->y,
6819 location->x + i - offset, location->y + location->height - 1);
6823 if (direction == GTK_TEXT_DIR_RTL)
6825 x = location->x - offset - 1;
6826 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
6828 for (i = 0; i < arrow_width; i++)
6830 gdk_draw_line (drawable, gc,
6832 x, y + 2 * arrow_width - i - 1);
6836 else if (direction == GTK_TEXT_DIR_LTR)
6838 x = location->x + stem_width - offset;
6839 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
6841 for (i = 0; i < arrow_width; i++)
6843 gdk_draw_line (drawable, gc,
6845 x, y + 2 * arrow_width - i - 1);
6853 * gtk_draw_insertion_cursor:
6854 * @widget: a #GtkWidget
6855 * @drawable: a #GdkDrawable
6856 * @area: rectangle to which the output is clipped, or %NULL if the
6857 * output should not be clipped
6858 * @location: location where to draw the cursor (@location->width is ignored)
6859 * @is_primary: if the cursor should be the primary cursor color.
6860 * @direction: whether the cursor is left-to-right or
6861 * right-to-left. Should never be #GTK_TEXT_DIR_NONE
6862 * @draw_arrow: %TRUE to draw a directional arrow on the
6863 * cursor. Should be %FALSE unless the cursor is split.
6865 * Draws a text caret on @drawable at @location. This is not a style function
6866 * but merely a convenience function for drawing the standard cursor shape.
6871 gtk_draw_insertion_cursor (GtkWidget *widget,
6872 GdkDrawable *drawable,
6874 GdkRectangle *location,
6875 gboolean is_primary,
6876 GtkTextDirection direction,
6877 gboolean draw_arrow)
6881 g_return_if_fail (GTK_IS_WIDGET (widget));
6882 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
6883 g_return_if_fail (location != NULL);
6884 g_return_if_fail (direction != GTK_TEXT_DIR_NONE);
6886 gc = get_insertion_cursor_gc (widget, is_primary);
6888 gdk_gc_set_clip_rectangle (gc, area);
6890 draw_insertion_cursor (widget, drawable, gc,
6891 location, direction, draw_arrow);
6894 gdk_gc_set_clip_rectangle (gc, NULL);