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/.
31 #include <gobject/gvaluecollector.h>
33 #include "gtkmarshalers.h"
34 #undef GTK_DISABLE_DEPRECATED
36 #include "gtkspinbutton.h"
38 #include "gtkwidget.h"
39 #include "gtkthemes.h"
40 #include "gtkiconfactory.h"
41 #include "gtksettings.h" /* _gtk_settings_parse_convert() */
44 #include "gtkspinner.h"
49 * @Short_description: An object that hold style information for widgets
52 * A #GtkStyle object encapsulates the information that provides the look and
53 * feel for a widget. Each #GtkWidget has an associated #GTkStyle object that
54 * is used when rendering that widget. Also, a #GtkStyle holds information for
55 * the five possible widget states though not every widget supports all five
56 * states; see #GtkStateType.
58 * Usually the #GtkStyle for a widget is the same as the default style that is
59 * set by GTK+ and modified the theme engine.
61 * Usually applications should not need to use or modify the #GtkStyle of their
66 #define LIGHTNESS_MULT 1.3
67 #define DARKNESS_MULT 0.7
69 /* --- typedefs & structures --- */
76 #define GTK_STYLE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_STYLE, GtkStylePrivate))
78 typedef struct _GtkStylePrivate GtkStylePrivate;
80 struct _GtkStylePrivate {
84 /* --- prototypes --- */
85 static void gtk_style_finalize (GObject *object);
86 static void gtk_style_realize (GtkStyle *style,
87 GdkColormap *colormap);
88 static void gtk_style_real_realize (GtkStyle *style);
89 static void gtk_style_real_unrealize (GtkStyle *style);
90 static void gtk_style_real_copy (GtkStyle *style,
92 static void gtk_style_real_set_background (GtkStyle *style,
94 GtkStateType state_type);
95 static GtkStyle *gtk_style_real_clone (GtkStyle *style);
96 static void gtk_style_real_init_from_rc (GtkStyle *style,
97 GtkRcStyle *rc_style);
98 static GdkPixbuf *gtk_default_render_icon (GtkStyle *style,
99 const GtkIconSource *source,
100 GtkTextDirection direction,
104 const gchar *detail);
105 static void gtk_default_draw_hline (GtkStyle *style,
107 GtkStateType state_type,
114 static void gtk_default_draw_vline (GtkStyle *style,
116 GtkStateType state_type,
123 static void gtk_default_draw_shadow (GtkStyle *style,
125 GtkStateType state_type,
126 GtkShadowType shadow_type,
134 static void gtk_default_draw_polygon (GtkStyle *style,
136 GtkStateType state_type,
137 GtkShadowType shadow_type,
144 static void gtk_default_draw_arrow (GtkStyle *style,
146 GtkStateType state_type,
147 GtkShadowType shadow_type,
151 GtkArrowType arrow_type,
157 static void gtk_default_draw_diamond (GtkStyle *style,
159 GtkStateType state_type,
160 GtkShadowType shadow_type,
168 static void gtk_default_draw_string (GtkStyle *style,
170 GtkStateType state_type,
176 const gchar *string);
177 static void gtk_default_draw_box (GtkStyle *style,
179 GtkStateType state_type,
180 GtkShadowType shadow_type,
188 static void gtk_default_draw_flat_box (GtkStyle *style,
190 GtkStateType state_type,
191 GtkShadowType shadow_type,
199 static void gtk_default_draw_check (GtkStyle *style,
201 GtkStateType state_type,
202 GtkShadowType shadow_type,
210 static void gtk_default_draw_option (GtkStyle *style,
212 GtkStateType state_type,
213 GtkShadowType shadow_type,
221 static void gtk_default_draw_tab (GtkStyle *style,
223 GtkStateType state_type,
224 GtkShadowType shadow_type,
232 static void gtk_default_draw_shadow_gap (GtkStyle *style,
234 GtkStateType state_type,
235 GtkShadowType shadow_type,
243 GtkPositionType gap_side,
246 static void gtk_default_draw_box_gap (GtkStyle *style,
248 GtkStateType state_type,
249 GtkShadowType shadow_type,
257 GtkPositionType gap_side,
260 static void gtk_default_draw_extension (GtkStyle *style,
262 GtkStateType state_type,
263 GtkShadowType shadow_type,
271 GtkPositionType gap_side);
272 static void gtk_default_draw_focus (GtkStyle *style,
274 GtkStateType state_type,
282 static void gtk_default_draw_slider (GtkStyle *style,
284 GtkStateType state_type,
285 GtkShadowType shadow_type,
293 GtkOrientation orientation);
294 static void gtk_default_draw_handle (GtkStyle *style,
296 GtkStateType state_type,
297 GtkShadowType shadow_type,
305 GtkOrientation orientation);
306 static void gtk_default_draw_expander (GtkStyle *style,
308 GtkStateType state_type,
314 GtkExpanderStyle expander_style);
315 static void gtk_default_draw_layout (GtkStyle *style,
317 GtkStateType state_type,
324 PangoLayout *layout);
325 static void gtk_default_draw_resize_grip (GtkStyle *style,
327 GtkStateType state_type,
336 static void gtk_default_draw_spinner (GtkStyle *style,
338 GtkStateType state_type,
348 static void rgb_to_hls (gdouble *r,
351 static void hls_to_rgb (gdouble *h,
355 static void style_unrealize_cursor_gcs (GtkStyle *style);
357 static GdkFont *gtk_style_get_font_internal (GtkStyle *style);
360 * Data for default check and radio buttons
363 static const GtkRequisition default_option_indicator_size = { 7, 13 };
364 static const GtkBorder default_option_indicator_spacing = { 7, 5, 2, 2 };
366 #define GTK_GRAY 0xdcdc, 0xdada, 0xd5d5
367 #define GTK_DARK_GRAY 0xc4c4, 0xc2c2, 0xbdbd
368 #define GTK_LIGHT_GRAY 0xeeee, 0xebeb, 0xe7e7
369 #define GTK_WHITE 0xffff, 0xffff, 0xffff
370 #define GTK_BLUE 0x4b4b, 0x6969, 0x8383
371 #define GTK_VERY_DARK_GRAY 0x9c9c, 0x9a9a, 0x9494
372 #define GTK_BLACK 0x0000, 0x0000, 0x0000
373 #define GTK_WEAK_GRAY 0x7530, 0x7530, 0x7530
375 /* --- variables --- */
376 static const GdkColor gtk_default_normal_fg = { 0, GTK_BLACK };
377 static const GdkColor gtk_default_active_fg = { 0, GTK_BLACK };
378 static const GdkColor gtk_default_prelight_fg = { 0, GTK_BLACK };
379 static const GdkColor gtk_default_selected_fg = { 0, GTK_WHITE };
380 static const GdkColor gtk_default_insensitive_fg = { 0, GTK_WEAK_GRAY };
382 static const GdkColor gtk_default_normal_bg = { 0, GTK_GRAY };
383 static const GdkColor gtk_default_active_bg = { 0, GTK_DARK_GRAY };
384 static const GdkColor gtk_default_prelight_bg = { 0, GTK_LIGHT_GRAY };
385 static const GdkColor gtk_default_selected_bg = { 0, GTK_BLUE };
386 static const GdkColor gtk_default_insensitive_bg = { 0, GTK_GRAY };
387 static const GdkColor gtk_default_selected_base = { 0, GTK_BLUE };
388 static const GdkColor gtk_default_active_base = { 0, GTK_VERY_DARK_GRAY };
390 /* --- signals --- */
391 static guint realize_signal = 0;
392 static guint unrealize_signal = 0;
394 G_DEFINE_TYPE (GtkStyle, gtk_style, G_TYPE_OBJECT)
396 /* --- functions --- */
399 * _gtk_style_init_for_settings:
400 * @style: a #GtkStyle
401 * @settings: a #GtkSettings
403 * Initializes the font description in @style according to the default
404 * font name of @settings. This is called for gtk_style_new() with
405 * the settings for the default screen (if any); if we are creating
406 * a style for a particular screen, we then call it again in a
407 * location where we know the correct settings.
408 * The reason for this is that gtk_rc_style_create_style() doesn't
409 * take the screen for an argument.
412 _gtk_style_init_for_settings (GtkStyle *style,
413 GtkSettings *settings)
415 const gchar *font_name = _gtk_rc_context_get_default_font_name (settings);
417 if (style->font_desc)
418 pango_font_description_free (style->font_desc);
420 style->font_desc = pango_font_description_from_string (font_name);
422 if (!pango_font_description_get_family (style->font_desc))
424 g_warning ("Default font does not have a family set");
425 pango_font_description_set_family (style->font_desc, "Sans");
427 if (pango_font_description_get_size (style->font_desc) <= 0)
429 g_warning ("Default font does not have a positive size");
430 pango_font_description_set_size (style->font_desc, 10 * PANGO_SCALE);
435 gtk_style_init (GtkStyle *style)
439 GtkSettings *settings = gtk_settings_get_default ();
442 _gtk_style_init_for_settings (style, settings);
444 style->font_desc = pango_font_description_from_string ("Sans 10");
446 style->attach_count = 0;
447 style->colormap = NULL;
450 style->black.red = 0;
451 style->black.green = 0;
452 style->black.blue = 0;
454 style->white.red = 65535;
455 style->white.green = 65535;
456 style->white.blue = 65535;
458 style->black_gc = NULL;
459 style->white_gc = NULL;
461 style->fg[GTK_STATE_NORMAL] = gtk_default_normal_fg;
462 style->fg[GTK_STATE_ACTIVE] = gtk_default_active_fg;
463 style->fg[GTK_STATE_PRELIGHT] = gtk_default_prelight_fg;
464 style->fg[GTK_STATE_SELECTED] = gtk_default_selected_fg;
465 style->fg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
467 style->bg[GTK_STATE_NORMAL] = gtk_default_normal_bg;
468 style->bg[GTK_STATE_ACTIVE] = gtk_default_active_bg;
469 style->bg[GTK_STATE_PRELIGHT] = gtk_default_prelight_bg;
470 style->bg[GTK_STATE_SELECTED] = gtk_default_selected_bg;
471 style->bg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_bg;
473 for (i = 0; i < 4; i++)
475 style->text[i] = style->fg[i];
476 style->base[i] = style->white;
479 style->base[GTK_STATE_SELECTED] = gtk_default_selected_base;
480 style->text[GTK_STATE_SELECTED] = style->white;
481 style->base[GTK_STATE_ACTIVE] = gtk_default_active_base;
482 style->text[GTK_STATE_ACTIVE] = style->white;
483 style->base[GTK_STATE_INSENSITIVE] = gtk_default_prelight_bg;
484 style->text[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
486 for (i = 0; i < 5; i++)
487 style->bg_pixmap[i] = NULL;
489 style->rc_style = NULL;
491 for (i = 0; i < 5; i++)
493 style->fg_gc[i] = NULL;
494 style->bg_gc[i] = NULL;
495 style->light_gc[i] = NULL;
496 style->dark_gc[i] = NULL;
497 style->mid_gc[i] = NULL;
498 style->text_gc[i] = NULL;
499 style->base_gc[i] = NULL;
500 style->text_aa_gc[i] = NULL;
503 style->xthickness = 2;
504 style->ythickness = 2;
506 style->property_cache = NULL;
510 gtk_style_class_init (GtkStyleClass *klass)
512 GObjectClass *object_class = G_OBJECT_CLASS (klass);
514 object_class->finalize = gtk_style_finalize;
516 klass->clone = gtk_style_real_clone;
517 klass->copy = gtk_style_real_copy;
518 klass->init_from_rc = gtk_style_real_init_from_rc;
519 klass->realize = gtk_style_real_realize;
520 klass->unrealize = gtk_style_real_unrealize;
521 klass->set_background = gtk_style_real_set_background;
522 klass->render_icon = gtk_default_render_icon;
524 klass->draw_hline = gtk_default_draw_hline;
525 klass->draw_vline = gtk_default_draw_vline;
526 klass->draw_shadow = gtk_default_draw_shadow;
527 klass->draw_polygon = gtk_default_draw_polygon;
528 klass->draw_arrow = gtk_default_draw_arrow;
529 klass->draw_diamond = gtk_default_draw_diamond;
530 klass->draw_string = gtk_default_draw_string;
531 klass->draw_box = gtk_default_draw_box;
532 klass->draw_flat_box = gtk_default_draw_flat_box;
533 klass->draw_check = gtk_default_draw_check;
534 klass->draw_option = gtk_default_draw_option;
535 klass->draw_tab = gtk_default_draw_tab;
536 klass->draw_shadow_gap = gtk_default_draw_shadow_gap;
537 klass->draw_box_gap = gtk_default_draw_box_gap;
538 klass->draw_extension = gtk_default_draw_extension;
539 klass->draw_focus = gtk_default_draw_focus;
540 klass->draw_slider = gtk_default_draw_slider;
541 klass->draw_handle = gtk_default_draw_handle;
542 klass->draw_expander = gtk_default_draw_expander;
543 klass->draw_layout = gtk_default_draw_layout;
544 klass->draw_resize_grip = gtk_default_draw_resize_grip;
545 klass->draw_spinner = gtk_default_draw_spinner;
547 g_type_class_add_private (object_class, sizeof (GtkStylePrivate));
551 * @style: the object which received the signal
553 * Emitted when the style has been initialized for a particular
554 * colormap and depth. Connecting to this signal is probably seldom
555 * useful since most of the time applications and widgets only
556 * deal with styles that have been already realized.
560 realize_signal = g_signal_new (I_("realize"),
561 G_TYPE_FROM_CLASS (object_class),
563 G_STRUCT_OFFSET (GtkStyleClass, realize),
565 _gtk_marshal_VOID__VOID,
568 * GtkStyle::unrealize:
569 * @style: the object which received the signal
571 * Emitted when the aspects of the style specific to a particular colormap
572 * and depth are being cleaned up. A connection to this signal can be useful
573 * if a widget wants to cache objects like a #GdkGC as object data on #GtkStyle.
574 * This signal provides a convenient place to free such cached objects.
578 unrealize_signal = g_signal_new (I_("unrealize"),
579 G_TYPE_FROM_CLASS (object_class),
581 G_STRUCT_OFFSET (GtkStyleClass, unrealize),
583 _gtk_marshal_VOID__VOID,
588 clear_property_cache (GtkStyle *style)
590 if (style->property_cache)
594 for (i = 0; i < style->property_cache->len; i++)
596 PropertyValue *node = &g_array_index (style->property_cache, PropertyValue, i);
598 g_param_spec_unref (node->pspec);
599 g_value_unset (&node->value);
601 g_array_free (style->property_cache, TRUE);
602 style->property_cache = NULL;
607 gtk_style_finalize (GObject *object)
609 GtkStyle *style = GTK_STYLE (object);
610 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
612 g_return_if_fail (style->attach_count == 0);
614 clear_property_cache (style);
616 /* All the styles in the list have the same
617 * style->styles pointer. If we delete the
618 * *first* style from the list, we need to update
619 * the style->styles pointers from all the styles.
620 * Otherwise we simply remove the node from
625 if (style->styles->data != style)
626 style->styles = g_slist_remove (style->styles, style);
629 GSList *tmp_list = style->styles->next;
633 GTK_STYLE (tmp_list->data)->styles = style->styles->next;
634 tmp_list = tmp_list->next;
636 g_slist_free_1 (style->styles);
640 g_slist_foreach (style->icon_factories, (GFunc) g_object_unref, NULL);
641 g_slist_free (style->icon_factories);
643 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_unref, NULL);
644 g_slist_free (priv->color_hashes);
646 pango_font_description_free (style->font_desc);
648 if (style->private_font)
649 gdk_font_unref (style->private_font);
651 if (style->private_font_desc)
652 pango_font_description_free (style->private_font_desc);
655 g_object_unref (style->rc_style);
657 G_OBJECT_CLASS (gtk_style_parent_class)->finalize (object);
663 * @style: a #GtkStyle
665 * Creates a copy of the passed in #GtkStyle object.
667 * Returns: a copy of @style
670 gtk_style_copy (GtkStyle *style)
674 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
676 new_style = GTK_STYLE_GET_CLASS (style)->clone (style);
677 GTK_STYLE_GET_CLASS (style)->copy (new_style, style);
683 gtk_style_duplicate (GtkStyle *style)
687 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
689 new_style = gtk_style_copy (style);
691 /* All the styles in the list have the same
692 * style->styles pointer. When we insert a new
693 * style, we append it to the list to avoid having
694 * to update the existing ones.
696 style->styles = g_slist_append (style->styles, new_style);
697 new_style->styles = style->styles;
704 * @returns: a new #GtkStyle.
706 * Creates a new #GtkStyle.
713 style = g_object_new (GTK_TYPE_STYLE, NULL);
720 * @style: a #GtkStyle.
721 * @window: a #GdkWindow.
723 * Attaches a style to a window; this process allocates the
724 * colors and creates the GC's for the style - it specializes
725 * it to a particular visual and colormap. The process may
726 * involve the creation of a new style if the style has already
727 * been attached to a window with a different style and colormap.
729 * Since this function may return a new object, you have to use it
730 * in the following way:
731 * <literal>style = gtk_style_attach (style, window)</literal>
733 * Returns: Either @style, or a newly-created #GtkStyle.
734 * If the style is newly created, the style parameter
735 * will be unref'ed, and the new style will have
736 * a reference count belonging to the caller.
739 gtk_style_attach (GtkStyle *style,
743 GtkStyle *new_style = NULL;
744 GdkColormap *colormap;
746 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
747 g_return_val_if_fail (window != NULL, NULL);
749 colormap = gdk_drawable_get_colormap (window);
752 style->styles = g_slist_append (NULL, style);
754 styles = style->styles;
757 new_style = styles->data;
759 if (new_style->colormap == colormap)
763 styles = styles->next;
768 styles = style->styles;
772 new_style = styles->data;
774 if (new_style->attach_count == 0)
776 gtk_style_realize (new_style, colormap);
781 styles = styles->next;
787 new_style = gtk_style_duplicate (style);
788 if (gdk_colormap_get_screen (style->colormap) != gdk_colormap_get_screen (colormap) &&
789 new_style->private_font)
791 gdk_font_unref (new_style->private_font);
792 new_style->private_font = NULL;
794 gtk_style_realize (new_style, colormap);
797 /* A style gets a refcount from being attached */
798 if (new_style->attach_count == 0)
799 g_object_ref (new_style);
801 /* Another refcount belongs to the parent */
802 if (style != new_style)
804 g_object_unref (style);
805 g_object_ref (new_style);
808 new_style->attach_count++;
815 * @style: a #GtkStyle
817 * Detaches a style from a window. If the style is not attached
818 * to any windows anymore, it is unrealized. See gtk_style_attach().
822 gtk_style_detach (GtkStyle *style)
824 g_return_if_fail (GTK_IS_STYLE (style));
825 g_return_if_fail (style->attach_count > 0);
827 style->attach_count -= 1;
828 if (style->attach_count == 0)
830 g_signal_emit (style, unrealize_signal, 0);
832 g_object_unref (style->colormap);
833 style->colormap = NULL;
835 if (style->private_font_desc)
837 if (style->private_font)
839 gdk_font_unref (style->private_font);
840 style->private_font = NULL;
843 pango_font_description_free (style->private_font_desc);
844 style->private_font_desc = NULL;
847 g_object_unref (style);
852 gtk_style_realize (GtkStyle *style,
853 GdkColormap *colormap)
855 style->colormap = g_object_ref (colormap);
856 style->depth = gdk_colormap_get_visual (colormap)->depth;
858 g_signal_emit (style, realize_signal, 0);
862 * gtk_style_lookup_icon_set:
863 * @style: a #GtkStyle
864 * @stock_id: an icon name
866 * Looks up @stock_id in the icon factories associated with @style
867 * and the default icon factory, returning an icon set if found,
870 * Return value: icon set of @stock_id
873 gtk_style_lookup_icon_set (GtkStyle *style,
874 const char *stock_id)
878 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
879 g_return_val_if_fail (stock_id != NULL, NULL);
881 iter = style->icon_factories;
884 GtkIconSet *icon_set = gtk_icon_factory_lookup (GTK_ICON_FACTORY (iter->data),
889 iter = g_slist_next (iter);
892 return gtk_icon_factory_lookup_default (stock_id);
896 * gtk_style_lookup_color:
897 * @style: a #GtkStyle
898 * @color_name: the name of the logical color to look up
899 * @color: the #GdkColor to fill in
901 * Looks up @color_name in the style's logical color mappings,
902 * filling in @color and returning %TRUE if found, otherwise
903 * returning %FALSE. Do not cache the found mapping, because
904 * it depends on the #GtkStyle and might change when a theme
907 * Return value: %TRUE if the mapping was found.
912 gtk_style_lookup_color (GtkStyle *style,
913 const char *color_name,
916 GtkStylePrivate *priv;
919 g_return_val_if_fail (GTK_IS_STYLE (style), FALSE);
920 g_return_val_if_fail (color_name != NULL, FALSE);
921 g_return_val_if_fail (color != NULL, FALSE);
923 priv = GTK_STYLE_GET_PRIVATE (style);
925 for (iter = priv->color_hashes; iter != NULL; iter = iter->next)
927 GHashTable *hash = iter->data;
928 GdkColor *mapping = g_hash_table_lookup (hash, color_name);
932 color->red = mapping->red;
933 color->green = mapping->green;
934 color->blue = mapping->blue;
943 * gtk_style_set_background:
944 * @style: a #GtkStyle
945 * @window: a #GdkWindow
946 * @state_type: a state
948 * Sets the background of @window to the background color or pixmap
949 * specified by @style for the given state.
952 gtk_style_set_background (GtkStyle *style,
954 GtkStateType state_type)
956 g_return_if_fail (GTK_IS_STYLE (style));
957 g_return_if_fail (window != NULL);
959 GTK_STYLE_GET_CLASS (style)->set_background (style, window, state_type);
962 /* Default functions */
964 gtk_style_real_clone (GtkStyle *style)
966 return g_object_new (G_OBJECT_TYPE (style), NULL);
970 gtk_style_real_copy (GtkStyle *style,
973 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
974 GtkStylePrivate *src_priv = GTK_STYLE_GET_PRIVATE (src);
977 for (i = 0; i < 5; i++)
979 style->fg[i] = src->fg[i];
980 style->bg[i] = src->bg[i];
981 style->text[i] = src->text[i];
982 style->base[i] = src->base[i];
984 if (style->bg_pixmap[i])
985 g_object_unref (style->bg_pixmap[i]),
986 style->bg_pixmap[i] = src->bg_pixmap[i];
987 if (style->bg_pixmap[i])
988 g_object_ref (style->bg_pixmap[i]);
991 if (style->private_font)
992 gdk_font_unref (style->private_font);
993 style->private_font = src->private_font;
994 if (style->private_font)
995 gdk_font_ref (style->private_font);
997 if (style->font_desc)
998 pango_font_description_free (style->font_desc);
1000 style->font_desc = pango_font_description_copy (src->font_desc);
1002 style->font_desc = NULL;
1004 style->xthickness = src->xthickness;
1005 style->ythickness = src->ythickness;
1007 if (style->rc_style)
1008 g_object_unref (style->rc_style);
1009 style->rc_style = src->rc_style;
1011 g_object_ref (src->rc_style);
1013 g_slist_foreach (style->icon_factories, (GFunc) g_object_unref, NULL);
1014 g_slist_free (style->icon_factories);
1015 style->icon_factories = g_slist_copy (src->icon_factories);
1016 g_slist_foreach (style->icon_factories, (GFunc) g_object_ref, NULL);
1018 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_unref, NULL);
1019 g_slist_free (priv->color_hashes);
1020 priv->color_hashes = g_slist_copy (src_priv->color_hashes);
1021 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_ref, NULL);
1023 /* don't copy, just clear cache */
1024 clear_property_cache (style);
1028 gtk_style_real_init_from_rc (GtkStyle *style,
1029 GtkRcStyle *rc_style)
1031 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
1034 /* cache _should_ be still empty */
1035 clear_property_cache (style);
1037 if (rc_style->font_desc)
1038 pango_font_description_merge (style->font_desc, rc_style->font_desc, TRUE);
1040 for (i = 0; i < 5; i++)
1042 if (rc_style->color_flags[i] & GTK_RC_FG)
1043 style->fg[i] = rc_style->fg[i];
1044 if (rc_style->color_flags[i] & GTK_RC_BG)
1045 style->bg[i] = rc_style->bg[i];
1046 if (rc_style->color_flags[i] & GTK_RC_TEXT)
1047 style->text[i] = rc_style->text[i];
1048 if (rc_style->color_flags[i] & GTK_RC_BASE)
1049 style->base[i] = rc_style->base[i];
1052 if (rc_style->xthickness >= 0)
1053 style->xthickness = rc_style->xthickness;
1054 if (rc_style->ythickness >= 0)
1055 style->ythickness = rc_style->ythickness;
1057 style->icon_factories = g_slist_copy (rc_style->icon_factories);
1058 g_slist_foreach (style->icon_factories, (GFunc) g_object_ref, NULL);
1060 priv->color_hashes = g_slist_copy (_gtk_rc_style_get_color_hashes (rc_style));
1061 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_ref, NULL);
1065 style_property_values_cmp (gconstpointer bsearch_node1,
1066 gconstpointer bsearch_node2)
1068 const PropertyValue *val1 = bsearch_node1;
1069 const PropertyValue *val2 = bsearch_node2;
1071 if (val1->widget_type == val2->widget_type)
1072 return val1->pspec < val2->pspec ? -1 : val1->pspec == val2->pspec ? 0 : 1;
1074 return val1->widget_type < val2->widget_type ? -1 : 1;
1078 * gtk_style_get_style_property:
1079 * @style: a #GtkStyle
1080 * @widget_type: the #GType of a descendant of #GtkWidget
1081 * @property_name: the name of the style property to get
1082 * @value: a #GValue where the value of the property being
1083 * queried will be stored
1085 * Queries the value of a style property corresponding to a
1086 * widget class is in the given style.
1091 gtk_style_get_style_property (GtkStyle *style,
1093 const gchar *property_name,
1096 GtkWidgetClass *klass;
1098 GtkRcPropertyParser parser;
1099 const GValue *peek_value;
1101 klass = g_type_class_ref (widget_type);
1102 pspec = gtk_widget_class_find_style_property (klass, property_name);
1103 g_type_class_unref (klass);
1107 g_warning ("%s: widget class `%s' has no property named `%s'",
1109 g_type_name (widget_type),
1114 parser = g_param_spec_get_qdata (pspec,
1115 g_quark_from_static_string ("gtk-rc-property-parser"));
1117 peek_value = _gtk_style_peek_property_value (style, widget_type, pspec, parser);
1119 if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec))
1120 g_value_copy (peek_value, value);
1121 else if (g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
1122 g_value_transform (peek_value, value);
1124 g_warning ("can't retrieve style property `%s' of type `%s' as value of type `%s'",
1126 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1127 G_VALUE_TYPE_NAME (value));
1131 * gtk_style_get_valist:
1132 * @style: a #GtkStyle
1133 * @widget_type: the #GType of a descendant of #GtkWidget
1134 * @first_property_name: the name of the first style property to get
1135 * @var_args: a <type>va_list</type> of pairs of property names and
1136 * locations to return the property values, starting with the
1137 * location for @first_property_name.
1139 * Non-vararg variant of gtk_style_get().
1140 * Used primarily by language bindings.
1145 gtk_style_get_valist (GtkStyle *style,
1147 const gchar *first_property_name,
1150 const char *property_name;
1151 GtkWidgetClass *klass;
1153 g_return_if_fail (GTK_IS_STYLE (style));
1155 klass = g_type_class_ref (widget_type);
1157 property_name = first_property_name;
1158 while (property_name)
1161 GtkRcPropertyParser parser;
1162 const GValue *peek_value;
1165 pspec = gtk_widget_class_find_style_property (klass, property_name);
1169 g_warning ("%s: widget class `%s' has no property named `%s'",
1171 g_type_name (widget_type),
1176 parser = g_param_spec_get_qdata (pspec,
1177 g_quark_from_static_string ("gtk-rc-property-parser"));
1179 peek_value = _gtk_style_peek_property_value (style, widget_type, pspec, parser);
1180 G_VALUE_LCOPY (peek_value, var_args, 0, &error);
1183 g_warning ("%s: %s", G_STRLOC, error);
1188 property_name = va_arg (var_args, gchar*);
1191 g_type_class_unref (klass);
1196 * @style: a #GtkStyle
1197 * @widget_type: the #GType of a descendant of #GtkWidget
1198 * @first_property_name: the name of the first style property to get
1199 * @Varargs: pairs of property names and locations to
1200 * return the property values, starting with the location for
1201 * @first_property_name, terminated by %NULL.
1203 * Gets the values of a multiple style properties for @widget_type
1209 gtk_style_get (GtkStyle *style,
1211 const gchar *first_property_name,
1216 va_start (var_args, first_property_name);
1217 gtk_style_get_valist (style, widget_type, first_property_name, var_args);
1222 _gtk_style_peek_property_value (GtkStyle *style,
1225 GtkRcPropertyParser parser)
1227 PropertyValue *pcache, key = { 0, NULL, { 0, } };
1228 const GtkRcProperty *rcprop = NULL;
1231 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1232 g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL);
1233 g_return_val_if_fail (g_type_is_a (pspec->owner_type, GTK_TYPE_WIDGET), NULL);
1234 g_return_val_if_fail (g_type_is_a (widget_type, pspec->owner_type), NULL);
1236 key.widget_type = widget_type;
1239 /* need value cache array */
1240 if (!style->property_cache)
1241 style->property_cache = g_array_new (FALSE, FALSE, sizeof (PropertyValue));
1244 pcache = bsearch (&key,
1245 style->property_cache->data, style->property_cache->len,
1246 sizeof (PropertyValue), style_property_values_cmp);
1248 return &pcache->value;
1252 while (i < style->property_cache->len &&
1253 style_property_values_cmp (&key, &g_array_index (style->property_cache, PropertyValue, i)) >= 0)
1256 g_array_insert_val (style->property_cache, i, key);
1257 pcache = &g_array_index (style->property_cache, PropertyValue, i);
1259 /* cache miss, initialize value type, then set contents */
1260 g_param_spec_ref (pcache->pspec);
1261 g_value_init (&pcache->value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1263 /* value provided by rc style? */
1264 if (style->rc_style)
1266 GQuark prop_quark = g_quark_from_string (pspec->name);
1270 rcprop = _gtk_rc_style_lookup_rc_property (style->rc_style,
1271 g_type_qname (widget_type),
1275 widget_type = g_type_parent (widget_type);
1277 while (g_type_is_a (widget_type, pspec->owner_type));
1280 /* when supplied by rc style, we need to convert */
1281 if (rcprop && !_gtk_settings_parse_convert (parser, &rcprop->value,
1282 pspec, &pcache->value))
1284 gchar *contents = g_strdup_value_contents (&rcprop->value);
1286 g_message ("%s: failed to retrieve property `%s::%s' of type `%s' from rc file value \"%s\" of type `%s'",
1287 rcprop->origin ? rcprop->origin : "(for origin information, set GTK_DEBUG)",
1288 g_type_name (pspec->owner_type), pspec->name,
1289 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1291 G_VALUE_TYPE_NAME (&rcprop->value));
1293 rcprop = NULL; /* needs default */
1296 /* not supplied by rc style (or conversion failed), revert to default */
1298 g_param_value_set_default (pspec, &pcache->value);
1300 return &pcache->value;
1304 load_bg_image (GdkColormap *colormap,
1306 const gchar *filename)
1308 if (strcmp (filename, "<parent>") == 0)
1309 return (GdkPixmap*) GDK_PARENT_RELATIVE;
1312 return gdk_pixmap_colormap_create_from_xpm (NULL, colormap, NULL,
1319 gtk_style_real_realize (GtkStyle *style)
1321 GdkGCValues gc_values;
1322 GdkGCValuesMask gc_values_mask;
1326 for (i = 0; i < 5; i++)
1328 _gtk_style_shade (&style->bg[i], &style->light[i], LIGHTNESS_MULT);
1329 _gtk_style_shade (&style->bg[i], &style->dark[i], DARKNESS_MULT);
1331 style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
1332 style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
1333 style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
1335 style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
1336 style->text_aa[i].green = (style->text[i].green + style->base[i].green) / 2;
1337 style->text_aa[i].blue = (style->text[i].blue + style->base[i].blue) / 2;
1340 style->black.red = 0x0000;
1341 style->black.green = 0x0000;
1342 style->black.blue = 0x0000;
1343 gdk_colormap_alloc_color (style->colormap, &style->black, FALSE, TRUE);
1345 style->white.red = 0xffff;
1346 style->white.green = 0xffff;
1347 style->white.blue = 0xffff;
1348 gdk_colormap_alloc_color (style->colormap, &style->white, FALSE, TRUE);
1350 gc_values_mask = GDK_GC_FOREGROUND | GDK_GC_BACKGROUND;
1352 gc_values.foreground = style->black;
1353 gc_values.background = style->white;
1354 style->black_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1356 gc_values.foreground = style->white;
1357 gc_values.background = style->black;
1358 style->white_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1360 gc_values_mask = GDK_GC_FOREGROUND;
1362 for (i = 0; i < 5; i++)
1364 if (style->rc_style && style->rc_style->bg_pixmap_name[i])
1365 style->bg_pixmap[i] = load_bg_image (style->colormap,
1367 style->rc_style->bg_pixmap_name[i]);
1369 if (!gdk_colormap_alloc_color (style->colormap, &style->fg[i], FALSE, TRUE))
1370 g_warning ("unable to allocate color: ( %d %d %d )",
1371 style->fg[i].red, style->fg[i].green, style->fg[i].blue);
1372 if (!gdk_colormap_alloc_color (style->colormap, &style->bg[i], FALSE, TRUE))
1373 g_warning ("unable to allocate color: ( %d %d %d )",
1374 style->bg[i].red, style->bg[i].green, style->bg[i].blue);
1375 if (!gdk_colormap_alloc_color (style->colormap, &style->light[i], FALSE, TRUE))
1376 g_warning ("unable to allocate color: ( %d %d %d )",
1377 style->light[i].red, style->light[i].green, style->light[i].blue);
1378 if (!gdk_colormap_alloc_color (style->colormap, &style->dark[i], FALSE, TRUE))
1379 g_warning ("unable to allocate color: ( %d %d %d )",
1380 style->dark[i].red, style->dark[i].green, style->dark[i].blue);
1381 if (!gdk_colormap_alloc_color (style->colormap, &style->mid[i], FALSE, TRUE))
1382 g_warning ("unable to allocate color: ( %d %d %d )",
1383 style->mid[i].red, style->mid[i].green, style->mid[i].blue);
1384 if (!gdk_colormap_alloc_color (style->colormap, &style->text[i], FALSE, TRUE))
1385 g_warning ("unable to allocate color: ( %d %d %d )",
1386 style->text[i].red, style->text[i].green, style->text[i].blue);
1387 if (!gdk_colormap_alloc_color (style->colormap, &style->base[i], FALSE, TRUE))
1388 g_warning ("unable to allocate color: ( %d %d %d )",
1389 style->base[i].red, style->base[i].green, style->base[i].blue);
1390 if (!gdk_colormap_alloc_color (style->colormap, &style->text_aa[i], FALSE, TRUE))
1391 g_warning ("unable to allocate color: ( %d %d %d )",
1392 style->text_aa[i].red, style->text_aa[i].green, style->text_aa[i].blue);
1394 gc_values.foreground = style->fg[i];
1395 style->fg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1397 gc_values.foreground = style->bg[i];
1398 style->bg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1400 gc_values.foreground = style->light[i];
1401 style->light_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1403 gc_values.foreground = style->dark[i];
1404 style->dark_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1406 gc_values.foreground = style->mid[i];
1407 style->mid_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1409 gc_values.foreground = style->text[i];
1410 style->text_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1412 gc_values.foreground = style->base[i];
1413 style->base_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1415 gc_values.foreground = style->text_aa[i];
1416 style->text_aa_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1421 gtk_style_real_unrealize (GtkStyle *style)
1425 gtk_gc_release (style->black_gc);
1426 gtk_gc_release (style->white_gc);
1428 for (i = 0; i < 5; i++)
1430 gtk_gc_release (style->fg_gc[i]);
1431 gtk_gc_release (style->bg_gc[i]);
1432 gtk_gc_release (style->light_gc[i]);
1433 gtk_gc_release (style->dark_gc[i]);
1434 gtk_gc_release (style->mid_gc[i]);
1435 gtk_gc_release (style->text_gc[i]);
1436 gtk_gc_release (style->base_gc[i]);
1437 gtk_gc_release (style->text_aa_gc[i]);
1439 if (style->bg_pixmap[i] && style->bg_pixmap[i] != (GdkPixmap*) GDK_PARENT_RELATIVE)
1441 g_object_unref (style->bg_pixmap[i]);
1442 style->bg_pixmap[i] = NULL;
1447 gdk_colormap_free_colors (style->colormap, style->fg, 5);
1448 gdk_colormap_free_colors (style->colormap, style->bg, 5);
1449 gdk_colormap_free_colors (style->colormap, style->light, 5);
1450 gdk_colormap_free_colors (style->colormap, style->dark, 5);
1451 gdk_colormap_free_colors (style->colormap, style->mid, 5);
1452 gdk_colormap_free_colors (style->colormap, style->text, 5);
1453 gdk_colormap_free_colors (style->colormap, style->base, 5);
1454 gdk_colormap_free_colors (style->colormap, style->text_aa, 5);
1456 style_unrealize_cursor_gcs (style);
1460 gtk_style_real_set_background (GtkStyle *style,
1462 GtkStateType state_type)
1465 gint parent_relative;
1467 if (style->bg_pixmap[state_type])
1469 if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
1472 parent_relative = TRUE;
1476 pixmap = style->bg_pixmap[state_type];
1477 parent_relative = FALSE;
1480 gdk_window_set_back_pixmap (window, pixmap, parent_relative);
1483 gdk_window_set_background (window, &style->bg[state_type]);
1487 * gtk_style_render_icon:
1488 * @style: a #GtkStyle
1489 * @source: the #GtkIconSource specifying the icon to render
1490 * @direction: a text direction
1492 * @size: (type int) the size to render the icon at. A size of
1493 * (GtkIconSize)-1 means render at the size of the source and
1495 * @widget: (allow-none): the widget
1496 * @detail: (allow-none): a style detail
1497 * @returns: a newly-created #GdkPixbuf containing the rendered icon
1499 * Renders the icon specified by @source at the given @size
1500 * according to the given parameters and returns the result in a
1504 gtk_style_render_icon (GtkStyle *style,
1505 const GtkIconSource *source,
1506 GtkTextDirection direction,
1510 const gchar *detail)
1514 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1515 g_return_val_if_fail (GTK_STYLE_GET_CLASS (style)->render_icon != NULL, NULL);
1517 pixbuf = GTK_STYLE_GET_CLASS (style)->render_icon (style, source, direction, state,
1518 size, widget, detail);
1520 g_return_val_if_fail (pixbuf != NULL, NULL);
1525 /* Default functions */
1528 * gtk_style_apply_default_background:
1533 * @area: (allow-none):
1540 gtk_style_apply_default_background (GtkStyle *style,
1543 GtkStateType state_type,
1544 const GdkRectangle *area,
1550 GdkRectangle new_rect, old_rect;
1556 old_rect.width = width;
1557 old_rect.height = height;
1559 if (!gdk_rectangle_intersect (area, &old_rect, &new_rect))
1566 new_rect.width = width;
1567 new_rect.height = height;
1570 if (!style->bg_pixmap[state_type] ||
1571 GDK_IS_PIXMAP (window) ||
1572 (!set_bg && style->bg_pixmap[state_type] != (GdkPixmap*) GDK_PARENT_RELATIVE))
1574 GdkGC *gc = style->bg_gc[state_type];
1576 if (style->bg_pixmap[state_type])
1578 gdk_gc_set_fill (gc, GDK_TILED);
1579 gdk_gc_set_tile (gc, style->bg_pixmap[state_type]);
1582 gdk_draw_rectangle (window, gc, TRUE,
1583 new_rect.x, new_rect.y, new_rect.width, new_rect.height);
1584 if (style->bg_pixmap[state_type])
1585 gdk_gc_set_fill (gc, GDK_SOLID);
1591 if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
1592 gdk_window_set_back_pixmap (window, NULL, TRUE);
1594 gdk_window_set_back_pixmap (window, style->bg_pixmap[state_type], FALSE);
1597 gdk_window_clear_area (window,
1598 new_rect.x, new_rect.y,
1599 new_rect.width, new_rect.height);
1604 scale_or_ref (GdkPixbuf *src,
1608 if (width == gdk_pixbuf_get_width (src) &&
1609 height == gdk_pixbuf_get_height (src))
1611 return g_object_ref (src);
1615 return gdk_pixbuf_scale_simple (src,
1617 GDK_INTERP_BILINEAR);
1622 lookup_icon_size (GtkStyle *style,
1629 GtkSettings *settings;
1631 if (widget && gtk_widget_has_screen (widget))
1633 screen = gtk_widget_get_screen (widget);
1634 settings = gtk_settings_get_for_screen (screen);
1636 else if (style && style->colormap)
1638 screen = gdk_colormap_get_screen (style->colormap);
1639 settings = gtk_settings_get_for_screen (screen);
1643 settings = gtk_settings_get_default ();
1644 GTK_NOTE (MULTIHEAD,
1645 g_warning ("Using the default screen for gtk_default_render_icon()"));
1648 return gtk_icon_size_lookup_for_settings (settings, size, width, height);
1652 gtk_default_render_icon (GtkStyle *style,
1653 const GtkIconSource *source,
1654 GtkTextDirection direction,
1658 const gchar *detail)
1664 GdkPixbuf *base_pixbuf;
1666 /* Oddly, style can be NULL in this function, because
1667 * GtkIconSet can be used without a style and if so
1668 * it uses this function.
1671 base_pixbuf = gtk_icon_source_get_pixbuf (source);
1673 g_return_val_if_fail (base_pixbuf != NULL, NULL);
1675 if (size != (GtkIconSize) -1 && !lookup_icon_size(style, widget, size, &width, &height))
1677 g_warning (G_STRLOC ": invalid icon size '%d'", size);
1681 /* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
1684 if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source))
1685 scaled = scale_or_ref (base_pixbuf, width, height);
1687 scaled = g_object_ref (base_pixbuf);
1689 /* If the state was wildcarded, then generate a state. */
1690 if (gtk_icon_source_get_state_wildcarded (source))
1692 if (state == GTK_STATE_INSENSITIVE)
1694 stated = gdk_pixbuf_copy (scaled);
1696 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
1699 g_object_unref (scaled);
1701 else if (state == GTK_STATE_PRELIGHT)
1703 stated = gdk_pixbuf_copy (scaled);
1705 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
1708 g_object_unref (scaled);
1722 sanitize_size (GdkWindow *window,
1726 if ((*width == -1) && (*height == -1))
1727 gdk_drawable_get_size (window, width, height);
1728 else if (*width == -1)
1729 gdk_drawable_get_size (window, width, NULL);
1730 else if (*height == -1)
1731 gdk_drawable_get_size (window, NULL, height);
1735 gtk_default_draw_hline (GtkStyle *style,
1737 GtkStateType state_type,
1740 const gchar *detail,
1745 gint thickness_light;
1746 gint thickness_dark;
1749 thickness_light = style->ythickness / 2;
1750 thickness_dark = style->ythickness - thickness_light;
1754 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
1755 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
1758 if (detail && !strcmp (detail, "label"))
1760 if (state_type == GTK_STATE_INSENSITIVE)
1761 gdk_draw_line (window, style->white_gc, x1 + 1, y + 1, x2 + 1, y + 1);
1762 gdk_draw_line (window, style->fg_gc[state_type], x1, y, x2, y);
1766 for (i = 0; i < thickness_dark; i++)
1768 gdk_draw_line (window, style->dark_gc[state_type], x1, y + i, x2 - i - 1, y + i);
1769 gdk_draw_line (window, style->light_gc[state_type], x2 - i, y + i, x2, y + i);
1772 y += thickness_dark;
1773 for (i = 0; i < thickness_light; i++)
1775 gdk_draw_line (window, style->dark_gc[state_type], x1, y + i, x1 + thickness_light - i - 1, y + i);
1776 gdk_draw_line (window, style->light_gc[state_type], x1 + thickness_light - i, y + i, x2, y + i);
1782 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
1783 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
1789 gtk_default_draw_vline (GtkStyle *style,
1791 GtkStateType state_type,
1794 const gchar *detail,
1799 gint thickness_light;
1800 gint thickness_dark;
1803 thickness_light = style->xthickness / 2;
1804 thickness_dark = style->xthickness - thickness_light;
1808 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
1809 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
1811 for (i = 0; i < thickness_dark; i++)
1813 gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i, y2 - i - 1);
1814 gdk_draw_line (window, style->light_gc[state_type], x + i, y2 - i, x + i, y2);
1817 x += thickness_dark;
1818 for (i = 0; i < thickness_light; i++)
1820 gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i, y1 + thickness_light - i - 1);
1821 gdk_draw_line (window, style->light_gc[state_type], x + i, y1 + thickness_light - i, x + i, y2);
1825 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
1826 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
1831 draw_thin_shadow (GtkStyle *style,
1842 sanitize_size (window, &width, &height);
1844 gc1 = style->light_gc[state];
1845 gc2 = style->dark_gc[state];
1849 gdk_gc_set_clip_rectangle (gc1, area);
1850 gdk_gc_set_clip_rectangle (gc2, area);
1853 gdk_draw_line (window, gc1,
1854 x, y + height - 1, x + width - 1, y + height - 1);
1855 gdk_draw_line (window, gc1,
1856 x + width - 1, y, x + width - 1, y + height - 1);
1858 gdk_draw_line (window, gc2,
1859 x, y, x + width - 2, y);
1860 gdk_draw_line (window, gc2,
1861 x, y, x, y + height - 2);
1865 gdk_gc_set_clip_rectangle (gc1, NULL);
1866 gdk_gc_set_clip_rectangle (gc2, NULL);
1871 draw_spinbutton_shadow (GtkStyle *style,
1874 GtkTextDirection direction,
1881 sanitize_size (window, &width, &height);
1885 gdk_gc_set_clip_rectangle (style->black_gc, area);
1886 gdk_gc_set_clip_rectangle (style->bg_gc[state], area);
1887 gdk_gc_set_clip_rectangle (style->dark_gc[state], area);
1888 gdk_gc_set_clip_rectangle (style->light_gc[state], area);
1891 if (direction == GTK_TEXT_DIR_LTR)
1893 gdk_draw_line (window, style->dark_gc[state],
1894 x, y, x + width - 1, y);
1895 gdk_draw_line (window, style->black_gc,
1896 x, y + 1, x + width - 2, y + 1);
1897 gdk_draw_line (window, style->black_gc,
1898 x + width - 2, y + 2, x + width - 2, y + height - 3);
1899 gdk_draw_line (window, style->light_gc[state],
1900 x + width - 1, y + 1, x + width - 1, y + height - 2);
1901 gdk_draw_line (window, style->light_gc[state],
1902 x, y + height - 1, x + width - 1, y + height - 1);
1903 gdk_draw_line (window, style->bg_gc[state],
1904 x, y + height - 2, x + width - 2, y + height - 2);
1905 gdk_draw_line (window, style->black_gc,
1906 x, y + 2, x, y + height - 3);
1910 gdk_draw_line (window, style->dark_gc[state],
1911 x, y, x + width - 1, y);
1912 gdk_draw_line (window, style->dark_gc[state],
1913 x, y + 1, x, y + height - 1);
1914 gdk_draw_line (window, style->black_gc,
1915 x + 1, y + 1, x + width - 1, y + 1);
1916 gdk_draw_line (window, style->black_gc,
1917 x + 1, y + 2, x + 1, y + height - 2);
1918 gdk_draw_line (window, style->black_gc,
1919 x + width - 1, y + 2, x + width - 1, y + height - 3);
1920 gdk_draw_line (window, style->light_gc[state],
1921 x + 1, y + height - 1, x + width - 1, y + height - 1);
1922 gdk_draw_line (window, style->bg_gc[state],
1923 x + 2, y + height - 2, x + width - 1, y + height - 2);
1928 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
1929 gdk_gc_set_clip_rectangle (style->bg_gc[state], NULL);
1930 gdk_gc_set_clip_rectangle (style->dark_gc[state], NULL);
1931 gdk_gc_set_clip_rectangle (style->light_gc[state], NULL);
1936 draw_menu_shadow (GtkStyle *style,
1945 if (style->ythickness > 0)
1947 if (style->ythickness > 1)
1949 gdk_draw_line (window, style->dark_gc[state],
1950 x + 1, y + height - 2, x + width - 2, y + height - 2);
1951 gdk_draw_line (window, style->black_gc,
1952 x, y + height - 1, x + width - 1, y + height - 1);
1956 gdk_draw_line (window, style->dark_gc[state],
1957 x + 1, y + height - 1, x + width - 1, y + height - 1);
1961 if (style->xthickness > 0)
1963 if (style->xthickness > 1)
1965 gdk_draw_line (window, style->dark_gc[state],
1966 x + width - 2, y + 1, x + width - 2, y + height - 2);
1968 gdk_draw_line (window, style->black_gc,
1969 x + width - 1, y, x + width - 1, y + height - 1);
1973 gdk_draw_line (window, style->dark_gc[state],
1974 x + width - 1, y + 1, x + width - 1, y + height - 1);
1978 /* Light around top and left */
1980 if (style->ythickness > 0)
1981 gdk_draw_line (window, style->black_gc,
1982 x, y, x + width - 2, y);
1983 if (style->xthickness > 0)
1984 gdk_draw_line (window, style->black_gc,
1985 x, y, x, y + height - 2);
1987 if (style->ythickness > 1)
1988 gdk_draw_line (window, style->light_gc[state],
1989 x + 1, y + 1, x + width - 3, y + 1);
1990 if (style->xthickness > 1)
1991 gdk_draw_line (window, style->light_gc[state],
1992 x + 1, y + 1, x + 1, y + height - 3);
1995 static GtkTextDirection
1996 get_direction (GtkWidget *widget)
1998 GtkTextDirection dir;
2001 dir = gtk_widget_get_direction (widget);
2003 dir = GTK_TEXT_DIR_LTR;
2010 gtk_default_draw_shadow (GtkStyle *style,
2012 GtkStateType state_type,
2013 GtkShadowType shadow_type,
2016 const gchar *detail,
2024 gint thickness_light;
2025 gint thickness_dark;
2028 if (shadow_type == GTK_SHADOW_IN)
2030 if (detail && strcmp (detail, "buttondefault") == 0)
2032 sanitize_size (window, &width, &height);
2034 gdk_draw_rectangle (window, style->black_gc, FALSE,
2035 x, y, width - 1, height - 1);
2039 if (detail && strcmp (detail, "trough") == 0)
2041 draw_thin_shadow (style, window, state_type, area,
2042 x, y, width, height);
2045 if (GTK_IS_SPIN_BUTTON (widget) &&
2046 detail && strcmp (detail, "spinbutton") == 0)
2048 draw_spinbutton_shadow (style, window, state_type,
2049 get_direction (widget), area, x, y, width, height);
2055 if (shadow_type == GTK_SHADOW_OUT && detail && strcmp (detail, "menu") == 0)
2057 draw_menu_shadow (style, window, state_type, area, x, y, width, height);
2061 sanitize_size (window, &width, &height);
2063 switch (shadow_type)
2065 case GTK_SHADOW_NONE:
2068 case GTK_SHADOW_ETCHED_IN:
2069 gc1 = style->light_gc[state_type];
2070 gc2 = style->dark_gc[state_type];
2072 case GTK_SHADOW_OUT:
2073 case GTK_SHADOW_ETCHED_OUT:
2074 gc1 = style->dark_gc[state_type];
2075 gc2 = style->light_gc[state_type];
2081 gdk_gc_set_clip_rectangle (gc1, area);
2082 gdk_gc_set_clip_rectangle (gc2, area);
2083 if (shadow_type == GTK_SHADOW_IN ||
2084 shadow_type == GTK_SHADOW_OUT)
2086 gdk_gc_set_clip_rectangle (style->black_gc, area);
2087 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
2091 switch (shadow_type)
2093 case GTK_SHADOW_NONE:
2097 /* Light around right and bottom edge */
2099 if (style->ythickness > 0)
2100 gdk_draw_line (window, gc1,
2101 x, y + height - 1, x + width - 1, y + height - 1);
2102 if (style->xthickness > 0)
2103 gdk_draw_line (window, gc1,
2104 x + width - 1, y, x + width - 1, y + height - 1);
2106 if (style->ythickness > 1)
2107 gdk_draw_line (window, style->bg_gc[state_type],
2108 x + 1, y + height - 2, x + width - 2, y + height - 2);
2109 if (style->xthickness > 1)
2110 gdk_draw_line (window, style->bg_gc[state_type],
2111 x + width - 2, y + 1, x + width - 2, y + height - 2);
2113 /* Dark around left and top */
2115 if (style->ythickness > 1)
2116 gdk_draw_line (window, style->black_gc,
2117 x + 1, y + 1, x + width - 2, y + 1);
2118 if (style->xthickness > 1)
2119 gdk_draw_line (window, style->black_gc,
2120 x + 1, y + 1, x + 1, y + height - 2);
2122 if (style->ythickness > 0)
2123 gdk_draw_line (window, gc2,
2124 x, y, x + width - 1, y);
2125 if (style->xthickness > 0)
2126 gdk_draw_line (window, gc2,
2127 x, y, x, y + height - 1);
2130 case GTK_SHADOW_OUT:
2131 /* Dark around right and bottom edge */
2133 if (style->ythickness > 0)
2135 if (style->ythickness > 1)
2137 gdk_draw_line (window, gc1,
2138 x + 1, y + height - 2, x + width - 2, y + height - 2);
2139 gdk_draw_line (window, style->black_gc,
2140 x, y + height - 1, x + width - 1, y + height - 1);
2144 gdk_draw_line (window, gc1,
2145 x + 1, y + height - 1, x + width - 1, y + height - 1);
2149 if (style->xthickness > 0)
2151 if (style->xthickness > 1)
2153 gdk_draw_line (window, gc1,
2154 x + width - 2, y + 1, x + width - 2, y + height - 2);
2156 gdk_draw_line (window, style->black_gc,
2157 x + width - 1, y, x + width - 1, y + height - 1);
2161 gdk_draw_line (window, gc1,
2162 x + width - 1, y + 1, x + width - 1, y + height - 1);
2166 /* Light around top and left */
2168 if (style->ythickness > 0)
2169 gdk_draw_line (window, gc2,
2170 x, y, x + width - 2, y);
2171 if (style->xthickness > 0)
2172 gdk_draw_line (window, gc2,
2173 x, y, x, y + height - 2);
2175 if (style->ythickness > 1)
2176 gdk_draw_line (window, style->bg_gc[state_type],
2177 x + 1, y + 1, x + width - 3, y + 1);
2178 if (style->xthickness > 1)
2179 gdk_draw_line (window, style->bg_gc[state_type],
2180 x + 1, y + 1, x + 1, y + height - 3);
2183 case GTK_SHADOW_ETCHED_IN:
2184 case GTK_SHADOW_ETCHED_OUT:
2185 if (style->xthickness > 0)
2187 if (style->xthickness > 1)
2189 thickness_light = 1;
2192 for (i = 0; i < thickness_dark; i++)
2194 gdk_draw_line (window, gc1,
2198 y + height - i - 1);
2199 gdk_draw_line (window, gc2,
2203 y + height - i - 2);
2206 for (i = 0; i < thickness_light; i++)
2208 gdk_draw_line (window, gc1,
2209 x + thickness_dark + i,
2210 y + thickness_dark + i,
2211 x + thickness_dark + i,
2212 y + height - thickness_dark - i - 1);
2213 gdk_draw_line (window, gc2,
2214 x + width - thickness_light - i - 1,
2215 y + thickness_dark + i,
2216 x + width - thickness_light - i - 1,
2217 y + height - thickness_light - 1);
2222 gdk_draw_line (window,
2223 style->dark_gc[state_type],
2224 x, y, x, y + height);
2225 gdk_draw_line (window,
2226 style->dark_gc[state_type],
2227 x + width, y, x + width, y + height);
2231 if (style->ythickness > 0)
2233 if (style->ythickness > 1)
2235 thickness_light = 1;
2238 for (i = 0; i < thickness_dark; i++)
2240 gdk_draw_line (window, gc1,
2244 y + height - i - 1);
2246 gdk_draw_line (window, gc2,
2253 for (i = 0; i < thickness_light; i++)
2255 gdk_draw_line (window, gc1,
2256 x + thickness_dark + i,
2257 y + thickness_dark + i,
2258 x + width - thickness_dark - i - 2,
2259 y + thickness_dark + i);
2261 gdk_draw_line (window, gc2,
2262 x + thickness_dark + i,
2263 y + height - thickness_light - i - 1,
2264 x + width - thickness_light - 1,
2265 y + height - thickness_light - i - 1);
2270 gdk_draw_line (window,
2271 style->dark_gc[state_type],
2272 x, y, x + width, y);
2273 gdk_draw_line (window,
2274 style->dark_gc[state_type],
2275 x, y + height, x + width, y + height);
2282 if (shadow_type == GTK_SHADOW_IN &&
2283 GTK_IS_SPIN_BUTTON (widget) &&
2284 detail && strcmp (detail, "entry") == 0)
2286 if (get_direction (widget) == GTK_TEXT_DIR_LTR)
2288 gdk_draw_line (window,
2289 style->base_gc[state_type],
2290 x + width - 1, y + 2,
2291 x + width - 1, y + height - 3);
2292 gdk_draw_line (window,
2293 style->base_gc[state_type],
2294 x + width - 2, y + 2,
2295 x + width - 2, y + height - 3);
2296 gdk_draw_point (window,
2298 x + width - 1, y + 1);
2299 gdk_draw_point (window,
2300 style->bg_gc[state_type],
2301 x + width - 1, y + height - 2);
2305 gdk_draw_line (window,
2306 style->base_gc[state_type],
2309 gdk_draw_line (window,
2310 style->base_gc[state_type],
2312 x + 1, y + height - 3);
2313 gdk_draw_point (window,
2316 gdk_draw_line (window,
2317 style->bg_gc[state_type],
2319 x + 1, y + height - 2);
2320 gdk_draw_point (window,
2321 style->light_gc[state_type],
2329 gdk_gc_set_clip_rectangle (gc1, NULL);
2330 gdk_gc_set_clip_rectangle (gc2, NULL);
2331 if (shadow_type == GTK_SHADOW_IN ||
2332 shadow_type == GTK_SHADOW_OUT)
2334 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
2335 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
2341 gtk_default_draw_polygon (GtkStyle *style,
2343 GtkStateType state_type,
2344 GtkShadowType shadow_type,
2347 const gchar *detail,
2352 static const gdouble pi_over_4 = G_PI_4;
2353 static const gdouble pi_3_over_4 = G_PI_4 * 3;
2363 switch (shadow_type)
2366 gc1 = style->bg_gc[state_type];
2367 gc2 = style->dark_gc[state_type];
2368 gc3 = style->light_gc[state_type];
2369 gc4 = style->black_gc;
2371 case GTK_SHADOW_ETCHED_IN:
2372 gc1 = style->light_gc[state_type];
2373 gc2 = style->dark_gc[state_type];
2374 gc3 = style->dark_gc[state_type];
2375 gc4 = style->light_gc[state_type];
2377 case GTK_SHADOW_OUT:
2378 gc1 = style->dark_gc[state_type];
2379 gc2 = style->light_gc[state_type];
2380 gc3 = style->black_gc;
2381 gc4 = style->bg_gc[state_type];
2383 case GTK_SHADOW_ETCHED_OUT:
2384 gc1 = style->dark_gc[state_type];
2385 gc2 = style->light_gc[state_type];
2386 gc3 = style->light_gc[state_type];
2387 gc4 = style->dark_gc[state_type];
2395 gdk_gc_set_clip_rectangle (gc1, area);
2396 gdk_gc_set_clip_rectangle (gc2, area);
2397 gdk_gc_set_clip_rectangle (gc3, area);
2398 gdk_gc_set_clip_rectangle (gc4, area);
2402 gdk_draw_polygon (window, style->bg_gc[state_type], TRUE, points, npoints);
2406 for (i = 0; i < npoints; i++)
2408 if ((points[i].x == points[i+1].x) &&
2409 (points[i].y == points[i+1].y))
2415 angle = atan2 (points[i+1].y - points[i].y,
2416 points[i+1].x - points[i].x);
2419 if ((angle > -pi_3_over_4) && (angle < pi_over_4))
2421 if (angle > -pi_over_4)
2432 gdk_draw_line (window, gc1,
2433 points[i].x-xadjust, points[i].y-yadjust,
2434 points[i+1].x-xadjust, points[i+1].y-yadjust);
2435 gdk_draw_line (window, gc3,
2436 points[i].x, points[i].y,
2437 points[i+1].x, points[i+1].y);
2441 if ((angle < -pi_3_over_4) || (angle > pi_3_over_4))
2452 gdk_draw_line (window, gc4,
2453 points[i].x+xadjust, points[i].y+yadjust,
2454 points[i+1].x+xadjust, points[i+1].y+yadjust);
2455 gdk_draw_line (window, gc2,
2456 points[i].x, points[i].y,
2457 points[i+1].x, points[i+1].y);
2463 gdk_gc_set_clip_rectangle (gc1, NULL);
2464 gdk_gc_set_clip_rectangle (gc2, NULL);
2465 gdk_gc_set_clip_rectangle (gc3, NULL);
2466 gdk_gc_set_clip_rectangle (gc4, NULL);
2471 draw_arrow (GdkWindow *window,
2474 GtkArrowType arrow_type,
2480 cairo_t *cr = gdk_cairo_create (window);
2481 gdk_cairo_set_source_color (cr, color);
2485 gdk_cairo_rectangle (cr, area);
2489 if (arrow_type == GTK_ARROW_DOWN)
2491 cairo_move_to (cr, x, y);
2492 cairo_line_to (cr, x + width, y);
2493 cairo_line_to (cr, x + width / 2., y + height);
2495 else if (arrow_type == GTK_ARROW_UP)
2497 cairo_move_to (cr, x, y + height);
2498 cairo_line_to (cr, x + width / 2., y);
2499 cairo_line_to (cr, x + width, y + height);
2501 else if (arrow_type == GTK_ARROW_LEFT)
2503 cairo_move_to (cr, x + width, y);
2504 cairo_line_to (cr, x + width, y + height);
2505 cairo_line_to (cr, x, y + height / 2.);
2507 else if (arrow_type == GTK_ARROW_RIGHT)
2509 cairo_move_to (cr, x, y);
2510 cairo_line_to (cr, x + width, y + height / 2.);
2511 cairo_line_to (cr, x, y + height);
2514 cairo_close_path (cr);
2521 calculate_arrow_geometry (GtkArrowType arrow_type,
2533 case GTK_ARROW_DOWN:
2543 if (arrow_type == GTK_ARROW_DOWN)
2545 if (*height % 2 == 1 || h % 2 == 0)
2550 if (*height % 2 == 0 || h % 2 == 0)
2555 case GTK_ARROW_RIGHT:
2556 case GTK_ARROW_LEFT:
2566 if (arrow_type == GTK_ARROW_RIGHT)
2568 if (*width % 2 == 1 || w % 2 == 0)
2573 if (*width % 2 == 0 || w % 2 == 0)
2579 /* should not be reached */
2583 *x += (*width - w) / 2;
2584 *y += (*height - h) / 2;
2590 gtk_default_draw_arrow (GtkStyle *style,
2593 GtkShadowType shadow,
2596 const gchar *detail,
2597 GtkArrowType arrow_type,
2604 sanitize_size (window, &width, &height);
2606 calculate_arrow_geometry (arrow_type, &x, &y, &width, &height);
2608 if (detail && strcmp (detail, "menu_scroll_arrow_up") == 0)
2611 if (state == GTK_STATE_INSENSITIVE)
2612 draw_arrow (window, &style->white, area, arrow_type,
2613 x + 1, y + 1, width, height);
2614 draw_arrow (window, &style->fg[state], area, arrow_type,
2615 x, y, width, height);
2619 gtk_default_draw_diamond (GtkStyle *style,
2621 GtkStateType state_type,
2622 GtkShadowType shadow_type,
2625 const gchar *detail,
2633 GdkGC *outer_nw = NULL;
2634 GdkGC *outer_ne = NULL;
2635 GdkGC *outer_sw = NULL;
2636 GdkGC *outer_se = NULL;
2637 GdkGC *middle_nw = NULL;
2638 GdkGC *middle_ne = NULL;
2639 GdkGC *middle_sw = NULL;
2640 GdkGC *middle_se = NULL;
2641 GdkGC *inner_nw = NULL;
2642 GdkGC *inner_ne = NULL;
2643 GdkGC *inner_sw = NULL;
2644 GdkGC *inner_se = NULL;
2646 sanitize_size (window, &width, &height);
2648 half_width = width / 2;
2649 half_height = height / 2;
2653 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2654 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
2655 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2656 gdk_gc_set_clip_rectangle (style->black_gc, area);
2659 switch (shadow_type)
2662 inner_sw = inner_se = style->bg_gc[state_type];
2663 middle_sw = middle_se = style->light_gc[state_type];
2664 outer_sw = outer_se = style->light_gc[state_type];
2665 inner_nw = inner_ne = style->black_gc;
2666 middle_nw = middle_ne = style->dark_gc[state_type];
2667 outer_nw = outer_ne = style->dark_gc[state_type];
2670 case GTK_SHADOW_OUT:
2671 inner_sw = inner_se = style->dark_gc[state_type];
2672 middle_sw = middle_se = style->dark_gc[state_type];
2673 outer_sw = outer_se = style->black_gc;
2674 inner_nw = inner_ne = style->bg_gc[state_type];
2675 middle_nw = middle_ne = style->light_gc[state_type];
2676 outer_nw = outer_ne = style->light_gc[state_type];
2679 case GTK_SHADOW_ETCHED_IN:
2680 inner_sw = inner_se = style->bg_gc[state_type];
2681 middle_sw = middle_se = style->dark_gc[state_type];
2682 outer_sw = outer_se = style->light_gc[state_type];
2683 inner_nw = inner_ne = style->bg_gc[state_type];
2684 middle_nw = middle_ne = style->light_gc[state_type];
2685 outer_nw = outer_ne = style->dark_gc[state_type];
2688 case GTK_SHADOW_ETCHED_OUT:
2689 inner_sw = inner_se = style->bg_gc[state_type];
2690 middle_sw = middle_se = style->light_gc[state_type];
2691 outer_sw = outer_se = style->dark_gc[state_type];
2692 inner_nw = inner_ne = style->bg_gc[state_type];
2693 middle_nw = middle_ne = style->dark_gc[state_type];
2694 outer_nw = outer_ne = style->light_gc[state_type];
2704 gdk_draw_line (window, inner_sw,
2705 x + 2, y + half_height,
2706 x + half_width, y + height - 2);
2707 gdk_draw_line (window, inner_se,
2708 x + half_width, y + height - 2,
2709 x + width - 2, y + half_height);
2710 gdk_draw_line (window, middle_sw,
2711 x + 1, y + half_height,
2712 x + half_width, y + height - 1);
2713 gdk_draw_line (window, middle_se,
2714 x + half_width, y + height - 1,
2715 x + width - 1, y + half_height);
2716 gdk_draw_line (window, outer_sw,
2718 x + half_width, y + height);
2719 gdk_draw_line (window, outer_se,
2720 x + half_width, y + height,
2721 x + width, y + half_height);
2723 gdk_draw_line (window, inner_nw,
2724 x + 2, y + half_height,
2725 x + half_width, y + 2);
2726 gdk_draw_line (window, inner_ne,
2727 x + half_width, y + 2,
2728 x + width - 2, y + half_height);
2729 gdk_draw_line (window, middle_nw,
2730 x + 1, y + half_height,
2731 x + half_width, y + 1);
2732 gdk_draw_line (window, middle_ne,
2733 x + half_width, y + 1,
2734 x + width - 1, y + half_height);
2735 gdk_draw_line (window, outer_nw,
2738 gdk_draw_line (window, outer_ne,
2740 x + width, y + half_height);
2745 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2746 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
2747 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2748 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
2753 gtk_default_draw_string (GtkStyle *style,
2755 GtkStateType state_type,
2758 const gchar *detail,
2761 const gchar *string)
2765 gdk_gc_set_clip_rectangle (style->white_gc, area);
2766 gdk_gc_set_clip_rectangle (style->fg_gc[state_type], area);
2769 if (state_type == GTK_STATE_INSENSITIVE)
2770 gdk_draw_string (window,
2771 gtk_style_get_font_internal (style),
2772 style->white_gc, x + 1, y + 1, string);
2774 gdk_draw_string (window,
2775 gtk_style_get_font_internal (style),
2776 style->fg_gc[state_type], x, y, string);
2780 gdk_gc_set_clip_rectangle (style->white_gc, NULL);
2781 gdk_gc_set_clip_rectangle (style->fg_gc[state_type], NULL);
2786 option_menu_get_props (GtkWidget *widget,
2787 GtkRequisition *indicator_size,
2788 GtkBorder *indicator_spacing)
2790 GtkRequisition *tmp_size = NULL;
2791 GtkBorder *tmp_spacing = NULL;
2795 *indicator_size = *tmp_size;
2796 gtk_requisition_free (tmp_size);
2799 *indicator_size = default_option_indicator_size;
2803 *indicator_spacing = *tmp_spacing;
2804 gtk_border_free (tmp_spacing);
2807 *indicator_spacing = default_option_indicator_spacing;
2811 gtk_default_draw_box (GtkStyle *style,
2813 GtkStateType state_type,
2814 GtkShadowType shadow_type,
2817 const gchar *detail,
2823 gboolean is_spinbutton_box = FALSE;
2825 sanitize_size (window, &width, &height);
2827 if (GTK_IS_SPIN_BUTTON (widget) && detail)
2829 if (strcmp (detail, "spinbutton_up") == 0)
2835 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
2840 is_spinbutton_box = TRUE;
2842 else if (strcmp (detail, "spinbutton_down") == 0)
2847 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
2852 is_spinbutton_box = TRUE;
2856 if (!style->bg_pixmap[state_type] ||
2857 GDK_IS_PIXMAP (window))
2859 GdkGC *gc = style->bg_gc[state_type];
2861 if (state_type == GTK_STATE_SELECTED && detail && strcmp (detail, "paned") == 0)
2863 if (widget && !gtk_widget_has_focus (widget))
2864 gc = style->base_gc[GTK_STATE_ACTIVE];
2868 gdk_gc_set_clip_rectangle (gc, area);
2870 gdk_draw_rectangle (window, gc, TRUE,
2871 x, y, width, height);
2873 gdk_gc_set_clip_rectangle (gc, NULL);
2876 gtk_style_apply_default_background (style, window,
2877 widget && gtk_widget_get_has_window (widget),
2878 state_type, area, x, y, width, height);
2880 if (is_spinbutton_box)
2885 lower_gc = style->dark_gc[state_type];
2886 if (shadow_type == GTK_SHADOW_OUT)
2887 upper_gc = style->light_gc[state_type];
2889 upper_gc = style->dark_gc[state_type];
2893 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2894 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2897 gdk_draw_line (window, upper_gc, x, y, x + width - 1, y);
2898 gdk_draw_line (window, lower_gc, x, y + height - 1, x + width - 1, y + height - 1);
2902 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2903 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2908 gtk_paint_shadow (style, window, state_type, shadow_type, area, widget, detail,
2909 x, y, width, height);
2911 if (detail && strcmp (detail, "optionmenu") == 0)
2913 GtkRequisition indicator_size;
2914 GtkBorder indicator_spacing;
2917 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
2919 sanitize_size (window, &width, &height);
2921 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
2922 vline_x = x + indicator_size.width + indicator_spacing.left + indicator_spacing.right;
2924 vline_x = x + width - (indicator_size.width + indicator_spacing.left + indicator_spacing.right) - style->xthickness;
2926 gtk_paint_vline (style, window, state_type, area, widget,
2928 y + style->ythickness + 1,
2929 y + height - style->ythickness - 3,
2935 get_darkened_gc (GdkWindow *window,
2936 const GdkColor *color,
2939 GdkColor src = *color;
2940 GdkColor shaded = *color;
2943 gc = gdk_gc_new (window);
2945 while (darken_count)
2947 _gtk_style_shade (&src, &shaded, 0.93);
2952 gdk_gc_set_rgb_fg_color (gc, &shaded);
2958 gtk_default_draw_flat_box (GtkStyle *style,
2960 GtkStateType state_type,
2961 GtkShadowType shadow_type,
2964 const gchar *detail,
2971 GdkGC *freeme = NULL;
2973 sanitize_size (window, &width, &height);
2977 if (state_type == GTK_STATE_SELECTED)
2979 if (!strcmp ("text", detail))
2980 gc1 = style->bg_gc[GTK_STATE_SELECTED];
2981 else if (!strcmp ("cell_even", detail) ||
2982 !strcmp ("cell_odd", detail) ||
2983 !strcmp ("cell_even_ruled", detail) ||
2984 !strcmp ("cell_even_ruled_sorted", detail))
2986 /* This has to be really broken; alex made me do it. -jrb */
2987 if (widget && gtk_widget_has_focus (widget))
2988 gc1 = style->base_gc[state_type];
2990 gc1 = style->base_gc[GTK_STATE_ACTIVE];
2992 else if (!strcmp ("cell_odd_ruled", detail) ||
2993 !strcmp ("cell_odd_ruled_sorted", detail))
2995 if (widget && gtk_widget_has_focus (widget))
2996 freeme = get_darkened_gc (window, &style->base[state_type], 1);
2998 freeme = get_darkened_gc (window, &style->base[GTK_STATE_ACTIVE], 1);
3003 gc1 = style->bg_gc[state_type];
3008 if (!strcmp ("viewportbin", detail))
3009 gc1 = style->bg_gc[GTK_STATE_NORMAL];
3010 else if (!strcmp ("entry_bg", detail))
3011 gc1 = style->base_gc[state_type];
3013 /* For trees: even rows are base color, odd rows are a shade of
3014 * the base color, the sort column is a shade of the original color
3018 else if (!strcmp ("cell_even", detail) ||
3019 !strcmp ("cell_odd", detail) ||
3020 !strcmp ("cell_even_ruled", detail))
3022 GdkColor *color = NULL;
3024 gtk_widget_style_get (widget,
3025 "even-row-color", &color,
3030 freeme = get_darkened_gc (window, color, 0);
3033 gdk_color_free (color);
3036 gc1 = style->base_gc[state_type];
3038 else if (!strcmp ("cell_odd_ruled", detail))
3040 GdkColor *color = NULL;
3042 gtk_widget_style_get (widget,
3043 "odd-row-color", &color,
3048 freeme = get_darkened_gc (window, color, 0);
3051 gdk_color_free (color);
3055 gtk_widget_style_get (widget,
3056 "even-row-color", &color,
3061 freeme = get_darkened_gc (window, color, 1);
3062 gdk_color_free (color);
3065 freeme = get_darkened_gc (window, &style->base[state_type], 1);
3069 else if (!strcmp ("cell_even_sorted", detail) ||
3070 !strcmp ("cell_odd_sorted", detail) ||
3071 !strcmp ("cell_even_ruled_sorted", detail))
3073 GdkColor *color = NULL;
3075 if (!strcmp ("cell_odd_sorted", detail))
3076 gtk_widget_style_get (widget,
3077 "odd-row-color", &color,
3080 gtk_widget_style_get (widget,
3081 "even-row-color", &color,
3086 freeme = get_darkened_gc (window, color, 1);
3089 gdk_color_free (color);
3093 freeme = get_darkened_gc (window, &style->base[state_type], 1);
3097 else if (!strcmp ("cell_odd_ruled_sorted", detail))
3099 GdkColor *color = NULL;
3101 gtk_widget_style_get (widget,
3102 "odd-row-color", &color,
3107 freeme = get_darkened_gc (window, color, 1);
3110 gdk_color_free (color);
3114 gtk_widget_style_get (widget,
3115 "even-row-color", &color,
3120 freeme = get_darkened_gc (window, color, 2);
3121 gdk_color_free (color);
3124 freeme = get_darkened_gc (window, &style->base[state_type], 2);
3129 gc1 = style->bg_gc[state_type];
3133 gc1 = style->bg_gc[state_type];
3135 if (!style->bg_pixmap[state_type] || gc1 != style->bg_gc[state_type] ||
3136 GDK_IS_PIXMAP (window))
3139 gdk_gc_set_clip_rectangle (gc1, area);
3141 gdk_draw_rectangle (window, gc1, TRUE,
3142 x, y, width, height);
3144 if (detail && !strcmp ("tooltip", detail))
3145 gdk_draw_rectangle (window, style->black_gc, FALSE,
3146 x, y, width - 1, height - 1);
3149 gdk_gc_set_clip_rectangle (gc1, NULL);
3152 gtk_style_apply_default_background (style, window,
3153 widget && gtk_widget_get_has_window (widget),
3154 state_type, area, x, y, width, height);
3158 g_object_unref (freeme);
3162 gtk_default_draw_check (GtkStyle *style,
3164 GtkStateType state_type,
3165 GtkShadowType shadow_type,
3168 const gchar *detail,
3174 cairo_t *cr = gdk_cairo_create (window);
3175 enum { BUTTON, MENU, CELL } type = BUTTON;
3182 if (strcmp (detail, "cellcheck") == 0)
3184 else if (strcmp (detail, "check") == 0)
3190 gdk_cairo_rectangle (cr, area);
3194 exterior_size = MIN (width, height);
3195 if (exterior_size % 2 == 0) /* Ensure odd */
3198 pad = style->xthickness + MAX (1, (exterior_size - 2 * style->xthickness) / 9);
3199 interior_size = MAX (1, exterior_size - 2 * pad);
3201 if (interior_size < 7)
3204 pad = MAX (0, (exterior_size - interior_size) / 2);
3207 x -= (1 + exterior_size - width) / 2;
3208 y -= (1 + exterior_size - height) / 2;
3215 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3217 gdk_cairo_set_source_color (cr, &style->text[state_type]);
3219 cairo_set_line_width (cr, 1.0);
3220 cairo_rectangle (cr, x + 0.5, y + 0.5, exterior_size - 1, exterior_size - 1);
3223 gdk_cairo_set_source_color (cr, &style->base[state_type]);
3224 cairo_rectangle (cr, x + 1, y + 1, exterior_size - 2, exterior_size - 2);
3236 gdk_cairo_set_source_color (cr, &style->text[state_type]);
3239 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3243 if (shadow_type == GTK_SHADOW_IN)
3245 cairo_translate (cr,
3248 cairo_scale (cr, interior_size / 7., interior_size / 7.);
3250 cairo_move_to (cr, 7.0, 0.0);
3251 cairo_line_to (cr, 7.5, 1.0);
3252 cairo_curve_to (cr, 5.3, 2.0,
3255 cairo_curve_to (cr, 3.0, 5.7,
3258 cairo_line_to (cr, 0.2, 3.5);
3259 cairo_curve_to (cr, 1.1, 3.5,
3262 cairo_curve_to (cr, 1.0, 3.9,
3265 cairo_curve_to (cr, 3.5, 3.1,
3271 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
3273 int line_thickness = MAX (1, (3 + interior_size * 2) / 7);
3275 cairo_rectangle (cr,
3277 y + pad + (1 + interior_size - line_thickness) / 2,
3287 gtk_default_draw_option (GtkStyle *style,
3289 GtkStateType state_type,
3290 GtkShadowType shadow_type,
3293 const gchar *detail,
3299 cairo_t *cr = gdk_cairo_create (window);
3300 enum { BUTTON, MENU, CELL } type = BUTTON;
3305 if (strcmp (detail, "radio") == 0)
3307 else if (strcmp (detail, "option") == 0)
3313 gdk_cairo_rectangle (cr, area);
3317 exterior_size = MIN (width, height);
3318 if (exterior_size % 2 == 0) /* Ensure odd */
3321 x -= (1 + exterior_size - width) / 2;
3322 y -= (1 + exterior_size - height) / 2;
3328 gdk_cairo_set_source_color (cr, &style->base[state_type]);
3331 x + exterior_size / 2.,
3332 y + exterior_size / 2.,
3333 (exterior_size - 1) / 2.,
3336 cairo_fill_preserve (cr);
3339 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3341 gdk_cairo_set_source_color (cr, &style->text[state_type]);
3343 cairo_set_line_width (cr, 1.);
3354 gdk_cairo_set_source_color (cr, &style->text[state_type]);
3359 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3363 if (shadow_type == GTK_SHADOW_IN)
3365 int pad = style->xthickness + MAX (1, 2 * (exterior_size - 2 * style->xthickness) / 9);
3366 int interior_size = MAX (1, exterior_size - 2 * pad);
3368 if (interior_size < 5)
3371 pad = MAX (0, (exterior_size - interior_size) / 2);
3375 x + pad + interior_size / 2.,
3376 y + pad + interior_size / 2.,
3381 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
3383 int pad = style->xthickness + MAX (1, (exterior_size - 2 * style->xthickness) / 9);
3384 int interior_size = MAX (1, exterior_size - 2 * pad);
3387 if (interior_size < 7)
3390 pad = MAX (0, (exterior_size - interior_size) / 2);
3393 line_thickness = MAX (1, (3 + interior_size * 2) / 7);
3395 cairo_rectangle (cr,
3397 y + pad + (interior_size - line_thickness) / 2.,
3407 gtk_default_draw_tab (GtkStyle *style,
3409 GtkStateType state_type,
3410 GtkShadowType shadow_type,
3413 const gchar *detail,
3419 #define ARROW_SPACE 4
3421 GtkRequisition indicator_size;
3422 GtkBorder indicator_spacing;
3425 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
3427 indicator_size.width += (indicator_size.width % 2) - 1;
3428 arrow_height = indicator_size.width / 2 + 1;
3430 x += (width - indicator_size.width) / 2;
3431 y += (height - (2 * arrow_height + ARROW_SPACE)) / 2;
3433 if (state_type == GTK_STATE_INSENSITIVE)
3435 draw_arrow (window, &style->white, area,
3436 GTK_ARROW_UP, x + 1, y + 1,
3437 indicator_size.width, arrow_height);
3439 draw_arrow (window, &style->white, area,
3440 GTK_ARROW_DOWN, x + 1, y + arrow_height + ARROW_SPACE + 1,
3441 indicator_size.width, arrow_height);
3444 draw_arrow (window, &style->fg[state_type], area,
3446 indicator_size.width, arrow_height);
3449 draw_arrow (window, &style->fg[state_type], area,
3450 GTK_ARROW_DOWN, x, y + arrow_height + ARROW_SPACE,
3451 indicator_size.width, arrow_height);
3455 gtk_default_draw_shadow_gap (GtkStyle *style,
3457 GtkStateType state_type,
3458 GtkShadowType shadow_type,
3461 const gchar *detail,
3466 GtkPositionType gap_side,
3475 sanitize_size (window, &width, &height);
3477 switch (shadow_type)
3479 case GTK_SHADOW_NONE:
3482 gc1 = style->dark_gc[state_type];
3483 gc2 = style->black_gc;
3484 gc3 = style->bg_gc[state_type];
3485 gc4 = style->light_gc[state_type];
3487 case GTK_SHADOW_ETCHED_IN:
3488 gc1 = style->dark_gc[state_type];
3489 gc2 = style->light_gc[state_type];
3490 gc3 = style->dark_gc[state_type];
3491 gc4 = style->light_gc[state_type];
3493 case GTK_SHADOW_OUT:
3494 gc1 = style->light_gc[state_type];
3495 gc2 = style->bg_gc[state_type];
3496 gc3 = style->dark_gc[state_type];
3497 gc4 = style->black_gc;
3499 case GTK_SHADOW_ETCHED_OUT:
3500 gc1 = style->light_gc[state_type];
3501 gc2 = style->dark_gc[state_type];
3502 gc3 = style->light_gc[state_type];
3503 gc4 = style->dark_gc[state_type];
3508 gdk_gc_set_clip_rectangle (gc1, area);
3509 gdk_gc_set_clip_rectangle (gc2, area);
3510 gdk_gc_set_clip_rectangle (gc3, area);
3511 gdk_gc_set_clip_rectangle (gc4, area);
3514 switch (shadow_type)
3516 case GTK_SHADOW_NONE:
3518 case GTK_SHADOW_OUT:
3519 case GTK_SHADOW_ETCHED_IN:
3520 case GTK_SHADOW_ETCHED_OUT:
3524 gdk_draw_line (window, gc1,
3525 x, y, x, y + height - 1);
3526 gdk_draw_line (window, gc2,
3527 x + 1, y, x + 1, y + height - 2);
3529 gdk_draw_line (window, gc3,
3530 x + 1, y + height - 2, x + width - 2, y + height - 2);
3531 gdk_draw_line (window, gc3,
3532 x + width - 2, y, x + width - 2, y + height - 2);
3533 gdk_draw_line (window, gc4,
3534 x, y + height - 1, x + width - 1, y + height - 1);
3535 gdk_draw_line (window, gc4,
3536 x + width - 1, y, x + width - 1, y + height - 1);
3539 gdk_draw_line (window, gc1,
3540 x, y, x + gap_x - 1, y);
3541 gdk_draw_line (window, gc2,
3542 x + 1, y + 1, x + gap_x - 1, y + 1);
3543 gdk_draw_line (window, gc2,
3544 x + gap_x, y, x + gap_x, y);
3546 if ((width - (gap_x + gap_width)) > 0)
3548 gdk_draw_line (window, gc1,
3549 x + gap_x + gap_width, y, x + width - 2, y);
3550 gdk_draw_line (window, gc2,
3551 x + gap_x + gap_width, y + 1, x + width - 3, y + 1);
3552 gdk_draw_line (window, gc2,
3553 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
3556 case GTK_POS_BOTTOM:
3557 gdk_draw_line (window, gc1,
3558 x, y, x + width - 1, y);
3559 gdk_draw_line (window, gc1,
3560 x, y, x, y + height - 1);
3561 gdk_draw_line (window, gc2,
3562 x + 1, y + 1, x + width - 2, y + 1);
3563 gdk_draw_line (window, gc2,
3564 x + 1, y + 1, x + 1, y + height - 1);
3566 gdk_draw_line (window, gc3,
3567 x + width - 2, y + 1, x + width - 2, y + height - 1);
3568 gdk_draw_line (window, gc4,
3569 x + width - 1, y, x + width - 1, y + height - 1);
3572 gdk_draw_line (window, gc4,
3573 x, y + height - 1, x + gap_x - 1, y + height - 1);
3574 gdk_draw_line (window, gc3,
3575 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
3576 gdk_draw_line (window, gc3,
3577 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
3579 if ((width - (gap_x + gap_width)) > 0)
3581 gdk_draw_line (window, gc4,
3582 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
3583 gdk_draw_line (window, gc3,
3584 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
3585 gdk_draw_line (window, gc3,
3586 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
3590 gdk_draw_line (window, gc1,
3591 x, y, x + width - 1, y);
3592 gdk_draw_line (window, gc2,
3593 x, y + 1, x + width - 2, y + 1);
3595 gdk_draw_line (window, gc3,
3596 x, y + height - 2, x + width - 2, y + height - 2);
3597 gdk_draw_line (window, gc3,
3598 x + width - 2, y + 1, x + width - 2, y + height - 2);
3599 gdk_draw_line (window, gc4,
3600 x, y + height - 1, x + width - 1, y + height - 1);
3601 gdk_draw_line (window, gc4,
3602 x + width - 1, y, x + width - 1, y + height - 1);
3605 gdk_draw_line (window, gc1,
3606 x, y, x, y + gap_x - 1);
3607 gdk_draw_line (window, gc2,
3608 x + 1, y + 1, x + 1, y + gap_x - 1);
3609 gdk_draw_line (window, gc2,
3610 x, y + gap_x, x, y + gap_x);
3612 if ((width - (gap_x + gap_width)) > 0)
3614 gdk_draw_line (window, gc1,
3615 x, y + gap_x + gap_width, x, y + height - 2);
3616 gdk_draw_line (window, gc2,
3617 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
3618 gdk_draw_line (window, gc2,
3619 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
3623 gdk_draw_line (window, gc1,
3624 x, y, x + width - 1, y);
3625 gdk_draw_line (window, gc1,
3626 x, y, x, y + height - 1);
3627 gdk_draw_line (window, gc2,
3628 x + 1, y + 1, x + width - 1, y + 1);
3629 gdk_draw_line (window, gc2,
3630 x + 1, y + 1, x + 1, y + height - 2);
3632 gdk_draw_line (window, gc3,
3633 x + 1, y + height - 2, x + width - 1, y + height - 2);
3634 gdk_draw_line (window, gc4,
3635 x, y + height - 1, x + width - 1, y + height - 1);
3638 gdk_draw_line (window, gc4,
3639 x + width - 1, y, x + width - 1, y + gap_x - 1);
3640 gdk_draw_line (window, gc3,
3641 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
3642 gdk_draw_line (window, gc3,
3643 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
3645 if ((width - (gap_x + gap_width)) > 0)
3647 gdk_draw_line (window, gc4,
3648 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
3649 gdk_draw_line (window, gc3,
3650 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
3651 gdk_draw_line (window, gc3,
3652 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
3660 gdk_gc_set_clip_rectangle (gc1, NULL);
3661 gdk_gc_set_clip_rectangle (gc2, NULL);
3662 gdk_gc_set_clip_rectangle (gc3, NULL);
3663 gdk_gc_set_clip_rectangle (gc4, NULL);
3668 gtk_default_draw_box_gap (GtkStyle *style,
3670 GtkStateType state_type,
3671 GtkShadowType shadow_type,
3674 const gchar *detail,
3679 GtkPositionType gap_side,
3688 gtk_style_apply_default_background (style, window,
3689 widget && gtk_widget_get_has_window (widget),
3690 state_type, area, x, y, width, height);
3692 sanitize_size (window, &width, &height);
3694 switch (shadow_type)
3696 case GTK_SHADOW_NONE:
3699 gc1 = style->dark_gc[state_type];
3700 gc2 = style->black_gc;
3701 gc3 = style->bg_gc[state_type];
3702 gc4 = style->light_gc[state_type];
3704 case GTK_SHADOW_ETCHED_IN:
3705 gc1 = style->dark_gc[state_type];
3706 gc2 = style->light_gc[state_type];
3707 gc3 = style->dark_gc[state_type];
3708 gc4 = style->light_gc[state_type];
3710 case GTK_SHADOW_OUT:
3711 gc1 = style->light_gc[state_type];
3712 gc2 = style->bg_gc[state_type];
3713 gc3 = style->dark_gc[state_type];
3714 gc4 = style->black_gc;
3716 case GTK_SHADOW_ETCHED_OUT:
3717 gc1 = style->light_gc[state_type];
3718 gc2 = style->dark_gc[state_type];
3719 gc3 = style->light_gc[state_type];
3720 gc4 = style->dark_gc[state_type];
3726 gdk_gc_set_clip_rectangle (gc1, area);
3727 gdk_gc_set_clip_rectangle (gc2, area);
3728 gdk_gc_set_clip_rectangle (gc3, area);
3729 gdk_gc_set_clip_rectangle (gc4, area);
3732 switch (shadow_type)
3734 case GTK_SHADOW_NONE:
3736 case GTK_SHADOW_OUT:
3737 case GTK_SHADOW_ETCHED_IN:
3738 case GTK_SHADOW_ETCHED_OUT:
3742 gdk_draw_line (window, gc1,
3743 x, y, x, y + height - 1);
3744 gdk_draw_line (window, gc2,
3745 x + 1, y, x + 1, y + height - 2);
3747 gdk_draw_line (window, gc3,
3748 x + 1, y + height - 2, x + width - 2, y + height - 2);
3749 gdk_draw_line (window, gc3,
3750 x + width - 2, y, x + width - 2, y + height - 2);
3751 gdk_draw_line (window, gc4,
3752 x, y + height - 1, x + width - 1, y + height - 1);
3753 gdk_draw_line (window, gc4,
3754 x + width - 1, y, x + width - 1, y + height - 1);
3757 gdk_draw_line (window, gc1,
3758 x, y, x + gap_x - 1, y);
3759 gdk_draw_line (window, gc2,
3760 x + 1, y + 1, x + gap_x - 1, y + 1);
3761 gdk_draw_line (window, gc2,
3762 x + gap_x, y, x + gap_x, y);
3764 if ((width - (gap_x + gap_width)) > 0)
3766 gdk_draw_line (window, gc1,
3767 x + gap_x + gap_width, y, x + width - 2, y);
3768 gdk_draw_line (window, gc2,
3769 x + gap_x + gap_width, y + 1, x + width - 2, y + 1);
3770 gdk_draw_line (window, gc2,
3771 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
3774 case GTK_POS_BOTTOM:
3775 gdk_draw_line (window, gc1,
3776 x, y, x + width - 1, y);
3777 gdk_draw_line (window, gc1,
3778 x, y, x, y + height - 1);
3779 gdk_draw_line (window, gc2,
3780 x + 1, y + 1, x + width - 2, y + 1);
3781 gdk_draw_line (window, gc2,
3782 x + 1, y + 1, x + 1, y + height - 1);
3784 gdk_draw_line (window, gc3,
3785 x + width - 2, y + 1, x + width - 2, y + height - 1);
3786 gdk_draw_line (window, gc4,
3787 x + width - 1, y, x + width - 1, y + height - 1);
3790 gdk_draw_line (window, gc4,
3791 x, y + height - 1, x + gap_x - 1, y + height - 1);
3792 gdk_draw_line (window, gc3,
3793 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
3794 gdk_draw_line (window, gc3,
3795 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
3797 if ((width - (gap_x + gap_width)) > 0)
3799 gdk_draw_line (window, gc4,
3800 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
3801 gdk_draw_line (window, gc3,
3802 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
3803 gdk_draw_line (window, gc3,
3804 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
3808 gdk_draw_line (window, gc1,
3809 x, y, x + width - 1, y);
3810 gdk_draw_line (window, gc2,
3811 x, y + 1, x + width - 2, y + 1);
3813 gdk_draw_line (window, gc3,
3814 x, y + height - 2, x + width - 2, y + height - 2);
3815 gdk_draw_line (window, gc3,
3816 x + width - 2, y + 1, x + width - 2, y + height - 2);
3817 gdk_draw_line (window, gc4,
3818 x, y + height - 1, x + width - 1, y + height - 1);
3819 gdk_draw_line (window, gc4,
3820 x + width - 1, y, x + width - 1, y + height - 1);
3823 gdk_draw_line (window, gc1,
3824 x, y, x, y + gap_x - 1);
3825 gdk_draw_line (window, gc2,
3826 x + 1, y + 1, x + 1, y + gap_x - 1);
3827 gdk_draw_line (window, gc2,
3828 x, y + gap_x, x, y + gap_x);
3830 if ((height - (gap_x + gap_width)) > 0)
3832 gdk_draw_line (window, gc1,
3833 x, y + gap_x + gap_width, x, y + height - 2);
3834 gdk_draw_line (window, gc2,
3835 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
3836 gdk_draw_line (window, gc2,
3837 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
3841 gdk_draw_line (window, gc1,
3842 x, y, x + width - 1, y);
3843 gdk_draw_line (window, gc1,
3844 x, y, x, y + height - 1);
3845 gdk_draw_line (window, gc2,
3846 x + 1, y + 1, x + width - 1, y + 1);
3847 gdk_draw_line (window, gc2,
3848 x + 1, y + 1, x + 1, y + height - 2);
3850 gdk_draw_line (window, gc3,
3851 x + 1, y + height - 2, x + width - 1, y + height - 2);
3852 gdk_draw_line (window, gc4,
3853 x, y + height - 1, x + width - 1, y + height - 1);
3856 gdk_draw_line (window, gc4,
3857 x + width - 1, y, x + width - 1, y + gap_x - 1);
3858 gdk_draw_line (window, gc3,
3859 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
3860 gdk_draw_line (window, gc3,
3861 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
3863 if ((height - (gap_x + gap_width)) > 0)
3865 gdk_draw_line (window, gc4,
3866 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
3867 gdk_draw_line (window, gc3,
3868 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
3869 gdk_draw_line (window, gc3,
3870 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
3878 gdk_gc_set_clip_rectangle (gc1, NULL);
3879 gdk_gc_set_clip_rectangle (gc2, NULL);
3880 gdk_gc_set_clip_rectangle (gc3, NULL);
3881 gdk_gc_set_clip_rectangle (gc4, NULL);
3886 gtk_default_draw_extension (GtkStyle *style,
3888 GtkStateType state_type,
3889 GtkShadowType shadow_type,
3892 const gchar *detail,
3897 GtkPositionType gap_side)
3904 gtk_style_apply_default_background (style, window,
3905 widget && gtk_widget_get_has_window (widget),
3906 GTK_STATE_NORMAL, area, x, y, width, height);
3908 sanitize_size (window, &width, &height);
3910 switch (shadow_type)
3912 case GTK_SHADOW_NONE:
3915 gc1 = style->dark_gc[state_type];
3916 gc2 = style->black_gc;
3917 gc3 = style->bg_gc[state_type];
3918 gc4 = style->light_gc[state_type];
3920 case GTK_SHADOW_ETCHED_IN:
3921 gc1 = style->dark_gc[state_type];
3922 gc2 = style->light_gc[state_type];
3923 gc3 = style->dark_gc[state_type];
3924 gc4 = style->light_gc[state_type];
3926 case GTK_SHADOW_OUT:
3927 gc1 = style->light_gc[state_type];
3928 gc2 = style->bg_gc[state_type];
3929 gc3 = style->dark_gc[state_type];
3930 gc4 = style->black_gc;
3932 case GTK_SHADOW_ETCHED_OUT:
3933 gc1 = style->light_gc[state_type];
3934 gc2 = style->dark_gc[state_type];
3935 gc3 = style->light_gc[state_type];
3936 gc4 = style->dark_gc[state_type];
3942 gdk_gc_set_clip_rectangle (gc1, area);
3943 gdk_gc_set_clip_rectangle (gc2, area);
3944 gdk_gc_set_clip_rectangle (gc3, area);
3945 gdk_gc_set_clip_rectangle (gc4, area);
3948 switch (shadow_type)
3950 case GTK_SHADOW_NONE:
3952 case GTK_SHADOW_OUT:
3953 case GTK_SHADOW_ETCHED_IN:
3954 case GTK_SHADOW_ETCHED_OUT:
3958 gtk_style_apply_default_background (style, window,
3959 widget && gtk_widget_get_has_window (widget),
3961 x + style->xthickness,
3963 width - (2 * style->xthickness),
3964 height - (style->ythickness));
3965 gdk_draw_line (window, gc1,
3966 x, y, x, y + height - 2);
3967 gdk_draw_line (window, gc2,
3968 x + 1, y, x + 1, y + height - 2);
3970 gdk_draw_line (window, gc3,
3971 x + 2, y + height - 2, x + width - 2, y + height - 2);
3972 gdk_draw_line (window, gc3,
3973 x + width - 2, y, x + width - 2, y + height - 2);
3974 gdk_draw_line (window, gc4,
3975 x + 1, y + height - 1, x + width - 2, y + height - 1);
3976 gdk_draw_line (window, gc4,
3977 x + width - 1, y, x + width - 1, y + height - 2);
3979 case GTK_POS_BOTTOM:
3980 gtk_style_apply_default_background (style, window,
3981 widget && gtk_widget_get_has_window (widget),
3983 x + style->xthickness,
3984 y + style->ythickness,
3985 width - (2 * style->xthickness),
3986 height - (style->ythickness));
3987 gdk_draw_line (window, gc1,
3988 x + 1, y, x + width - 2, y);
3989 gdk_draw_line (window, gc1,
3990 x, y + 1, x, y + height - 1);
3991 gdk_draw_line (window, gc2,
3992 x + 1, y + 1, x + width - 2, y + 1);
3993 gdk_draw_line (window, gc2,
3994 x + 1, y + 1, x + 1, y + height - 1);
3996 gdk_draw_line (window, gc3,
3997 x + width - 2, y + 2, x + width - 2, y + height - 1);
3998 gdk_draw_line (window, gc4,
3999 x + width - 1, y + 1, x + width - 1, y + height - 1);
4002 gtk_style_apply_default_background (style, window,
4003 widget && gtk_widget_get_has_window (widget),
4006 y + style->ythickness,
4007 width - (style->xthickness),
4008 height - (2 * style->ythickness));
4009 gdk_draw_line (window, gc1,
4010 x, y, x + width - 2, y);
4011 gdk_draw_line (window, gc2,
4012 x + 1, y + 1, x + width - 2, y + 1);
4014 gdk_draw_line (window, gc3,
4015 x, y + height - 2, x + width - 2, y + height - 2);
4016 gdk_draw_line (window, gc3,
4017 x + width - 2, y + 2, x + width - 2, y + height - 2);
4018 gdk_draw_line (window, gc4,
4019 x, y + height - 1, x + width - 2, y + height - 1);
4020 gdk_draw_line (window, gc4,
4021 x + width - 1, y + 1, x + width - 1, y + height - 2);
4024 gtk_style_apply_default_background (style, window,
4025 widget && gtk_widget_get_has_window (widget),
4027 x + style->xthickness,
4028 y + style->ythickness,
4029 width - (style->xthickness),
4030 height - (2 * style->ythickness));
4031 gdk_draw_line (window, gc1,
4032 x + 1, y, x + width - 1, y);
4033 gdk_draw_line (window, gc1,
4034 x, y + 1, x, y + height - 2);
4035 gdk_draw_line (window, gc2,
4036 x + 1, y + 1, x + width - 1, y + 1);
4037 gdk_draw_line (window, gc2,
4038 x + 1, y + 1, x + 1, y + height - 2);
4040 gdk_draw_line (window, gc3,
4041 x + 2, y + height - 2, x + width - 1, y + height - 2);
4042 gdk_draw_line (window, gc4,
4043 x + 1, y + height - 1, x + width - 1, y + height - 1);
4050 gdk_gc_set_clip_rectangle (gc1, NULL);
4051 gdk_gc_set_clip_rectangle (gc2, NULL);
4052 gdk_gc_set_clip_rectangle (gc3, NULL);
4053 gdk_gc_set_clip_rectangle (gc4, NULL);
4058 gtk_default_draw_focus (GtkStyle *style,
4060 GtkStateType state_type,
4063 const gchar *detail,
4070 gboolean free_dash_list = FALSE;
4071 gint line_width = 1;
4072 gint8 *dash_list = (gint8 *) "\1\1";
4076 gtk_widget_style_get (widget,
4077 "focus-line-width", &line_width,
4078 "focus-line-pattern", (gchar *)&dash_list,
4081 free_dash_list = TRUE;
4084 if (detail && !strcmp (detail, "add-mode"))
4089 dash_list = (gint8 *) "\4\4";
4090 free_dash_list = FALSE;
4093 sanitize_size (window, &width, &height);
4095 cr = gdk_cairo_create (window);
4097 if (detail && !strcmp (detail, "colorwheel_light"))
4098 cairo_set_source_rgb (cr, 0., 0., 0.);
4099 else if (detail && !strcmp (detail, "colorwheel_dark"))
4100 cairo_set_source_rgb (cr, 1., 1., 1.);
4102 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
4104 cairo_set_line_width (cr, line_width);
4108 gint n_dashes = strlen ((const gchar *) dash_list);
4109 gdouble *dashes = g_new (gdouble, n_dashes);
4110 gdouble total_length = 0;
4111 gdouble dash_offset;
4114 for (i = 0; i < n_dashes; i++)
4116 dashes[i] = dash_list[i];
4117 total_length += dash_list[i];
4120 /* The dash offset here aligns the pattern to integer pixels
4121 * by starting the dash at the right side of the left border
4122 * Negative dash offsets in cairo don't work
4123 * (https://bugs.freedesktop.org/show_bug.cgi?id=2729)
4125 dash_offset = - line_width / 2.;
4126 while (dash_offset < 0)
4127 dash_offset += total_length;
4129 cairo_set_dash (cr, dashes, n_dashes, dash_offset);
4135 gdk_cairo_rectangle (cr, area);
4139 cairo_rectangle (cr,
4140 x + line_width / 2.,
4141 y + line_width / 2.,
4143 height - line_width);
4152 gtk_default_draw_slider (GtkStyle *style,
4154 GtkStateType state_type,
4155 GtkShadowType shadow_type,
4158 const gchar *detail,
4163 GtkOrientation orientation)
4165 sanitize_size (window, &width, &height);
4167 gtk_paint_box (style, window, state_type, shadow_type,
4168 area, widget, detail, x, y, width, height);
4171 (strcmp ("hscale", detail) == 0 ||
4172 strcmp ("vscale", detail) == 0))
4174 if (orientation == GTK_ORIENTATION_HORIZONTAL)
4175 gtk_paint_vline (style, window, state_type, area, widget, detail,
4176 y + style->ythickness,
4177 y + height - style->ythickness - 1, x + width / 2);
4179 gtk_paint_hline (style, window, state_type, area, widget, detail,
4180 x + style->xthickness,
4181 x + width - style->xthickness - 1, y + height / 2);
4186 draw_dot (GdkWindow *window,
4193 size = CLAMP (size, 2, 3);
4197 gdk_draw_point (window, light_gc, x, y);
4198 gdk_draw_point (window, light_gc, x+1, y+1);
4202 gdk_draw_point (window, light_gc, x, y);
4203 gdk_draw_point (window, light_gc, x+1, y);
4204 gdk_draw_point (window, light_gc, x, y+1);
4205 gdk_draw_point (window, dark_gc, x+1, y+2);
4206 gdk_draw_point (window, dark_gc, x+2, y+1);
4207 gdk_draw_point (window, dark_gc, x+2, y+2);
4212 gtk_default_draw_handle (GtkStyle *style,
4214 GtkStateType state_type,
4215 GtkShadowType shadow_type,
4218 const gchar *detail,
4223 GtkOrientation orientation)
4226 gint xthick, ythick;
4227 GdkGC *light_gc, *dark_gc;
4228 GdkGC *free_me = NULL;
4233 sanitize_size (window, &width, &height);
4235 gtk_paint_box (style, window, state_type, shadow_type, area, widget,
4236 detail, x, y, width, height);
4239 if (detail && !strcmp (detail, "paned"))
4241 /* we want to ignore the shadow border in paned widgets */
4245 if (state_type == GTK_STATE_SELECTED && widget && !gtk_widget_has_focus (widget))
4247 GdkColor unfocused_light;
4249 _gtk_style_shade (&style->base[GTK_STATE_ACTIVE], &unfocused_light,
4252 light_gc = free_me = gdk_gc_new (window);
4253 gdk_gc_set_rgb_fg_color (light_gc, &unfocused_light);
4256 light_gc = style->light_gc[state_type];
4258 dark_gc = style->black_gc;
4262 xthick = style->xthickness;
4263 ythick = style->ythickness;
4265 light_gc = style->light_gc[state_type];
4266 dark_gc = style->dark_gc[state_type];
4269 rect.x = x + xthick;
4270 rect.y = y + ythick;
4271 rect.width = width - (xthick * 2);
4272 rect.height = height - (ythick * 2);
4275 intersect = gdk_rectangle_intersect (area, &rect, &dest);
4285 gdk_gc_set_clip_rectangle (light_gc, &dest);
4286 gdk_gc_set_clip_rectangle (dark_gc, &dest);
4288 if (detail && !strcmp (detail, "paned"))
4290 if (orientation == GTK_ORIENTATION_HORIZONTAL)
4291 for (xx = x + width/2 - 15; xx <= x + width/2 + 15; xx += 5)
4292 draw_dot (window, light_gc, dark_gc, xx, y + height/2 - 1, 3);
4294 for (yy = y + height/2 - 15; yy <= y + height/2 + 15; yy += 5)
4295 draw_dot (window, light_gc, dark_gc, x + width/2 - 1, yy, 3);
4299 for (yy = y + ythick; yy < (y + height - ythick); yy += 3)
4300 for (xx = x + xthick; xx < (x + width - xthick); xx += 6)
4302 draw_dot (window, light_gc, dark_gc, xx, yy, 2);
4303 draw_dot (window, light_gc, dark_gc, xx + 3, yy + 1, 2);
4307 gdk_gc_set_clip_rectangle (light_gc, NULL);
4308 gdk_gc_set_clip_rectangle (dark_gc, NULL);
4312 g_object_unref (free_me);
4316 gtk_default_draw_expander (GtkStyle *style,
4318 GtkStateType state_type,
4321 const gchar *detail,
4324 GtkExpanderStyle expander_style)
4326 #define DEFAULT_EXPANDER_SIZE 12
4330 double vertical_overshoot;
4333 double interp; /* interpolation factor for center position */
4334 double x_double_horz, y_double_horz;
4335 double x_double_vert, y_double_vert;
4336 double x_double, y_double;
4339 cairo_t *cr = gdk_cairo_create (window);
4343 gdk_cairo_rectangle (cr, area);
4348 gtk_widget_class_find_style_property (GTK_WIDGET_GET_CLASS (widget),
4351 gtk_widget_style_get (widget,
4352 "expander-size", &expander_size,
4356 expander_size = DEFAULT_EXPANDER_SIZE;
4358 line_width = MAX (1, expander_size/9);
4360 switch (expander_style)
4362 case GTK_EXPANDER_COLLAPSED:
4363 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 180 : 0;
4366 case GTK_EXPANDER_SEMI_COLLAPSED:
4367 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 150 : 30;
4370 case GTK_EXPANDER_SEMI_EXPANDED:
4371 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 120 : 60;
4374 case GTK_EXPANDER_EXPANDED:
4379 g_assert_not_reached ();
4382 /* Compute distance that the stroke extends beyonds the end
4383 * of the triangle we draw.
4385 vertical_overshoot = line_width / 2.0 * (1. / tan (G_PI / 8));
4387 /* For odd line widths, we end the vertical line of the triangle
4388 * at a half pixel, so we round differently.
4390 if (line_width % 2 == 1)
4391 vertical_overshoot = ceil (0.5 + vertical_overshoot) - 0.5;
4393 vertical_overshoot = ceil (vertical_overshoot);
4395 /* Adjust the size of the triangle we draw so that the entire stroke fits
4397 diameter = MAX (3, expander_size - 2 * vertical_overshoot);
4399 /* If the line width is odd, we want the diameter to be even,
4400 * and vice versa, so force the sum to be odd. This relationship
4401 * makes the point of the triangle look right.
4403 diameter -= (1 - (diameter + line_width) % 2);
4405 radius = diameter / 2.;
4407 /* Adjust the center so that the stroke is properly aligned with
4408 * the pixel grid. The center adjustment is different for the
4409 * horizontal and vertical orientations. For intermediate positions
4410 * we interpolate between the two.
4412 x_double_vert = floor (x - (radius + line_width) / 2.) + (radius + line_width) / 2.;
4413 y_double_vert = y - 0.5;
4415 x_double_horz = x - 0.5;
4416 y_double_horz = floor (y - (radius + line_width) / 2.) + (radius + line_width) / 2.;
4418 x_double = x_double_vert * (1 - interp) + x_double_horz * interp;
4419 y_double = y_double_vert * (1 - interp) + y_double_horz * interp;
4421 cairo_translate (cr, x_double, y_double);
4422 cairo_rotate (cr, degrees * G_PI / 180);
4424 cairo_move_to (cr, - radius / 2., - radius);
4425 cairo_line_to (cr, radius / 2., 0);
4426 cairo_line_to (cr, - radius / 2., radius);
4427 cairo_close_path (cr);
4429 cairo_set_line_width (cr, line_width);
4431 if (state_type == GTK_STATE_PRELIGHT)
4432 gdk_cairo_set_source_color (cr,
4433 &style->fg[GTK_STATE_PRELIGHT]);
4434 else if (state_type == GTK_STATE_ACTIVE)
4435 gdk_cairo_set_source_color (cr,
4436 &style->light[GTK_STATE_ACTIVE]);
4438 gdk_cairo_set_source_color (cr,
4439 &style->base[GTK_STATE_NORMAL]);
4441 cairo_fill_preserve (cr);
4443 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
4449 typedef struct _ByteRange ByteRange;
4458 range_new (guint start,
4461 ByteRange *br = g_new (ByteRange, 1);
4470 get_insensitive_layout (GdkDrawable *drawable,
4471 PangoLayout *layout)
4473 GSList *embossed_ranges = NULL;
4474 GSList *stippled_ranges = NULL;
4475 PangoLayoutIter *iter;
4476 GSList *tmp_list = NULL;
4477 PangoLayout *new_layout;
4478 PangoAttrList *attrs;
4479 GdkBitmap *stipple = NULL;
4481 iter = pango_layout_get_iter (layout);
4485 PangoLayoutRun *run;
4486 PangoAttribute *attr;
4487 gboolean need_stipple = FALSE;
4490 run = pango_layout_iter_get_run_readonly (iter);
4494 tmp_list = run->item->analysis.extra_attrs;
4496 while (tmp_list != NULL)
4498 attr = tmp_list->data;
4499 switch (attr->klass->type)
4501 case PANGO_ATTR_FOREGROUND:
4502 case PANGO_ATTR_BACKGROUND:
4503 need_stipple = TRUE;
4513 tmp_list = g_slist_next (tmp_list);
4516 br = range_new (run->item->offset, run->item->offset + run->item->length);
4519 stippled_ranges = g_slist_prepend (stippled_ranges, br);
4521 embossed_ranges = g_slist_prepend (embossed_ranges, br);
4524 while (pango_layout_iter_next_run (iter));
4526 pango_layout_iter_free (iter);
4528 new_layout = pango_layout_copy (layout);
4530 attrs = pango_layout_get_attributes (new_layout);
4534 /* Create attr list if there wasn't one */
4535 attrs = pango_attr_list_new ();
4536 pango_layout_set_attributes (new_layout, attrs);
4537 pango_attr_list_unref (attrs);
4540 tmp_list = embossed_ranges;
4541 while (tmp_list != NULL)
4543 PangoAttribute *attr;
4544 ByteRange *br = tmp_list->data;
4546 attr = gdk_pango_attr_embossed_new (TRUE);
4548 attr->start_index = br->start;
4549 attr->end_index = br->end;
4551 pango_attr_list_change (attrs, attr);
4555 tmp_list = g_slist_next (tmp_list);
4558 g_slist_free (embossed_ranges);
4560 tmp_list = stippled_ranges;
4561 while (tmp_list != NULL)
4563 PangoAttribute *attr;
4564 ByteRange *br = tmp_list->data;
4566 if (stipple == NULL)
4568 #define gray50_width 2
4569 #define gray50_height 2
4570 static const char gray50_bits[] = {
4574 stipple = gdk_bitmap_create_from_data (drawable,
4575 gray50_bits, gray50_width,
4579 attr = gdk_pango_attr_stipple_new (stipple);
4581 attr->start_index = br->start;
4582 attr->end_index = br->end;
4584 pango_attr_list_change (attrs, attr);
4588 tmp_list = g_slist_next (tmp_list);
4591 g_slist_free (stippled_ranges);
4594 g_object_unref (stipple);
4600 gtk_default_draw_layout (GtkStyle *style,
4602 GtkStateType state_type,
4606 const gchar *detail,
4609 PangoLayout *layout)
4613 gc = use_text ? style->text_gc[state_type] : style->fg_gc[state_type];
4616 gdk_gc_set_clip_rectangle (gc, area);
4618 if (state_type == GTK_STATE_INSENSITIVE)
4622 ins = get_insensitive_layout (window, layout);
4624 gdk_draw_layout (window, gc, x, y, ins);
4626 g_object_unref (ins);
4630 gdk_draw_layout (window, gc, x, y, layout);
4634 gdk_gc_set_clip_rectangle (gc, NULL);
4638 gtk_default_draw_resize_grip (GtkStyle *style,
4640 GtkStateType state_type,
4643 const gchar *detail,
4655 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
4656 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
4657 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
4663 case GDK_WINDOW_EDGE_NORTH_WEST:
4664 /* make it square */
4667 else if (height < width)
4671 case GDK_WINDOW_EDGE_NORTH:
4675 case GDK_WINDOW_EDGE_NORTH_EAST:
4676 /* make it square, aligning to top right */
4679 else if (height < width)
4681 x += (width - height);
4686 case GDK_WINDOW_EDGE_WEST:
4690 case GDK_WINDOW_EDGE_EAST:
4691 /* aligning to right */
4694 x += (width - height);
4698 case GDK_WINDOW_EDGE_SOUTH_WEST:
4699 /* make it square, aligning to bottom left */
4702 y += (height - width);
4705 else if (height < width)
4709 case GDK_WINDOW_EDGE_SOUTH:
4710 /* align to bottom */
4713 y += (height - width);
4717 case GDK_WINDOW_EDGE_SOUTH_EAST:
4718 /* make it square, aligning to bottom right */
4721 y += (height - width);
4724 else if (height < width)
4726 x += (width - height);
4732 g_assert_not_reached ();
4734 /* Clear background */
4736 for (i = 0; i < 4; i++)
4740 points[j].x = (i == 0 || i == 3) ? x : x + width;
4741 points[j].y = (i < 2) ? y : y + height;
4746 gdk_draw_polygon (window, style->bg_gc[state_type], TRUE,
4747 points, skip < 0 ? 4 : 3);
4751 case GDK_WINDOW_EDGE_WEST:
4752 case GDK_WINDOW_EDGE_EAST:
4758 while (xi < x + width)
4760 gdk_draw_line (window,
4761 style->light_gc[state_type],
4766 gdk_draw_line (window,
4767 style->dark_gc[state_type],
4775 case GDK_WINDOW_EDGE_NORTH:
4776 case GDK_WINDOW_EDGE_SOUTH:
4782 while (yi < y + height)
4784 gdk_draw_line (window,
4785 style->light_gc[state_type],
4790 gdk_draw_line (window,
4791 style->dark_gc[state_type],
4799 case GDK_WINDOW_EDGE_NORTH_WEST:
4808 gdk_draw_line (window,
4809 style->dark_gc[state_type],
4816 gdk_draw_line (window,
4817 style->dark_gc[state_type],
4824 gdk_draw_line (window,
4825 style->light_gc[state_type],
4835 case GDK_WINDOW_EDGE_NORTH_EAST:
4842 while (xi < (x + width - 3))
4844 gdk_draw_line (window,
4845 style->light_gc[state_type],
4852 gdk_draw_line (window,
4853 style->dark_gc[state_type],
4860 gdk_draw_line (window,
4861 style->dark_gc[state_type],
4870 case GDK_WINDOW_EDGE_SOUTH_WEST:
4879 gdk_draw_line (window,
4880 style->dark_gc[state_type],
4887 gdk_draw_line (window,
4888 style->dark_gc[state_type],
4895 gdk_draw_line (window,
4896 style->light_gc[state_type],
4906 case GDK_WINDOW_EDGE_SOUTH_EAST:
4913 while (xi < (x + width - 3))
4915 gdk_draw_line (window,
4916 style->light_gc[state_type],
4923 gdk_draw_line (window,
4924 style->dark_gc[state_type],
4931 gdk_draw_line (window,
4932 style->dark_gc[state_type],
4942 g_assert_not_reached ();
4948 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
4949 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
4950 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
4955 gtk_default_draw_spinner (GtkStyle *style,
4957 GtkStateType state_type,
4960 const gchar *detail,
4976 gtk_style_get (style, GTK_TYPE_SPINNER,
4977 "num-steps", &num_steps,
4979 real_step = step % num_steps;
4981 /* get cairo context */
4982 cr = gdk_cairo_create (window);
4984 /* set a clip region for the expose event */
4985 cairo_rectangle (cr, x, y, width, height);
4988 cairo_translate (cr, x, y);
4990 /* draw clip region */
4991 cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
4993 color = &style->fg[state_type];
4996 radius = MIN (width / 2, height / 2);
4997 half = num_steps / 2;
4999 for (i = 0; i < num_steps; i++)
5001 gint inset = 0.7 * radius;
5003 /* transparency is a function of time and intial value */
5004 gdouble t = (gdouble) ((i + num_steps - real_step)
5005 % num_steps) / num_steps;
5009 cairo_set_source_rgba (cr,
5010 color->red / 65535.,
5011 color->green / 65535.,
5012 color->blue / 65535.,
5015 cairo_set_line_width (cr, 2.0);
5017 dx + (radius - inset) * cos (i * G_PI / half),
5018 dy + (radius - inset) * sin (i * G_PI / half));
5020 dx + radius * cos (i * G_PI / half),
5021 dy + radius * sin (i * G_PI / half));
5032 _gtk_style_shade (const GdkColor *a,
5040 red = (gdouble) a->red / 65535.0;
5041 green = (gdouble) a->green / 65535.0;
5042 blue = (gdouble) a->blue / 65535.0;
5044 rgb_to_hls (&red, &green, &blue);
5049 else if (green < 0.0)
5055 else if (blue < 0.0)
5058 hls_to_rgb (&red, &green, &blue);
5060 b->red = red * 65535.0;
5061 b->green = green * 65535.0;
5062 b->blue = blue * 65535.0;
5066 rgb_to_hls (gdouble *r,
5107 l = (max + min) / 2;
5114 s = (max - min) / (max + min);
5116 s = (max - min) / (2 - max - min);
5120 h = (green - blue) / delta;
5121 else if (green == max)
5122 h = 2 + (blue - red) / delta;
5123 else if (blue == max)
5124 h = 4 + (red - green) / delta;
5137 hls_to_rgb (gdouble *h,
5150 if (lightness <= 0.5)
5151 m2 = lightness * (1 + saturation);
5153 m2 = lightness + saturation - lightness * saturation;
5154 m1 = 2 * lightness - m2;
5156 if (saturation == 0)
5171 r = m1 + (m2 - m1) * hue / 60;
5175 r = m1 + (m2 - m1) * (240 - hue) / 60;
5186 g = m1 + (m2 - m1) * hue / 60;
5190 g = m1 + (m2 - m1) * (240 - hue) / 60;
5201 b = m1 + (m2 - m1) * hue / 60;
5205 b = m1 + (m2 - m1) * (240 - hue) / 60;
5218 * @style: a #GtkStyle
5219 * @window: a #GdkWindow
5220 * @state_type: a state
5221 * @area: (allow-none): rectangle to which the output is clipped, or %NULL if the
5222 * output should not be clipped
5223 * @widget: (allow-none): the widget
5224 * @detail: (allow-none): a style detail
5225 * @x1: the starting x coordinate
5226 * @x2: the ending x coordinate
5227 * @y: the y coordinate
5229 * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @window
5230 * using the given style and state.
5233 gtk_paint_hline (GtkStyle *style,
5235 GtkStateType state_type,
5236 const GdkRectangle *area,
5238 const gchar *detail,
5243 g_return_if_fail (GTK_IS_STYLE (style));
5244 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
5245 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5247 GTK_STYLE_GET_CLASS (style)->draw_hline (style, window, state_type,
5248 (GdkRectangle *) area, widget, detail,
5254 * @style: a #GtkStyle
5255 * @window: a #GdkWindow
5256 * @state_type: a state
5257 * @area: (allow-none): rectangle to which the output is clipped, or %NULL if the
5258 * output should not be clipped
5259 * @widget: (allow-none): the widget
5260 * @detail: (allow-none): a style detail
5261 * @y1_: the starting y coordinate
5262 * @y2_: the ending y coordinate
5263 * @x: the x coordinate
5265 * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @window
5266 * using the given style and state.
5269 gtk_paint_vline (GtkStyle *style,
5271 GtkStateType state_type,
5272 const GdkRectangle *area,
5274 const gchar *detail,
5279 g_return_if_fail (GTK_IS_STYLE (style));
5280 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
5281 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5283 GTK_STYLE_GET_CLASS (style)->draw_vline (style, window, state_type,
5284 (GdkRectangle *) area, widget, detail,
5290 * @style: a #GtkStyle
5291 * @window: a #GdkWindow
5292 * @state_type: a state
5293 * @shadow_type: type of shadow to draw
5294 * @area: (allow-none): clip rectangle or %NULL if the
5295 * output should not be clipped
5296 * @widget: (allow-none): the widget
5297 * @detail: (allow-none): a style detail
5298 * @x: x origin of the rectangle
5299 * @y: y origin of the rectangle
5300 * @width: width of the rectangle
5301 * @height: width of the rectangle
5303 * Draws a shadow around the given rectangle in @window
5304 * using the given style and state and shadow type.
5307 gtk_paint_shadow (GtkStyle *style,
5309 GtkStateType state_type,
5310 GtkShadowType shadow_type,
5311 const GdkRectangle *area,
5313 const gchar *detail,
5319 g_return_if_fail (GTK_IS_STYLE (style));
5320 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
5321 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5323 GTK_STYLE_GET_CLASS (style)->draw_shadow (style, window, state_type, shadow_type,
5324 (GdkRectangle *) area, widget, detail,
5325 x, y, width, height);
5329 * gtk_paint_polygon:
5330 * @style: a #GtkStyle
5331 * @window: a #GdkWindow
5332 * @state_type: a state
5333 * @shadow_type: type of shadow to draw
5334 * @area: (allow-none): clip rectangle, or %NULL if the
5335 * output should not be clipped
5336 * @widget: (allow-none): the widget
5337 * @detail: (allow-none): a style detail
5338 * @points: an array of #GdkPoint<!-- -->s
5339 * @n_points: length of @points
5340 * @fill: %TRUE if the polygon should be filled
5342 * Draws a polygon on @window with the given parameters.
5345 gtk_paint_polygon (GtkStyle *style,
5347 GtkStateType state_type,
5348 GtkShadowType shadow_type,
5349 const GdkRectangle *area,
5351 const gchar *detail,
5352 const GdkPoint *points,
5356 g_return_if_fail (GTK_IS_STYLE (style));
5357 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_polygon != NULL);
5358 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5360 GTK_STYLE_GET_CLASS (style)->draw_polygon (style, window, state_type, shadow_type,
5361 (GdkRectangle *) area, widget, detail,
5362 (GdkPoint *) points, n_points, fill);
5367 * @style: a #GtkStyle
5368 * @window: a #GdkWindow
5369 * @state_type: a state
5370 * @shadow_type: the type of shadow to draw
5371 * @area: (allow-none): clip rectangle, or %NULL if the
5372 * output should not be clipped
5373 * @widget: (allow-none): the widget
5374 * @detail: (allow-none): a style detail
5375 * @arrow_type: the type of arrow to draw
5376 * @fill: %TRUE if the arrow tip should be filled
5377 * @x: x origin of the rectangle to draw the arrow in
5378 * @y: y origin of the rectangle to draw the arrow in
5379 * @width: width of the rectangle to draw the arrow in
5380 * @height: height of the rectangle to draw the arrow in
5382 * Draws an arrow in the given rectangle on @window using the given
5383 * parameters. @arrow_type determines the direction of the arrow.
5386 gtk_paint_arrow (GtkStyle *style,
5388 GtkStateType state_type,
5389 GtkShadowType shadow_type,
5390 const GdkRectangle *area,
5392 const gchar *detail,
5393 GtkArrowType arrow_type,
5400 g_return_if_fail (GTK_IS_STYLE (style));
5401 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
5402 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5404 GTK_STYLE_GET_CLASS (style)->draw_arrow (style, window, state_type, shadow_type,
5405 (GdkRectangle *) area, widget, detail,
5406 arrow_type, fill, x, y, width, height);
5410 * gtk_paint_diamond:
5411 * @style: a #GtkStyle
5412 * @window: a #GdkWindow
5413 * @state_type: a state
5414 * @shadow_type: the type of shadow to draw
5415 * @area: (allow-none): clip rectangle, or %NULL if the
5416 * output should not be clipped
5417 * @widget: (allow-none): the widget
5418 * @detail: (allow-none): a style detail
5419 * @x: x origin of the rectangle to draw the diamond in
5420 * @y: y origin of the rectangle to draw the diamond in
5421 * @width: width of the rectangle to draw the diamond in
5422 * @height: height of the rectangle to draw the diamond in
5424 * Draws a diamond in the given rectangle on @window using the given
5428 gtk_paint_diamond (GtkStyle *style,
5430 GtkStateType state_type,
5431 GtkShadowType shadow_type,
5432 const GdkRectangle *area,
5434 const gchar *detail,
5440 g_return_if_fail (GTK_IS_STYLE (style));
5441 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
5442 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5444 GTK_STYLE_GET_CLASS (style)->draw_diamond (style, window, state_type, shadow_type,
5445 (GdkRectangle *) area, widget, detail,
5446 x, y, width, height);
5451 * @style: a #GtkStyle
5452 * @window: a #GdkWindow
5453 * @state_type: a state
5454 * @shadow_type: the type of shadow to draw
5455 * @area: (allow-none): clip rectangle, or %NULL if the
5456 * output should not be clipped
5457 * @widget: (allow-none): the widget
5458 * @detail: (allow-none): a style detail
5459 * @x: x origin of the box
5460 * @y: y origin of the box
5461 * @width: the width of the box
5462 * @height: the height of the box
5464 * Draws a box on @window with the given parameters.
5467 gtk_paint_box (GtkStyle *style,
5469 GtkStateType state_type,
5470 GtkShadowType shadow_type,
5471 const GdkRectangle *area,
5473 const gchar *detail,
5479 g_return_if_fail (GTK_IS_STYLE (style));
5480 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
5481 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5483 GTK_STYLE_GET_CLASS (style)->draw_box (style, window, state_type, shadow_type,
5484 (GdkRectangle *) area, widget, detail,
5485 x, y, width, height);
5489 * gtk_paint_flat_box:
5490 * @style: a #GtkStyle
5491 * @window: a #GdkWindow
5492 * @state_type: a state
5493 * @shadow_type: the type of shadow to draw
5494 * @area: (allow-none): clip rectangle, or %NULL if the
5495 * output should not be clipped
5496 * @widget: (allow-none): the widget
5497 * @detail: (allow-none): a style detail
5498 * @x: x origin of the box
5499 * @y: y origin of the box
5500 * @width: the width of the box
5501 * @height: the height of the box
5503 * Draws a flat box on @window with the given parameters.
5506 gtk_paint_flat_box (GtkStyle *style,
5508 GtkStateType state_type,
5509 GtkShadowType shadow_type,
5510 const GdkRectangle *area,
5512 const gchar *detail,
5518 g_return_if_fail (GTK_IS_STYLE (style));
5519 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
5520 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5522 GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, window, state_type, shadow_type,
5523 (GdkRectangle *) area, widget, detail,
5524 x, y, width, height);
5529 * @style: a #GtkStyle
5530 * @window: a #GdkWindow
5531 * @state_type: a state
5532 * @shadow_type: the type of shadow to draw
5533 * @area: (allow-none): clip rectangle, or %NULL if the
5534 * output should not be clipped
5535 * @widget: (allow-none): the widget
5536 * @detail: (allow-none): a style detail
5537 * @x: x origin of the rectangle to draw the check in
5538 * @y: y origin of the rectangle to draw the check in
5539 * @width: the width of the rectangle to draw the check in
5540 * @height: the height of the rectangle to draw the check in
5542 * Draws a check button indicator in the given rectangle on @window with
5543 * the given parameters.
5546 gtk_paint_check (GtkStyle *style,
5548 GtkStateType state_type,
5549 GtkShadowType shadow_type,
5550 const GdkRectangle *area,
5552 const gchar *detail,
5558 g_return_if_fail (GTK_IS_STYLE (style));
5559 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
5560 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5562 GTK_STYLE_GET_CLASS (style)->draw_check (style, window, state_type, shadow_type,
5563 (GdkRectangle *) area, widget, detail,
5564 x, y, width, height);
5569 * @style: a #GtkStyle
5570 * @window: a #GdkWindow
5571 * @state_type: a state
5572 * @shadow_type: the type of shadow to draw
5573 * @area: (allow-none): clip rectangle, or %NULL if the
5574 * output should not be clipped
5575 * @widget: (allow-none): the widget
5576 * @detail: (allow-none): a style detail
5577 * @x: x origin of the rectangle to draw the option in
5578 * @y: y origin of the rectangle to draw the option in
5579 * @width: the width of the rectangle to draw the option in
5580 * @height: the height of the rectangle to draw the option in
5582 * Draws a radio button indicator in the given rectangle on @window with
5583 * the given parameters.
5586 gtk_paint_option (GtkStyle *style,
5588 GtkStateType state_type,
5589 GtkShadowType shadow_type,
5590 const GdkRectangle *area,
5592 const gchar *detail,
5598 g_return_if_fail (GTK_IS_STYLE (style));
5599 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
5600 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5602 GTK_STYLE_GET_CLASS (style)->draw_option (style, window, state_type, shadow_type,
5603 (GdkRectangle *) area, widget, detail,
5604 x, y, width, height);
5609 * @style: a #GtkStyle
5610 * @window: a #GdkWindow
5611 * @state_type: a state
5612 * @shadow_type: the type of shadow to draw
5613 * @area: (allow-none): clip rectangle, or %NULL if the
5614 * output should not be clipped
5615 * @widget: (allow-none): the widget
5616 * @detail: (allow-none): a style detail
5617 * @x: x origin of the rectangle to draw the tab in
5618 * @y: y origin of the rectangle to draw the tab in
5619 * @width: the width of the rectangle to draw the tab in
5620 * @height: the height of the rectangle to draw the tab in
5622 * Draws an option menu tab (i.e. the up and down pointing arrows)
5623 * in the given rectangle on @window using the given parameters.
5626 gtk_paint_tab (GtkStyle *style,
5628 GtkStateType state_type,
5629 GtkShadowType shadow_type,
5630 const GdkRectangle *area,
5632 const gchar *detail,
5638 g_return_if_fail (GTK_IS_STYLE (style));
5639 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
5640 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5642 GTK_STYLE_GET_CLASS (style)->draw_tab (style, window, state_type, shadow_type,
5643 (GdkRectangle *) area, widget, detail,
5644 x, y, width, height);
5648 * gtk_paint_shadow_gap:
5649 * @style: a #GtkStyle
5650 * @window: a #GdkWindow
5651 * @state_type: a state
5652 * @shadow_type: type of shadow to draw
5653 * @area: (allow-none): clip rectangle, or %NULL if the
5654 * output should not be clipped
5655 * @widget: (allow-none): the widget
5656 * @detail: (allow-none): a style detail
5657 * @x: x origin of the rectangle
5658 * @y: y origin of the rectangle
5659 * @width: width of the rectangle
5660 * @height: width of the rectangle
5661 * @gap_side: side in which to leave the gap
5662 * @gap_x: starting position of the gap
5663 * @gap_width: width of the gap
5665 * Draws a shadow around the given rectangle in @window
5666 * using the given style and state and shadow type, leaving a
5670 gtk_paint_shadow_gap (GtkStyle *style,
5672 GtkStateType state_type,
5673 GtkShadowType shadow_type,
5674 const GdkRectangle *area,
5676 const gchar *detail,
5681 GtkPositionType gap_side,
5685 g_return_if_fail (GTK_IS_STYLE (style));
5686 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
5687 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5689 GTK_STYLE_GET_CLASS (style)->draw_shadow_gap (style, window, state_type, shadow_type,
5690 (GdkRectangle *) area, widget, detail,
5691 x, y, width, height, gap_side, gap_x, gap_width);
5696 * gtk_paint_box_gap:
5697 * @style: a #GtkStyle
5698 * @window: a #GdkWindow
5699 * @state_type: a state
5700 * @shadow_type: type of shadow to draw
5701 * @area: (allow-none): clip rectangle, or %NULL if the
5702 * output should not be clipped
5703 * @widget: (allow-none): the widget
5704 * @detail: (allow-none): a style detail
5705 * @x: x origin of the rectangle
5706 * @y: y origin of the rectangle
5707 * @width: width of the rectangle
5708 * @height: width of the rectangle
5709 * @gap_side: side in which to leave the gap
5710 * @gap_x: starting position of the gap
5711 * @gap_width: width of the gap
5713 * Draws a box in @window using the given style and state and shadow type,
5714 * leaving a gap in one side.
5717 gtk_paint_box_gap (GtkStyle *style,
5719 GtkStateType state_type,
5720 GtkShadowType shadow_type,
5721 const GdkRectangle *area,
5723 const gchar *detail,
5728 GtkPositionType gap_side,
5732 g_return_if_fail (GTK_IS_STYLE (style));
5733 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
5734 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5736 GTK_STYLE_GET_CLASS (style)->draw_box_gap (style, window, state_type, shadow_type,
5737 (GdkRectangle *) area, widget, detail,
5738 x, y, width, height, gap_side, gap_x, gap_width);
5742 * gtk_paint_extension:
5743 * @style: a #GtkStyle
5744 * @window: a #GdkWindow
5745 * @state_type: a state
5746 * @shadow_type: type of shadow to draw
5747 * @area: (allow-none): clip rectangle, or %NULL if the
5748 * output should not be clipped
5749 * @widget: (allow-none): the widget
5750 * @detail: (allow-none): a style detail
5751 * @x: x origin of the extension
5752 * @y: y origin of the extension
5753 * @width: width of the extension
5754 * @height: width of the extension
5755 * @gap_side: the side on to which the extension is attached
5757 * Draws an extension, i.e. a notebook tab.
5760 gtk_paint_extension (GtkStyle *style,
5762 GtkStateType state_type,
5763 GtkShadowType shadow_type,
5764 const GdkRectangle *area,
5766 const gchar *detail,
5771 GtkPositionType gap_side)
5773 g_return_if_fail (GTK_IS_STYLE (style));
5774 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
5775 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5777 GTK_STYLE_GET_CLASS (style)->draw_extension (style, window, state_type, shadow_type,
5778 (GdkRectangle *) area, widget, detail,
5779 x, y, width, height, gap_side);
5784 * @style: a #GtkStyle
5785 * @window: a #GdkWindow
5786 * @state_type: a state
5787 * @area: (allow-none): clip rectangle, or %NULL if the
5788 * output should not be clipped
5789 * @widget: (allow-none): the widget
5790 * @detail: (allow-none): a style detail
5791 * @x: the x origin of the rectangle around which to draw a focus indicator
5792 * @y: the y origin of the rectangle around which to draw a focus indicator
5793 * @width: the width of the rectangle around which to draw a focus indicator
5794 * @height: the height of the rectangle around which to draw a focus indicator
5796 * Draws a focus indicator around the given rectangle on @window using the
5800 gtk_paint_focus (GtkStyle *style,
5802 GtkStateType state_type,
5803 const GdkRectangle *area,
5805 const gchar *detail,
5811 g_return_if_fail (GTK_IS_STYLE (style));
5812 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
5813 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5815 GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, state_type,
5816 (GdkRectangle *) area, widget, detail,
5817 x, y, width, height);
5822 * @style: a #GtkStyle
5823 * @window: a #GdkWindow
5824 * @state_type: a state
5825 * @shadow_type: a shadow
5826 * @area: (allow-none): clip rectangle, or %NULL if the
5827 * output should not be clipped
5828 * @widget: (allow-none): the widget
5829 * @detail: (allow-none): a style detail
5830 * @x: the x origin of the rectangle in which to draw a slider
5831 * @y: the y origin of the rectangle in which to draw a slider
5832 * @width: the width of the rectangle in which to draw a slider
5833 * @height: the height of the rectangle in which to draw a slider
5834 * @orientation: the orientation to be used
5836 * Draws a slider in the given rectangle on @window using the
5837 * given style and orientation.
5840 gtk_paint_slider (GtkStyle *style,
5842 GtkStateType state_type,
5843 GtkShadowType shadow_type,
5844 const GdkRectangle *area,
5846 const gchar *detail,
5851 GtkOrientation orientation)
5853 g_return_if_fail (GTK_IS_STYLE (style));
5854 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
5855 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5857 GTK_STYLE_GET_CLASS (style)->draw_slider (style, window, state_type, shadow_type,
5858 (GdkRectangle *) area, widget, detail,
5859 x, y, width, height, orientation);
5864 * @style: a #GtkStyle
5865 * @window: a #GdkWindow
5866 * @state_type: a state
5867 * @shadow_type: type of shadow to draw
5868 * @area: (allow-none): clip rectangle, or %NULL if the
5869 * output should not be clipped
5870 * @widget: (allow-none): the widget
5871 * @detail: (allow-none): a style detail
5872 * @x: x origin of the handle
5873 * @y: y origin of the handle
5874 * @width: with of the handle
5875 * @height: height of the handle
5876 * @orientation: the orientation of the handle
5878 * Draws a handle as used in #GtkHandleBox and #GtkPaned.
5881 gtk_paint_handle (GtkStyle *style,
5883 GtkStateType state_type,
5884 GtkShadowType shadow_type,
5885 const GdkRectangle *area,
5887 const gchar *detail,
5892 GtkOrientation orientation)
5894 g_return_if_fail (GTK_IS_STYLE (style));
5895 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
5896 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5898 GTK_STYLE_GET_CLASS (style)->draw_handle (style, window, state_type, shadow_type,
5899 (GdkRectangle *) area, widget, detail,
5900 x, y, width, height, orientation);
5904 * gtk_paint_expander:
5905 * @style: a #GtkStyle
5906 * @window: a #GdkWindow
5907 * @state_type: a state
5908 * @area: (allow-none): clip rectangle, or %NULL if the
5909 * output should not be clipped
5910 * @widget: (allow-none): the widget
5911 * @detail: (allow-none): a style detail
5912 * @x: the x position to draw the expander at
5913 * @y: the y position to draw the expander at
5914 * @expander_style: the style to draw the expander in; determines
5915 * whether the expander is collapsed, expanded, or in an
5916 * intermediate state.
5918 * Draws an expander as used in #GtkTreeView. @x and @y specify the
5919 * center the expander. The size of the expander is determined by the
5920 * "expander-size" style property of @widget. (If widget is not
5921 * specified or doesn't have an "expander-size" property, an
5922 * unspecified default size will be used, since the caller doesn't
5923 * have sufficient information to position the expander, this is
5924 * likely not useful.) The expander is expander_size pixels tall
5925 * in the collapsed position and expander_size pixels wide in the
5926 * expanded position.
5929 gtk_paint_expander (GtkStyle *style,
5931 GtkStateType state_type,
5932 const GdkRectangle *area,
5934 const gchar *detail,
5937 GtkExpanderStyle expander_style)
5939 g_return_if_fail (GTK_IS_STYLE (style));
5940 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
5941 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5943 GTK_STYLE_GET_CLASS (style)->draw_expander (style, window, state_type,
5944 (GdkRectangle *) area, widget, detail,
5945 x, y, expander_style);
5950 * @style: a #GtkStyle
5951 * @window: a #GdkWindow
5952 * @state_type: a state
5953 * @use_text: whether to use the text or foreground
5954 * graphics context of @style
5955 * @area: (allow-none): clip rectangle, or %NULL if the
5956 * output should not be clipped
5957 * @widget: (allow-none): the widget
5958 * @detail: (allow-none): a style detail
5961 * @layout: the layout to draw
5963 * Draws a layout on @window using the given parameters.
5966 gtk_paint_layout (GtkStyle *style,
5968 GtkStateType state_type,
5970 const GdkRectangle *area,
5972 const gchar *detail,
5975 PangoLayout *layout)
5977 g_return_if_fail (GTK_IS_STYLE (style));
5978 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
5979 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5981 GTK_STYLE_GET_CLASS (style)->draw_layout (style, window, state_type, use_text,
5982 (GdkRectangle *) area, widget, detail,
5987 * gtk_paint_resize_grip:
5988 * @style: a #GtkStyle
5989 * @window: a #GdkWindow
5990 * @state_type: a state
5991 * @area: (allow-none): clip rectangle, or %NULL if the
5992 * output should not be clipped
5993 * @widget: (allow-none): the widget
5994 * @detail: (allow-none): a style detail
5995 * @edge: the edge in which to draw the resize grip
5996 * @x: the x origin of the rectangle in which to draw the resize grip
5997 * @y: the y origin of the rectangle in which to draw the resize grip
5998 * @width: the width of the rectangle in which to draw the resize grip
5999 * @height: the height of the rectangle in which to draw the resize grip
6001 * Draws a resize grip in the given rectangle on @window using the given
6005 gtk_paint_resize_grip (GtkStyle *style,
6007 GtkStateType state_type,
6008 const GdkRectangle *area,
6010 const gchar *detail,
6018 g_return_if_fail (GTK_IS_STYLE (style));
6019 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
6020 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6022 GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, window, state_type,
6023 (GdkRectangle *) area, widget, detail,
6024 edge, x, y, width, height);
6028 * gtk_paint_spinner:
6029 * @style: a #GtkStyle
6030 * @window: a #GdkWindow
6031 * @state_type: a state
6032 * @area: (allow-none): clip rectangle, or %NULL if the
6033 * output should not be clipped
6034 * @widget: (allow-none): the widget (may be %NULL)
6035 * @detail: (allow-none): a style detail (may be %NULL)
6036 * @step: the nth step, a value between 0 and #GtkSpinner:num-steps
6037 * @x: the x origin of the rectangle in which to draw the spinner
6038 * @y: the y origin of the rectangle in which to draw the spinner
6039 * @width: the width of the rectangle in which to draw the spinner
6040 * @height: the height of the rectangle in which to draw the spinner
6042 * Draws a spinner on @window using the given parameters.
6047 gtk_paint_spinner (GtkStyle *style,
6049 GtkStateType state_type,
6050 const GdkRectangle *area,
6052 const gchar *detail,
6059 g_return_if_fail (GTK_IS_STYLE (style));
6060 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_spinner != NULL);
6061 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6063 GTK_STYLE_GET_CLASS (style)->draw_spinner (style, window, state_type,
6064 (GdkRectangle *)area, widget, detail,
6065 step, x, y, width, height);
6071 * Allocates a new #GtkBorder structure and initializes its elements to zero.
6073 * Returns: a new empty #GtkBorder. The newly allocated #GtkBorder should be
6074 * freed with gtk_border_free()
6079 gtk_border_new (void)
6081 return g_slice_new0 (GtkBorder);
6086 * @border_: a #GtkBorder.
6087 * @returns: a copy of @border_.
6089 * Copies a #GtkBorder structure.
6092 gtk_border_copy (const GtkBorder *border)
6094 g_return_val_if_fail (border != NULL, NULL);
6096 return g_slice_dup (GtkBorder, border);
6101 * @border_: a #GtkBorder.
6103 * Frees a #GtkBorder structure.
6106 gtk_border_free (GtkBorder *border)
6108 g_slice_free (GtkBorder, border);
6112 gtk_border_get_type (void)
6114 static GType our_type = 0;
6117 our_type = g_boxed_type_register_static (I_("GtkBorder"),
6118 (GBoxedCopyFunc) gtk_border_copy,
6119 (GBoxedFreeFunc) gtk_border_free);
6125 gtk_style_get_font_internal (GtkStyle *style)
6127 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
6129 if (style->private_font && style->private_font_desc)
6131 if (!style->font_desc ||
6132 !pango_font_description_equal (style->private_font_desc, style->font_desc))
6134 gdk_font_unref (style->private_font);
6135 style->private_font = NULL;
6137 if (style->private_font_desc)
6139 pango_font_description_free (style->private_font_desc);
6140 style->private_font_desc = NULL;
6145 if (!style->private_font)
6147 GdkDisplay *display;
6149 if (style->colormap)
6151 display = gdk_screen_get_display (gdk_colormap_get_screen (style->colormap));
6155 display = gdk_display_get_default ();
6156 GTK_NOTE (MULTIHEAD,
6157 g_warning ("gtk_style_get_font() should not be called on an unattached style"));
6160 if (style->font_desc)
6162 style->private_font = gdk_font_from_description_for_display (display, style->font_desc);
6163 style->private_font_desc = pango_font_description_copy (style->font_desc);
6166 if (!style->private_font)
6167 style->private_font = gdk_font_load_for_display (display, "fixed");
6169 if (!style->private_font)
6170 g_error ("Unable to load \"fixed\" font");
6173 return style->private_font;
6176 typedef struct _CursorInfo CursorInfo;
6182 GdkGC *secondary_gc;
6186 style_unrealize_cursor_gcs (GtkStyle *style)
6190 cursor_info = g_object_get_data (G_OBJECT (style), "gtk-style-cursor-info");
6193 if (cursor_info->primary_gc)
6194 gtk_gc_release (cursor_info->primary_gc);
6196 if (cursor_info->secondary_gc)
6197 gtk_gc_release (cursor_info->secondary_gc);
6199 g_free (cursor_info);
6200 g_object_set_data (G_OBJECT (style), I_("gtk-style-cursor-info"), NULL);
6205 make_cursor_gc (GtkWidget *widget,
6206 const gchar *property_name,
6207 const GdkColor *fallback)
6209 GdkGCValues gc_values;
6210 GdkGCValuesMask gc_values_mask;
6211 GdkColor *cursor_color;
6213 gtk_widget_style_get (widget, property_name, &cursor_color, NULL);
6215 gc_values_mask = GDK_GC_FOREGROUND;
6218 gc_values.foreground = *cursor_color;
6219 gdk_color_free (cursor_color);
6222 gc_values.foreground = *fallback;
6224 gdk_rgb_find_color (widget->style->colormap, &gc_values.foreground);
6225 return gtk_gc_get (widget->style->depth, widget->style->colormap, &gc_values, gc_values_mask);
6229 get_insertion_cursor_gc (GtkWidget *widget,
6230 gboolean is_primary)
6232 CursorInfo *cursor_info;
6234 cursor_info = g_object_get_data (G_OBJECT (widget->style), "gtk-style-cursor-info");
6237 cursor_info = g_new (CursorInfo, 1);
6238 g_object_set_data (G_OBJECT (widget->style), I_("gtk-style-cursor-info"), cursor_info);
6239 cursor_info->primary_gc = NULL;
6240 cursor_info->secondary_gc = NULL;
6241 cursor_info->for_type = G_TYPE_INVALID;
6244 /* We have to keep track of the type because gtk_widget_style_get()
6245 * can return different results when called on the same property and
6246 * same style but for different widgets. :-(. That is,
6247 * GtkEntry::cursor-color = "red" in a style will modify the cursor
6248 * color for entries but not for text view.
6250 if (cursor_info->for_type != G_OBJECT_TYPE (widget))
6252 cursor_info->for_type = G_OBJECT_TYPE (widget);
6253 if (cursor_info->primary_gc)
6255 gtk_gc_release (cursor_info->primary_gc);
6256 cursor_info->primary_gc = NULL;
6258 if (cursor_info->secondary_gc)
6260 gtk_gc_release (cursor_info->secondary_gc);
6261 cursor_info->secondary_gc = NULL;
6265 /* Cursors in text widgets are drawn only in NORMAL state,
6266 * so we can use text[GTK_STATE_NORMAL] as text color here */
6269 if (!cursor_info->primary_gc)
6270 cursor_info->primary_gc = make_cursor_gc (widget,
6272 &widget->style->text[GTK_STATE_NORMAL]);
6274 return cursor_info->primary_gc;
6278 if (!cursor_info->secondary_gc)
6279 cursor_info->secondary_gc = make_cursor_gc (widget,
6280 "secondary-cursor-color",
6281 /* text_aa is the average of text and base colors,
6282 * in usual black-on-white case it's grey. */
6283 &widget->style->text_aa[GTK_STATE_NORMAL]);
6285 return cursor_info->secondary_gc;
6290 _gtk_widget_get_cursor_gc (GtkWidget *widget)
6292 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
6293 g_return_val_if_fail (gtk_widget_get_realized (widget), NULL);
6294 return get_insertion_cursor_gc (widget, TRUE);
6298 _gtk_widget_get_cursor_color (GtkWidget *widget,
6301 GdkColor *style_color;
6303 g_return_if_fail (GTK_IS_WIDGET (widget));
6304 g_return_if_fail (color != NULL);
6306 gtk_widget_style_get (widget, "cursor-color", &style_color, NULL);
6310 *color = *style_color;
6311 gdk_color_free (style_color);
6314 *color = widget->style->text[GTK_STATE_NORMAL];
6318 draw_insertion_cursor (GtkWidget *widget,
6319 GdkDrawable *drawable,
6321 const GdkRectangle *location,
6322 GtkTextDirection direction,
6323 gboolean draw_arrow)
6329 gfloat cursor_aspect_ratio;
6332 /* When changing the shape or size of the cursor here,
6333 * propagate the changes to gtktextview.c:text_window_invalidate_cursors().
6336 gtk_widget_style_get (widget, "cursor-aspect-ratio", &cursor_aspect_ratio, NULL);
6338 stem_width = location->height * cursor_aspect_ratio + 1;
6339 arrow_width = stem_width + 1;
6341 /* put (stem_width % 2) on the proper side of the cursor */
6342 if (direction == GTK_TEXT_DIR_LTR)
6343 offset = stem_width / 2;
6345 offset = stem_width - stem_width / 2;
6347 for (i = 0; i < stem_width; i++)
6348 gdk_draw_line (drawable, gc,
6349 location->x + i - offset, location->y,
6350 location->x + i - offset, location->y + location->height - 1);
6354 if (direction == GTK_TEXT_DIR_RTL)
6356 x = location->x - offset - 1;
6357 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
6359 for (i = 0; i < arrow_width; i++)
6361 gdk_draw_line (drawable, gc,
6363 x, y + 2 * arrow_width - i - 1);
6367 else if (direction == GTK_TEXT_DIR_LTR)
6369 x = location->x + stem_width - offset;
6370 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
6372 for (i = 0; i < arrow_width; i++)
6374 gdk_draw_line (drawable, gc,
6376 x, y + 2 * arrow_width - i - 1);
6384 * gtk_draw_insertion_cursor:
6385 * @widget: a #GtkWidget
6386 * @drawable: a #GdkDrawable
6387 * @area: (allow-none): rectangle to which the output is clipped, or %NULL if the
6388 * output should not be clipped
6389 * @location: location where to draw the cursor (@location->width is ignored)
6390 * @is_primary: if the cursor should be the primary cursor color.
6391 * @direction: whether the cursor is left-to-right or
6392 * right-to-left. Should never be #GTK_TEXT_DIR_NONE
6393 * @draw_arrow: %TRUE to draw a directional arrow on the
6394 * cursor. Should be %FALSE unless the cursor is split.
6396 * Draws a text caret on @drawable at @location. This is not a style function
6397 * but merely a convenience function for drawing the standard cursor shape.
6402 gtk_draw_insertion_cursor (GtkWidget *widget,
6403 GdkDrawable *drawable,
6404 const GdkRectangle *area,
6405 const GdkRectangle *location,
6406 gboolean is_primary,
6407 GtkTextDirection direction,
6408 gboolean draw_arrow)
6412 g_return_if_fail (GTK_IS_WIDGET (widget));
6413 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
6414 g_return_if_fail (location != NULL);
6415 g_return_if_fail (direction != GTK_TEXT_DIR_NONE);
6417 gc = get_insertion_cursor_gc (widget, is_primary);
6419 gdk_gc_set_clip_rectangle (gc, area);
6421 draw_insertion_cursor (widget, drawable, gc,
6422 location, direction, draw_arrow);
6425 gdk_gc_set_clip_rectangle (gc, NULL);
6428 #define __GTK_STYLE_C__
6429 #include "gtkaliasdef.c"