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>
32 #include "gtkmarshalers.h"
35 #include "gtkspinbutton.h"
37 #include "gtkwidget.h"
38 #include "gtkthemes.h"
39 #include "gtkiconfactory.h"
40 #include "gtksettings.h" /* _gtk_settings_parse_convert() */
42 #include "gtkspinner.h"
47 * @Short_description: An object that hold style information for widgets
50 * A #GtkStyle object encapsulates the information that provides the look and
51 * feel for a widget. Each #GtkWidget has an associated #GTkStyle object that
52 * is used when rendering that widget. Also, a #GtkStyle holds information for
53 * the five possible widget states though not every widget supports all five
54 * states; see #GtkStateType.
56 * Usually the #GtkStyle for a widget is the same as the default style that is
57 * set by GTK+ and modified the theme engine.
59 * Usually applications should not need to use or modify the #GtkStyle of their
64 #define LIGHTNESS_MULT 1.3
65 #define DARKNESS_MULT 0.7
67 /* --- typedefs & structures --- */
74 #define GTK_STYLE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_STYLE, GtkStylePrivate))
76 typedef struct _GtkStylePrivate GtkStylePrivate;
78 struct _GtkStylePrivate {
82 /* --- prototypes --- */
83 static void gtk_style_finalize (GObject *object);
84 static void gtk_style_realize (GtkStyle *style,
85 GdkColormap *colormap);
86 static void gtk_style_real_realize (GtkStyle *style);
87 static void gtk_style_real_unrealize (GtkStyle *style);
88 static void gtk_style_real_copy (GtkStyle *style,
90 static void gtk_style_real_set_background (GtkStyle *style,
92 GtkStateType state_type);
93 static GtkStyle *gtk_style_real_clone (GtkStyle *style);
94 static void gtk_style_real_init_from_rc (GtkStyle *style,
95 GtkRcStyle *rc_style);
96 static GdkPixbuf *gtk_default_render_icon (GtkStyle *style,
97 const GtkIconSource *source,
98 GtkTextDirection direction,
102 const gchar *detail);
103 static void gtk_default_draw_hline (GtkStyle *style,
105 GtkStateType state_type,
111 static void gtk_default_draw_vline (GtkStyle *style,
113 GtkStateType state_type,
119 static void gtk_default_draw_shadow (GtkStyle *style,
121 GtkStateType state_type,
122 GtkShadowType shadow_type,
129 static void gtk_default_draw_arrow (GtkStyle *style,
131 GtkStateType state_type,
132 GtkShadowType shadow_type,
135 GtkArrowType arrow_type,
141 static void gtk_default_draw_diamond (GtkStyle *style,
143 GtkStateType state_type,
144 GtkShadowType shadow_type,
151 static void gtk_default_draw_box (GtkStyle *style,
153 GtkStateType state_type,
154 GtkShadowType shadow_type,
161 static void gtk_default_draw_flat_box (GtkStyle *style,
163 GtkStateType state_type,
164 GtkShadowType shadow_type,
171 static void gtk_default_draw_check (GtkStyle *style,
173 GtkStateType state_type,
174 GtkShadowType shadow_type,
181 static void gtk_default_draw_option (GtkStyle *style,
183 GtkStateType state_type,
184 GtkShadowType shadow_type,
191 static void gtk_default_draw_tab (GtkStyle *style,
193 GtkStateType state_type,
194 GtkShadowType shadow_type,
201 static void gtk_default_draw_shadow_gap (GtkStyle *style,
203 GtkStateType state_type,
204 GtkShadowType shadow_type,
211 GtkPositionType gap_side,
214 static void gtk_default_draw_box_gap (GtkStyle *style,
216 GtkStateType state_type,
217 GtkShadowType shadow_type,
224 GtkPositionType gap_side,
227 static void gtk_default_draw_extension (GtkStyle *style,
229 GtkStateType state_type,
230 GtkShadowType shadow_type,
237 GtkPositionType gap_side);
238 static void gtk_default_draw_focus (GtkStyle *style,
240 GtkStateType state_type,
247 static void gtk_default_draw_slider (GtkStyle *style,
249 GtkStateType state_type,
250 GtkShadowType shadow_type,
257 GtkOrientation orientation);
258 static void gtk_default_draw_handle (GtkStyle *style,
260 GtkStateType state_type,
261 GtkShadowType shadow_type,
268 GtkOrientation orientation);
269 static void gtk_default_draw_expander (GtkStyle *style,
271 GtkStateType state_type,
276 GtkExpanderStyle expander_style);
277 static void gtk_default_draw_layout (GtkStyle *style,
279 GtkStateType state_type,
285 PangoLayout *layout);
286 static void gtk_default_draw_resize_grip (GtkStyle *style,
288 GtkStateType state_type,
296 static void gtk_default_draw_spinner (GtkStyle *style,
298 GtkStateType state_type,
308 static void rgb_to_hls (gdouble *r,
311 static void hls_to_rgb (gdouble *h,
315 static void style_unrealize_cursors (GtkStyle *style);
318 * Data for default check and radio buttons
321 static const GtkRequisition default_option_indicator_size = { 7, 13 };
322 static const GtkBorder default_option_indicator_spacing = { 7, 5, 2, 2 };
324 #define GTK_GRAY 0xdcdc, 0xdada, 0xd5d5
325 #define GTK_DARK_GRAY 0xc4c4, 0xc2c2, 0xbdbd
326 #define GTK_LIGHT_GRAY 0xeeee, 0xebeb, 0xe7e7
327 #define GTK_WHITE 0xffff, 0xffff, 0xffff
328 #define GTK_BLUE 0x4b4b, 0x6969, 0x8383
329 #define GTK_VERY_DARK_GRAY 0x9c9c, 0x9a9a, 0x9494
330 #define GTK_BLACK 0x0000, 0x0000, 0x0000
331 #define GTK_WEAK_GRAY 0x7530, 0x7530, 0x7530
333 /* --- variables --- */
334 static const GdkColor gtk_default_normal_fg = { 0, GTK_BLACK };
335 static const GdkColor gtk_default_active_fg = { 0, GTK_BLACK };
336 static const GdkColor gtk_default_prelight_fg = { 0, GTK_BLACK };
337 static const GdkColor gtk_default_selected_fg = { 0, GTK_WHITE };
338 static const GdkColor gtk_default_insensitive_fg = { 0, GTK_WEAK_GRAY };
340 static const GdkColor gtk_default_normal_bg = { 0, GTK_GRAY };
341 static const GdkColor gtk_default_active_bg = { 0, GTK_DARK_GRAY };
342 static const GdkColor gtk_default_prelight_bg = { 0, GTK_LIGHT_GRAY };
343 static const GdkColor gtk_default_selected_bg = { 0, GTK_BLUE };
344 static const GdkColor gtk_default_insensitive_bg = { 0, GTK_GRAY };
345 static const GdkColor gtk_default_selected_base = { 0, GTK_BLUE };
346 static const GdkColor gtk_default_active_base = { 0, GTK_VERY_DARK_GRAY };
348 /* --- signals --- */
349 static guint realize_signal = 0;
350 static guint unrealize_signal = 0;
352 G_DEFINE_TYPE (GtkStyle, gtk_style, G_TYPE_OBJECT)
354 /* --- functions --- */
357 * _gtk_style_init_for_settings:
358 * @style: a #GtkStyle
359 * @settings: a #GtkSettings
361 * Initializes the font description in @style according to the default
362 * font name of @settings. This is called for gtk_style_new() with
363 * the settings for the default screen (if any); if we are creating
364 * a style for a particular screen, we then call it again in a
365 * location where we know the correct settings.
366 * The reason for this is that gtk_rc_style_create_style() doesn't
367 * take the screen for an argument.
370 _gtk_style_init_for_settings (GtkStyle *style,
371 GtkSettings *settings)
373 const gchar *font_name = _gtk_rc_context_get_default_font_name (settings);
375 if (style->font_desc)
376 pango_font_description_free (style->font_desc);
378 style->font_desc = pango_font_description_from_string (font_name);
380 if (!pango_font_description_get_family (style->font_desc))
382 g_warning ("Default font does not have a family set");
383 pango_font_description_set_family (style->font_desc, "Sans");
385 if (pango_font_description_get_size (style->font_desc) <= 0)
387 g_warning ("Default font does not have a positive size");
388 pango_font_description_set_size (style->font_desc, 10 * PANGO_SCALE);
393 gtk_style_init (GtkStyle *style)
397 GtkSettings *settings = gtk_settings_get_default ();
400 _gtk_style_init_for_settings (style, settings);
402 style->font_desc = pango_font_description_from_string ("Sans 10");
404 style->attach_count = 0;
405 style->colormap = NULL;
408 style->black.red = 0;
409 style->black.green = 0;
410 style->black.blue = 0;
412 style->white.red = 65535;
413 style->white.green = 65535;
414 style->white.blue = 65535;
416 style->fg[GTK_STATE_NORMAL] = gtk_default_normal_fg;
417 style->fg[GTK_STATE_ACTIVE] = gtk_default_active_fg;
418 style->fg[GTK_STATE_PRELIGHT] = gtk_default_prelight_fg;
419 style->fg[GTK_STATE_SELECTED] = gtk_default_selected_fg;
420 style->fg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
422 style->bg[GTK_STATE_NORMAL] = gtk_default_normal_bg;
423 style->bg[GTK_STATE_ACTIVE] = gtk_default_active_bg;
424 style->bg[GTK_STATE_PRELIGHT] = gtk_default_prelight_bg;
425 style->bg[GTK_STATE_SELECTED] = gtk_default_selected_bg;
426 style->bg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_bg;
428 for (i = 0; i < 4; i++)
430 style->text[i] = style->fg[i];
431 style->base[i] = style->white;
434 style->base[GTK_STATE_SELECTED] = gtk_default_selected_base;
435 style->text[GTK_STATE_SELECTED] = style->white;
436 style->base[GTK_STATE_ACTIVE] = gtk_default_active_base;
437 style->text[GTK_STATE_ACTIVE] = style->white;
438 style->base[GTK_STATE_INSENSITIVE] = gtk_default_prelight_bg;
439 style->text[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
441 for (i = 0; i < 5; i++)
442 style->bg_pixmap[i] = NULL;
444 style->rc_style = NULL;
446 style->xthickness = 2;
447 style->ythickness = 2;
449 style->property_cache = NULL;
453 gtk_style_class_init (GtkStyleClass *klass)
455 GObjectClass *object_class = G_OBJECT_CLASS (klass);
457 object_class->finalize = gtk_style_finalize;
459 klass->clone = gtk_style_real_clone;
460 klass->copy = gtk_style_real_copy;
461 klass->init_from_rc = gtk_style_real_init_from_rc;
462 klass->realize = gtk_style_real_realize;
463 klass->unrealize = gtk_style_real_unrealize;
464 klass->set_background = gtk_style_real_set_background;
465 klass->render_icon = gtk_default_render_icon;
467 klass->draw_hline = gtk_default_draw_hline;
468 klass->draw_vline = gtk_default_draw_vline;
469 klass->draw_shadow = gtk_default_draw_shadow;
470 klass->draw_arrow = gtk_default_draw_arrow;
471 klass->draw_diamond = gtk_default_draw_diamond;
472 klass->draw_box = gtk_default_draw_box;
473 klass->draw_flat_box = gtk_default_draw_flat_box;
474 klass->draw_check = gtk_default_draw_check;
475 klass->draw_option = gtk_default_draw_option;
476 klass->draw_tab = gtk_default_draw_tab;
477 klass->draw_shadow_gap = gtk_default_draw_shadow_gap;
478 klass->draw_box_gap = gtk_default_draw_box_gap;
479 klass->draw_extension = gtk_default_draw_extension;
480 klass->draw_focus = gtk_default_draw_focus;
481 klass->draw_slider = gtk_default_draw_slider;
482 klass->draw_handle = gtk_default_draw_handle;
483 klass->draw_expander = gtk_default_draw_expander;
484 klass->draw_layout = gtk_default_draw_layout;
485 klass->draw_resize_grip = gtk_default_draw_resize_grip;
486 klass->draw_spinner = gtk_default_draw_spinner;
488 g_type_class_add_private (object_class, sizeof (GtkStylePrivate));
492 * @style: the object which received the signal
494 * Emitted when the style has been initialized for a particular
495 * colormap and depth. Connecting to this signal is probably seldom
496 * useful since most of the time applications and widgets only
497 * deal with styles that have been already realized.
501 realize_signal = g_signal_new (I_("realize"),
502 G_TYPE_FROM_CLASS (object_class),
504 G_STRUCT_OFFSET (GtkStyleClass, realize),
506 _gtk_marshal_VOID__VOID,
509 * GtkStyle::unrealize:
510 * @style: the object which received the signal
512 * Emitted when the aspects of the style specific to a particular colormap
513 * and depth are being cleaned up. A connection to this signal can be useful
514 * if a widget wants to cache objects as object data on #GtkStyle.
515 * This signal provides a convenient place to free such cached objects.
519 unrealize_signal = g_signal_new (I_("unrealize"),
520 G_TYPE_FROM_CLASS (object_class),
522 G_STRUCT_OFFSET (GtkStyleClass, unrealize),
524 _gtk_marshal_VOID__VOID,
529 clear_property_cache (GtkStyle *style)
531 if (style->property_cache)
535 for (i = 0; i < style->property_cache->len; i++)
537 PropertyValue *node = &g_array_index (style->property_cache, PropertyValue, i);
539 g_param_spec_unref (node->pspec);
540 g_value_unset (&node->value);
542 g_array_free (style->property_cache, TRUE);
543 style->property_cache = NULL;
548 gtk_style_finalize (GObject *object)
550 GtkStyle *style = GTK_STYLE (object);
551 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
553 g_return_if_fail (style->attach_count == 0);
555 clear_property_cache (style);
557 /* All the styles in the list have the same
558 * style->styles pointer. If we delete the
559 * *first* style from the list, we need to update
560 * the style->styles pointers from all the styles.
561 * Otherwise we simply remove the node from
566 if (style->styles->data != style)
567 style->styles = g_slist_remove (style->styles, style);
570 GSList *tmp_list = style->styles->next;
574 GTK_STYLE (tmp_list->data)->styles = style->styles->next;
575 tmp_list = tmp_list->next;
577 g_slist_free_1 (style->styles);
581 g_slist_foreach (style->icon_factories, (GFunc) g_object_unref, NULL);
582 g_slist_free (style->icon_factories);
584 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_unref, NULL);
585 g_slist_free (priv->color_hashes);
587 pango_font_description_free (style->font_desc);
589 if (style->private_font_desc)
590 pango_font_description_free (style->private_font_desc);
593 g_object_unref (style->rc_style);
595 G_OBJECT_CLASS (gtk_style_parent_class)->finalize (object);
601 * @style: a #GtkStyle
603 * Creates a copy of the passed in #GtkStyle object.
605 * Returns: (transfer full): a copy of @style
608 gtk_style_copy (GtkStyle *style)
612 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
614 new_style = GTK_STYLE_GET_CLASS (style)->clone (style);
615 GTK_STYLE_GET_CLASS (style)->copy (new_style, style);
621 gtk_style_duplicate (GtkStyle *style)
625 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
627 new_style = gtk_style_copy (style);
629 /* All the styles in the list have the same
630 * style->styles pointer. When we insert a new
631 * style, we append it to the list to avoid having
632 * to update the existing ones.
634 style->styles = g_slist_append (style->styles, new_style);
635 new_style->styles = style->styles;
642 * @returns: a new #GtkStyle.
644 * Creates a new #GtkStyle.
651 style = g_object_new (GTK_TYPE_STYLE, NULL);
658 * @style: a #GtkStyle.
659 * @window: a #GdkWindow.
661 * Attaches a style to a window; this process allocates the
662 * colors and creates the GC's for the style - it specializes
663 * it to a particular visual and colormap. The process may
664 * involve the creation of a new style if the style has already
665 * been attached to a window with a different style and colormap.
667 * Since this function may return a new object, you have to use it
668 * in the following way:
669 * <literal>style = gtk_style_attach (style, window)</literal>
671 * Returns: Either @style, or a newly-created #GtkStyle.
672 * If the style is newly created, the style parameter
673 * will be unref'ed, and the new style will have
674 * a reference count belonging to the caller.
677 gtk_style_attach (GtkStyle *style,
681 GtkStyle *new_style = NULL;
682 GdkColormap *colormap;
684 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
685 g_return_val_if_fail (window != NULL, NULL);
687 colormap = gdk_drawable_get_colormap (window);
690 style->styles = g_slist_append (NULL, style);
692 styles = style->styles;
695 new_style = styles->data;
697 if (new_style->colormap == colormap)
701 styles = styles->next;
706 styles = style->styles;
710 new_style = styles->data;
712 if (new_style->attach_count == 0)
714 gtk_style_realize (new_style, colormap);
719 styles = styles->next;
725 new_style = gtk_style_duplicate (style);
726 gtk_style_realize (new_style, colormap);
729 /* A style gets a refcount from being attached */
730 if (new_style->attach_count == 0)
731 g_object_ref (new_style);
733 /* Another refcount belongs to the parent */
734 if (style != new_style)
736 g_object_unref (style);
737 g_object_ref (new_style);
740 new_style->attach_count++;
747 * @style: a #GtkStyle
749 * Detaches a style from a window. If the style is not attached
750 * to any windows anymore, it is unrealized. See gtk_style_attach().
754 gtk_style_detach (GtkStyle *style)
756 g_return_if_fail (GTK_IS_STYLE (style));
757 g_return_if_fail (style->attach_count > 0);
759 style->attach_count -= 1;
760 if (style->attach_count == 0)
762 g_signal_emit (style, unrealize_signal, 0);
764 g_object_unref (style->colormap);
765 style->colormap = NULL;
767 if (style->private_font_desc)
769 pango_font_description_free (style->private_font_desc);
770 style->private_font_desc = NULL;
773 g_object_unref (style);
778 gtk_style_realize (GtkStyle *style,
779 GdkColormap *colormap)
781 style->colormap = g_object_ref (colormap);
782 style->depth = gdk_colormap_get_visual (colormap)->depth;
784 g_signal_emit (style, realize_signal, 0);
788 * gtk_style_lookup_icon_set:
789 * @style: a #GtkStyle
790 * @stock_id: an icon name
792 * Looks up @stock_id in the icon factories associated with @style
793 * and the default icon factory, returning an icon set if found,
796 * Return value: icon set of @stock_id
799 gtk_style_lookup_icon_set (GtkStyle *style,
800 const char *stock_id)
804 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
805 g_return_val_if_fail (stock_id != NULL, NULL);
807 iter = style->icon_factories;
810 GtkIconSet *icon_set = gtk_icon_factory_lookup (GTK_ICON_FACTORY (iter->data),
815 iter = g_slist_next (iter);
818 return gtk_icon_factory_lookup_default (stock_id);
822 * gtk_style_lookup_color:
823 * @style: a #GtkStyle
824 * @color_name: the name of the logical color to look up
825 * @color: the #GdkColor to fill in
827 * Looks up @color_name in the style's logical color mappings,
828 * filling in @color and returning %TRUE if found, otherwise
829 * returning %FALSE. Do not cache the found mapping, because
830 * it depends on the #GtkStyle and might change when a theme
833 * Return value: %TRUE if the mapping was found.
838 gtk_style_lookup_color (GtkStyle *style,
839 const char *color_name,
842 GtkStylePrivate *priv;
845 g_return_val_if_fail (GTK_IS_STYLE (style), FALSE);
846 g_return_val_if_fail (color_name != NULL, FALSE);
847 g_return_val_if_fail (color != NULL, FALSE);
849 priv = GTK_STYLE_GET_PRIVATE (style);
851 for (iter = priv->color_hashes; iter != NULL; iter = iter->next)
853 GHashTable *hash = iter->data;
854 GdkColor *mapping = g_hash_table_lookup (hash, color_name);
858 color->red = mapping->red;
859 color->green = mapping->green;
860 color->blue = mapping->blue;
869 * gtk_style_set_background:
870 * @style: a #GtkStyle
871 * @window: a #GdkWindow
872 * @state_type: a state
874 * Sets the background of @window to the background color or pixmap
875 * specified by @style for the given state.
878 gtk_style_set_background (GtkStyle *style,
880 GtkStateType state_type)
882 g_return_if_fail (GTK_IS_STYLE (style));
883 g_return_if_fail (window != NULL);
885 GTK_STYLE_GET_CLASS (style)->set_background (style, window, state_type);
888 /* Default functions */
890 gtk_style_real_clone (GtkStyle *style)
892 return g_object_new (G_OBJECT_TYPE (style), NULL);
896 gtk_style_real_copy (GtkStyle *style,
899 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
900 GtkStylePrivate *src_priv = GTK_STYLE_GET_PRIVATE (src);
903 for (i = 0; i < 5; i++)
905 style->fg[i] = src->fg[i];
906 style->bg[i] = src->bg[i];
907 style->text[i] = src->text[i];
908 style->base[i] = src->base[i];
910 if (style->bg_pixmap[i])
911 g_object_unref (style->bg_pixmap[i]),
912 style->bg_pixmap[i] = src->bg_pixmap[i];
913 if (style->bg_pixmap[i])
914 g_object_ref (style->bg_pixmap[i]);
917 if (style->font_desc)
918 pango_font_description_free (style->font_desc);
920 style->font_desc = pango_font_description_copy (src->font_desc);
922 style->font_desc = NULL;
924 style->xthickness = src->xthickness;
925 style->ythickness = src->ythickness;
928 g_object_unref (style->rc_style);
929 style->rc_style = src->rc_style;
931 g_object_ref (src->rc_style);
933 g_slist_foreach (style->icon_factories, (GFunc) g_object_unref, NULL);
934 g_slist_free (style->icon_factories);
935 style->icon_factories = g_slist_copy (src->icon_factories);
936 g_slist_foreach (style->icon_factories, (GFunc) g_object_ref, NULL);
938 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_unref, NULL);
939 g_slist_free (priv->color_hashes);
940 priv->color_hashes = g_slist_copy (src_priv->color_hashes);
941 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_ref, NULL);
943 /* don't copy, just clear cache */
944 clear_property_cache (style);
948 gtk_style_real_init_from_rc (GtkStyle *style,
949 GtkRcStyle *rc_style)
951 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
954 /* cache _should_ be still empty */
955 clear_property_cache (style);
957 if (rc_style->font_desc)
958 pango_font_description_merge (style->font_desc, rc_style->font_desc, TRUE);
960 for (i = 0; i < 5; i++)
962 if (rc_style->color_flags[i] & GTK_RC_FG)
963 style->fg[i] = rc_style->fg[i];
964 if (rc_style->color_flags[i] & GTK_RC_BG)
965 style->bg[i] = rc_style->bg[i];
966 if (rc_style->color_flags[i] & GTK_RC_TEXT)
967 style->text[i] = rc_style->text[i];
968 if (rc_style->color_flags[i] & GTK_RC_BASE)
969 style->base[i] = rc_style->base[i];
972 if (rc_style->xthickness >= 0)
973 style->xthickness = rc_style->xthickness;
974 if (rc_style->ythickness >= 0)
975 style->ythickness = rc_style->ythickness;
977 style->icon_factories = g_slist_copy (rc_style->icon_factories);
978 g_slist_foreach (style->icon_factories, (GFunc) g_object_ref, NULL);
980 priv->color_hashes = g_slist_copy (_gtk_rc_style_get_color_hashes (rc_style));
981 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_ref, NULL);
985 style_property_values_cmp (gconstpointer bsearch_node1,
986 gconstpointer bsearch_node2)
988 const PropertyValue *val1 = bsearch_node1;
989 const PropertyValue *val2 = bsearch_node2;
991 if (val1->widget_type == val2->widget_type)
992 return val1->pspec < val2->pspec ? -1 : val1->pspec == val2->pspec ? 0 : 1;
994 return val1->widget_type < val2->widget_type ? -1 : 1;
998 * gtk_style_get_style_property:
999 * @style: a #GtkStyle
1000 * @widget_type: the #GType of a descendant of #GtkWidget
1001 * @property_name: the name of the style property to get
1002 * @value: a #GValue where the value of the property being
1003 * queried will be stored
1005 * Queries the value of a style property corresponding to a
1006 * widget class is in the given style.
1011 gtk_style_get_style_property (GtkStyle *style,
1013 const gchar *property_name,
1016 GtkWidgetClass *klass;
1018 GtkRcPropertyParser parser;
1019 const GValue *peek_value;
1021 klass = g_type_class_ref (widget_type);
1022 pspec = gtk_widget_class_find_style_property (klass, property_name);
1023 g_type_class_unref (klass);
1027 g_warning ("%s: widget class `%s' has no property named `%s'",
1029 g_type_name (widget_type),
1034 parser = g_param_spec_get_qdata (pspec,
1035 g_quark_from_static_string ("gtk-rc-property-parser"));
1037 peek_value = _gtk_style_peek_property_value (style, widget_type, pspec, parser);
1039 if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec))
1040 g_value_copy (peek_value, value);
1041 else if (g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
1042 g_value_transform (peek_value, value);
1044 g_warning ("can't retrieve style property `%s' of type `%s' as value of type `%s'",
1046 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1047 G_VALUE_TYPE_NAME (value));
1051 * gtk_style_get_valist:
1052 * @style: a #GtkStyle
1053 * @widget_type: the #GType of a descendant of #GtkWidget
1054 * @first_property_name: the name of the first style property to get
1055 * @var_args: a <type>va_list</type> of pairs of property names and
1056 * locations to return the property values, starting with the
1057 * location for @first_property_name.
1059 * Non-vararg variant of gtk_style_get().
1060 * Used primarily by language bindings.
1065 gtk_style_get_valist (GtkStyle *style,
1067 const gchar *first_property_name,
1070 const char *property_name;
1071 GtkWidgetClass *klass;
1073 g_return_if_fail (GTK_IS_STYLE (style));
1075 klass = g_type_class_ref (widget_type);
1077 property_name = first_property_name;
1078 while (property_name)
1081 GtkRcPropertyParser parser;
1082 const GValue *peek_value;
1085 pspec = gtk_widget_class_find_style_property (klass, property_name);
1089 g_warning ("%s: widget class `%s' has no property named `%s'",
1091 g_type_name (widget_type),
1096 parser = g_param_spec_get_qdata (pspec,
1097 g_quark_from_static_string ("gtk-rc-property-parser"));
1099 peek_value = _gtk_style_peek_property_value (style, widget_type, pspec, parser);
1100 G_VALUE_LCOPY (peek_value, var_args, 0, &error);
1103 g_warning ("%s: %s", G_STRLOC, error);
1108 property_name = va_arg (var_args, gchar*);
1111 g_type_class_unref (klass);
1116 * @style: a #GtkStyle
1117 * @widget_type: the #GType of a descendant of #GtkWidget
1118 * @first_property_name: the name of the first style property to get
1119 * @Varargs: pairs of property names and locations to
1120 * return the property values, starting with the location for
1121 * @first_property_name, terminated by %NULL.
1123 * Gets the values of a multiple style properties for @widget_type
1129 gtk_style_get (GtkStyle *style,
1131 const gchar *first_property_name,
1136 va_start (var_args, first_property_name);
1137 gtk_style_get_valist (style, widget_type, first_property_name, var_args);
1142 _gtk_style_peek_property_value (GtkStyle *style,
1145 GtkRcPropertyParser parser)
1147 PropertyValue *pcache, key = { 0, NULL, { 0, } };
1148 const GtkRcProperty *rcprop = NULL;
1151 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1152 g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL);
1153 g_return_val_if_fail (g_type_is_a (pspec->owner_type, GTK_TYPE_WIDGET), NULL);
1154 g_return_val_if_fail (g_type_is_a (widget_type, pspec->owner_type), NULL);
1156 key.widget_type = widget_type;
1159 /* need value cache array */
1160 if (!style->property_cache)
1161 style->property_cache = g_array_new (FALSE, FALSE, sizeof (PropertyValue));
1164 pcache = bsearch (&key,
1165 style->property_cache->data, style->property_cache->len,
1166 sizeof (PropertyValue), style_property_values_cmp);
1168 return &pcache->value;
1172 while (i < style->property_cache->len &&
1173 style_property_values_cmp (&key, &g_array_index (style->property_cache, PropertyValue, i)) >= 0)
1176 g_array_insert_val (style->property_cache, i, key);
1177 pcache = &g_array_index (style->property_cache, PropertyValue, i);
1179 /* cache miss, initialize value type, then set contents */
1180 g_param_spec_ref (pcache->pspec);
1181 g_value_init (&pcache->value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1183 /* value provided by rc style? */
1184 if (style->rc_style)
1186 GQuark prop_quark = g_quark_from_string (pspec->name);
1190 rcprop = _gtk_rc_style_lookup_rc_property (style->rc_style,
1191 g_type_qname (widget_type),
1195 widget_type = g_type_parent (widget_type);
1197 while (g_type_is_a (widget_type, pspec->owner_type));
1200 /* when supplied by rc style, we need to convert */
1201 if (rcprop && !_gtk_settings_parse_convert (parser, &rcprop->value,
1202 pspec, &pcache->value))
1204 gchar *contents = g_strdup_value_contents (&rcprop->value);
1206 g_message ("%s: failed to retrieve property `%s::%s' of type `%s' from rc file value \"%s\" of type `%s'",
1207 rcprop->origin ? rcprop->origin : "(for origin information, set GTK_DEBUG)",
1208 g_type_name (pspec->owner_type), pspec->name,
1209 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1211 G_VALUE_TYPE_NAME (&rcprop->value));
1213 rcprop = NULL; /* needs default */
1216 /* not supplied by rc style (or conversion failed), revert to default */
1218 g_param_value_set_default (pspec, &pcache->value);
1220 return &pcache->value;
1224 load_bg_image (GdkColormap *colormap,
1226 const gchar *filename)
1228 if (strcmp (filename, "<parent>") == 0)
1229 return (GdkPixmap*) GDK_PARENT_RELATIVE;
1235 GdkScreen *screen = gdk_colormap_get_screen (colormap);
1237 pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
1241 pixmap = gdk_pixmap_new (gdk_screen_get_root_window (screen),
1242 gdk_pixbuf_get_width (pixbuf),
1243 gdk_pixbuf_get_height (pixbuf),
1244 gdk_colormap_get_visual (colormap)->depth);
1245 gdk_drawable_set_colormap (pixmap, colormap);
1247 cr = gdk_cairo_create (pixmap);
1249 gdk_cairo_set_source_color (cr, bg_color);
1252 gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
1256 g_object_unref (pixbuf);
1263 gtk_style_real_realize (GtkStyle *style)
1267 for (i = 0; i < 5; i++)
1269 _gtk_style_shade (&style->bg[i], &style->light[i], LIGHTNESS_MULT);
1270 _gtk_style_shade (&style->bg[i], &style->dark[i], DARKNESS_MULT);
1272 style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
1273 style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
1274 style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
1276 style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
1277 style->text_aa[i].green = (style->text[i].green + style->base[i].green) / 2;
1278 style->text_aa[i].blue = (style->text[i].blue + style->base[i].blue) / 2;
1281 style->black.red = 0x0000;
1282 style->black.green = 0x0000;
1283 style->black.blue = 0x0000;
1285 style->white.red = 0xffff;
1286 style->white.green = 0xffff;
1287 style->white.blue = 0xffff;
1289 for (i = 0; i < 5; i++)
1291 if (style->rc_style && style->rc_style->bg_pixmap_name[i])
1292 style->bg_pixmap[i] = load_bg_image (style->colormap,
1294 style->rc_style->bg_pixmap_name[i]);
1299 gtk_style_real_unrealize (GtkStyle *style)
1303 for (i = 0; i < 5; i++)
1305 if (style->bg_pixmap[i] && style->bg_pixmap[i] != (GdkPixmap*) GDK_PARENT_RELATIVE)
1307 g_object_unref (style->bg_pixmap[i]);
1308 style->bg_pixmap[i] = NULL;
1313 style_unrealize_cursors (style);
1317 gtk_style_real_set_background (GtkStyle *style,
1319 GtkStateType state_type)
1322 gint parent_relative;
1324 if (style->bg_pixmap[state_type])
1326 if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
1329 parent_relative = TRUE;
1333 pixmap = style->bg_pixmap[state_type];
1334 parent_relative = FALSE;
1337 gdk_window_set_back_pixmap (window, pixmap, parent_relative);
1340 gdk_window_set_background (window, &style->bg[state_type]);
1344 * gtk_style_render_icon:
1345 * @style: a #GtkStyle
1346 * @source: the #GtkIconSource specifying the icon to render
1347 * @direction: a text direction
1349 * @size: (type int): the size to render the icon at. A size of
1350 * (GtkIconSize)-1 means render at the size of the source and
1352 * @widget: (allow-none): the widget
1353 * @detail: (allow-none): a style detail
1355 * Renders the icon specified by @source at the given @size
1356 * according to the given parameters and returns the result in a
1359 * Return value: (transfer full): a newly-created #GdkPixbuf
1360 * containing the rendered icon
1363 gtk_style_render_icon (GtkStyle *style,
1364 const GtkIconSource *source,
1365 GtkTextDirection direction,
1369 const gchar *detail)
1373 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1374 g_return_val_if_fail (GTK_STYLE_GET_CLASS (style)->render_icon != NULL, NULL);
1376 pixbuf = GTK_STYLE_GET_CLASS (style)->render_icon (style, source, direction, state,
1377 size, widget, detail);
1379 g_return_val_if_fail (pixbuf != NULL, NULL);
1384 /* Default functions */
1387 * gtk_style_apply_default_background:
1393 * @area: (allow-none):
1400 gtk_style_apply_default_background (GtkStyle *style,
1403 GtkStateType state_type,
1411 if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
1413 GdkWindow *parent = gdk_window_get_parent (window);
1414 int x_offset, y_offset;
1418 gdk_window_get_position (window, &x_offset, &y_offset);
1419 cairo_translate (cr, -x_offset, -y_offset);
1420 gtk_style_apply_default_background (style, cr,
1422 x + x_offset, y + y_offset,
1427 gdk_cairo_set_source_color (cr, &style->bg[state_type]);
1429 else if (style->bg_pixmap[state_type])
1431 gdk_cairo_set_source_pixmap (cr, style->bg_pixmap[state_type], 0, 0);
1432 cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
1435 gdk_cairo_set_source_color (cr, &style->bg[state_type]);
1437 cairo_rectangle (cr, x, y, width, height);
1445 scale_or_ref (GdkPixbuf *src,
1449 if (width == gdk_pixbuf_get_width (src) &&
1450 height == gdk_pixbuf_get_height (src))
1452 return g_object_ref (src);
1456 return gdk_pixbuf_scale_simple (src,
1458 GDK_INTERP_BILINEAR);
1463 lookup_icon_size (GtkStyle *style,
1470 GtkSettings *settings;
1472 if (widget && gtk_widget_has_screen (widget))
1474 screen = gtk_widget_get_screen (widget);
1475 settings = gtk_settings_get_for_screen (screen);
1477 else if (style && style->colormap)
1479 screen = gdk_colormap_get_screen (style->colormap);
1480 settings = gtk_settings_get_for_screen (screen);
1484 settings = gtk_settings_get_default ();
1485 GTK_NOTE (MULTIHEAD,
1486 g_warning ("Using the default screen for gtk_default_render_icon()"));
1489 return gtk_icon_size_lookup_for_settings (settings, size, width, height);
1493 gtk_default_render_icon (GtkStyle *style,
1494 const GtkIconSource *source,
1495 GtkTextDirection direction,
1499 const gchar *detail)
1505 GdkPixbuf *base_pixbuf;
1507 /* Oddly, style can be NULL in this function, because
1508 * GtkIconSet can be used without a style and if so
1509 * it uses this function.
1512 base_pixbuf = gtk_icon_source_get_pixbuf (source);
1514 g_return_val_if_fail (base_pixbuf != NULL, NULL);
1516 if (size != (GtkIconSize) -1 && !lookup_icon_size(style, widget, size, &width, &height))
1518 g_warning (G_STRLOC ": invalid icon size '%d'", size);
1522 /* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
1525 if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source))
1526 scaled = scale_or_ref (base_pixbuf, width, height);
1528 scaled = g_object_ref (base_pixbuf);
1530 /* If the state was wildcarded, then generate a state. */
1531 if (gtk_icon_source_get_state_wildcarded (source))
1533 if (state == GTK_STATE_INSENSITIVE)
1535 stated = gdk_pixbuf_copy (scaled);
1537 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
1540 g_object_unref (scaled);
1542 else if (state == GTK_STATE_PRELIGHT)
1544 stated = gdk_pixbuf_copy (scaled);
1546 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
1549 g_object_unref (scaled);
1563 sanitize_size (GdkWindow *window,
1567 if ((*width == -1) && (*height == -1))
1568 gdk_drawable_get_size (window, width, height);
1569 else if (*width == -1)
1570 gdk_drawable_get_size (window, width, NULL);
1571 else if (*height == -1)
1572 gdk_drawable_get_size (window, NULL, height);
1576 _cairo_draw_line (cairo_t *cr,
1585 gdk_cairo_set_source_color (cr, color);
1586 cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
1588 cairo_move_to (cr, x1 + 0.5, y1 + 0.5);
1589 cairo_line_to (cr, x2 + 0.5, y2 + 0.5);
1596 _cairo_draw_rectangle (cairo_t *cr,
1604 gdk_cairo_set_source_color (cr, color);
1608 cairo_rectangle (cr, x, y, width, height);
1613 cairo_rectangle (cr, x + 0.5, y + 0.5, width, height);
1619 _cairo_draw_point (cairo_t *cr,
1624 gdk_cairo_set_source_color (cr, color);
1625 cairo_rectangle (cr, x, y, 1, 1);
1630 gtk_default_draw_hline (GtkStyle *style,
1632 GtkStateType state_type,
1634 const gchar *detail,
1639 gint thickness_light;
1640 gint thickness_dark;
1643 thickness_light = style->ythickness / 2;
1644 thickness_dark = style->ythickness - thickness_light;
1646 cairo_set_line_width (cr, 1.0);
1648 if (detail && !strcmp (detail, "label"))
1650 if (state_type == GTK_STATE_INSENSITIVE)
1651 _cairo_draw_line (cr, &style->white, x1 + 1, y + 1, x2 + 1, y + 1);
1652 _cairo_draw_line (cr, &style->fg[state_type], x1, y, x2, y);
1656 for (i = 0; i < thickness_dark; i++)
1658 _cairo_draw_line (cr, &style->dark[state_type], x1, y + i, x2 - i - 1, y + i);
1659 _cairo_draw_line (cr, &style->light[state_type], x2 - i, y + i, x2, y + i);
1662 y += thickness_dark;
1663 for (i = 0; i < thickness_light; i++)
1665 _cairo_draw_line (cr, &style->dark[state_type], x1, y + i, x1 + thickness_light - i - 1, y + i);
1666 _cairo_draw_line (cr, &style->light[state_type], x1 + thickness_light - i, y + i, x2, y + i);
1673 gtk_default_draw_vline (GtkStyle *style,
1675 GtkStateType state_type,
1677 const gchar *detail,
1682 gint thickness_light;
1683 gint thickness_dark;
1686 thickness_light = style->xthickness / 2;
1687 thickness_dark = style->xthickness - thickness_light;
1689 cairo_set_line_width (cr, 1.0);
1691 for (i = 0; i < thickness_dark; i++)
1693 _cairo_draw_line (cr, &style->dark[state_type],
1694 x + i, y1, x + i, y2 - i - 1);
1695 _cairo_draw_line (cr, &style->light[state_type],
1696 x + i, y2 - i, x + i, y2);
1699 x += thickness_dark;
1700 for (i = 0; i < thickness_light; i++)
1702 _cairo_draw_line (cr, &style->dark[state_type],
1703 x + i, y1, x + i, y1 + thickness_light - i - 1);
1704 _cairo_draw_line (cr, &style->light[state_type],
1705 x + i, y1 + thickness_light - i, x + i, y2);
1710 draw_thin_shadow (GtkStyle *style,
1718 GdkColor *gc1, *gc2;
1720 gc1 = &style->light[state];
1721 gc2 = &style->dark[state];
1723 _cairo_draw_line (cr, gc1,
1724 x, y + height - 1, x + width - 1, y + height - 1);
1725 _cairo_draw_line (cr, gc1,
1726 x + width - 1, y, x + width - 1, y + height - 1);
1728 _cairo_draw_line (cr, gc2,
1729 x, y, x + width - 2, y);
1730 _cairo_draw_line (cr, gc2,
1731 x, y, x, y + height - 2);
1735 draw_spinbutton_shadow (GtkStyle *style,
1738 GtkTextDirection direction,
1745 if (direction == GTK_TEXT_DIR_LTR)
1747 _cairo_draw_line (cr, &style->dark[state],
1748 x, y, x + width - 1, y);
1749 _cairo_draw_line (cr, &style->black,
1750 x, y + 1, x + width - 2, y + 1);
1751 _cairo_draw_line (cr, &style->black,
1752 x + width - 2, y + 2, x + width - 2, y + height - 3);
1753 _cairo_draw_line (cr, &style->light[state],
1754 x + width - 1, y + 1, x + width - 1, y + height - 2);
1755 _cairo_draw_line (cr, &style->light[state],
1756 x, y + height - 1, x + width - 1, y + height - 1);
1757 _cairo_draw_line (cr, &style->bg[state],
1758 x, y + height - 2, x + width - 2, y + height - 2);
1759 _cairo_draw_line (cr, &style->black,
1760 x, y + 2, x, y + height - 3);
1764 _cairo_draw_line (cr, &style->dark[state],
1765 x, y, x + width - 1, y);
1766 _cairo_draw_line (cr, &style->dark[state],
1767 x, y + 1, x, y + height - 1);
1768 _cairo_draw_line (cr, &style->black,
1769 x + 1, y + 1, x + width - 1, y + 1);
1770 _cairo_draw_line (cr, &style->black,
1771 x + 1, y + 2, x + 1, y + height - 2);
1772 _cairo_draw_line (cr, &style->black,
1773 x + width - 1, y + 2, x + width - 1, y + height - 3);
1774 _cairo_draw_line (cr, &style->light[state],
1775 x + 1, y + height - 1, x + width - 1, y + height - 1);
1776 _cairo_draw_line (cr, &style->bg[state],
1777 x + 2, y + height - 2, x + width - 1, y + height - 2);
1782 draw_menu_shadow (GtkStyle *style,
1790 if (style->ythickness > 0)
1792 if (style->ythickness > 1)
1794 _cairo_draw_line (cr, &style->dark[state],
1795 x + 1, y + height - 2,
1796 x + width - 2, y + height - 2);
1797 _cairo_draw_line (cr, &style->black,
1798 x, y + height - 1, x + width - 1, y + height - 1);
1802 _cairo_draw_line (cr, &style->dark[state],
1803 x + 1, y + height - 1, x + width - 1, y + height - 1);
1807 if (style->xthickness > 0)
1809 if (style->xthickness > 1)
1811 _cairo_draw_line (cr, &style->dark[state],
1812 x + width - 2, y + 1,
1813 x + width - 2, y + height - 2);
1815 _cairo_draw_line (cr, &style->black,
1816 x + width - 1, y, x + width - 1, y + height - 1);
1820 _cairo_draw_line (cr, &style->dark[state],
1821 x + width - 1, y + 1, x + width - 1, y + height - 1);
1825 /* Light around top and left */
1827 if (style->ythickness > 0)
1828 _cairo_draw_line (cr, &style->black,
1829 x, y, x + width - 2, y);
1830 if (style->xthickness > 0)
1831 _cairo_draw_line (cr, &style->black,
1832 x, y, x, y + height - 2);
1834 if (style->ythickness > 1)
1835 _cairo_draw_line (cr, &style->light[state],
1836 x + 1, y + 1, x + width - 3, y + 1);
1837 if (style->xthickness > 1)
1838 _cairo_draw_line (cr, &style->light[state],
1839 x + 1, y + 1, x + 1, y + height - 3);
1842 static GtkTextDirection
1843 get_direction (GtkWidget *widget)
1845 GtkTextDirection dir;
1848 dir = gtk_widget_get_direction (widget);
1850 dir = GTK_TEXT_DIR_LTR;
1857 gtk_default_draw_shadow (GtkStyle *style,
1859 GtkStateType state_type,
1860 GtkShadowType shadow_type,
1862 const gchar *detail,
1868 GdkColor *gc1 = NULL;
1869 GdkColor *gc2 = NULL;
1870 gint thickness_light;
1871 gint thickness_dark;
1874 cairo_set_line_width (cr, 1.0);
1876 if (shadow_type == GTK_SHADOW_IN)
1878 if (detail && strcmp (detail, "buttondefault") == 0)
1880 _cairo_draw_rectangle (cr, &style->black, FALSE,
1881 x, y, width - 1, height - 1);
1885 if (detail && strcmp (detail, "trough") == 0)
1887 draw_thin_shadow (style, cr, state_type,
1888 x, y, width, height);
1892 if (GTK_IS_SPIN_BUTTON (widget) &&
1893 detail && strcmp (detail, "spinbutton") == 0)
1895 draw_spinbutton_shadow (style, cr, state_type,
1896 get_direction (widget), x, y, width, height);
1902 if (shadow_type == GTK_SHADOW_OUT && detail && strcmp (detail, "menu") == 0)
1904 draw_menu_shadow (style, cr, state_type, x, y, width, height);
1908 switch (shadow_type)
1910 case GTK_SHADOW_NONE:
1913 case GTK_SHADOW_ETCHED_IN:
1914 gc1 = &style->light[state_type];
1915 gc2 = &style->dark[state_type];
1917 case GTK_SHADOW_OUT:
1918 case GTK_SHADOW_ETCHED_OUT:
1919 gc1 = &style->dark[state_type];
1920 gc2 = &style->light[state_type];
1924 switch (shadow_type)
1926 case GTK_SHADOW_NONE:
1930 /* Light around right and bottom edge */
1932 if (style->ythickness > 0)
1933 _cairo_draw_line (cr, gc1,
1934 x, y + height - 1, x + width - 1, y + height - 1);
1935 if (style->xthickness > 0)
1936 _cairo_draw_line (cr, gc1,
1937 x + width - 1, y, x + width - 1, y + height - 1);
1939 if (style->ythickness > 1)
1940 _cairo_draw_line (cr, &style->bg[state_type],
1941 x + 1, y + height - 2, x + width - 2, y + height - 2);
1942 if (style->xthickness > 1)
1943 _cairo_draw_line (cr, &style->bg[state_type],
1944 x + width - 2, y + 1, x + width - 2, y + height - 2);
1946 /* Dark around left and top */
1948 if (style->ythickness > 1)
1949 _cairo_draw_line (cr, &style->black,
1950 x + 1, y + 1, x + width - 2, y + 1);
1951 if (style->xthickness > 1)
1952 _cairo_draw_line (cr, &style->black,
1953 x + 1, y + 1, x + 1, y + height - 2);
1955 if (style->ythickness > 0)
1956 _cairo_draw_line (cr, gc2,
1957 x, y, x + width - 1, y);
1958 if (style->xthickness > 0)
1959 _cairo_draw_line (cr, gc2,
1960 x, y, x, y + height - 1);
1963 case GTK_SHADOW_OUT:
1964 /* Dark around right and bottom edge */
1966 if (style->ythickness > 0)
1968 if (style->ythickness > 1)
1970 _cairo_draw_line (cr, gc1,
1971 x + 1, y + height - 2, x + width - 2, y + height - 2);
1972 _cairo_draw_line (cr, &style->black,
1973 x, y + height - 1, x + width - 1, y + height - 1);
1977 _cairo_draw_line (cr, gc1,
1978 x + 1, y + height - 1, x + width - 1, y + height - 1);
1982 if (style->xthickness > 0)
1984 if (style->xthickness > 1)
1986 _cairo_draw_line (cr, gc1,
1987 x + width - 2, y + 1, x + width - 2, y + height - 2);
1989 _cairo_draw_line (cr, &style->black,
1990 x + width - 1, y, x + width - 1, y + height - 1);
1994 _cairo_draw_line (cr, gc1,
1995 x + width - 1, y + 1, x + width - 1, y + height - 1);
1999 /* Light around top and left */
2001 if (style->ythickness > 0)
2002 _cairo_draw_line (cr, gc2,
2003 x, y, x + width - 2, y);
2004 if (style->xthickness > 0)
2005 _cairo_draw_line (cr, gc2,
2006 x, y, x, y + height - 2);
2008 if (style->ythickness > 1)
2009 _cairo_draw_line (cr, &style->bg[state_type],
2010 x + 1, y + 1, x + width - 3, y + 1);
2011 if (style->xthickness > 1)
2012 _cairo_draw_line (cr, &style->bg[state_type],
2013 x + 1, y + 1, x + 1, y + height - 3);
2016 case GTK_SHADOW_ETCHED_IN:
2017 case GTK_SHADOW_ETCHED_OUT:
2018 if (style->xthickness > 0)
2020 if (style->xthickness > 1)
2022 thickness_light = 1;
2025 for (i = 0; i < thickness_dark; i++)
2027 _cairo_draw_line (cr, gc1,
2031 y + height - i - 1);
2032 _cairo_draw_line (cr, gc2,
2036 y + height - i - 2);
2039 for (i = 0; i < thickness_light; i++)
2041 _cairo_draw_line (cr, gc1,
2042 x + thickness_dark + i,
2043 y + thickness_dark + i,
2044 x + thickness_dark + i,
2045 y + height - thickness_dark - i - 1);
2046 _cairo_draw_line (cr, gc2,
2047 x + width - thickness_light - i - 1,
2048 y + thickness_dark + i,
2049 x + width - thickness_light - i - 1,
2050 y + height - thickness_light - 1);
2055 _cairo_draw_line (cr,
2056 &style->dark[state_type],
2057 x, y, x, y + height);
2058 _cairo_draw_line (cr,
2059 &style->dark[state_type],
2060 x + width, y, x + width, y + height);
2064 if (style->ythickness > 0)
2066 if (style->ythickness > 1)
2068 thickness_light = 1;
2071 for (i = 0; i < thickness_dark; i++)
2073 _cairo_draw_line (cr, gc1,
2077 y + height - i - 1);
2079 _cairo_draw_line (cr, gc2,
2086 for (i = 0; i < thickness_light; i++)
2088 _cairo_draw_line (cr, gc1,
2089 x + thickness_dark + i,
2090 y + thickness_dark + i,
2091 x + width - thickness_dark - i - 2,
2092 y + thickness_dark + i);
2094 _cairo_draw_line (cr, gc2,
2095 x + thickness_dark + i,
2096 y + height - thickness_light - i - 1,
2097 x + width - thickness_light - 1,
2098 y + height - thickness_light - i - 1);
2103 _cairo_draw_line (cr,
2104 &style->dark[state_type],
2105 x, y, x + width, y);
2106 _cairo_draw_line (cr,
2107 &style->dark[state_type],
2108 x, y + height, x + width, y + height);
2115 if (shadow_type == GTK_SHADOW_IN &&
2116 GTK_IS_SPIN_BUTTON (widget) &&
2117 detail && strcmp (detail, "entry") == 0)
2119 if (get_direction (widget) == GTK_TEXT_DIR_LTR)
2121 _cairo_draw_line (cr,
2122 &style->base[state_type],
2123 x + width - 1, y + 2,
2124 x + width - 1, y + height - 3);
2125 _cairo_draw_line (cr,
2126 &style->base[state_type],
2127 x + width - 2, y + 2,
2128 x + width - 2, y + height - 3);
2130 _cairo_draw_point (cr,
2132 x + width - 1, y + 1);
2133 _cairo_draw_point (cr,
2134 &style->bg[state_type],
2135 x + width - 1, y + height - 2);
2139 _cairo_draw_line (cr,
2140 &style->base[state_type],
2143 _cairo_draw_line (cr,
2144 &style->base[state_type],
2146 x + 1, y + height - 3);
2148 _cairo_draw_point (cr,
2152 _cairo_draw_line (cr,
2153 &style->bg[state_type],
2155 x + 1, y + height - 2);
2156 _cairo_draw_point (cr,
2157 &style->light[state_type],
2164 draw_arrow (cairo_t *cr,
2166 GtkArrowType arrow_type,
2172 gdk_cairo_set_source_color (cr, color);
2175 if (arrow_type == GTK_ARROW_DOWN)
2177 cairo_move_to (cr, x, y);
2178 cairo_line_to (cr, x + width, y);
2179 cairo_line_to (cr, x + width / 2., y + height);
2181 else if (arrow_type == GTK_ARROW_UP)
2183 cairo_move_to (cr, x, y + height);
2184 cairo_line_to (cr, x + width / 2., y);
2185 cairo_line_to (cr, x + width, y + height);
2187 else if (arrow_type == GTK_ARROW_LEFT)
2189 cairo_move_to (cr, x + width, y);
2190 cairo_line_to (cr, x + width, y + height);
2191 cairo_line_to (cr, x, y + height / 2.);
2193 else if (arrow_type == GTK_ARROW_RIGHT)
2195 cairo_move_to (cr, x, y);
2196 cairo_line_to (cr, x + width, y + height / 2.);
2197 cairo_line_to (cr, x, y + height);
2200 cairo_close_path (cr);
2207 calculate_arrow_geometry (GtkArrowType arrow_type,
2219 case GTK_ARROW_DOWN:
2229 if (arrow_type == GTK_ARROW_DOWN)
2231 if (*height % 2 == 1 || h % 2 == 0)
2236 if (*height % 2 == 0 || h % 2 == 0)
2241 case GTK_ARROW_RIGHT:
2242 case GTK_ARROW_LEFT:
2252 if (arrow_type == GTK_ARROW_RIGHT)
2254 if (*width % 2 == 1 || w % 2 == 0)
2259 if (*width % 2 == 0 || w % 2 == 0)
2265 /* should not be reached */
2269 *x += (*width - w) / 2;
2270 *y += (*height - h) / 2;
2276 gtk_default_draw_arrow (GtkStyle *style,
2279 GtkShadowType shadow,
2281 const gchar *detail,
2282 GtkArrowType arrow_type,
2289 calculate_arrow_geometry (arrow_type, &x, &y, &width, &height);
2291 if (detail && strcmp (detail, "menu_scroll_arrow_up") == 0)
2294 if (state == GTK_STATE_INSENSITIVE)
2295 draw_arrow (cr, &style->white, arrow_type,
2296 x + 1, y + 1, width, height);
2297 draw_arrow (cr, &style->fg[state], arrow_type,
2298 x, y, width, height);
2302 gtk_default_draw_diamond (GtkStyle *style,
2304 GtkStateType state_type,
2305 GtkShadowType shadow_type,
2307 const gchar *detail,
2315 GdkColor *outer_nw = NULL;
2316 GdkColor *outer_ne = NULL;
2317 GdkColor *outer_sw = NULL;
2318 GdkColor *outer_se = NULL;
2319 GdkColor *middle_nw = NULL;
2320 GdkColor *middle_ne = NULL;
2321 GdkColor *middle_sw = NULL;
2322 GdkColor *middle_se = NULL;
2323 GdkColor *inner_nw = NULL;
2324 GdkColor *inner_ne = NULL;
2325 GdkColor *inner_sw = NULL;
2326 GdkColor *inner_se = NULL;
2328 half_width = width / 2;
2329 half_height = height / 2;
2331 switch (shadow_type)
2334 inner_sw = inner_se = &style->bg[state_type];
2335 middle_sw = middle_se = &style->light[state_type];
2336 outer_sw = outer_se = &style->light[state_type];
2337 inner_nw = inner_ne = &style->black;
2338 middle_nw = middle_ne = &style->dark[state_type];
2339 outer_nw = outer_ne = &style->dark[state_type];
2342 case GTK_SHADOW_OUT:
2343 inner_sw = inner_se = &style->dark[state_type];
2344 middle_sw = middle_se = &style->dark[state_type];
2345 outer_sw = outer_se = &style->black;
2346 inner_nw = inner_ne = &style->bg[state_type];
2347 middle_nw = middle_ne = &style->light[state_type];
2348 outer_nw = outer_ne = &style->light[state_type];
2351 case GTK_SHADOW_ETCHED_IN:
2352 inner_sw = inner_se = &style->bg[state_type];
2353 middle_sw = middle_se = &style->dark[state_type];
2354 outer_sw = outer_se = &style->light[state_type];
2355 inner_nw = inner_ne = &style->bg[state_type];
2356 middle_nw = middle_ne = &style->light[state_type];
2357 outer_nw = outer_ne = &style->dark[state_type];
2360 case GTK_SHADOW_ETCHED_OUT:
2361 inner_sw = inner_se = &style->bg[state_type];
2362 middle_sw = middle_se = &style->light[state_type];
2363 outer_sw = outer_se = &style->dark[state_type];
2364 inner_nw = inner_ne = &style->bg[state_type];
2365 middle_nw = middle_ne = &style->dark[state_type];
2366 outer_nw = outer_ne = &style->light[state_type];
2376 _cairo_draw_line (cr, inner_sw,
2377 x + 2, y + half_height,
2378 x + half_width, y + height - 2);
2379 _cairo_draw_line (cr, inner_se,
2380 x + half_width, y + height - 2,
2381 x + width - 2, y + half_height);
2382 _cairo_draw_line (cr, middle_sw,
2383 x + 1, y + half_height,
2384 x + half_width, y + height - 1);
2385 _cairo_draw_line (cr, middle_se,
2386 x + half_width, y + height - 1,
2387 x + width - 1, y + half_height);
2388 _cairo_draw_line (cr, outer_sw,
2390 x + half_width, y + height);
2391 _cairo_draw_line (cr, outer_se,
2392 x + half_width, y + height,
2393 x + width, y + half_height);
2395 _cairo_draw_line (cr, inner_nw,
2396 x + 2, y + half_height,
2397 x + half_width, y + 2);
2398 _cairo_draw_line (cr, inner_ne,
2399 x + half_width, y + 2,
2400 x + width - 2, y + half_height);
2401 _cairo_draw_line (cr, middle_nw,
2402 x + 1, y + half_height,
2403 x + half_width, y + 1);
2404 _cairo_draw_line (cr, middle_ne,
2405 x + half_width, y + 1,
2406 x + width - 1, y + half_height);
2407 _cairo_draw_line (cr, outer_nw,
2410 _cairo_draw_line (cr, outer_ne,
2412 x + width, y + half_height);
2417 option_menu_get_props (GtkWidget *widget,
2418 GtkRequisition *indicator_size,
2419 GtkBorder *indicator_spacing)
2421 GtkRequisition *tmp_size = NULL;
2422 GtkBorder *tmp_spacing = NULL;
2426 *indicator_size = *tmp_size;
2427 gtk_requisition_free (tmp_size);
2430 *indicator_size = default_option_indicator_size;
2434 *indicator_spacing = *tmp_spacing;
2435 gtk_border_free (tmp_spacing);
2438 *indicator_spacing = default_option_indicator_spacing;
2442 gtk_default_draw_box (GtkStyle *style,
2444 GtkStateType state_type,
2445 GtkShadowType shadow_type,
2447 const gchar *detail,
2453 gboolean is_spinbutton_box = FALSE;
2455 if (GTK_IS_SPIN_BUTTON (widget) && detail)
2457 if (strcmp (detail, "spinbutton_up") == 0)
2463 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
2468 is_spinbutton_box = TRUE;
2470 else if (strcmp (detail, "spinbutton_down") == 0)
2475 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
2480 is_spinbutton_box = TRUE;
2484 if (!style->bg_pixmap[state_type])
2486 GdkColor *gc = &style->bg[state_type];
2488 if (state_type == GTK_STATE_SELECTED && detail && strcmp (detail, "paned") == 0)
2490 if (widget && !gtk_widget_has_focus (widget))
2491 gc = &style->base[GTK_STATE_ACTIVE];
2494 _cairo_draw_rectangle (cr, gc, TRUE,
2495 x, y, width, height);
2498 gtk_style_apply_default_background (style, cr, gtk_widget_get_window (widget),
2499 state_type, x, y, width, height);
2502 if (is_spinbutton_box)
2507 lower = &style->dark[state_type];
2508 if (shadow_type == GTK_SHADOW_OUT)
2509 upper = &style->light[state_type];
2511 upper = &style->dark[state_type];
2513 _cairo_draw_line (cr, upper, x, y, x + width - 1, y);
2514 _cairo_draw_line (cr, lower, x, y + height - 1, x + width - 1, y + height - 1);
2519 gtk_cairo_paint_shadow (style, cr, state_type, shadow_type, widget, detail,
2520 x, y, width, height);
2522 if (detail && strcmp (detail, "optionmenu") == 0)
2524 GtkRequisition indicator_size;
2525 GtkBorder indicator_spacing;
2528 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
2530 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
2531 vline_x = x + indicator_size.width + indicator_spacing.left + indicator_spacing.right;
2533 vline_x = x + width - (indicator_size.width + indicator_spacing.left + indicator_spacing.right) - style->xthickness;
2535 gtk_cairo_paint_vline (style, cr, state_type, widget,
2537 y + style->ythickness + 1,
2538 y + height - style->ythickness - 3,
2544 get_darkened (const GdkColor *color,
2547 GdkColor src = *color;
2548 GdkColor shaded = *color;
2550 while (darken_count)
2552 _gtk_style_shade (&src, &shaded, 0.93);
2557 return gdk_color_copy (&shaded);
2561 gtk_default_draw_flat_box (GtkStyle *style,
2563 GtkStateType state_type,
2564 GtkShadowType shadow_type,
2566 const gchar *detail,
2573 GdkColor *freeme = NULL;
2575 cairo_set_line_width (cr, 1.0);
2579 int trimmed_len = strlen (detail);
2581 if (g_str_has_prefix (detail, "cell_"))
2583 if (g_str_has_suffix (detail, "_start"))
2585 else if (g_str_has_suffix (detail, "_middle"))
2587 else if (g_str_has_suffix (detail, "_end"))
2591 if (state_type == GTK_STATE_SELECTED)
2593 if (!strcmp ("text", detail))
2594 gc1 = &style->bg[GTK_STATE_SELECTED];
2595 else if (!strncmp ("cell_even", detail, trimmed_len) ||
2596 !strncmp ("cell_odd", detail, trimmed_len) ||
2597 !strncmp ("cell_even_ruled", detail, trimmed_len) ||
2598 !strncmp ("cell_even_ruled_sorted", detail, trimmed_len))
2600 /* This has to be really broken; alex made me do it. -jrb */
2601 if (widget && gtk_widget_has_focus (widget))
2602 gc1 = &style->base[state_type];
2604 gc1 = &style->base[GTK_STATE_ACTIVE];
2606 else if (!strncmp ("cell_odd_ruled", detail, trimmed_len) ||
2607 !strncmp ("cell_odd_ruled_sorted", detail, trimmed_len))
2609 if (widget && gtk_widget_has_focus (widget))
2610 freeme = get_darkened (&style->base[state_type], 1);
2612 freeme = get_darkened (&style->base[GTK_STATE_ACTIVE], 1);
2617 gc1 = &style->bg[state_type];
2622 if (!strcmp ("viewportbin", detail))
2623 gc1 = &style->bg[GTK_STATE_NORMAL];
2624 else if (!strcmp ("entry_bg", detail))
2625 gc1 = &style->base[gtk_widget_get_state (widget)];
2627 /* For trees: even rows are base color, odd rows are a shade of
2628 * the base color, the sort column is a shade of the original color
2632 else if (!strncmp ("cell_even", detail, trimmed_len) ||
2633 !strncmp ("cell_odd", detail, trimmed_len) ||
2634 !strncmp ("cell_even_ruled", detail, trimmed_len))
2636 GdkColor *color = NULL;
2638 gtk_widget_style_get (widget,
2639 "even-row-color", &color,
2644 freeme = get_darkened (color, 0);
2647 gdk_color_free (color);
2650 gc1 = &style->base[state_type];
2652 else if (!strncmp ("cell_odd_ruled", detail, trimmed_len))
2654 GdkColor *color = NULL;
2656 gtk_widget_style_get (widget,
2657 "odd-row-color", &color,
2662 freeme = get_darkened (color, 0);
2665 gdk_color_free (color);
2669 gtk_widget_style_get (widget,
2670 "even-row-color", &color,
2675 freeme = get_darkened (color, 1);
2676 gdk_color_free (color);
2679 freeme = get_darkened (&style->base[state_type], 1);
2683 else if (!strncmp ("cell_even_sorted", detail, trimmed_len) ||
2684 !strncmp ("cell_odd_sorted", detail, trimmed_len) ||
2685 !strncmp ("cell_even_ruled_sorted", detail, trimmed_len))
2687 GdkColor *color = NULL;
2689 if (!strncmp ("cell_odd_sorted", detail, trimmed_len))
2690 gtk_widget_style_get (widget,
2691 "odd-row-color", &color,
2694 gtk_widget_style_get (widget,
2695 "even-row-color", &color,
2700 freeme = get_darkened (color, 1);
2703 gdk_color_free (color);
2707 freeme = get_darkened (&style->base[state_type], 1);
2711 else if (!strncmp ("cell_odd_ruled_sorted", detail, trimmed_len))
2713 GdkColor *color = NULL;
2715 gtk_widget_style_get (widget,
2716 "odd-row-color", &color,
2721 freeme = get_darkened (color, 1);
2724 gdk_color_free (color);
2728 gtk_widget_style_get (widget,
2729 "even-row-color", &color,
2734 freeme = get_darkened (color, 2);
2735 gdk_color_free (color);
2738 freeme = get_darkened (&style->base[state_type], 2);
2743 gc1 = &style->bg[state_type];
2747 gc1 = &style->bg[state_type];
2749 if (!style->bg_pixmap[state_type] || gc1 != &style->bg[state_type])
2751 _cairo_draw_rectangle (cr, gc1, TRUE,
2752 x, y, width, height);
2754 if (detail && !strcmp ("tooltip", detail))
2755 _cairo_draw_rectangle (cr, &style->black, FALSE,
2756 x, y, width - 1, height - 1);
2759 gtk_style_apply_default_background (style, cr, gtk_widget_get_window (widget),
2760 state_type, x, y, width, height);
2763 gdk_color_free (freeme);
2767 gtk_default_draw_check (GtkStyle *style,
2769 GtkStateType state_type,
2770 GtkShadowType shadow_type,
2772 const gchar *detail,
2778 enum { BUTTON, MENU, CELL } type = BUTTON;
2785 if (strcmp (detail, "cellcheck") == 0)
2787 else if (strcmp (detail, "check") == 0)
2791 exterior_size = MIN (width, height);
2792 if (exterior_size % 2 == 0) /* Ensure odd */
2795 pad = style->xthickness + MAX (1, (exterior_size - 2 * style->xthickness) / 9);
2796 interior_size = MAX (1, exterior_size - 2 * pad);
2798 if (interior_size < 7)
2801 pad = MAX (0, (exterior_size - interior_size) / 2);
2804 x -= (1 + exterior_size - width) / 2;
2805 y -= (1 + exterior_size - height) / 2;
2812 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
2814 gdk_cairo_set_source_color (cr, &style->text[state_type]);
2816 cairo_set_line_width (cr, 1.0);
2817 cairo_rectangle (cr, x + 0.5, y + 0.5, exterior_size - 1, exterior_size - 1);
2820 gdk_cairo_set_source_color (cr, &style->base[state_type]);
2821 cairo_rectangle (cr, x + 1, y + 1, exterior_size - 2, exterior_size - 2);
2833 gdk_cairo_set_source_color (cr, &style->text[state_type]);
2836 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
2840 if (shadow_type == GTK_SHADOW_IN)
2842 cairo_translate (cr,
2845 cairo_scale (cr, interior_size / 7., interior_size / 7.);
2847 cairo_move_to (cr, 7.0, 0.0);
2848 cairo_line_to (cr, 7.5, 1.0);
2849 cairo_curve_to (cr, 5.3, 2.0,
2852 cairo_curve_to (cr, 3.0, 5.7,
2855 cairo_line_to (cr, 0.2, 3.5);
2856 cairo_curve_to (cr, 1.1, 3.5,
2859 cairo_curve_to (cr, 1.0, 3.9,
2862 cairo_curve_to (cr, 3.5, 3.1,
2868 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
2870 int line_thickness = MAX (1, (3 + interior_size * 2) / 7);
2872 cairo_rectangle (cr,
2874 y + pad + (1 + interior_size - line_thickness) / 2,
2882 gtk_default_draw_option (GtkStyle *style,
2884 GtkStateType state_type,
2885 GtkShadowType shadow_type,
2887 const gchar *detail,
2893 enum { BUTTON, MENU, CELL } type = BUTTON;
2898 if (strcmp (detail, "radio") == 0)
2900 else if (strcmp (detail, "option") == 0)
2904 exterior_size = MIN (width, height);
2905 if (exterior_size % 2 == 0) /* Ensure odd */
2908 x -= (1 + exterior_size - width) / 2;
2909 y -= (1 + exterior_size - height) / 2;
2915 gdk_cairo_set_source_color (cr, &style->base[state_type]);
2918 x + exterior_size / 2.,
2919 y + exterior_size / 2.,
2920 (exterior_size - 1) / 2.,
2923 cairo_fill_preserve (cr);
2926 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
2928 gdk_cairo_set_source_color (cr, &style->text[state_type]);
2930 cairo_set_line_width (cr, 1.);
2941 gdk_cairo_set_source_color (cr, &style->text[state_type]);
2946 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
2950 if (shadow_type == GTK_SHADOW_IN)
2952 int pad = style->xthickness + MAX (1, 2 * (exterior_size - 2 * style->xthickness) / 9);
2953 int interior_size = MAX (1, exterior_size - 2 * pad);
2955 if (interior_size < 5)
2958 pad = MAX (0, (exterior_size - interior_size) / 2);
2962 x + pad + interior_size / 2.,
2963 y + pad + interior_size / 2.,
2968 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
2970 int pad = style->xthickness + MAX (1, (exterior_size - 2 * style->xthickness) / 9);
2971 int interior_size = MAX (1, exterior_size - 2 * pad);
2974 if (interior_size < 7)
2977 pad = MAX (0, (exterior_size - interior_size) / 2);
2980 line_thickness = MAX (1, (3 + interior_size * 2) / 7);
2982 cairo_rectangle (cr,
2984 y + pad + (interior_size - line_thickness) / 2.,
2992 gtk_default_draw_tab (GtkStyle *style,
2994 GtkStateType state_type,
2995 GtkShadowType shadow_type,
2997 const gchar *detail,
3003 #define ARROW_SPACE 4
3005 GtkRequisition indicator_size;
3006 GtkBorder indicator_spacing;
3009 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
3011 indicator_size.width += (indicator_size.width % 2) - 1;
3012 arrow_height = indicator_size.width / 2 + 1;
3014 x += (width - indicator_size.width) / 2;
3015 y += (height - (2 * arrow_height + ARROW_SPACE)) / 2;
3017 if (state_type == GTK_STATE_INSENSITIVE)
3019 draw_arrow (cr, &style->white,
3020 GTK_ARROW_UP, x + 1, y + 1,
3021 indicator_size.width, arrow_height);
3023 draw_arrow (cr, &style->white,
3024 GTK_ARROW_DOWN, x + 1, y + arrow_height + ARROW_SPACE + 1,
3025 indicator_size.width, arrow_height);
3028 draw_arrow (cr, &style->fg[state_type],
3030 indicator_size.width, arrow_height);
3033 draw_arrow (cr, &style->fg[state_type],
3034 GTK_ARROW_DOWN, x, y + arrow_height + ARROW_SPACE,
3035 indicator_size.width, arrow_height);
3039 gtk_default_draw_shadow_gap (GtkStyle *style,
3041 GtkStateType state_type,
3042 GtkShadowType shadow_type,
3044 const gchar *detail,
3049 GtkPositionType gap_side,
3053 GdkColor *color1 = NULL;
3054 GdkColor *color2 = NULL;
3055 GdkColor *color3 = NULL;
3056 GdkColor *color4 = NULL;
3058 switch (shadow_type)
3060 case GTK_SHADOW_NONE:
3064 color1 = &style->dark[state_type];
3065 color2 = &style->black;
3066 color3 = &style->bg[state_type];
3067 color4 = &style->light[state_type];
3069 case GTK_SHADOW_ETCHED_IN:
3070 color1 = &style->dark[state_type];
3071 color2 = &style->light[state_type];
3072 color3 = &style->dark[state_type];
3073 color4 = &style->light[state_type];
3075 case GTK_SHADOW_OUT:
3076 color1 = &style->light[state_type];
3077 color2 = &style->bg[state_type];
3078 color3 = &style->dark[state_type];
3079 color4 = &style->black;
3081 case GTK_SHADOW_ETCHED_OUT:
3082 color1 = &style->light[state_type];
3083 color2 = &style->dark[state_type];
3084 color3 = &style->light[state_type];
3085 color4 = &style->dark[state_type];
3089 switch (shadow_type)
3091 case GTK_SHADOW_NONE:
3093 case GTK_SHADOW_OUT:
3094 case GTK_SHADOW_ETCHED_IN:
3095 case GTK_SHADOW_ETCHED_OUT:
3099 _cairo_draw_line (cr, color1,
3100 x, y, x, y + height - 1);
3101 _cairo_draw_line (cr, color2,
3102 x + 1, y, x + 1, y + height - 2);
3104 _cairo_draw_line (cr, color3,
3105 x + 1, y + height - 2, x + width - 2, y + height - 2);
3106 _cairo_draw_line (cr, color3,
3107 x + width - 2, y, x + width - 2, y + height - 2);
3108 _cairo_draw_line (cr, color4,
3109 x, y + height - 1, x + width - 1, y + height - 1);
3110 _cairo_draw_line (cr, color4,
3111 x + width - 1, y, x + width - 1, y + height - 1);
3114 _cairo_draw_line (cr, color1,
3115 x, y, x + gap_x - 1, y);
3116 _cairo_draw_line (cr, color2,
3117 x + 1, y + 1, x + gap_x - 1, y + 1);
3118 _cairo_draw_line (cr, color2,
3119 x + gap_x, y, x + gap_x, y);
3121 if ((width - (gap_x + gap_width)) > 0)
3123 _cairo_draw_line (cr, color1,
3124 x + gap_x + gap_width, y, x + width - 2, y);
3125 _cairo_draw_line (cr, color2,
3126 x + gap_x + gap_width, y + 1, x + width - 3, y + 1);
3127 _cairo_draw_line (cr, color2,
3128 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
3131 case GTK_POS_BOTTOM:
3132 _cairo_draw_line (cr, color1,
3133 x, y, x + width - 1, y);
3134 _cairo_draw_line (cr, color1,
3135 x, y, x, y + height - 1);
3136 _cairo_draw_line (cr, color2,
3137 x + 1, y + 1, x + width - 2, y + 1);
3138 _cairo_draw_line (cr, color2,
3139 x + 1, y + 1, x + 1, y + height - 1);
3141 _cairo_draw_line (cr, color3,
3142 x + width - 2, y + 1, x + width - 2, y + height - 1);
3143 _cairo_draw_line (cr, color4,
3144 x + width - 1, y, x + width - 1, y + height - 1);
3147 _cairo_draw_line (cr, color4,
3148 x, y + height - 1, x + gap_x - 1, y + height - 1);
3149 _cairo_draw_line (cr, color3,
3150 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
3151 _cairo_draw_line (cr, color3,
3152 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
3154 if ((width - (gap_x + gap_width)) > 0)
3156 _cairo_draw_line (cr, color4,
3157 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
3158 _cairo_draw_line (cr, color3,
3159 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
3160 _cairo_draw_line (cr, color3,
3161 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
3165 _cairo_draw_line (cr, color1,
3166 x, y, x + width - 1, y);
3167 _cairo_draw_line (cr, color2,
3168 x, y + 1, x + width - 2, y + 1);
3170 _cairo_draw_line (cr, color3,
3171 x, y + height - 2, x + width - 2, y + height - 2);
3172 _cairo_draw_line (cr, color3,
3173 x + width - 2, y + 1, x + width - 2, y + height - 2);
3174 _cairo_draw_line (cr, color4,
3175 x, y + height - 1, x + width - 1, y + height - 1);
3176 _cairo_draw_line (cr, color4,
3177 x + width - 1, y, x + width - 1, y + height - 1);
3180 _cairo_draw_line (cr, color1,
3181 x, y, x, y + gap_x - 1);
3182 _cairo_draw_line (cr, color2,
3183 x + 1, y + 1, x + 1, y + gap_x - 1);
3184 _cairo_draw_line (cr, color2,
3185 x, y + gap_x, x, y + gap_x);
3187 if ((width - (gap_x + gap_width)) > 0)
3189 _cairo_draw_line (cr, color1,
3190 x, y + gap_x + gap_width, x, y + height - 2);
3191 _cairo_draw_line (cr, color2,
3192 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
3193 _cairo_draw_line (cr, color2,
3194 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
3198 _cairo_draw_line (cr, color1,
3199 x, y, x + width - 1, y);
3200 _cairo_draw_line (cr, color1,
3201 x, y, x, y + height - 1);
3202 _cairo_draw_line (cr, color2,
3203 x + 1, y + 1, x + width - 1, y + 1);
3204 _cairo_draw_line (cr, color2,
3205 x + 1, y + 1, x + 1, y + height - 2);
3207 _cairo_draw_line (cr, color3,
3208 x + 1, y + height - 2, x + width - 1, y + height - 2);
3209 _cairo_draw_line (cr, color4,
3210 x, y + height - 1, x + width - 1, y + height - 1);
3213 _cairo_draw_line (cr, color4,
3214 x + width - 1, y, x + width - 1, y + gap_x - 1);
3215 _cairo_draw_line (cr, color3,
3216 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
3217 _cairo_draw_line (cr, color3,
3218 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
3220 if ((width - (gap_x + gap_width)) > 0)
3222 _cairo_draw_line (cr, color4,
3223 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
3224 _cairo_draw_line (cr, color3,
3225 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
3226 _cairo_draw_line (cr, color3,
3227 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
3235 gtk_default_draw_box_gap (GtkStyle *style,
3237 GtkStateType state_type,
3238 GtkShadowType shadow_type,
3240 const gchar *detail,
3245 GtkPositionType gap_side,
3254 gtk_style_apply_default_background (style, cr, gtk_widget_get_window (widget),
3255 state_type, x, y, width, height);
3257 switch (shadow_type)
3259 case GTK_SHADOW_NONE:
3262 color1 = style->dark[state_type];
3263 color2 = style->black;
3264 color3 = style->bg[state_type];
3265 color4 = style->light[state_type];
3267 case GTK_SHADOW_ETCHED_IN:
3268 color1 = style->dark[state_type];
3269 color2 = style->light[state_type];
3270 color3 = style->dark[state_type];
3271 color4 = style->light[state_type];
3273 case GTK_SHADOW_OUT:
3274 color1 = style->light[state_type];
3275 color2 = style->bg[state_type];
3276 color3 = style->dark[state_type];
3277 color4 = style->black;
3279 case GTK_SHADOW_ETCHED_OUT:
3280 color1 = style->light[state_type];
3281 color2 = style->dark[state_type];
3282 color3 = style->light[state_type];
3283 color4 = style->dark[state_type];
3287 cairo_set_line_width (cr, 1.0);
3289 switch (shadow_type)
3291 case GTK_SHADOW_NONE:
3293 case GTK_SHADOW_OUT:
3294 case GTK_SHADOW_ETCHED_IN:
3295 case GTK_SHADOW_ETCHED_OUT:
3299 _cairo_draw_line (cr, &color1,
3300 x, y, x, y + height - 1);
3301 _cairo_draw_line (cr, &color2,
3302 x + 1, y, x + 1, y + height - 2);
3304 _cairo_draw_line (cr, &color3,
3305 x + 1, y + height - 2, x + width - 2, y + height - 2);
3306 _cairo_draw_line (cr, &color3,
3307 x + width - 2, y, x + width - 2, y + height - 2);
3308 _cairo_draw_line (cr, &color4,
3309 x, y + height - 1, x + width - 1, y + height - 1);
3310 _cairo_draw_line (cr, &color4,
3311 x + width - 1, y, x + width - 1, y + height - 1);
3314 _cairo_draw_line (cr, &color1,
3315 x, y, x + gap_x - 1, y);
3316 _cairo_draw_line (cr, &color2,
3317 x + 1, y + 1, x + gap_x - 1, y + 1);
3318 _cairo_draw_line (cr, &color2,
3319 x + gap_x, y, x + gap_x, y);
3321 if ((width - (gap_x + gap_width)) > 0)
3323 _cairo_draw_line (cr, &color1,
3324 x + gap_x + gap_width, y, x + width - 2, y);
3325 _cairo_draw_line (cr, &color2,
3326 x + gap_x + gap_width, y + 1, x + width - 2, y + 1);
3327 _cairo_draw_line (cr, &color2,
3328 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
3331 case GTK_POS_BOTTOM:
3332 _cairo_draw_line (cr, &color1,
3333 x, y, x + width - 1, y);
3334 _cairo_draw_line (cr, &color1,
3335 x, y, x, y + height - 1);
3336 _cairo_draw_line (cr, &color2,
3337 x + 1, y + 1, x + width - 2, y + 1);
3338 _cairo_draw_line (cr, &color2,
3339 x + 1, y + 1, x + 1, y + height - 1);
3341 _cairo_draw_line (cr, &color3,
3342 x + width - 2, y + 1, x + width - 2, y + height - 1);
3343 _cairo_draw_line (cr, &color4,
3344 x + width - 1, y, x + width - 1, y + height - 1);
3347 _cairo_draw_line (cr, &color4,
3348 x, y + height - 1, x + gap_x - 1, y + height - 1);
3349 _cairo_draw_line (cr, &color3,
3350 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
3351 _cairo_draw_line (cr, &color3,
3352 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
3354 if ((width - (gap_x + gap_width)) > 0)
3356 _cairo_draw_line (cr, &color4,
3357 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
3358 _cairo_draw_line (cr, &color3,
3359 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
3360 _cairo_draw_line (cr, &color3,
3361 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
3365 _cairo_draw_line (cr, &color1,
3366 x, y, x + width - 1, y);
3367 _cairo_draw_line (cr, &color2,
3368 x, y + 1, x + width - 2, y + 1);
3370 _cairo_draw_line (cr, &color3,
3371 x, y + height - 2, x + width - 2, y + height - 2);
3372 _cairo_draw_line (cr, &color3,
3373 x + width - 2, y + 1, x + width - 2, y + height - 2);
3374 _cairo_draw_line (cr, &color4,
3375 x, y + height - 1, x + width - 1, y + height - 1);
3376 _cairo_draw_line (cr, &color4,
3377 x + width - 1, y, x + width - 1, y + height - 1);
3380 _cairo_draw_line (cr, &color1,
3381 x, y, x, y + gap_x - 1);
3382 _cairo_draw_line (cr, &color2,
3383 x + 1, y + 1, x + 1, y + gap_x - 1);
3384 _cairo_draw_line (cr, &color2,
3385 x, y + gap_x, x, y + gap_x);
3387 if ((height - (gap_x + gap_width)) > 0)
3389 _cairo_draw_line (cr, &color1,
3390 x, y + gap_x + gap_width, x, y + height - 2);
3391 _cairo_draw_line (cr, &color2,
3392 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
3393 _cairo_draw_line (cr, &color2,
3394 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
3398 _cairo_draw_line (cr, &color1,
3399 x, y, x + width - 1, y);
3400 _cairo_draw_line (cr, &color1,
3401 x, y, x, y + height - 1);
3402 _cairo_draw_line (cr, &color2,
3403 x + 1, y + 1, x + width - 1, y + 1);
3404 _cairo_draw_line (cr, &color2,
3405 x + 1, y + 1, x + 1, y + height - 2);
3407 _cairo_draw_line (cr, &color3,
3408 x + 1, y + height - 2, x + width - 1, y + height - 2);
3409 _cairo_draw_line (cr, &color4,
3410 x, y + height - 1, x + width - 1, y + height - 1);
3413 _cairo_draw_line (cr, &color4,
3414 x + width - 1, y, x + width - 1, y + gap_x - 1);
3415 _cairo_draw_line (cr, &color3,
3416 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
3417 _cairo_draw_line (cr, &color3,
3418 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
3420 if ((height - (gap_x + gap_width)) > 0)
3422 _cairo_draw_line (cr, &color4,
3423 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
3424 _cairo_draw_line (cr, &color3,
3425 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
3426 _cairo_draw_line (cr, &color3,
3427 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
3435 gtk_default_draw_extension (GtkStyle *style,
3437 GtkStateType state_type,
3438 GtkShadowType shadow_type,
3440 const gchar *detail,
3445 GtkPositionType gap_side)
3447 GdkWindow *window = gtk_widget_get_window (widget);
3456 gtk_style_apply_default_background (style, cr, window,
3463 case GTK_POS_BOTTOM:
3464 gtk_style_apply_default_background (style, cr, window,
3472 gtk_style_apply_default_background (style, cr, window,
3480 gtk_style_apply_default_background (style, cr, window,
3489 switch (shadow_type)
3491 case GTK_SHADOW_NONE:
3494 color1 = style->dark[state_type];
3495 color2 = style->black;
3496 color3 = style->bg[state_type];
3497 color4 = style->light[state_type];
3499 case GTK_SHADOW_ETCHED_IN:
3500 color1 = style->dark[state_type];
3501 color2 = style->light[state_type];
3502 color3 = style->dark[state_type];
3503 color4 = style->light[state_type];
3505 case GTK_SHADOW_OUT:
3506 color1 = style->light[state_type];
3507 color2 = style->bg[state_type];
3508 color3 = style->dark[state_type];
3509 color4 = style->black;
3511 case GTK_SHADOW_ETCHED_OUT:
3512 color1 = style->light[state_type];
3513 color2 = style->dark[state_type];
3514 color3 = style->light[state_type];
3515 color4 = style->dark[state_type];
3519 cairo_set_line_width (cr, 1.0);
3521 switch (shadow_type)
3523 case GTK_SHADOW_NONE:
3525 case GTK_SHADOW_OUT:
3526 case GTK_SHADOW_ETCHED_IN:
3527 case GTK_SHADOW_ETCHED_OUT:
3531 _cairo_draw_line (cr, &color1,
3532 x, y, x, y + height - 2);
3533 _cairo_draw_line (cr, &color2,
3534 x + 1, y, x + 1, y + height - 2);
3536 _cairo_draw_line (cr, &color3,
3537 x + 2, y + height - 2, x + width - 2, y + height - 2);
3538 _cairo_draw_line (cr, &color3,
3539 x + width - 2, y, x + width - 2, y + height - 2);
3540 _cairo_draw_line (cr, &color4,
3541 x + 1, y + height - 1, x + width - 2, y + height - 1);
3542 _cairo_draw_line (cr, &color4,
3543 x + width - 1, y, x + width - 1, y + height - 2);
3545 case GTK_POS_BOTTOM:
3546 _cairo_draw_line (cr, &color1,
3547 x + 1, y, x + width - 2, y);
3548 _cairo_draw_line (cr, &color1,
3549 x, y + 1, x, y + height - 1);
3550 _cairo_draw_line (cr, &color2,
3551 x + 1, y + 1, x + width - 2, y + 1);
3552 _cairo_draw_line (cr, &color2,
3553 x + 1, y + 1, x + 1, y + height - 1);
3555 _cairo_draw_line (cr, &color3,
3556 x + width - 2, y + 2, x + width - 2, y + height - 1);
3557 _cairo_draw_line (cr, &color4,
3558 x + width - 1, y + 1, x + width - 1, y + height - 1);
3561 _cairo_draw_line (cr, &color1,
3562 x, y, x + width - 2, y);
3563 _cairo_draw_line (cr, &color2,
3564 x + 1, y + 1, x + width - 2, y + 1);
3566 _cairo_draw_line (cr, &color3,
3567 x, y + height - 2, x + width - 2, y + height - 2);
3568 _cairo_draw_line (cr, &color3,
3569 x + width - 2, y + 2, x + width - 2, y + height - 2);
3570 _cairo_draw_line (cr, &color4,
3571 x, y + height - 1, x + width - 2, y + height - 1);
3572 _cairo_draw_line (cr, &color4,
3573 x + width - 1, y + 1, x + width - 1, y + height - 2);
3576 _cairo_draw_line (cr, &color1,
3577 x + 1, y, x + width - 1, y);
3578 _cairo_draw_line (cr, &color1,
3579 x, y + 1, x, y + height - 2);
3580 _cairo_draw_line (cr, &color2,
3581 x + 1, y + 1, x + width - 1, y + 1);
3582 _cairo_draw_line (cr, &color2,
3583 x + 1, y + 1, x + 1, y + height - 2);
3585 _cairo_draw_line (cr, &color3,
3586 x + 2, y + height - 2, x + width - 1, y + height - 2);
3587 _cairo_draw_line (cr, &color4,
3588 x + 1, y + height - 1, x + width - 1, y + height - 1);
3595 gtk_default_draw_focus (GtkStyle *style,
3597 GtkStateType state_type,
3599 const gchar *detail,
3605 gboolean free_dash_list = FALSE;
3606 gint line_width = 1;
3607 gint8 *dash_list = (gint8 *) "\1\1";
3611 gtk_widget_style_get (widget,
3612 "focus-line-width", &line_width,
3613 "focus-line-pattern", (gchar *)&dash_list,
3616 free_dash_list = TRUE;
3619 if (detail && !strcmp (detail, "add-mode"))
3624 dash_list = (gint8 *) "\4\4";
3625 free_dash_list = FALSE;
3628 if (detail && !strcmp (detail, "colorwheel_light"))
3629 cairo_set_source_rgb (cr, 0., 0., 0.);
3630 else if (detail && !strcmp (detail, "colorwheel_dark"))
3631 cairo_set_source_rgb (cr, 1., 1., 1.);
3633 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3635 cairo_set_line_width (cr, line_width);
3639 gint n_dashes = strlen ((const gchar *) dash_list);
3640 gdouble *dashes = g_new (gdouble, n_dashes);
3641 gdouble total_length = 0;
3642 gdouble dash_offset;
3645 for (i = 0; i < n_dashes; i++)
3647 dashes[i] = dash_list[i];
3648 total_length += dash_list[i];
3651 /* The dash offset here aligns the pattern to integer pixels
3652 * by starting the dash at the right side of the left border
3653 * Negative dash offsets in cairo don't work
3654 * (https://bugs.freedesktop.org/show_bug.cgi?id=2729)
3656 dash_offset = - line_width / 2.;
3657 while (dash_offset < 0)
3658 dash_offset += total_length;
3660 cairo_set_dash (cr, dashes, n_dashes, dash_offset);
3664 cairo_rectangle (cr,
3665 x + line_width / 2.,
3666 y + line_width / 2.,
3668 height - line_width);
3676 gtk_default_draw_slider (GtkStyle *style,
3678 GtkStateType state_type,
3679 GtkShadowType shadow_type,
3681 const gchar *detail,
3686 GtkOrientation orientation)
3688 gtk_cairo_paint_box (style, cr, state_type, shadow_type,
3689 widget, detail, x, y, width, height);
3692 (strcmp ("hscale", detail) == 0 ||
3693 strcmp ("vscale", detail) == 0))
3695 if (orientation == GTK_ORIENTATION_HORIZONTAL)
3696 gtk_cairo_paint_vline (style, cr, state_type, widget, detail,
3697 y + style->ythickness,
3698 y + height - style->ythickness - 1, x + width / 2);
3700 gtk_cairo_paint_hline (style, cr, state_type, widget, detail,
3701 x + style->xthickness,
3702 x + width - style->xthickness - 1, y + height / 2);
3707 draw_dot (cairo_t *cr,
3714 size = CLAMP (size, 2, 3);
3718 _cairo_draw_point (cr, light, x, y);
3719 _cairo_draw_point (cr, light, x+1, y+1);
3723 _cairo_draw_point (cr, light, x, y);
3724 _cairo_draw_point (cr, light, x+1, y);
3725 _cairo_draw_point (cr, light, x, y+1);
3726 _cairo_draw_point (cr, dark, x+1, y+2);
3727 _cairo_draw_point (cr, dark, x+2, y+1);
3728 _cairo_draw_point (cr, dark, x+2, y+2);
3733 gtk_default_draw_handle (GtkStyle *style,
3735 GtkStateType state_type,
3736 GtkShadowType shadow_type,
3738 const gchar *detail,
3743 GtkOrientation orientation)
3746 gint xthick, ythick;
3747 GdkColor light, dark;
3749 gtk_cairo_paint_box (style, cr, state_type, shadow_type, widget,
3750 detail, x, y, width, height);
3752 if (detail && !strcmp (detail, "paned"))
3754 /* we want to ignore the shadow border in paned widgets */
3758 if (state_type == GTK_STATE_SELECTED && widget && !gtk_widget_has_focus (widget))
3759 _gtk_style_shade (&style->base[GTK_STATE_ACTIVE], &light,
3762 light = style->light[state_type];
3764 dark = style->black;
3768 xthick = style->xthickness;
3769 ythick = style->ythickness;
3771 light = style->light[state_type];
3772 dark = style->dark[state_type];
3775 cairo_rectangle(cr, x + xthick, y + ythick,
3776 width - (xthick * 2), height - (ythick * 2));
3779 if (detail && !strcmp (detail, "paned"))
3781 if (orientation == GTK_ORIENTATION_HORIZONTAL)
3782 for (xx = x + width/2 - 15; xx <= x + width/2 + 15; xx += 5)
3783 draw_dot (cr, &light, &dark, xx, y + height/2 - 1, 3);
3785 for (yy = y + height/2 - 15; yy <= y + height/2 + 15; yy += 5)
3786 draw_dot (cr, &light, &dark, x + width/2 - 1, yy, 3);
3790 for (yy = y + ythick; yy < (y + height - ythick); yy += 3)
3791 for (xx = x + xthick; xx < (x + width - xthick); xx += 6)
3793 draw_dot (cr, &light, &dark, xx, yy, 2);
3794 draw_dot (cr, &light, &dark, xx + 3, yy + 1, 2);
3800 gtk_default_draw_expander (GtkStyle *style,
3802 GtkStateType state_type,
3804 const gchar *detail,
3807 GtkExpanderStyle expander_style)
3809 #define DEFAULT_EXPANDER_SIZE 12
3813 double vertical_overshoot;
3816 double interp; /* interpolation factor for center position */
3817 double x_double_horz, y_double_horz;
3818 double x_double_vert, y_double_vert;
3819 double x_double, y_double;
3823 gtk_widget_class_find_style_property (GTK_WIDGET_GET_CLASS (widget),
3826 gtk_widget_style_get (widget,
3827 "expander-size", &expander_size,
3831 expander_size = DEFAULT_EXPANDER_SIZE;
3833 line_width = MAX (1, expander_size/9);
3835 switch (expander_style)
3837 case GTK_EXPANDER_COLLAPSED:
3838 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 180 : 0;
3841 case GTK_EXPANDER_SEMI_COLLAPSED:
3842 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 150 : 30;
3845 case GTK_EXPANDER_SEMI_EXPANDED:
3846 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 120 : 60;
3849 case GTK_EXPANDER_EXPANDED:
3854 g_assert_not_reached ();
3857 /* Compute distance that the stroke extends beyonds the end
3858 * of the triangle we draw.
3860 vertical_overshoot = line_width / 2.0 * (1. / tan (G_PI / 8));
3862 /* For odd line widths, we end the vertical line of the triangle
3863 * at a half pixel, so we round differently.
3865 if (line_width % 2 == 1)
3866 vertical_overshoot = ceil (0.5 + vertical_overshoot) - 0.5;
3868 vertical_overshoot = ceil (vertical_overshoot);
3870 /* Adjust the size of the triangle we draw so that the entire stroke fits
3872 diameter = MAX (3, expander_size - 2 * vertical_overshoot);
3874 /* If the line width is odd, we want the diameter to be even,
3875 * and vice versa, so force the sum to be odd. This relationship
3876 * makes the point of the triangle look right.
3878 diameter -= (1 - (diameter + line_width) % 2);
3880 radius = diameter / 2.;
3882 /* Adjust the center so that the stroke is properly aligned with
3883 * the pixel grid. The center adjustment is different for the
3884 * horizontal and vertical orientations. For intermediate positions
3885 * we interpolate between the two.
3887 x_double_vert = floor (x - (radius + line_width) / 2.) + (radius + line_width) / 2.;
3888 y_double_vert = y - 0.5;
3890 x_double_horz = x - 0.5;
3891 y_double_horz = floor (y - (radius + line_width) / 2.) + (radius + line_width) / 2.;
3893 x_double = x_double_vert * (1 - interp) + x_double_horz * interp;
3894 y_double = y_double_vert * (1 - interp) + y_double_horz * interp;
3896 cairo_translate (cr, x_double, y_double);
3897 cairo_rotate (cr, degrees * G_PI / 180);
3899 cairo_move_to (cr, - radius / 2., - radius);
3900 cairo_line_to (cr, radius / 2., 0);
3901 cairo_line_to (cr, - radius / 2., radius);
3902 cairo_close_path (cr);
3904 cairo_set_line_width (cr, line_width);
3906 if (state_type == GTK_STATE_PRELIGHT)
3907 gdk_cairo_set_source_color (cr,
3908 &style->fg[GTK_STATE_PRELIGHT]);
3909 else if (state_type == GTK_STATE_ACTIVE)
3910 gdk_cairo_set_source_color (cr,
3911 &style->light[GTK_STATE_ACTIVE]);
3913 gdk_cairo_set_source_color (cr,
3914 &style->base[GTK_STATE_NORMAL]);
3916 cairo_fill_preserve (cr);
3918 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3923 gtk_default_draw_layout (GtkStyle *style,
3925 GtkStateType state_type,
3928 const gchar *detail,
3931 PangoLayout *layout)
3934 const PangoMatrix *matrix;
3936 matrix = pango_context_get_matrix (pango_layout_get_context (layout));
3939 cairo_matrix_t cairo_matrix;
3940 PangoMatrix tmp_matrix;
3941 PangoRectangle rect;
3943 cairo_matrix_init (&cairo_matrix,
3944 matrix->xx, matrix->yx,
3945 matrix->xy, matrix->yy,
3946 matrix->x0, matrix->y0);
3948 pango_layout_get_extents (layout, NULL, &rect);
3949 pango_matrix_transform_rectangle (matrix, &rect);
3950 pango_extents_to_pixels (&rect, NULL);
3952 tmp_matrix = *matrix;
3953 cairo_matrix.x0 += x - rect.x;
3954 cairo_matrix.y0 += y - rect.y;
3956 cairo_set_matrix (cr, &cairo_matrix);
3959 cairo_translate (cr, x, y);
3961 cairo_new_path (cr);
3963 if (state_type == GTK_STATE_INSENSITIVE)
3965 gdk_cairo_set_source_color (cr, &style->white);
3966 cairo_move_to (cr, 1, 1);
3967 _gtk_pango_fill_layout (cr, layout);
3968 cairo_new_path (cr);
3971 gc = use_text ? &style->text[state_type] : &style->fg[state_type];
3973 gdk_cairo_set_source_color (cr, gc);
3975 pango_cairo_show_layout (cr, layout);
3979 gtk_default_draw_resize_grip (GtkStyle *style,
3981 GtkStateType state_type,
3983 const gchar *detail,
3992 cairo_rectangle (cr, x, y, width, height);
3995 cairo_set_line_width (cr, 1.0);
4000 case GDK_WINDOW_EDGE_NORTH_WEST:
4001 /* make it square */
4004 else if (height < width)
4008 case GDK_WINDOW_EDGE_NORTH:
4012 case GDK_WINDOW_EDGE_NORTH_EAST:
4013 /* make it square, aligning to top right */
4016 else if (height < width)
4018 x += (width - height);
4023 case GDK_WINDOW_EDGE_WEST:
4027 case GDK_WINDOW_EDGE_EAST:
4028 /* aligning to right */
4031 x += (width - height);
4035 case GDK_WINDOW_EDGE_SOUTH_WEST:
4036 /* make it square, aligning to bottom left */
4039 y += (height - width);
4042 else if (height < width)
4046 case GDK_WINDOW_EDGE_SOUTH:
4047 /* align to bottom */
4050 y += (height - width);
4054 case GDK_WINDOW_EDGE_SOUTH_EAST:
4055 /* make it square, aligning to bottom right */
4058 y += (height - width);
4061 else if (height < width)
4063 x += (width - height);
4069 g_assert_not_reached ();
4074 case GDK_WINDOW_EDGE_WEST:
4075 case GDK_WINDOW_EDGE_EAST:
4081 while (xi < x + width)
4083 _cairo_draw_line (cr,
4084 &style->light[state_type],
4089 _cairo_draw_line (cr,
4090 &style->dark[state_type],
4098 case GDK_WINDOW_EDGE_NORTH:
4099 case GDK_WINDOW_EDGE_SOUTH:
4105 while (yi < y + height)
4107 _cairo_draw_line (cr,
4108 &style->light[state_type],
4113 _cairo_draw_line (cr,
4114 &style->dark[state_type],
4122 case GDK_WINDOW_EDGE_NORTH_WEST:
4131 _cairo_draw_line (cr,
4132 &style->dark[state_type],
4139 _cairo_draw_line (cr,
4140 &style->dark[state_type],
4147 _cairo_draw_line (cr,
4148 &style->light[state_type],
4158 case GDK_WINDOW_EDGE_NORTH_EAST:
4165 while (xi < (x + width - 3))
4167 _cairo_draw_line (cr,
4168 &style->light[state_type],
4175 _cairo_draw_line (cr,
4176 &style->dark[state_type],
4183 _cairo_draw_line (cr,
4184 &style->dark[state_type],
4193 case GDK_WINDOW_EDGE_SOUTH_WEST:
4202 _cairo_draw_line (cr,
4203 &style->dark[state_type],
4210 _cairo_draw_line (cr,
4211 &style->dark[state_type],
4218 _cairo_draw_line (cr,
4219 &style->light[state_type],
4229 case GDK_WINDOW_EDGE_SOUTH_EAST:
4236 while (xi < (x + width - 3))
4238 _cairo_draw_line (cr,
4239 &style->light[state_type],
4246 _cairo_draw_line (cr,
4247 &style->dark[state_type],
4254 _cairo_draw_line (cr,
4255 &style->dark[state_type],
4265 g_assert_not_reached ();
4271 gtk_default_draw_spinner (GtkStyle *style,
4273 GtkStateType state_type,
4276 const gchar *detail,
4292 gtk_style_get (style, GTK_TYPE_SPINNER,
4293 "num-steps", &num_steps,
4295 real_step = step % num_steps;
4297 /* get cairo context */
4298 cr = gdk_cairo_create (window);
4300 /* set a clip region for the expose event */
4301 cairo_rectangle (cr, x, y, width, height);
4304 cairo_translate (cr, x, y);
4306 /* draw clip region */
4307 cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
4309 color = &style->fg[state_type];
4312 radius = MIN (width / 2, height / 2);
4313 half = num_steps / 2;
4315 for (i = 0; i < num_steps; i++)
4317 gint inset = 0.7 * radius;
4319 /* transparency is a function of time and intial value */
4320 gdouble t = (gdouble) ((i + num_steps - real_step)
4321 % num_steps) / num_steps;
4325 cairo_set_source_rgba (cr,
4326 color->red / 65535.,
4327 color->green / 65535.,
4328 color->blue / 65535.,
4331 cairo_set_line_width (cr, 2.0);
4333 dx + (radius - inset) * cos (i * G_PI / half),
4334 dy + (radius - inset) * sin (i * G_PI / half));
4336 dx + radius * cos (i * G_PI / half),
4337 dy + radius * sin (i * G_PI / half));
4348 _gtk_style_shade (const GdkColor *a,
4356 red = (gdouble) a->red / 65535.0;
4357 green = (gdouble) a->green / 65535.0;
4358 blue = (gdouble) a->blue / 65535.0;
4360 rgb_to_hls (&red, &green, &blue);
4365 else if (green < 0.0)
4371 else if (blue < 0.0)
4374 hls_to_rgb (&red, &green, &blue);
4376 b->red = red * 65535.0;
4377 b->green = green * 65535.0;
4378 b->blue = blue * 65535.0;
4382 rgb_to_hls (gdouble *r,
4423 l = (max + min) / 2;
4430 s = (max - min) / (max + min);
4432 s = (max - min) / (2 - max - min);
4436 h = (green - blue) / delta;
4437 else if (green == max)
4438 h = 2 + (blue - red) / delta;
4439 else if (blue == max)
4440 h = 4 + (red - green) / delta;
4453 hls_to_rgb (gdouble *h,
4466 if (lightness <= 0.5)
4467 m2 = lightness * (1 + saturation);
4469 m2 = lightness + saturation - lightness * saturation;
4470 m1 = 2 * lightness - m2;
4472 if (saturation == 0)
4487 r = m1 + (m2 - m1) * hue / 60;
4491 r = m1 + (m2 - m1) * (240 - hue) / 60;
4502 g = m1 + (m2 - m1) * hue / 60;
4506 g = m1 + (m2 - m1) * (240 - hue) / 60;
4517 b = m1 + (m2 - m1) * hue / 60;
4521 b = m1 + (m2 - m1) * (240 - hue) / 60;
4533 gtk_style_cairo_create (GdkWindow *window, const GdkRectangle *area)
4537 cr = gdk_cairo_create (window);
4541 gdk_cairo_rectangle (cr, area);
4550 * @style: a #GtkStyle
4551 * @window: a #GdkWindow
4552 * @state_type: a state
4553 * @area: (allow-none): rectangle to which the output is clipped, or %NULL if the
4554 * output should not be clipped
4555 * @widget: (allow-none): the widget
4556 * @detail: (allow-none): a style detail
4557 * @x1: the starting x coordinate
4558 * @x2: the ending x coordinate
4559 * @y: the y coordinate
4561 * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @window
4562 * using the given style and state.
4565 gtk_paint_hline (GtkStyle *style,
4567 GtkStateType state_type,
4568 const GdkRectangle *area,
4570 const gchar *detail,
4577 g_return_if_fail (GTK_IS_STYLE (style));
4578 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
4579 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
4581 cr = gtk_style_cairo_create (window, area);
4583 gtk_cairo_paint_hline (style, cr, state_type,
4591 * gtk_cairo_paint_hline:
4592 * @style: a #GtkStyle
4594 * @state_type: a state
4595 * @widget: (allow-none): the widget
4596 * @detail: (allow-none): a style detail
4597 * @x1: the starting x coordinate
4598 * @x2: the ending x coordinate
4599 * @y: the y coordinate
4601 * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @cr
4602 * using the given style and state.
4605 gtk_cairo_paint_hline (GtkStyle *style,
4607 GtkStateType state_type,
4609 const gchar *detail,
4614 g_return_if_fail (GTK_IS_STYLE (style));
4615 g_return_if_fail (cr != NULL);
4616 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
4620 GTK_STYLE_GET_CLASS (style)->draw_hline (style, cr, state_type,
4629 * @style: a #GtkStyle
4630 * @window: a #GdkWindow
4631 * @state_type: a state
4632 * @area: (allow-none): rectangle to which the output is clipped, or %NULL if the
4633 * output should not be clipped
4634 * @widget: (allow-none): the widget
4635 * @detail: (allow-none): a style detail
4636 * @y1_: the starting y coordinate
4637 * @y2_: the ending y coordinate
4638 * @x: the x coordinate
4640 * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @window
4641 * using the given style and state.
4644 gtk_paint_vline (GtkStyle *style,
4646 GtkStateType state_type,
4647 const GdkRectangle *area,
4649 const gchar *detail,
4656 g_return_if_fail (GTK_IS_STYLE (style));
4657 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
4658 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
4660 cr = gtk_style_cairo_create (window, area);
4662 GTK_STYLE_GET_CLASS (style)->draw_vline (style, cr, state_type,
4670 * gtk_cairo_paint_vline:
4671 * @style: a #GtkStyle
4673 * @state_type: a state
4674 * @widget: (allow-none): the widget
4675 * @detail: (allow-none): a style detail
4676 * @y1_: the starting y coordinate
4677 * @y2_: the ending y coordinate
4678 * @x: the x coordinate
4680 * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @cr
4681 * using the given style and state.
4684 gtk_cairo_paint_vline (GtkStyle *style,
4686 GtkStateType state_type,
4688 const gchar *detail,
4693 g_return_if_fail (GTK_IS_STYLE (style));
4694 g_return_if_fail (cr != NULL);
4695 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
4699 GTK_STYLE_GET_CLASS (style)->draw_vline (style, cr, state_type,
4708 * @style: a #GtkStyle
4709 * @window: a #GdkWindow
4710 * @state_type: a state
4711 * @shadow_type: type of shadow to draw
4712 * @area: (allow-none): clip rectangle or %NULL if the
4713 * output should not be clipped
4714 * @widget: (allow-none): the widget
4715 * @detail: (allow-none): a style detail
4716 * @x: x origin of the rectangle
4717 * @y: y origin of the rectangle
4718 * @width: width of the rectangle
4719 * @height: width of the rectangle
4721 * Draws a shadow around the given rectangle in @window
4722 * using the given style and state and shadow type.
4725 gtk_paint_shadow (GtkStyle *style,
4727 GtkStateType state_type,
4728 GtkShadowType shadow_type,
4729 const GdkRectangle *area,
4731 const gchar *detail,
4739 g_return_if_fail (GTK_IS_STYLE (style));
4740 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
4741 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
4743 sanitize_size (window, &width, &height);
4745 cr = gtk_style_cairo_create (window, area);
4747 gtk_cairo_paint_shadow (style, cr, state_type, shadow_type,
4749 x, y, width, height);
4755 * gtk_cairo_paint_shadow:
4756 * @style: a #GtkStyle
4758 * @state_type: a state
4759 * @shadow_type: type of shadow to draw
4760 * @widget: (allow-none): the widget
4761 * @detail: (allow-none): a style detail
4762 * @x: x origin of the rectangle
4763 * @y: y origin of the rectangle
4764 * @width: width of the rectangle
4765 * @height: width of the rectangle
4767 * Draws a shadow around the given rectangle in @cr
4768 * using the given style and state and shadow type.
4771 gtk_cairo_paint_shadow (GtkStyle *style,
4773 GtkStateType state_type,
4774 GtkShadowType shadow_type,
4776 const gchar *detail,
4782 g_return_if_fail (GTK_IS_STYLE (style));
4783 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
4784 g_return_if_fail (cr != NULL);
4785 g_return_if_fail (width >= 0);
4786 g_return_if_fail (height >= 0);
4790 GTK_STYLE_GET_CLASS (style)->draw_shadow (style, cr, state_type, shadow_type,
4792 x, y, width, height);
4799 * @style: a #GtkStyle
4800 * @window: a #GdkWindow
4801 * @state_type: a state
4802 * @shadow_type: the type of shadow to draw
4803 * @area: (allow-none): clip rectangle, or %NULL if the
4804 * output should not be clipped
4805 * @widget: (allow-none): the widget
4806 * @detail: (allow-none): a style detail
4807 * @arrow_type: the type of arrow to draw
4808 * @fill: %TRUE if the arrow tip should be filled
4809 * @x: x origin of the rectangle to draw the arrow in
4810 * @y: y origin of the rectangle to draw the arrow in
4811 * @width: width of the rectangle to draw the arrow in
4812 * @height: height of the rectangle to draw the arrow in
4814 * Draws an arrow in the given rectangle on @window using the given
4815 * parameters. @arrow_type determines the direction of the arrow.
4818 gtk_paint_arrow (GtkStyle *style,
4820 GtkStateType state_type,
4821 GtkShadowType shadow_type,
4822 const GdkRectangle *area,
4824 const gchar *detail,
4825 GtkArrowType arrow_type,
4834 g_return_if_fail (GTK_IS_STYLE (style));
4835 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
4836 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
4838 sanitize_size (window, &width, &height);
4840 cr = gtk_style_cairo_create (window, area);
4842 gtk_cairo_paint_arrow (style, cr, state_type, shadow_type,
4844 arrow_type, fill, x, y, width, height);
4850 * gtk_cairo_paint_arrow:
4851 * @style: a #GtkStyle
4853 * @state_type: a state
4854 * @shadow_type: the type of shadow to draw
4855 * @widget: (allow-none): the widget
4856 * @detail: (allow-none): a style detail
4857 * @arrow_type: the type of arrow to draw
4858 * @fill: %TRUE if the arrow tip should be filled
4859 * @x: x origin of the rectangle to draw the arrow in
4860 * @y: y origin of the rectangle to draw the arrow in
4861 * @width: width of the rectangle to draw the arrow in
4862 * @height: height of the rectangle to draw the arrow in
4864 * Draws an arrow in the given rectangle on @cr using the given
4865 * parameters. @arrow_type determines the direction of the arrow.
4868 gtk_cairo_paint_arrow (GtkStyle *style,
4870 GtkStateType state_type,
4871 GtkShadowType shadow_type,
4873 const gchar *detail,
4874 GtkArrowType arrow_type,
4881 g_return_if_fail (GTK_IS_STYLE (style));
4882 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
4883 g_return_if_fail (cr != NULL);
4884 g_return_if_fail (width >= 0);
4885 g_return_if_fail (height >= 0);
4889 GTK_STYLE_GET_CLASS (style)->draw_arrow (style, cr, state_type, shadow_type,
4891 arrow_type, fill, x, y, width, height);
4897 * gtk_paint_diamond:
4898 * @style: a #GtkStyle
4899 * @window: a #GdkWindow
4900 * @state_type: a state
4901 * @shadow_type: the type of shadow to draw
4902 * @area: (allow-none): clip rectangle, or %NULL if the
4903 * output should not be clipped
4904 * @widget: (allow-none): the widget
4905 * @detail: (allow-none): a style detail
4906 * @x: x origin of the rectangle to draw the diamond in
4907 * @y: y origin of the rectangle to draw the diamond in
4908 * @width: width of the rectangle to draw the diamond in
4909 * @height: height of the rectangle to draw the diamond in
4911 * Draws a diamond in the given rectangle on @window using the given
4915 gtk_paint_diamond (GtkStyle *style,
4917 GtkStateType state_type,
4918 GtkShadowType shadow_type,
4919 const GdkRectangle *area,
4921 const gchar *detail,
4929 g_return_if_fail (GTK_IS_STYLE (style));
4930 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
4931 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
4933 sanitize_size (window, &width, &height);
4935 cr = gtk_style_cairo_create (window, area);
4937 gtk_cairo_paint_diamond (style, cr, state_type, shadow_type,
4939 x, y, width, height);
4945 * gtk_cairo_paint_diamond:
4946 * @style: a #GtkStyle
4948 * @state_type: a state
4949 * @shadow_type: the type of shadow to draw
4950 * @widget: (allow-none): the widget
4951 * @detail: (allow-none): a style detail
4952 * @x: x origin of the rectangle to draw the diamond in
4953 * @y: y origin of the rectangle to draw the diamond in
4954 * @width: width of the rectangle to draw the diamond in
4955 * @height: height of the rectangle to draw the diamond in
4957 * Draws a diamond in the given rectangle on @window using the given
4961 gtk_cairo_paint_diamond (GtkStyle *style,
4963 GtkStateType state_type,
4964 GtkShadowType shadow_type,
4966 const gchar *detail,
4972 g_return_if_fail (GTK_IS_STYLE (style));
4973 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
4974 g_return_if_fail (cr != NULL);
4975 g_return_if_fail (width >= 0);
4976 g_return_if_fail (height >= 0);
4980 GTK_STYLE_GET_CLASS (style)->draw_diamond (style, cr, state_type, shadow_type,
4982 x, y, width, height);
4989 * @style: a #GtkStyle
4990 * @window: a #GdkWindow
4991 * @state_type: a state
4992 * @shadow_type: the type of shadow to draw
4993 * @area: (allow-none): clip rectangle, or %NULL if the
4994 * output should not be clipped
4995 * @widget: (allow-none): the widget
4996 * @detail: (allow-none): a style detail
4997 * @x: x origin of the box
4998 * @y: y origin of the box
4999 * @width: the width of the box
5000 * @height: the height of the box
5002 * Draws a box on @window with the given parameters.
5005 gtk_paint_box (GtkStyle *style,
5007 GtkStateType state_type,
5008 GtkShadowType shadow_type,
5009 const GdkRectangle *area,
5011 const gchar *detail,
5019 g_return_if_fail (GTK_IS_STYLE (style));
5020 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
5021 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5023 sanitize_size (window, &width, &height);
5025 cr = gtk_style_cairo_create (window, area);
5027 gtk_cairo_paint_box (style, cr, state_type, shadow_type,
5029 x, y, width, height);
5035 * gtk_cairo_paint_box:
5036 * @style: a #GtkStyle
5038 * @state_type: a state
5039 * @shadow_type: the type of shadow to draw
5040 * @widget: (allow-none): the widget
5041 * @detail: (allow-none): a style detail
5042 * @x: x origin of the box
5043 * @y: y origin of the box
5044 * @width: the width of the box
5045 * @height: the height of the box
5047 * Draws a box on @cr with the given parameters.
5050 gtk_cairo_paint_box (GtkStyle *style,
5052 GtkStateType state_type,
5053 GtkShadowType shadow_type,
5055 const gchar *detail,
5061 g_return_if_fail (GTK_IS_STYLE (style));
5062 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
5063 g_return_if_fail (cr != NULL);
5067 GTK_STYLE_GET_CLASS (style)->draw_box (style, cr, state_type, shadow_type,
5069 x, y, width, height);
5075 * gtk_paint_flat_box:
5076 * @style: a #GtkStyle
5077 * @window: a #GdkWindow
5078 * @state_type: a state
5079 * @shadow_type: the type of shadow to draw
5080 * @area: (allow-none): clip rectangle, or %NULL if the
5081 * output should not be clipped
5082 * @widget: (allow-none): the widget
5083 * @detail: (allow-none): a style detail
5084 * @x: x origin of the box
5085 * @y: y origin of the box
5086 * @width: the width of the box
5087 * @height: the height of the box
5089 * Draws a flat box on @window with the given parameters.
5092 gtk_paint_flat_box (GtkStyle *style,
5094 GtkStateType state_type,
5095 GtkShadowType shadow_type,
5096 const GdkRectangle *area,
5098 const gchar *detail,
5106 g_return_if_fail (GTK_IS_STYLE (style));
5107 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
5108 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5110 sanitize_size (window, &width, &height);
5112 cr = gtk_style_cairo_create (window, area);
5114 gtk_cairo_paint_flat_box (style, cr, state_type, shadow_type,
5116 x, y, width, height);
5122 * gtk_cairo_paint_flat_box:
5123 * @style: a #GtkStyle
5125 * @state_type: a state
5126 * @shadow_type: the type of shadow to draw
5127 * @area: (allow-none): clip rectangle, or %NULL if the
5128 * output should not be clipped
5129 * @widget: (allow-none): the widget
5130 * @detail: (allow-none): a style detail
5131 * @x: x origin of the box
5132 * @y: y origin of the box
5133 * @width: the width of the box
5134 * @height: the height of the box
5136 * Draws a flat box on @cr with the given parameters.
5139 gtk_cairo_paint_flat_box (GtkStyle *style,
5141 GtkStateType state_type,
5142 GtkShadowType shadow_type,
5144 const gchar *detail,
5150 g_return_if_fail (GTK_IS_STYLE (style));
5151 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
5152 g_return_if_fail (cr != NULL);
5153 g_return_if_fail (width >= 0);
5154 g_return_if_fail (height >= 0);
5158 GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, cr, state_type, shadow_type,
5160 x, y, width, height);
5167 * @style: a #GtkStyle
5168 * @window: a #GdkWindow
5169 * @state_type: a state
5170 * @shadow_type: the type of shadow to draw
5171 * @area: (allow-none): clip rectangle, or %NULL if the
5172 * output should not be clipped
5173 * @widget: (allow-none): the widget
5174 * @detail: (allow-none): a style detail
5175 * @x: x origin of the rectangle to draw the check in
5176 * @y: y origin of the rectangle to draw the check in
5177 * @width: the width of the rectangle to draw the check in
5178 * @height: the height of the rectangle to draw the check in
5180 * Draws a check button indicator in the given rectangle on @window with
5181 * the given parameters.
5184 gtk_paint_check (GtkStyle *style,
5186 GtkStateType state_type,
5187 GtkShadowType shadow_type,
5188 const GdkRectangle *area,
5190 const gchar *detail,
5198 g_return_if_fail (GTK_IS_STYLE (style));
5199 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
5200 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5202 cr = gtk_style_cairo_create (window, area);
5204 gtk_cairo_paint_check (style, cr, state_type, shadow_type,
5206 x, y, width, height);
5212 * gtk_cairo_paint_check:
5213 * @style: a #GtkStyle
5215 * @state_type: a state
5216 * @shadow_type: the type of shadow to draw
5217 * @widget: (allow-none): the widget
5218 * @detail: (allow-none): a style detail
5219 * @x: x origin of the rectangle to draw the check in
5220 * @y: y origin of the rectangle to draw the check in
5221 * @width: the width of the rectangle to draw the check in
5222 * @height: the height of the rectangle to draw the check in
5224 * Draws a check button indicator in the given rectangle on @cr with
5225 * the given parameters.
5228 gtk_cairo_paint_check (GtkStyle *style,
5230 GtkStateType state_type,
5231 GtkShadowType shadow_type,
5233 const gchar *detail,
5239 g_return_if_fail (GTK_IS_STYLE (style));
5240 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
5241 g_return_if_fail (cr != NULL);
5245 GTK_STYLE_GET_CLASS (style)->draw_check (style, cr, state_type, shadow_type,
5247 x, y, width, height);
5254 * @style: a #GtkStyle
5255 * @window: a #GdkWindow
5256 * @state_type: a state
5257 * @shadow_type: the type of shadow to draw
5258 * @area: (allow-none): clip rectangle, or %NULL if the
5259 * output should not be clipped
5260 * @widget: (allow-none): the widget
5261 * @detail: (allow-none): a style detail
5262 * @x: x origin of the rectangle to draw the option in
5263 * @y: y origin of the rectangle to draw the option in
5264 * @width: the width of the rectangle to draw the option in
5265 * @height: the height of the rectangle to draw the option in
5267 * Draws a radio button indicator in the given rectangle on @window with
5268 * the given parameters.
5271 gtk_paint_option (GtkStyle *style,
5273 GtkStateType state_type,
5274 GtkShadowType shadow_type,
5275 const GdkRectangle *area,
5277 const gchar *detail,
5285 g_return_if_fail (GTK_IS_STYLE (style));
5286 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
5287 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5289 cr = gtk_style_cairo_create (window, area);
5291 gtk_cairo_paint_option (style, cr, state_type, shadow_type,
5293 x, y, width, height);
5299 * gtk_cairo_paint_option:
5300 * @style: a #GtkStyle
5302 * @state_type: a state
5303 * @shadow_type: the type of shadow to draw
5304 * @widget: (allow-none): the widget
5305 * @detail: (allow-none): a style detail
5306 * @x: x origin of the rectangle to draw the option in
5307 * @y: y origin of the rectangle to draw the option in
5308 * @width: the width of the rectangle to draw the option in
5309 * @height: the height of the rectangle to draw the option in
5311 * Draws a radio button indicator in the given rectangle on @cr with
5312 * the given parameters.
5315 gtk_cairo_paint_option (GtkStyle *style,
5317 GtkStateType state_type,
5318 GtkShadowType shadow_type,
5320 const gchar *detail,
5326 g_return_if_fail (GTK_IS_STYLE (style));
5327 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
5328 g_return_if_fail (cr != NULL);
5332 GTK_STYLE_GET_CLASS (style)->draw_option (style, cr, state_type, shadow_type,
5334 x, y, width, height);
5341 * @style: a #GtkStyle
5342 * @window: a #GdkWindow
5343 * @state_type: a state
5344 * @shadow_type: the type of shadow to draw
5345 * @area: (allow-none): clip rectangle, or %NULL if the
5346 * output should not be clipped
5347 * @widget: (allow-none): the widget
5348 * @detail: (allow-none): a style detail
5349 * @x: x origin of the rectangle to draw the tab in
5350 * @y: y origin of the rectangle to draw the tab in
5351 * @width: the width of the rectangle to draw the tab in
5352 * @height: the height of the rectangle to draw the tab in
5354 * Draws an option menu tab (i.e. the up and down pointing arrows)
5355 * in the given rectangle on @window using the given parameters.
5358 gtk_paint_tab (GtkStyle *style,
5360 GtkStateType state_type,
5361 GtkShadowType shadow_type,
5362 const GdkRectangle *area,
5364 const gchar *detail,
5372 g_return_if_fail (GTK_IS_STYLE (style));
5373 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
5374 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5376 cr = gtk_style_cairo_create (window, area);
5378 gtk_cairo_paint_tab (style, cr, state_type, shadow_type,
5380 x, y, width, height);
5386 * gtk_cairo_paint_tab:
5387 * @style: a #GtkStyle
5389 * @state_type: a state
5390 * @shadow_type: the type of shadow to draw
5391 * @widget: (allow-none): the widget
5392 * @detail: (allow-none): a style detail
5393 * @x: x origin of the rectangle to draw the tab in
5394 * @y: y origin of the rectangle to draw the tab in
5395 * @width: the width of the rectangle to draw the tab in
5396 * @height: the height of the rectangle to draw the tab in
5398 * Draws an option menu tab (i.e. the up and down pointing arrows)
5399 * in the given rectangle on @cr using the given parameters.
5402 gtk_cairo_paint_tab (GtkStyle *style,
5404 GtkStateType state_type,
5405 GtkShadowType shadow_type,
5407 const gchar *detail,
5413 g_return_if_fail (GTK_IS_STYLE (style));
5414 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
5415 g_return_if_fail (cr != NULL);
5419 GTK_STYLE_GET_CLASS (style)->draw_tab (style, cr, state_type, shadow_type,
5421 x, y, width, height);
5427 * gtk_paint_shadow_gap:
5428 * @style: a #GtkStyle
5429 * @window: a #GdkWindow
5430 * @state_type: a state
5431 * @shadow_type: type of shadow to draw
5432 * @area: (allow-none): clip rectangle, or %NULL if the
5433 * output should not be clipped
5434 * @widget: (allow-none): the widget
5435 * @detail: (allow-none): a style detail
5436 * @x: x origin of the rectangle
5437 * @y: y origin of the rectangle
5438 * @width: width of the rectangle
5439 * @height: width of the rectangle
5440 * @gap_side: side in which to leave the gap
5441 * @gap_x: starting position of the gap
5442 * @gap_width: width of the gap
5444 * Draws a shadow around the given rectangle in @window
5445 * using the given style and state and shadow type, leaving a
5449 gtk_paint_shadow_gap (GtkStyle *style,
5451 GtkStateType state_type,
5452 GtkShadowType shadow_type,
5453 const GdkRectangle *area,
5455 const gchar *detail,
5460 GtkPositionType gap_side,
5466 g_return_if_fail (GTK_IS_STYLE (style));
5467 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
5468 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5470 sanitize_size (window, &width, &height);
5472 cr = gtk_style_cairo_create (window, area);
5474 gtk_cairo_paint_shadow_gap (style, cr, state_type, shadow_type,
5476 x, y, width, height, gap_side, gap_x, gap_width);
5483 * gtk_cairo_paint_shadow_gap:
5484 * @style: a #GtkStyle
5486 * @state_type: a state
5487 * @shadow_type: type of shadow to draw
5488 * @widget: (allow-none): the widget
5489 * @detail: (allow-none): a style detail
5490 * @x: x origin of the rectangle
5491 * @y: y origin of the rectangle
5492 * @width: width of the rectangle
5493 * @height: width of the rectangle
5494 * @gap_side: side in which to leave the gap
5495 * @gap_x: starting position of the gap
5496 * @gap_width: width of the gap
5498 * Draws a shadow around the given rectangle in @cr
5499 * using the given style and state and shadow type, leaving a
5503 gtk_cairo_paint_shadow_gap (GtkStyle *style,
5505 GtkStateType state_type,
5506 GtkShadowType shadow_type,
5508 const gchar *detail,
5513 GtkPositionType gap_side,
5517 g_return_if_fail (GTK_IS_STYLE (style));
5518 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
5519 g_return_if_fail (cr != NULL);
5520 g_return_if_fail (width >= 0);
5521 g_return_if_fail (height >= 0);
5525 GTK_STYLE_GET_CLASS (style)->draw_shadow_gap (style, cr, state_type, shadow_type,
5527 x, y, width, height, gap_side, gap_x, gap_width);
5534 * gtk_paint_box_gap:
5535 * @style: a #GtkStyle
5536 * @window: a #GdkWindow
5537 * @state_type: a state
5538 * @shadow_type: type of shadow to draw
5539 * @area: (allow-none): clip rectangle, or %NULL if the
5540 * output should not be clipped
5541 * @widget: (allow-none): the widget
5542 * @detail: (allow-none): a style detail
5543 * @x: x origin of the rectangle
5544 * @y: y origin of the rectangle
5545 * @width: width of the rectangle
5546 * @height: width of the rectangle
5547 * @gap_side: side in which to leave the gap
5548 * @gap_x: starting position of the gap
5549 * @gap_width: width of the gap
5551 * Draws a box in @window using the given style and state and shadow type,
5552 * leaving a gap in one side.
5555 gtk_paint_box_gap (GtkStyle *style,
5557 GtkStateType state_type,
5558 GtkShadowType shadow_type,
5559 const GdkRectangle *area,
5561 const gchar *detail,
5566 GtkPositionType gap_side,
5572 g_return_if_fail (GTK_IS_STYLE (style));
5573 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
5574 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5576 sanitize_size (window, &width, &height);
5578 cr = gtk_style_cairo_create (window, area);
5580 gtk_cairo_paint_box_gap (style, cr, state_type, shadow_type,
5582 x, y, width, height, gap_side, gap_x, gap_width);
5588 * gtk_cairo_paint_box_gap:
5589 * @style: a #GtkStyle
5591 * @state_type: a state
5592 * @shadow_type: type of shadow to draw
5593 * @widget: (allow-none): the widget
5594 * @detail: (allow-none): a style detail
5595 * @x: x origin of the rectangle
5596 * @y: y origin of the rectangle
5597 * @width: width of the rectangle
5598 * @height: width of the rectangle
5599 * @gap_side: side in which to leave the gap
5600 * @gap_x: starting position of the gap
5601 * @gap_width: width of the gap
5603 * Draws a box in @cr using the given style and state and shadow type,
5604 * leaving a gap in one side.
5607 gtk_cairo_paint_box_gap (GtkStyle *style,
5609 GtkStateType state_type,
5610 GtkShadowType shadow_type,
5612 const gchar *detail,
5617 GtkPositionType gap_side,
5621 g_return_if_fail (GTK_IS_STYLE (style));
5622 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
5623 g_return_if_fail (cr != NULL);
5624 g_return_if_fail (width >= 0);
5625 g_return_if_fail (height >= 0);
5629 GTK_STYLE_GET_CLASS (style)->draw_box_gap (style, cr, state_type, shadow_type,
5631 x, y, width, height, gap_side, gap_x, gap_width);
5637 * gtk_paint_extension:
5638 * @style: a #GtkStyle
5639 * @window: a #GdkWindow
5640 * @state_type: a state
5641 * @shadow_type: type of shadow to draw
5642 * @area: (allow-none): clip rectangle, or %NULL if the
5643 * output should not be clipped
5644 * @widget: (allow-none): the widget
5645 * @detail: (allow-none): a style detail
5646 * @x: x origin of the extension
5647 * @y: y origin of the extension
5648 * @width: width of the extension
5649 * @height: width of the extension
5650 * @gap_side: the side on to which the extension is attached
5652 * Draws an extension, i.e. a notebook tab.
5655 gtk_paint_extension (GtkStyle *style,
5657 GtkStateType state_type,
5658 GtkShadowType shadow_type,
5659 const GdkRectangle *area,
5661 const gchar *detail,
5666 GtkPositionType gap_side)
5670 g_return_if_fail (GTK_IS_STYLE (style));
5671 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
5672 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5674 sanitize_size (window, &width, &height);
5676 cr = gtk_style_cairo_create (window, area);
5678 gtk_cairo_paint_extension (style, cr, state_type, shadow_type,
5680 x, y, width, height, gap_side);
5686 * gtk_cairo_paint_extension:
5687 * @style: a #GtkStyle
5689 * @state_type: a state
5690 * @shadow_type: type of shadow to draw
5691 * @widget: (allow-none): the widget
5692 * @detail: (allow-none): a style detail
5693 * @x: x origin of the extension
5694 * @y: y origin of the extension
5695 * @width: width of the extension
5696 * @height: width of the extension
5697 * @gap_side: the side on to which the extension is attached
5699 * Draws an extension, i.e. a notebook tab.
5702 gtk_cairo_paint_extension (GtkStyle *style,
5704 GtkStateType state_type,
5705 GtkShadowType shadow_type,
5707 const gchar *detail,
5712 GtkPositionType gap_side)
5714 g_return_if_fail (GTK_IS_STYLE (style));
5715 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
5716 g_return_if_fail (cr != NULL);
5717 g_return_if_fail (width >= 0);
5718 g_return_if_fail (height >= 0);
5722 GTK_STYLE_GET_CLASS (style)->draw_extension (style, cr, state_type, shadow_type,
5724 x, y, width, height, gap_side);
5731 * @style: a #GtkStyle
5732 * @window: a #GdkWindow
5733 * @state_type: a state
5734 * @area: (allow-none): clip rectangle, or %NULL if the
5735 * output should not be clipped
5736 * @widget: (allow-none): the widget
5737 * @detail: (allow-none): a style detail
5738 * @x: the x origin of the rectangle around which to draw a focus indicator
5739 * @y: the y origin of the rectangle around which to draw a focus indicator
5740 * @width: the width of the rectangle around which to draw a focus indicator
5741 * @height: the height of the rectangle around which to draw a focus indicator
5743 * Draws a focus indicator around the given rectangle on @window using the
5747 gtk_paint_focus (GtkStyle *style,
5749 GtkStateType state_type,
5750 const GdkRectangle *area,
5752 const gchar *detail,
5760 g_return_if_fail (GTK_IS_STYLE (style));
5761 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
5762 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5764 sanitize_size (window, &width, &height);
5766 cr = gtk_style_cairo_create (window, area);
5768 gtk_cairo_paint_focus (style, cr, state_type,
5770 x, y, width, height);
5776 * gtk_cairo_paint_focus:
5777 * @style: a #GtkStyle
5779 * @state_type: a state
5780 * @widget: (allow-none): the widget
5781 * @detail: (allow-none): a style detail
5782 * @x: the x origin of the rectangle around which to draw a focus indicator
5783 * @y: the y origin of the rectangle around which to draw a focus indicator
5784 * @width: the width of the rectangle around which to draw a focus indicator
5785 * @height: the height of the rectangle around which to draw a focus indicator
5787 * Draws a focus indicator around the given rectangle on @cr using the
5791 gtk_cairo_paint_focus (GtkStyle *style,
5793 GtkStateType state_type,
5795 const gchar *detail,
5801 g_return_if_fail (GTK_IS_STYLE (style));
5802 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
5803 g_return_if_fail (cr != NULL);
5804 g_return_if_fail (width >= 0);
5805 g_return_if_fail (height >= 0);
5809 GTK_STYLE_GET_CLASS (style)->draw_focus (style, cr, state_type,
5811 x, y, width, height);
5818 * @style: a #GtkStyle
5819 * @window: a #GdkWindow
5820 * @state_type: a state
5821 * @shadow_type: a shadow
5822 * @area: (allow-none): clip rectangle, or %NULL if the
5823 * output should not be clipped
5824 * @widget: (allow-none): the widget
5825 * @detail: (allow-none): a style detail
5826 * @x: the x origin of the rectangle in which to draw a slider
5827 * @y: the y origin of the rectangle in which to draw a slider
5828 * @width: the width of the rectangle in which to draw a slider
5829 * @height: the height of the rectangle in which to draw a slider
5830 * @orientation: the orientation to be used
5832 * Draws a slider in the given rectangle on @window using the
5833 * given style and orientation.
5836 gtk_paint_slider (GtkStyle *style,
5838 GtkStateType state_type,
5839 GtkShadowType shadow_type,
5840 const GdkRectangle *area,
5842 const gchar *detail,
5847 GtkOrientation orientation)
5851 g_return_if_fail (GTK_IS_STYLE (style));
5852 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
5853 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5855 sanitize_size (window, &width, &height);
5857 cr = gtk_style_cairo_create (window, area);
5859 GTK_STYLE_GET_CLASS (style)->draw_slider (style, cr, state_type, shadow_type,
5861 x, y, width, height, orientation);
5867 * gtk_cairo_paint_slider:
5868 * @style: a #GtkStyle
5870 * @state_type: a state
5871 * @shadow_type: a shadow
5872 * @widget: (allow-none): the widget
5873 * @detail: (allow-none): a style detail
5874 * @x: the x origin of the rectangle in which to draw a slider
5875 * @y: the y origin of the rectangle in which to draw a slider
5876 * @width: the width of the rectangle in which to draw a slider
5877 * @height: the height of the rectangle in which to draw a slider
5878 * @orientation: the orientation to be used
5880 * Draws a slider in the given rectangle on @cr using the
5881 * given style and orientation.
5884 gtk_cairo_paint_slider (GtkStyle *style,
5886 GtkStateType state_type,
5887 GtkShadowType shadow_type,
5889 const gchar *detail,
5894 GtkOrientation orientation)
5896 g_return_if_fail (GTK_IS_STYLE (style));
5897 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
5898 g_return_if_fail (cr != NULL);
5899 g_return_if_fail (width >= 0);
5900 g_return_if_fail (height >= 0);
5904 GTK_STYLE_GET_CLASS (style)->draw_slider (style, cr, state_type, shadow_type,
5906 x, y, width, height, orientation);
5913 * @style: a #GtkStyle
5914 * @window: a #GdkWindow
5915 * @state_type: a state
5916 * @shadow_type: type of shadow to draw
5917 * @area: (allow-none): clip rectangle, or %NULL if the
5918 * output should not be clipped
5919 * @widget: (allow-none): the widget
5920 * @detail: (allow-none): a style detail
5921 * @x: x origin of the handle
5922 * @y: y origin of the handle
5923 * @width: with of the handle
5924 * @height: height of the handle
5925 * @orientation: the orientation of the handle
5927 * Draws a handle as used in #GtkHandleBox and #GtkPaned.
5930 gtk_paint_handle (GtkStyle *style,
5932 GtkStateType state_type,
5933 GtkShadowType shadow_type,
5934 const GdkRectangle *area,
5936 const gchar *detail,
5941 GtkOrientation orientation)
5945 g_return_if_fail (GTK_IS_STYLE (style));
5946 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
5947 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5949 sanitize_size (window, &width, &height);
5951 cr = gtk_style_cairo_create (window, area);
5953 gtk_cairo_paint_handle (style, cr, state_type, shadow_type,
5955 x, y, width, height, orientation);
5961 * gtk_cairo_paint_handle:
5962 * @style: a #GtkStyle
5964 * @state_type: a state
5965 * @shadow_type: type of shadow to draw
5966 * @widget: (allow-none): the widget
5967 * @detail: (allow-none): a style detail
5968 * @x: x origin of the handle
5969 * @y: y origin of the handle
5970 * @width: with of the handle
5971 * @height: height of the handle
5972 * @orientation: the orientation of the handle
5974 * Draws a handle as used in #GtkHandleBox and #GtkPaned.
5977 gtk_cairo_paint_handle (GtkStyle *style,
5979 GtkStateType state_type,
5980 GtkShadowType shadow_type,
5982 const gchar *detail,
5987 GtkOrientation orientation)
5989 g_return_if_fail (GTK_IS_STYLE (style));
5990 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
5991 g_return_if_fail (cr != NULL);
5992 g_return_if_fail (width >= 0);
5993 g_return_if_fail (height >= 0);
5997 GTK_STYLE_GET_CLASS (style)->draw_handle (style, cr, state_type, shadow_type,
5999 x, y, width, height, orientation);
6005 * gtk_paint_expander:
6006 * @style: a #GtkStyle
6007 * @window: a #GdkWindow
6008 * @state_type: a state
6009 * @area: (allow-none): clip rectangle, or %NULL if the
6010 * output should not be clipped
6011 * @widget: (allow-none): the widget
6012 * @detail: (allow-none): a style detail
6013 * @x: the x position to draw the expander at
6014 * @y: the y position to draw the expander at
6015 * @expander_style: the style to draw the expander in; determines
6016 * whether the expander is collapsed, expanded, or in an
6017 * intermediate state.
6019 * Draws an expander as used in #GtkTreeView. @x and @y specify the
6020 * center the expander. The size of the expander is determined by the
6021 * "expander-size" style property of @widget. (If widget is not
6022 * specified or doesn't have an "expander-size" property, an
6023 * unspecified default size will be used, since the caller doesn't
6024 * have sufficient information to position the expander, this is
6025 * likely not useful.) The expander is expander_size pixels tall
6026 * in the collapsed position and expander_size pixels wide in the
6027 * expanded position.
6030 gtk_paint_expander (GtkStyle *style,
6032 GtkStateType state_type,
6033 const GdkRectangle *area,
6035 const gchar *detail,
6038 GtkExpanderStyle expander_style)
6042 g_return_if_fail (GTK_IS_STYLE (style));
6043 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
6044 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6046 cr = gtk_style_cairo_create (window, area);
6048 gtk_cairo_paint_expander (style, cr, state_type,
6050 x, y, expander_style);
6056 * gtk_cairo_paint_expander:
6057 * @style: a #GtkStyle
6059 * @state_type: a state
6060 * @widget: (allow-none): the widget
6061 * @detail: (allow-none): a style detail
6062 * @x: the x position to draw the expander at
6063 * @y: the y position to draw the expander at
6064 * @expander_style: the style to draw the expander in; determines
6065 * whether the expander is collapsed, expanded, or in an
6066 * intermediate state.
6068 * Draws an expander as used in #GtkTreeView. @x and @y specify the
6069 * center the expander. The size of the expander is determined by the
6070 * "expander-size" style property of @widget. (If widget is not
6071 * specified or doesn't have an "expander-size" property, an
6072 * unspecified default size will be used, since the caller doesn't
6073 * have sufficient information to position the expander, this is
6074 * likely not useful.) The expander is expander_size pixels tall
6075 * in the collapsed position and expander_size pixels wide in the
6076 * expanded position.
6079 gtk_cairo_paint_expander (GtkStyle *style,
6081 GtkStateType state_type,
6083 const gchar *detail,
6086 GtkExpanderStyle expander_style)
6088 g_return_if_fail (GTK_IS_STYLE (style));
6089 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
6090 g_return_if_fail (cr != NULL);
6094 GTK_STYLE_GET_CLASS (style)->draw_expander (style, cr, state_type,
6096 x, y, expander_style);
6103 * @style: a #GtkStyle
6104 * @window: a #GdkWindow
6105 * @state_type: a state
6106 * @use_text: whether to use the text or foreground
6107 * graphics context of @style
6108 * @area: (allow-none): clip rectangle, or %NULL if the
6109 * output should not be clipped
6110 * @widget: (allow-none): the widget
6111 * @detail: (allow-none): a style detail
6114 * @layout: the layout to draw
6116 * Draws a layout on @window using the given parameters.
6119 gtk_paint_layout (GtkStyle *style,
6121 GtkStateType state_type,
6123 const GdkRectangle *area,
6125 const gchar *detail,
6128 PangoLayout *layout)
6132 g_return_if_fail (GTK_IS_STYLE (style));
6133 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
6134 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6136 cr = gtk_style_cairo_create (window, area);
6138 gtk_cairo_paint_layout (style, cr, state_type, use_text,
6146 * gtk_cairo_paint_layout:
6147 * @style: a #GtkStyle
6149 * @state_type: a state
6150 * @use_text: whether to use the text or foreground
6151 * graphics context of @style
6152 * @widget: (allow-none): the widget
6153 * @detail: (allow-none): a style detail
6156 * @layout: the layout to draw
6158 * Draws a layout on @cr using the given parameters.
6161 gtk_cairo_paint_layout (GtkStyle *style,
6163 GtkStateType state_type,
6166 const gchar *detail,
6169 PangoLayout *layout)
6171 g_return_if_fail (GTK_IS_STYLE (style));
6172 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
6173 g_return_if_fail (cr != NULL);
6177 GTK_STYLE_GET_CLASS (style)->draw_layout (style, cr, state_type, use_text,
6185 * gtk_paint_resize_grip:
6186 * @style: a #GtkStyle
6187 * @window: a #GdkWindow
6188 * @state_type: a state
6189 * @area: (allow-none): clip rectangle, or %NULL if the
6190 * output should not be clipped
6191 * @widget: (allow-none): the widget
6192 * @detail: (allow-none): a style detail
6193 * @edge: the edge in which to draw the resize grip
6194 * @x: the x origin of the rectangle in which to draw the resize grip
6195 * @y: the y origin of the rectangle in which to draw the resize grip
6196 * @width: the width of the rectangle in which to draw the resize grip
6197 * @height: the height of the rectangle in which to draw the resize grip
6199 * Draws a resize grip in the given rectangle on @window using the given
6203 gtk_paint_resize_grip (GtkStyle *style,
6205 GtkStateType state_type,
6206 const GdkRectangle *area,
6208 const gchar *detail,
6218 g_return_if_fail (GTK_IS_STYLE (style));
6219 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
6220 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6222 cr = gtk_style_cairo_create (window, area);
6224 GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, cr, state_type,
6226 edge, x, y, width, height);
6231 * gtk_cairo_paint_resize_grip:
6232 * @style: a #GtkStyle
6234 * @state_type: a state
6235 * @widget: (allow-none): the widget
6236 * @detail: (allow-none): a style detail
6237 * @edge: the edge in which to draw the resize grip
6238 * @x: the x origin of the rectangle in which to draw the resize grip
6239 * @y: the y origin of the rectangle in which to draw the resize grip
6240 * @width: the width of the rectangle in which to draw the resize grip
6241 * @height: the height of the rectangle in which to draw the resize grip
6243 * Draws a resize grip in the given rectangle on @cr using the given
6247 gtk_cairo_paint_resize_grip (GtkStyle *style,
6249 GtkStateType state_type,
6251 const gchar *detail,
6258 g_return_if_fail (GTK_IS_STYLE (style));
6259 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
6260 g_return_if_fail (cr != NULL);
6264 GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, cr, state_type,
6266 edge, x, y, width, height);
6271 * gtk_paint_spinner:
6272 * @style: a #GtkStyle
6273 * @window: a #GdkWindow
6274 * @state_type: a state
6275 * @area: (allow-none): clip rectangle, or %NULL if the
6276 * output should not be clipped
6277 * @widget: (allow-none): the widget (may be %NULL)
6278 * @detail: (allow-none): a style detail (may be %NULL)
6279 * @step: the nth step, a value between 0 and #GtkSpinner:num-steps
6280 * @x: the x origin of the rectangle in which to draw the spinner
6281 * @y: the y origin of the rectangle in which to draw the spinner
6282 * @width: the width of the rectangle in which to draw the spinner
6283 * @height: the height of the rectangle in which to draw the spinner
6285 * Draws a spinner on @window using the given parameters.
6290 gtk_paint_spinner (GtkStyle *style,
6292 GtkStateType state_type,
6293 const GdkRectangle *area,
6295 const gchar *detail,
6302 g_return_if_fail (GTK_IS_STYLE (style));
6303 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_spinner != NULL);
6304 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6306 GTK_STYLE_GET_CLASS (style)->draw_spinner (style, window, state_type,
6307 (GdkRectangle *)area, widget, detail,
6308 step, x, y, width, height);
6314 * Allocates a new #GtkBorder structure and initializes its elements to zero.
6316 * Returns: a new empty #GtkBorder. The newly allocated #GtkBorder should be
6317 * freed with gtk_border_free()
6322 gtk_border_new (void)
6324 return g_slice_new0 (GtkBorder);
6329 * @border_: a #GtkBorder.
6330 * @returns: a copy of @border_.
6332 * Copies a #GtkBorder structure.
6335 gtk_border_copy (const GtkBorder *border)
6337 g_return_val_if_fail (border != NULL, NULL);
6339 return g_slice_dup (GtkBorder, border);
6344 * @border_: a #GtkBorder.
6346 * Frees a #GtkBorder structure.
6349 gtk_border_free (GtkBorder *border)
6351 g_slice_free (GtkBorder, border);
6354 G_DEFINE_BOXED_TYPE (GtkBorder, gtk_border,
6358 typedef struct _CursorInfo CursorInfo;
6368 style_unrealize_cursors (GtkStyle *style)
6372 cursor_info = g_object_get_data (G_OBJECT (style), "gtk-style-cursor-info");
6375 g_free (cursor_info);
6376 g_object_set_data (G_OBJECT (style), I_("gtk-style-cursor-info"), NULL);
6380 static const GdkColor *
6381 get_insertion_cursor_color (GtkWidget *widget,
6382 gboolean is_primary)
6384 CursorInfo *cursor_info;
6386 GdkColor *cursor_color;
6388 style = gtk_widget_get_style (widget);
6390 cursor_info = g_object_get_data (G_OBJECT (style), "gtk-style-cursor-info");
6393 cursor_info = g_new0 (CursorInfo, 1);
6394 g_object_set_data (G_OBJECT (style), I_("gtk-style-cursor-info"), cursor_info);
6395 cursor_info->for_type = G_TYPE_INVALID;
6398 /* We have to keep track of the type because gtk_widget_style_get()
6399 * can return different results when called on the same property and
6400 * same style but for different widgets. :-(. That is,
6401 * GtkEntry::cursor-color = "red" in a style will modify the cursor
6402 * color for entries but not for text view.
6404 if (cursor_info->for_type != G_OBJECT_TYPE (widget))
6406 cursor_info->for_type = G_OBJECT_TYPE (widget);
6408 /* Cursors in text widgets are drawn only in NORMAL state,
6409 * so we can use text[GTK_STATE_NORMAL] as text color here */
6410 gtk_widget_style_get (widget, "cursor-color", &cursor_color, NULL);
6413 cursor_info->primary = *cursor_color;
6414 gdk_color_free (cursor_color);
6418 cursor_info->primary = style->text[GTK_STATE_NORMAL];
6421 gtk_widget_style_get (widget, "secondary-cursor-color", &cursor_color, NULL);
6424 cursor_info->secondary = *cursor_color;
6425 gdk_color_free (cursor_color);
6429 /* text_aa is the average of text and base colors,
6430 * in usual black-on-white case it's grey. */
6431 cursor_info->secondary = style->text_aa[GTK_STATE_NORMAL];
6436 return &cursor_info->primary;
6438 return &cursor_info->secondary;
6442 _gtk_widget_get_cursor_color (GtkWidget *widget,
6445 GdkColor *style_color;
6447 g_return_if_fail (GTK_IS_WIDGET (widget));
6448 g_return_if_fail (color != NULL);
6450 gtk_widget_style_get (widget, "cursor-color", &style_color, NULL);
6454 *color = *style_color;
6455 gdk_color_free (style_color);
6458 *color = gtk_widget_get_style (widget)->text[GTK_STATE_NORMAL];
6462 draw_insertion_cursor (GtkWidget *widget,
6464 const GdkRectangle *location,
6465 GtkTextDirection direction,
6466 gboolean draw_arrow)
6471 gfloat cursor_aspect_ratio;
6474 /* When changing the shape or size of the cursor here,
6475 * propagate the changes to gtktextview.c:text_window_invalidate_cursors().
6478 gtk_widget_style_get (widget, "cursor-aspect-ratio", &cursor_aspect_ratio, NULL);
6480 stem_width = location->height * cursor_aspect_ratio + 1;
6481 arrow_width = stem_width + 1;
6483 /* put (stem_width % 2) on the proper side of the cursor */
6484 if (direction == GTK_TEXT_DIR_LTR)
6485 offset = stem_width / 2;
6487 offset = stem_width - stem_width / 2;
6489 cairo_rectangle (cr,
6490 location->x - offset, location->y,
6491 stem_width, location->height);
6496 if (direction == GTK_TEXT_DIR_RTL)
6498 x = location->x - offset - 1;
6499 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
6501 cairo_move_to (cr, x, y + 1);
6502 cairo_line_to (cr, x - arrow_width, y + arrow_width);
6503 cairo_line_to (cr, x, y + 2 * arrow_width);
6506 else if (direction == GTK_TEXT_DIR_LTR)
6508 x = location->x + stem_width - offset;
6509 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
6511 cairo_move_to (cr, x, y + 1);
6512 cairo_line_to (cr, x + arrow_width, y + arrow_width);
6513 cairo_line_to (cr, x, y + 2 * arrow_width);
6520 * gtk_draw_insertion_cursor:
6521 * @widget: a #GtkWidget
6522 * @drawable: a #GdkDrawable
6523 * @area: (allow-none): rectangle to which the output is clipped, or %NULL if the
6524 * output should not be clipped
6525 * @location: location where to draw the cursor (@location->width is ignored)
6526 * @is_primary: if the cursor should be the primary cursor color.
6527 * @direction: whether the cursor is left-to-right or
6528 * right-to-left. Should never be #GTK_TEXT_DIR_NONE
6529 * @draw_arrow: %TRUE to draw a directional arrow on the
6530 * cursor. Should be %FALSE unless the cursor is split.
6532 * Draws a text caret on @drawable at @location. This is not a style function
6533 * but merely a convenience function for drawing the standard cursor shape.
6538 gtk_draw_insertion_cursor (GtkWidget *widget,
6539 GdkDrawable *drawable,
6540 const GdkRectangle *area,
6541 const GdkRectangle *location,
6542 gboolean is_primary,
6543 GtkTextDirection direction,
6544 gboolean draw_arrow)
6548 g_return_if_fail (GTK_IS_WIDGET (widget));
6549 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
6550 g_return_if_fail (location != NULL);
6551 g_return_if_fail (direction != GTK_TEXT_DIR_NONE);
6553 cr = gdk_cairo_create (drawable);
6556 gdk_cairo_rectangle (cr, area);
6560 gdk_cairo_set_source_color (cr, get_insertion_cursor_color (widget, is_primary));
6561 draw_insertion_cursor (widget, cr, location, direction, draw_arrow);