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() */
43 #include "gtkspinner.h"
48 * @Short_description: An object that hold style information for widgets
51 * A #GtkStyle object encapsulates the information that provides the look and
52 * feel for a widget. Each #GtkWidget has an associated #GTkStyle object that
53 * is used when rendering that widget. Also, a #GtkStyle holds information for
54 * the five possible widget states though not every widget supports all five
55 * states; see #GtkStateType.
57 * Usually the #GtkStyle for a widget is the same as the default style that is
58 * set by GTK+ and modified the theme engine.
60 * Usually applications should not need to use or modify the #GtkStyle of their
65 #define LIGHTNESS_MULT 1.3
66 #define DARKNESS_MULT 0.7
68 /* --- typedefs & structures --- */
75 #define GTK_STYLE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_STYLE, GtkStylePrivate))
77 typedef struct _GtkStylePrivate GtkStylePrivate;
79 struct _GtkStylePrivate {
81 GtkStyleContext *context;
82 gulong context_changed_id;
90 /* --- prototypes --- */
91 static void gtk_style_finalize (GObject *object);
92 static void gtk_style_constructed (GObject *object);
93 static void gtk_style_set_property (GObject *object,
98 static void gtk_style_realize (GtkStyle *style,
100 static void gtk_style_real_realize (GtkStyle *style);
101 static void gtk_style_real_unrealize (GtkStyle *style);
102 static void gtk_style_real_copy (GtkStyle *style,
104 static void gtk_style_real_set_background (GtkStyle *style,
106 GtkStateType state_type);
107 static GtkStyle *gtk_style_real_clone (GtkStyle *style);
108 static void gtk_style_real_init_from_rc (GtkStyle *style,
109 GtkRcStyle *rc_style);
110 static GdkPixbuf *gtk_default_render_icon (GtkStyle *style,
111 const GtkIconSource *source,
112 GtkTextDirection direction,
116 const gchar *detail);
117 static void gtk_default_draw_hline (GtkStyle *style,
119 GtkStateType state_type,
125 static void gtk_default_draw_vline (GtkStyle *style,
127 GtkStateType state_type,
133 static void gtk_default_draw_shadow (GtkStyle *style,
135 GtkStateType state_type,
136 GtkShadowType shadow_type,
143 static void gtk_default_draw_arrow (GtkStyle *style,
145 GtkStateType state_type,
146 GtkShadowType shadow_type,
149 GtkArrowType arrow_type,
155 static void gtk_default_draw_diamond (GtkStyle *style,
157 GtkStateType state_type,
158 GtkShadowType shadow_type,
165 static void gtk_default_draw_box (GtkStyle *style,
167 GtkStateType state_type,
168 GtkShadowType shadow_type,
175 static void gtk_default_draw_flat_box (GtkStyle *style,
177 GtkStateType state_type,
178 GtkShadowType shadow_type,
185 static void gtk_default_draw_check (GtkStyle *style,
187 GtkStateType state_type,
188 GtkShadowType shadow_type,
195 static void gtk_default_draw_option (GtkStyle *style,
197 GtkStateType state_type,
198 GtkShadowType shadow_type,
205 static void gtk_default_draw_tab (GtkStyle *style,
207 GtkStateType state_type,
208 GtkShadowType shadow_type,
215 static void gtk_default_draw_shadow_gap (GtkStyle *style,
217 GtkStateType state_type,
218 GtkShadowType shadow_type,
225 GtkPositionType gap_side,
228 static void gtk_default_draw_box_gap (GtkStyle *style,
230 GtkStateType state_type,
231 GtkShadowType shadow_type,
238 GtkPositionType gap_side,
241 static void gtk_default_draw_extension (GtkStyle *style,
243 GtkStateType state_type,
244 GtkShadowType shadow_type,
251 GtkPositionType gap_side);
252 static void gtk_default_draw_focus (GtkStyle *style,
254 GtkStateType state_type,
261 static void gtk_default_draw_slider (GtkStyle *style,
263 GtkStateType state_type,
264 GtkShadowType shadow_type,
271 GtkOrientation orientation);
272 static void gtk_default_draw_handle (GtkStyle *style,
274 GtkStateType state_type,
275 GtkShadowType shadow_type,
282 GtkOrientation orientation);
283 static void gtk_default_draw_expander (GtkStyle *style,
285 GtkStateType state_type,
290 GtkExpanderStyle expander_style);
291 static void gtk_default_draw_layout (GtkStyle *style,
293 GtkStateType state_type,
299 PangoLayout *layout);
300 static void gtk_default_draw_resize_grip (GtkStyle *style,
302 GtkStateType state_type,
310 static void gtk_default_draw_spinner (GtkStyle *style,
312 GtkStateType state_type,
321 static void rgb_to_hls (gdouble *r,
324 static void hls_to_rgb (gdouble *h,
328 static void style_unrealize_cursors (GtkStyle *style);
330 static void transform_detail_string (const gchar *detail,
331 GtkStyleContext *context);
334 * Data for default check and radio buttons
337 static const GtkRequisition default_option_indicator_size = { 7, 13 };
338 static const GtkBorder default_option_indicator_spacing = { 7, 5, 2, 2 };
340 #define GTK_GRAY 0xdcdc, 0xdada, 0xd5d5
341 #define GTK_DARK_GRAY 0xc4c4, 0xc2c2, 0xbdbd
342 #define GTK_LIGHT_GRAY 0xeeee, 0xebeb, 0xe7e7
343 #define GTK_WHITE 0xffff, 0xffff, 0xffff
344 #define GTK_BLUE 0x4b4b, 0x6969, 0x8383
345 #define GTK_VERY_DARK_GRAY 0x9c9c, 0x9a9a, 0x9494
346 #define GTK_BLACK 0x0000, 0x0000, 0x0000
347 #define GTK_WEAK_GRAY 0x7530, 0x7530, 0x7530
349 /* --- variables --- */
350 static const GdkColor gtk_default_normal_fg = { 0, GTK_BLACK };
351 static const GdkColor gtk_default_active_fg = { 0, GTK_BLACK };
352 static const GdkColor gtk_default_prelight_fg = { 0, GTK_BLACK };
353 static const GdkColor gtk_default_selected_fg = { 0, GTK_WHITE };
354 static const GdkColor gtk_default_insensitive_fg = { 0, GTK_WEAK_GRAY };
356 static const GdkColor gtk_default_normal_bg = { 0, GTK_GRAY };
357 static const GdkColor gtk_default_active_bg = { 0, GTK_DARK_GRAY };
358 static const GdkColor gtk_default_prelight_bg = { 0, GTK_LIGHT_GRAY };
359 static const GdkColor gtk_default_selected_bg = { 0, GTK_BLUE };
360 static const GdkColor gtk_default_insensitive_bg = { 0, GTK_GRAY };
361 static const GdkColor gtk_default_selected_base = { 0, GTK_BLUE };
362 static const GdkColor gtk_default_active_base = { 0, GTK_VERY_DARK_GRAY };
364 /* --- signals --- */
365 static guint realize_signal = 0;
366 static guint unrealize_signal = 0;
368 G_DEFINE_TYPE (GtkStyle, gtk_style, G_TYPE_OBJECT)
370 /* --- functions --- */
373 * _gtk_style_init_for_settings:
374 * @style: a #GtkStyle
375 * @settings: a #GtkSettings
377 * Initializes the font description in @style according to the default
378 * font name of @settings. This is called for gtk_style_new() with
379 * the settings for the default screen (if any); if we are creating
380 * a style for a particular screen, we then call it again in a
381 * location where we know the correct settings.
382 * The reason for this is that gtk_rc_style_create_style() doesn't
383 * take the screen for an argument.
386 _gtk_style_init_for_settings (GtkStyle *style,
387 GtkSettings *settings)
389 const gchar *font_name = _gtk_rc_context_get_default_font_name (settings);
391 if (style->font_desc)
392 pango_font_description_free (style->font_desc);
394 style->font_desc = pango_font_description_from_string (font_name);
396 if (!pango_font_description_get_family (style->font_desc))
398 g_warning ("Default font does not have a family set");
399 pango_font_description_set_family (style->font_desc, "Sans");
401 if (pango_font_description_get_size (style->font_desc) <= 0)
403 g_warning ("Default font does not have a positive size");
404 pango_font_description_set_size (style->font_desc, 10 * PANGO_SCALE);
409 gtk_style_init (GtkStyle *style)
413 GtkSettings *settings = gtk_settings_get_default ();
416 _gtk_style_init_for_settings (style, settings);
418 style->font_desc = pango_font_description_from_string ("Sans 10");
420 style->attach_count = 0;
422 style->black.red = 0;
423 style->black.green = 0;
424 style->black.blue = 0;
426 style->white.red = 65535;
427 style->white.green = 65535;
428 style->white.blue = 65535;
430 style->fg[GTK_STATE_NORMAL] = gtk_default_normal_fg;
431 style->fg[GTK_STATE_ACTIVE] = gtk_default_active_fg;
432 style->fg[GTK_STATE_PRELIGHT] = gtk_default_prelight_fg;
433 style->fg[GTK_STATE_SELECTED] = gtk_default_selected_fg;
434 style->fg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
436 style->bg[GTK_STATE_NORMAL] = gtk_default_normal_bg;
437 style->bg[GTK_STATE_ACTIVE] = gtk_default_active_bg;
438 style->bg[GTK_STATE_PRELIGHT] = gtk_default_prelight_bg;
439 style->bg[GTK_STATE_SELECTED] = gtk_default_selected_bg;
440 style->bg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_bg;
442 for (i = 0; i < 4; i++)
444 style->text[i] = style->fg[i];
445 style->base[i] = style->white;
448 style->base[GTK_STATE_SELECTED] = gtk_default_selected_base;
449 style->text[GTK_STATE_SELECTED] = style->white;
450 style->base[GTK_STATE_ACTIVE] = gtk_default_active_base;
451 style->text[GTK_STATE_ACTIVE] = style->white;
452 style->base[GTK_STATE_INSENSITIVE] = gtk_default_prelight_bg;
453 style->text[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
455 style->rc_style = NULL;
457 style->xthickness = 2;
458 style->ythickness = 2;
460 style->property_cache = NULL;
464 gtk_style_class_init (GtkStyleClass *klass)
466 GObjectClass *object_class = G_OBJECT_CLASS (klass);
468 object_class->finalize = gtk_style_finalize;
469 object_class->set_property = gtk_style_set_property;
470 object_class->constructed = gtk_style_constructed;
472 klass->clone = gtk_style_real_clone;
473 klass->copy = gtk_style_real_copy;
474 klass->init_from_rc = gtk_style_real_init_from_rc;
475 klass->realize = gtk_style_real_realize;
476 klass->unrealize = gtk_style_real_unrealize;
477 klass->set_background = gtk_style_real_set_background;
478 klass->render_icon = gtk_default_render_icon;
480 klass->draw_hline = gtk_default_draw_hline;
481 klass->draw_vline = gtk_default_draw_vline;
482 klass->draw_shadow = gtk_default_draw_shadow;
483 klass->draw_arrow = gtk_default_draw_arrow;
484 klass->draw_diamond = gtk_default_draw_diamond;
485 klass->draw_box = gtk_default_draw_box;
486 klass->draw_flat_box = gtk_default_draw_flat_box;
487 klass->draw_check = gtk_default_draw_check;
488 klass->draw_option = gtk_default_draw_option;
489 klass->draw_tab = gtk_default_draw_tab;
490 klass->draw_shadow_gap = gtk_default_draw_shadow_gap;
491 klass->draw_box_gap = gtk_default_draw_box_gap;
492 klass->draw_extension = gtk_default_draw_extension;
493 klass->draw_focus = gtk_default_draw_focus;
494 klass->draw_slider = gtk_default_draw_slider;
495 klass->draw_handle = gtk_default_draw_handle;
496 klass->draw_expander = gtk_default_draw_expander;
497 klass->draw_layout = gtk_default_draw_layout;
498 klass->draw_resize_grip = gtk_default_draw_resize_grip;
499 klass->draw_spinner = gtk_default_draw_spinner;
501 g_type_class_add_private (object_class, sizeof (GtkStylePrivate));
503 g_object_class_install_property (object_class,
505 g_param_spec_object ("context",
507 P_("GtkStyleContext to get style from"),
508 GTK_TYPE_STYLE_CONTEXT,
509 G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE));
513 * @style: the object which received the signal
515 * Emitted when the style has been initialized for a particular
516 * visual. Connecting to this signal is probably seldom
517 * useful since most of the time applications and widgets only
518 * deal with styles that have been already realized.
522 realize_signal = g_signal_new (I_("realize"),
523 G_TYPE_FROM_CLASS (object_class),
525 G_STRUCT_OFFSET (GtkStyleClass, realize),
527 _gtk_marshal_VOID__VOID,
530 * GtkStyle::unrealize:
531 * @style: the object which received the signal
533 * Emitted when the aspects of the style specific to a particular visual
534 * is being cleaned up. A connection to this signal can be useful
535 * if a widget wants to cache objects as object data on #GtkStyle.
536 * This signal provides a convenient place to free such cached objects.
540 unrealize_signal = g_signal_new (I_("unrealize"),
541 G_TYPE_FROM_CLASS (object_class),
543 G_STRUCT_OFFSET (GtkStyleClass, unrealize),
545 _gtk_marshal_VOID__VOID,
550 clear_property_cache (GtkStyle *style)
552 if (style->property_cache)
556 for (i = 0; i < style->property_cache->len; i++)
558 PropertyValue *node = &g_array_index (style->property_cache, PropertyValue, i);
560 g_param_spec_unref (node->pspec);
561 g_value_unset (&node->value);
563 g_array_free (style->property_cache, TRUE);
564 style->property_cache = NULL;
569 gtk_style_finalize (GObject *object)
571 GtkStyle *style = GTK_STYLE (object);
572 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
574 g_return_if_fail (style->attach_count == 0);
576 clear_property_cache (style);
578 /* All the styles in the list have the same
579 * style->styles pointer. If we delete the
580 * *first* style from the list, we need to update
581 * the style->styles pointers from all the styles.
582 * Otherwise we simply remove the node from
587 if (style->styles->data != style)
588 style->styles = g_slist_remove (style->styles, style);
591 GSList *tmp_list = style->styles->next;
595 GTK_STYLE (tmp_list->data)->styles = style->styles->next;
596 tmp_list = tmp_list->next;
598 g_slist_free_1 (style->styles);
602 g_slist_foreach (style->icon_factories, (GFunc) g_object_unref, NULL);
603 g_slist_free (style->icon_factories);
605 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_unref, NULL);
606 g_slist_free (priv->color_hashes);
608 pango_font_description_free (style->font_desc);
610 if (style->private_font_desc)
611 pango_font_description_free (style->private_font_desc);
614 g_object_unref (style->rc_style);
618 if (priv->context_changed_id)
619 g_signal_handler_disconnect (priv->context, priv->context_changed_id);
621 g_object_unref (priv->context);
624 G_OBJECT_CLASS (gtk_style_parent_class)->finalize (object);
628 gtk_style_set_property (GObject *object,
633 GtkStylePrivate *priv;
635 priv = GTK_STYLE_GET_PRIVATE (object);
640 priv->context = g_value_dup_object (value);
643 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
649 set_color (GtkStyle *style,
650 GtkStyleContext *context,
655 GdkRGBA *color = NULL;
656 GdkColor *dest = { 0 }; /* Shut up gcc */
660 case GTK_STATE_ACTIVE:
661 flags = GTK_STATE_FLAG_ACTIVE;
663 case GTK_STATE_PRELIGHT:
664 flags = GTK_STATE_FLAG_PRELIGHT;
666 case GTK_STATE_SELECTED:
667 flags = GTK_STATE_FLAG_SELECTED;
669 case GTK_STATE_INSENSITIVE:
670 flags = GTK_STATE_FLAG_INSENSITIVE;
679 gtk_style_context_get (context, flags,
680 "background-color", &color,
682 dest = &style->bg[state];
685 gtk_style_context_get (context, flags,
688 dest = &style->fg[state];
691 gtk_style_context_get (context, flags,
694 dest = &style->text[state];
697 gtk_style_context_get (context, flags,
698 "background-color", &color,
700 dest = &style->base[state];
707 dest->red = CLAMP ((guint) (color->red * 65535), 0, 65535);
708 dest->green = CLAMP ((guint) (color->green * 65535), 0, 65535);
709 dest->blue = CLAMP ((guint) (color->blue * 65535), 0, 65535);
710 gdk_rgba_free (color);
715 gtk_style_update_from_context (GtkStyle *style)
717 GtkStylePrivate *priv;
721 priv = GTK_STYLE_GET_PRIVATE (style);
723 for (state = GTK_STATE_NORMAL; state <= GTK_STATE_INSENSITIVE; state++)
725 if (gtk_style_context_has_class (priv->context, "entry"))
727 gtk_style_context_save (priv->context);
728 gtk_style_context_remove_class (priv->context, "entry");
729 set_color (style, priv->context, state, GTK_RC_BG);
730 set_color (style, priv->context, state, GTK_RC_FG);
731 gtk_style_context_restore (priv->context);
733 set_color (style, priv->context, state, GTK_RC_BASE);
734 set_color (style, priv->context, state, GTK_RC_TEXT);
738 gtk_style_context_save (priv->context);
739 gtk_style_context_add_class (priv->context, "entry");
740 set_color (style, priv->context, state, GTK_RC_BASE);
741 set_color (style, priv->context, state, GTK_RC_TEXT);
742 gtk_style_context_restore (priv->context);
744 set_color (style, priv->context, state, GTK_RC_BG);
745 set_color (style, priv->context, state, GTK_RC_FG);
749 if (style->font_desc)
750 pango_font_description_free (style->font_desc);
752 gtk_style_context_get (priv->context, state,
753 "font", &style->font_desc,
759 style->xthickness = padding->left;
760 style->ythickness = padding->top;
762 gtk_border_free (padding);
767 style_context_changed (GtkStyleContext *context,
770 gtk_style_update_from_context (GTK_STYLE (user_data));
774 gtk_style_constructed (GObject *object)
776 GtkStylePrivate *priv;
778 priv = GTK_STYLE_GET_PRIVATE (object);
782 gtk_style_update_from_context (GTK_STYLE (object));
784 priv->context_changed_id = g_signal_connect (priv->context, "changed",
785 G_CALLBACK (style_context_changed), object);
791 * @style: a #GtkStyle
793 * Creates a copy of the passed in #GtkStyle object.
795 * Returns: (transfer full): a copy of @style
798 gtk_style_copy (GtkStyle *style)
802 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
804 new_style = GTK_STYLE_GET_CLASS (style)->clone (style);
805 GTK_STYLE_GET_CLASS (style)->copy (new_style, style);
811 gtk_style_duplicate (GtkStyle *style)
815 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
817 new_style = gtk_style_copy (style);
819 /* All the styles in the list have the same
820 * style->styles pointer. When we insert a new
821 * style, we append it to the list to avoid having
822 * to update the existing ones.
824 style->styles = g_slist_append (style->styles, new_style);
825 new_style->styles = style->styles;
832 * @returns: a new #GtkStyle.
834 * Creates a new #GtkStyle.
841 style = g_object_new (GTK_TYPE_STYLE, NULL);
847 gtk_style_has_context (GtkStyle *style)
849 GtkStylePrivate *priv;
851 priv = GTK_STYLE_GET_PRIVATE (style);
853 return priv->context != NULL;
858 * @style: a #GtkStyle.
859 * @window: a #GdkWindow.
861 * Attaches a style to a window; this process allocates the
862 * colors and creates the GC's for the style - it specializes
863 * it to a particular visual. The process may involve the creation
864 * of a new style if the style has already been attached to a
865 * window with a different style and visual.
867 * Since this function may return a new object, you have to use it
868 * in the following way:
869 * <literal>style = gtk_style_attach (style, window)</literal>
871 * Returns: Either @style, or a newly-created #GtkStyle.
872 * If the style is newly created, the style parameter
873 * will be unref'ed, and the new style will have
874 * a reference count belonging to the caller.
877 gtk_style_attach (GtkStyle *style,
881 GtkStyle *new_style = NULL;
884 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
885 g_return_val_if_fail (window != NULL, NULL);
887 visual = gdk_window_get_visual (window);
890 style->styles = g_slist_append (NULL, style);
892 styles = style->styles;
895 new_style = styles->data;
897 if (new_style->visual == visual)
901 styles = styles->next;
906 styles = style->styles;
910 new_style = styles->data;
912 if (new_style->attach_count == 0)
914 gtk_style_realize (new_style, visual);
919 styles = styles->next;
925 new_style = gtk_style_duplicate (style);
926 gtk_style_realize (new_style, visual);
929 /* A style gets a refcount from being attached */
930 if (new_style->attach_count == 0)
931 g_object_ref (new_style);
933 /* Another refcount belongs to the parent */
934 if (style != new_style)
936 g_object_unref (style);
937 g_object_ref (new_style);
940 new_style->attach_count++;
947 * @style: a #GtkStyle
949 * Detaches a style from a window. If the style is not attached
950 * to any windows anymore, it is unrealized. See gtk_style_attach().
954 gtk_style_detach (GtkStyle *style)
956 g_return_if_fail (GTK_IS_STYLE (style));
957 g_return_if_fail (style->attach_count > 0);
959 style->attach_count -= 1;
960 if (style->attach_count == 0)
962 g_signal_emit (style, unrealize_signal, 0);
964 g_object_unref (style->visual);
965 style->visual = NULL;
967 if (style->private_font_desc)
969 pango_font_description_free (style->private_font_desc);
970 style->private_font_desc = NULL;
973 g_object_unref (style);
978 gtk_style_realize (GtkStyle *style,
981 style->visual = g_object_ref (visual);
983 g_signal_emit (style, realize_signal, 0);
987 * gtk_style_lookup_icon_set:
988 * @style: a #GtkStyle
989 * @stock_id: an icon name
991 * Looks up @stock_id in the icon factories associated with @style
992 * and the default icon factory, returning an icon set if found,
995 * Return value: icon set of @stock_id
998 gtk_style_lookup_icon_set (GtkStyle *style,
999 const char *stock_id)
1001 GtkStylePrivate *priv;
1003 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1004 g_return_val_if_fail (stock_id != NULL, NULL);
1006 priv = GTK_STYLE_GET_PRIVATE (style);
1008 return gtk_style_context_lookup_icon_set (priv->context, stock_id);
1012 * gtk_style_lookup_color:
1013 * @style: a #GtkStyle
1014 * @color_name: the name of the logical color to look up
1015 * @color: the #GdkColor to fill in
1017 * Looks up @color_name in the style's logical color mappings,
1018 * filling in @color and returning %TRUE if found, otherwise
1019 * returning %FALSE. Do not cache the found mapping, because
1020 * it depends on the #GtkStyle and might change when a theme
1023 * Return value: %TRUE if the mapping was found.
1028 gtk_style_lookup_color (GtkStyle *style,
1029 const char *color_name,
1032 GtkStylePrivate *priv;
1036 g_return_val_if_fail (GTK_IS_STYLE (style), FALSE);
1037 g_return_val_if_fail (color_name != NULL, FALSE);
1038 g_return_val_if_fail (color != NULL, FALSE);
1040 priv = GTK_STYLE_GET_PRIVATE (style);
1045 result = gtk_style_context_lookup_color (priv->context, color_name, &rgba);
1049 color->red = (guint16) (rgba.red * 65535);
1050 color->green = (guint16) (rgba.green * 65535);
1051 color->blue = (guint16) (rgba.blue * 65535);
1059 * gtk_style_set_background:
1060 * @style: a #GtkStyle
1061 * @window: a #GdkWindow
1062 * @state_type: a state
1064 * Sets the background of @window to the background color or pixmap
1065 * specified by @style for the given state.
1068 gtk_style_set_background (GtkStyle *style,
1070 GtkStateType state_type)
1072 g_return_if_fail (GTK_IS_STYLE (style));
1073 g_return_if_fail (window != NULL);
1075 GTK_STYLE_GET_CLASS (style)->set_background (style, window, state_type);
1078 /* Default functions */
1080 gtk_style_real_clone (GtkStyle *style)
1082 GtkStylePrivate *priv;
1084 priv = GTK_STYLE_GET_PRIVATE (style);
1086 return g_object_new (G_OBJECT_TYPE (style),
1087 "context", priv->context,
1092 gtk_style_real_copy (GtkStyle *style,
1095 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
1096 GtkStylePrivate *src_priv = GTK_STYLE_GET_PRIVATE (src);
1099 for (i = 0; i < 5; i++)
1101 style->fg[i] = src->fg[i];
1102 style->bg[i] = src->bg[i];
1103 style->text[i] = src->text[i];
1104 style->base[i] = src->base[i];
1106 if (style->background[i])
1107 cairo_pattern_destroy (style->background[i]),
1108 style->background[i] = src->background[i];
1109 if (style->background[i])
1110 cairo_pattern_reference (style->background[i]);
1113 if (style->font_desc)
1114 pango_font_description_free (style->font_desc);
1116 style->font_desc = pango_font_description_copy (src->font_desc);
1118 style->font_desc = NULL;
1120 style->xthickness = src->xthickness;
1121 style->ythickness = src->ythickness;
1123 if (style->rc_style)
1124 g_object_unref (style->rc_style);
1125 style->rc_style = src->rc_style;
1127 g_object_ref (src->rc_style);
1129 g_slist_foreach (style->icon_factories, (GFunc) g_object_unref, NULL);
1130 g_slist_free (style->icon_factories);
1131 style->icon_factories = g_slist_copy (src->icon_factories);
1132 g_slist_foreach (style->icon_factories, (GFunc) g_object_ref, NULL);
1134 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_unref, NULL);
1135 g_slist_free (priv->color_hashes);
1136 priv->color_hashes = g_slist_copy (src_priv->color_hashes);
1137 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_ref, NULL);
1139 /* don't copy, just clear cache */
1140 clear_property_cache (style);
1144 gtk_style_real_init_from_rc (GtkStyle *style,
1145 GtkRcStyle *rc_style)
1147 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
1150 /* cache _should_ be still empty */
1151 clear_property_cache (style);
1153 if (rc_style->font_desc)
1154 pango_font_description_merge (style->font_desc, rc_style->font_desc, TRUE);
1156 for (i = 0; i < 5; i++)
1158 if (rc_style->color_flags[i] & GTK_RC_FG)
1159 style->fg[i] = rc_style->fg[i];
1160 if (rc_style->color_flags[i] & GTK_RC_BG)
1161 style->bg[i] = rc_style->bg[i];
1162 if (rc_style->color_flags[i] & GTK_RC_TEXT)
1163 style->text[i] = rc_style->text[i];
1164 if (rc_style->color_flags[i] & GTK_RC_BASE)
1165 style->base[i] = rc_style->base[i];
1168 if (rc_style->xthickness >= 0)
1169 style->xthickness = rc_style->xthickness;
1170 if (rc_style->ythickness >= 0)
1171 style->ythickness = rc_style->ythickness;
1173 style->icon_factories = g_slist_copy (rc_style->icon_factories);
1174 g_slist_foreach (style->icon_factories, (GFunc) g_object_ref, NULL);
1176 priv->color_hashes = g_slist_copy (_gtk_rc_style_get_color_hashes (rc_style));
1177 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_ref, NULL);
1181 style_property_values_cmp (gconstpointer bsearch_node1,
1182 gconstpointer bsearch_node2)
1184 const PropertyValue *val1 = bsearch_node1;
1185 const PropertyValue *val2 = bsearch_node2;
1187 if (val1->widget_type == val2->widget_type)
1188 return val1->pspec < val2->pspec ? -1 : val1->pspec == val2->pspec ? 0 : 1;
1190 return val1->widget_type < val2->widget_type ? -1 : 1;
1194 * gtk_style_get_style_property:
1195 * @style: a #GtkStyle
1196 * @widget_type: the #GType of a descendant of #GtkWidget
1197 * @property_name: the name of the style property to get
1198 * @value: a #GValue where the value of the property being
1199 * queried will be stored
1201 * Queries the value of a style property corresponding to a
1202 * widget class is in the given style.
1207 gtk_style_get_style_property (GtkStyle *style,
1209 const gchar *property_name,
1212 GtkWidgetClass *klass;
1214 GtkRcPropertyParser parser;
1215 const GValue *peek_value;
1217 klass = g_type_class_ref (widget_type);
1218 pspec = gtk_widget_class_find_style_property (klass, property_name);
1219 g_type_class_unref (klass);
1223 g_warning ("%s: widget class `%s' has no property named `%s'",
1225 g_type_name (widget_type),
1230 parser = g_param_spec_get_qdata (pspec,
1231 g_quark_from_static_string ("gtk-rc-property-parser"));
1233 peek_value = _gtk_style_peek_property_value (style, widget_type, pspec, parser);
1235 if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec))
1236 g_value_copy (peek_value, value);
1237 else if (g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
1238 g_value_transform (peek_value, value);
1240 g_warning ("can't retrieve style property `%s' of type `%s' as value of type `%s'",
1242 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1243 G_VALUE_TYPE_NAME (value));
1247 * gtk_style_get_valist:
1248 * @style: a #GtkStyle
1249 * @widget_type: the #GType of a descendant of #GtkWidget
1250 * @first_property_name: the name of the first style property to get
1251 * @var_args: a <type>va_list</type> of pairs of property names and
1252 * locations to return the property values, starting with the
1253 * location for @first_property_name.
1255 * Non-vararg variant of gtk_style_get().
1256 * Used primarily by language bindings.
1261 gtk_style_get_valist (GtkStyle *style,
1263 const gchar *first_property_name,
1266 const char *property_name;
1267 GtkWidgetClass *klass;
1269 g_return_if_fail (GTK_IS_STYLE (style));
1271 klass = g_type_class_ref (widget_type);
1273 property_name = first_property_name;
1274 while (property_name)
1277 GtkRcPropertyParser parser;
1278 const GValue *peek_value;
1281 pspec = gtk_widget_class_find_style_property (klass, property_name);
1285 g_warning ("%s: widget class `%s' has no property named `%s'",
1287 g_type_name (widget_type),
1292 parser = g_param_spec_get_qdata (pspec,
1293 g_quark_from_static_string ("gtk-rc-property-parser"));
1295 peek_value = _gtk_style_peek_property_value (style, widget_type, pspec, parser);
1296 G_VALUE_LCOPY (peek_value, var_args, 0, &error);
1299 g_warning ("%s: %s", G_STRLOC, error);
1304 property_name = va_arg (var_args, gchar*);
1307 g_type_class_unref (klass);
1312 * @style: a #GtkStyle
1313 * @widget_type: the #GType of a descendant of #GtkWidget
1314 * @first_property_name: the name of the first style property to get
1315 * @Varargs: pairs of property names and locations to
1316 * return the property values, starting with the location for
1317 * @first_property_name, terminated by %NULL.
1319 * Gets the values of a multiple style properties for @widget_type
1325 gtk_style_get (GtkStyle *style,
1327 const gchar *first_property_name,
1332 va_start (var_args, first_property_name);
1333 gtk_style_get_valist (style, widget_type, first_property_name, var_args);
1338 _gtk_style_peek_property_value (GtkStyle *style,
1341 GtkRcPropertyParser parser)
1343 PropertyValue *pcache, key = { 0, NULL, { 0, } };
1344 const GtkRcProperty *rcprop = NULL;
1347 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1348 g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL);
1349 g_return_val_if_fail (g_type_is_a (pspec->owner_type, GTK_TYPE_WIDGET), NULL);
1350 g_return_val_if_fail (g_type_is_a (widget_type, pspec->owner_type), NULL);
1352 key.widget_type = widget_type;
1355 /* need value cache array */
1356 if (!style->property_cache)
1357 style->property_cache = g_array_new (FALSE, FALSE, sizeof (PropertyValue));
1360 pcache = bsearch (&key,
1361 style->property_cache->data, style->property_cache->len,
1362 sizeof (PropertyValue), style_property_values_cmp);
1364 return &pcache->value;
1368 while (i < style->property_cache->len &&
1369 style_property_values_cmp (&key, &g_array_index (style->property_cache, PropertyValue, i)) >= 0)
1372 g_array_insert_val (style->property_cache, i, key);
1373 pcache = &g_array_index (style->property_cache, PropertyValue, i);
1375 /* cache miss, initialize value type, then set contents */
1376 g_param_spec_ref (pcache->pspec);
1377 g_value_init (&pcache->value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1379 /* value provided by rc style? */
1380 if (style->rc_style)
1382 GQuark prop_quark = g_quark_from_string (pspec->name);
1386 rcprop = _gtk_rc_style_lookup_rc_property (style->rc_style,
1387 g_type_qname (widget_type),
1391 widget_type = g_type_parent (widget_type);
1393 while (g_type_is_a (widget_type, pspec->owner_type));
1396 /* when supplied by rc style, we need to convert */
1397 if (rcprop && !_gtk_settings_parse_convert (parser, &rcprop->value,
1398 pspec, &pcache->value))
1400 gchar *contents = g_strdup_value_contents (&rcprop->value);
1402 g_message ("%s: failed to retrieve property `%s::%s' of type `%s' from rc file value \"%s\" of type `%s'",
1403 rcprop->origin ? rcprop->origin : "(for origin information, set GTK_DEBUG)",
1404 g_type_name (pspec->owner_type), pspec->name,
1405 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1407 G_VALUE_TYPE_NAME (&rcprop->value));
1409 rcprop = NULL; /* needs default */
1412 /* not supplied by rc style (or conversion failed), revert to default */
1414 g_param_value_set_default (pspec, &pcache->value);
1416 return &pcache->value;
1419 static cairo_pattern_t *
1420 load_background (GdkVisual *visual,
1422 const gchar *filename)
1424 if (filename == NULL)
1426 return cairo_pattern_create_rgb (bg_color->red / 65535.0,
1427 bg_color->green / 65535.0,
1428 bg_color->blue / 65535.0);
1430 if (strcmp (filename, "<parent>") == 0)
1435 cairo_surface_t *surface;
1436 cairo_pattern_t *pattern;
1438 GdkScreen *screen = gdk_visual_get_screen (visual);
1440 pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
1444 surface = gdk_window_create_similar_surface (gdk_screen_get_root_window (screen),
1445 CAIRO_CONTENT_COLOR,
1446 gdk_pixbuf_get_width (pixbuf),
1447 gdk_pixbuf_get_height (pixbuf));
1449 cr = cairo_create (surface);
1451 gdk_cairo_set_source_color (cr, bg_color);
1454 gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
1458 g_object_unref (pixbuf);
1460 pattern = cairo_pattern_create_for_surface (surface);
1462 cairo_surface_destroy (surface);
1469 gtk_style_real_realize (GtkStyle *style)
1473 for (i = 0; i < 5; i++)
1475 _gtk_style_shade (&style->bg[i], &style->light[i], LIGHTNESS_MULT);
1476 _gtk_style_shade (&style->bg[i], &style->dark[i], DARKNESS_MULT);
1478 style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
1479 style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
1480 style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
1482 style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
1483 style->text_aa[i].green = (style->text[i].green + style->base[i].green) / 2;
1484 style->text_aa[i].blue = (style->text[i].blue + style->base[i].blue) / 2;
1487 style->black.red = 0x0000;
1488 style->black.green = 0x0000;
1489 style->black.blue = 0x0000;
1491 style->white.red = 0xffff;
1492 style->white.green = 0xffff;
1493 style->white.blue = 0xffff;
1495 for (i = 0; i < 5; i++)
1497 const char *image_name;
1499 if (style->rc_style)
1500 image_name = style->rc_style->bg_pixmap_name[i];
1504 style->background[i] = load_background (style->visual,
1511 gtk_style_real_unrealize (GtkStyle *style)
1515 for (i = 0; i < 5; i++)
1517 if (style->background[i])
1519 cairo_pattern_destroy (style->background[i]);
1520 style->background[i] = NULL;
1525 style_unrealize_cursors (style);
1529 gtk_style_real_set_background (GtkStyle *style,
1531 GtkStateType state_type)
1533 gdk_window_set_background_pattern (window, style->background[state_type]);
1537 * gtk_style_render_icon:
1538 * @style: a #GtkStyle
1539 * @source: the #GtkIconSource specifying the icon to render
1540 * @direction: a text direction
1542 * @size: (type int): the size to render the icon at. A size of
1543 * (GtkIconSize)-1 means render at the size of the source and
1545 * @widget: (allow-none): the widget
1546 * @detail: (allow-none): a style detail
1548 * Renders the icon specified by @source at the given @size
1549 * according to the given parameters and returns the result in a
1552 * Return value: (transfer full): a newly-created #GdkPixbuf
1553 * containing the rendered icon
1556 gtk_style_render_icon (GtkStyle *style,
1557 const GtkIconSource *source,
1558 GtkTextDirection direction,
1562 const gchar *detail)
1566 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1567 g_return_val_if_fail (GTK_STYLE_GET_CLASS (style)->render_icon != NULL, NULL);
1569 pixbuf = GTK_STYLE_GET_CLASS (style)->render_icon (style, source, direction, state,
1570 size, widget, detail);
1572 g_return_val_if_fail (pixbuf != NULL, NULL);
1577 /* Default functions */
1580 * gtk_style_apply_default_background:
1586 * @area: (allow-none):
1593 gtk_style_apply_default_background (GtkStyle *style,
1596 GtkStateType state_type,
1604 if (style->background[state_type] == NULL)
1606 GdkWindow *parent = gdk_window_get_parent (window);
1607 int x_offset, y_offset;
1611 gdk_window_get_position (window, &x_offset, &y_offset);
1612 cairo_translate (cr, -x_offset, -y_offset);
1613 gtk_style_apply_default_background (style, cr,
1615 x + x_offset, y + y_offset,
1620 gdk_cairo_set_source_color (cr, &style->bg[state_type]);
1623 cairo_set_source (cr, style->background[state_type]);
1625 cairo_rectangle (cr, x, y, width, height);
1633 gtk_default_render_icon (GtkStyle *style,
1634 const GtkIconSource *source,
1635 GtkTextDirection direction,
1639 const gchar *detail)
1641 GtkStyleContext *context;
1642 GtkStylePrivate *priv;
1646 context = gtk_widget_get_style_context (widget);
1649 priv = GTK_STYLE_GET_PRIVATE (style);
1650 context = priv->context;
1656 gtk_style_context_save (context);
1659 transform_detail_string (detail, context);
1661 pixbuf = gtk_render_icon_pixbuf (context, source, size);
1663 gtk_style_context_restore (context);
1669 _cairo_draw_line (cairo_t *cr,
1678 gdk_cairo_set_source_color (cr, color);
1679 cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
1681 cairo_move_to (cr, x1 + 0.5, y1 + 0.5);
1682 cairo_line_to (cr, x2 + 0.5, y2 + 0.5);
1689 _cairo_draw_rectangle (cairo_t *cr,
1697 gdk_cairo_set_source_color (cr, color);
1701 cairo_rectangle (cr, x, y, width, height);
1706 cairo_rectangle (cr, x + 0.5, y + 0.5, width, height);
1712 _cairo_draw_point (cairo_t *cr,
1717 gdk_cairo_set_source_color (cr, color);
1718 cairo_rectangle (cr, x, y, 1, 1);
1723 transform_detail_string (const gchar *detail,
1724 GtkStyleContext *context)
1729 if (strcmp (detail, "arrow") == 0)
1730 gtk_style_context_add_class (context, "arrow");
1731 else if (strcmp (detail, "button") == 0)
1732 gtk_style_context_add_class (context, "button");
1733 else if (strcmp (detail, "buttondefault") == 0)
1735 gtk_style_context_add_class (context, "button");
1736 gtk_style_context_add_class (context, "default");
1738 else if (strcmp (detail, "calendar") == 0)
1739 gtk_style_context_add_class (context, "calendar");
1740 else if (strcmp (detail, "cellcheck") == 0)
1742 gtk_style_context_add_class (context, "cell");
1743 gtk_style_context_add_class (context, "check");
1745 else if (strcmp (detail, "cellradio") == 0)
1747 gtk_style_context_add_class (context, "cell");
1748 gtk_style_context_add_class (context, "radio");
1750 else if (strcmp (detail, "checkbutton") == 0)
1751 gtk_style_context_add_class (context, "check");
1752 else if (strcmp (detail, "check") == 0)
1754 gtk_style_context_add_class (context, "check");
1755 gtk_style_context_add_class (context, "menu");
1757 else if (strcmp (detail, "radiobutton") == 0)
1759 gtk_style_context_add_class (context, "radio");
1761 else if (strcmp (detail, "option") == 0)
1763 gtk_style_context_add_class (context, "radio");
1764 gtk_style_context_add_class (context, "menu");
1766 else if (strcmp (detail, "entry") == 0 ||
1767 strcmp (detail, "entry_bg") == 0)
1768 gtk_style_context_add_class (context, "entry");
1769 else if (strcmp (detail, "expander") == 0)
1770 gtk_style_context_add_class (context, "expander");
1771 else if (strcmp (detail, "tooltip") == 0)
1772 gtk_style_context_add_class (context, "tooltip");
1773 else if (strcmp (detail, "frame") == 0)
1774 gtk_style_context_add_class (context, "frame");
1775 else if (strcmp (detail, "scrolled_window") == 0)
1776 gtk_style_context_add_class (context, "scrolled-window");
1777 else if (strcmp (detail, "viewport") == 0 ||
1778 strcmp (detail, "viewportbin") == 0)
1779 gtk_style_context_add_class (context, "viewport");
1780 else if (strncmp (detail, "trough", 6) == 0)
1782 gtk_style_context_add_class (context, "scrollbar");
1783 gtk_style_context_add_class (context, "trough");
1785 else if (strcmp (detail, "spinbutton") == 0)
1786 gtk_style_context_add_class (context, "spinbutton");
1787 else if (strcmp (detail, "spinbutton_up") == 0)
1789 gtk_style_context_add_class (context, "spinbutton");
1790 gtk_style_context_add_class (context, "button");
1791 gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
1793 else if (strcmp (detail, "spinbutton_down") == 0)
1795 gtk_style_context_add_class (context, "spinbutton");
1796 gtk_style_context_add_class (context, "button");
1797 gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
1799 else if ((detail[0] == 'h' || detail[0] == 'v') &&
1800 strncmp (&detail[1], "scrollbar_", 10) == 0)
1802 gtk_style_context_add_class (context, "button");
1803 gtk_style_context_add_class (context, "scrollbar");
1805 else if (strcmp (detail, "slider") == 0)
1807 gtk_style_context_add_class (context, "slider");
1808 gtk_style_context_add_class (context, "scrollbar");
1810 else if (strcmp (detail, "vscale") == 0 ||
1811 strcmp (detail, "hscale") == 0)
1813 gtk_style_context_add_class (context, "slider");
1814 gtk_style_context_add_class (context, "scale");
1816 else if (strcmp (detail, "menuitem") == 0)
1818 gtk_style_context_add_class (context, "menuitem");
1819 gtk_style_context_add_class (context, "menu");
1821 else if (strcmp (detail, "menu") == 0)
1823 gtk_style_context_add_class (context, "popup");
1824 gtk_style_context_add_class (context, "menu");
1826 else if (strcmp (detail, "accellabel") == 0)
1827 gtk_style_context_add_class (context, "accelerator");
1828 else if (strcmp (detail, "menubar") == 0)
1829 gtk_style_context_add_class (context, "menubar");
1830 else if (strcmp (detail, "base") == 0)
1831 gtk_style_context_add_class (context, "background");
1832 else if (strcmp (detail, "bar") == 0 ||
1833 strcmp (detail, "progressbar") == 0)
1834 gtk_style_context_add_class (context, "progressbar");
1835 else if (strcmp (detail, "toolbar") == 0)
1836 gtk_style_context_add_class (context, "toolbar");
1837 else if (strcmp (detail, "handlebox_bin") == 0)
1838 gtk_style_context_add_class (context, "dock");
1839 else if (strcmp (detail, "notebook") == 0)
1840 gtk_style_context_add_class (context, "notebook");
1841 else if (strcmp (detail, "tab") == 0)
1843 gtk_style_context_add_class (context, "notebook");
1844 gtk_style_context_add_region (context, GTK_STYLE_REGION_TAB, 0);
1846 else if (g_str_has_prefix (detail, "cell"))
1848 GtkRegionFlags row, col;
1849 gboolean ruled = FALSE;
1853 tokens = g_strsplit (detail, "_", -1);
1859 if (strcmp (tokens[i], "even") == 0)
1860 row |= GTK_REGION_EVEN;
1861 else if (strcmp (tokens[i], "odd") == 0)
1862 row |= GTK_REGION_ODD;
1863 else if (strcmp (tokens[i], "start") == 0)
1864 col |= GTK_REGION_FIRST;
1865 else if (strcmp (tokens[i], "end") == 0)
1866 col |= GTK_REGION_LAST;
1867 else if (strcmp (tokens[i], "ruled") == 0)
1869 else if (strcmp (tokens[i], "sorted") == 0)
1870 col |= GTK_REGION_SORTED;
1876 row &= ~(GTK_REGION_EVEN | GTK_REGION_ODD);
1878 gtk_style_context_add_class (context, "cell");
1879 gtk_style_context_add_region (context, "row", row);
1880 gtk_style_context_add_region (context, "column", col);
1882 g_strfreev (tokens);
1887 gtk_default_draw_hline (GtkStyle *style,
1889 GtkStateType state_type,
1891 const gchar *detail,
1896 GtkStyleContext *context;
1897 GtkStylePrivate *priv;
1900 context = gtk_widget_get_style_context (widget);
1903 priv = GTK_STYLE_GET_PRIVATE (style);
1904 context = priv->context;
1907 gtk_style_context_save (context);
1910 transform_detail_string (detail, context);
1914 gtk_render_line (context, cr,
1919 gtk_style_context_restore (context);
1924 gtk_default_draw_vline (GtkStyle *style,
1926 GtkStateType state_type,
1928 const gchar *detail,
1933 GtkStyleContext *context;
1934 GtkStylePrivate *priv;
1937 context = gtk_widget_get_style_context (widget);
1940 priv = GTK_STYLE_GET_PRIVATE (style);
1941 context = priv->context;
1944 gtk_style_context_save (context);
1947 transform_detail_string (detail, context);
1951 gtk_render_line (context, cr,
1955 gtk_style_context_restore (context);
1959 draw_thin_shadow (GtkStyle *style,
1967 GdkColor *gc1, *gc2;
1969 gc1 = &style->light[state];
1970 gc2 = &style->dark[state];
1972 _cairo_draw_line (cr, gc1,
1973 x, y + height - 1, x + width - 1, y + height - 1);
1974 _cairo_draw_line (cr, gc1,
1975 x + width - 1, y, x + width - 1, y + height - 1);
1977 _cairo_draw_line (cr, gc2,
1978 x, y, x + width - 2, y);
1979 _cairo_draw_line (cr, gc2,
1980 x, y, x, y + height - 2);
1984 draw_spinbutton_shadow (GtkStyle *style,
1987 GtkTextDirection direction,
1994 if (direction == GTK_TEXT_DIR_LTR)
1996 _cairo_draw_line (cr, &style->dark[state],
1997 x, y, x + width - 1, y);
1998 _cairo_draw_line (cr, &style->black,
1999 x, y + 1, x + width - 2, y + 1);
2000 _cairo_draw_line (cr, &style->black,
2001 x + width - 2, y + 2, x + width - 2, y + height - 3);
2002 _cairo_draw_line (cr, &style->light[state],
2003 x + width - 1, y + 1, x + width - 1, y + height - 2);
2004 _cairo_draw_line (cr, &style->light[state],
2005 x, y + height - 1, x + width - 1, y + height - 1);
2006 _cairo_draw_line (cr, &style->bg[state],
2007 x, y + height - 2, x + width - 2, y + height - 2);
2008 _cairo_draw_line (cr, &style->black,
2009 x, y + 2, x, y + height - 3);
2013 _cairo_draw_line (cr, &style->dark[state],
2014 x, y, x + width - 1, y);
2015 _cairo_draw_line (cr, &style->dark[state],
2016 x, y + 1, x, y + height - 1);
2017 _cairo_draw_line (cr, &style->black,
2018 x + 1, y + 1, x + width - 1, y + 1);
2019 _cairo_draw_line (cr, &style->black,
2020 x + 1, y + 2, x + 1, y + height - 2);
2021 _cairo_draw_line (cr, &style->black,
2022 x + width - 1, y + 2, x + width - 1, y + height - 3);
2023 _cairo_draw_line (cr, &style->light[state],
2024 x + 1, y + height - 1, x + width - 1, y + height - 1);
2025 _cairo_draw_line (cr, &style->bg[state],
2026 x + 2, y + height - 2, x + width - 1, y + height - 2);
2031 draw_menu_shadow (GtkStyle *style,
2039 if (style->ythickness > 0)
2041 if (style->ythickness > 1)
2043 _cairo_draw_line (cr, &style->dark[state],
2044 x + 1, y + height - 2,
2045 x + width - 2, y + height - 2);
2046 _cairo_draw_line (cr, &style->black,
2047 x, y + height - 1, x + width - 1, y + height - 1);
2051 _cairo_draw_line (cr, &style->dark[state],
2052 x + 1, y + height - 1, x + width - 1, y + height - 1);
2056 if (style->xthickness > 0)
2058 if (style->xthickness > 1)
2060 _cairo_draw_line (cr, &style->dark[state],
2061 x + width - 2, y + 1,
2062 x + width - 2, y + height - 2);
2064 _cairo_draw_line (cr, &style->black,
2065 x + width - 1, y, x + width - 1, y + height - 1);
2069 _cairo_draw_line (cr, &style->dark[state],
2070 x + width - 1, y + 1, x + width - 1, y + height - 1);
2074 /* Light around top and left */
2076 if (style->ythickness > 0)
2077 _cairo_draw_line (cr, &style->black,
2078 x, y, x + width - 2, y);
2079 if (style->xthickness > 0)
2080 _cairo_draw_line (cr, &style->black,
2081 x, y, x, y + height - 2);
2083 if (style->ythickness > 1)
2084 _cairo_draw_line (cr, &style->light[state],
2085 x + 1, y + 1, x + width - 3, y + 1);
2086 if (style->xthickness > 1)
2087 _cairo_draw_line (cr, &style->light[state],
2088 x + 1, y + 1, x + 1, y + height - 3);
2091 static GtkTextDirection
2092 get_direction (GtkWidget *widget)
2094 GtkTextDirection dir;
2097 dir = gtk_widget_get_direction (widget);
2099 dir = GTK_TEXT_DIR_LTR;
2106 gtk_default_draw_shadow (GtkStyle *style,
2108 GtkStateType state_type,
2109 GtkShadowType shadow_type,
2111 const gchar *detail,
2117 GtkStyleContext *context;
2118 GtkStylePrivate *priv;
2121 context = gtk_widget_get_style_context (widget);
2124 priv = GTK_STYLE_GET_PRIVATE (style);
2125 context = priv->context;
2128 gtk_style_context_save (context);
2131 transform_detail_string (detail, context);
2135 gtk_render_frame (context, cr,
2142 gtk_style_context_restore (context);
2146 draw_arrow (cairo_t *cr,
2148 GtkArrowType arrow_type,
2154 gdk_cairo_set_source_color (cr, color);
2157 if (arrow_type == GTK_ARROW_DOWN)
2159 cairo_move_to (cr, x, y);
2160 cairo_line_to (cr, x + width, y);
2161 cairo_line_to (cr, x + width / 2., y + height);
2163 else if (arrow_type == GTK_ARROW_UP)
2165 cairo_move_to (cr, x, y + height);
2166 cairo_line_to (cr, x + width / 2., y);
2167 cairo_line_to (cr, x + width, y + height);
2169 else if (arrow_type == GTK_ARROW_LEFT)
2171 cairo_move_to (cr, x + width, y);
2172 cairo_line_to (cr, x + width, y + height);
2173 cairo_line_to (cr, x, y + height / 2.);
2175 else if (arrow_type == GTK_ARROW_RIGHT)
2177 cairo_move_to (cr, x, y);
2178 cairo_line_to (cr, x + width, y + height / 2.);
2179 cairo_line_to (cr, x, y + height);
2182 cairo_close_path (cr);
2189 calculate_arrow_geometry (GtkArrowType arrow_type,
2201 case GTK_ARROW_DOWN:
2211 if (arrow_type == GTK_ARROW_DOWN)
2213 if (*height % 2 == 1 || h % 2 == 0)
2218 if (*height % 2 == 0 || h % 2 == 0)
2223 case GTK_ARROW_RIGHT:
2224 case GTK_ARROW_LEFT:
2234 if (arrow_type == GTK_ARROW_RIGHT)
2236 if (*width % 2 == 1 || w % 2 == 0)
2241 if (*width % 2 == 0 || w % 2 == 0)
2247 /* should not be reached */
2251 *x += (*width - w) / 2;
2252 *y += (*height - h) / 2;
2258 gtk_default_draw_arrow (GtkStyle *style,
2261 GtkShadowType shadow,
2263 const gchar *detail,
2264 GtkArrowType arrow_type,
2271 GtkStyleContext *context;
2272 GtkStylePrivate *priv;
2273 GtkStateFlags flags = 0;
2274 gdouble angle, size;
2276 if (arrow_type == GTK_ARROW_NONE)
2280 context = gtk_widget_get_style_context (widget);
2283 priv = GTK_STYLE_GET_PRIVATE (style);
2284 context = priv->context;
2287 gtk_style_context_save (context);
2290 transform_detail_string (detail, context);
2298 case GTK_ARROW_RIGHT:
2302 case GTK_ARROW_DOWN:
2306 case GTK_ARROW_LEFT:
2307 angle = 3 * (G_PI / 2);
2311 g_assert_not_reached ();
2316 case GTK_STATE_PRELIGHT:
2317 flags |= GTK_STATE_FLAG_PRELIGHT;
2319 case GTK_STATE_SELECTED:
2320 flags |= GTK_STATE_FLAG_SELECTED;
2322 case GTK_STATE_INSENSITIVE:
2323 flags |= GTK_STATE_FLAG_INSENSITIVE;
2325 case GTK_STATE_ACTIVE:
2326 flags |= GTK_STATE_FLAG_ACTIVE;
2332 gtk_style_context_set_state (context, flags);
2336 gtk_render_arrow (context,
2343 gtk_style_context_restore (context);
2347 gtk_default_draw_diamond (GtkStyle *style,
2349 GtkStateType state_type,
2350 GtkShadowType shadow_type,
2352 const gchar *detail,
2360 GdkColor *outer_nw = NULL;
2361 GdkColor *outer_ne = NULL;
2362 GdkColor *outer_sw = NULL;
2363 GdkColor *outer_se = NULL;
2364 GdkColor *middle_nw = NULL;
2365 GdkColor *middle_ne = NULL;
2366 GdkColor *middle_sw = NULL;
2367 GdkColor *middle_se = NULL;
2368 GdkColor *inner_nw = NULL;
2369 GdkColor *inner_ne = NULL;
2370 GdkColor *inner_sw = NULL;
2371 GdkColor *inner_se = NULL;
2373 half_width = width / 2;
2374 half_height = height / 2;
2376 switch (shadow_type)
2379 inner_sw = inner_se = &style->bg[state_type];
2380 middle_sw = middle_se = &style->light[state_type];
2381 outer_sw = outer_se = &style->light[state_type];
2382 inner_nw = inner_ne = &style->black;
2383 middle_nw = middle_ne = &style->dark[state_type];
2384 outer_nw = outer_ne = &style->dark[state_type];
2387 case GTK_SHADOW_OUT:
2388 inner_sw = inner_se = &style->dark[state_type];
2389 middle_sw = middle_se = &style->dark[state_type];
2390 outer_sw = outer_se = &style->black;
2391 inner_nw = inner_ne = &style->bg[state_type];
2392 middle_nw = middle_ne = &style->light[state_type];
2393 outer_nw = outer_ne = &style->light[state_type];
2396 case GTK_SHADOW_ETCHED_IN:
2397 inner_sw = inner_se = &style->bg[state_type];
2398 middle_sw = middle_se = &style->dark[state_type];
2399 outer_sw = outer_se = &style->light[state_type];
2400 inner_nw = inner_ne = &style->bg[state_type];
2401 middle_nw = middle_ne = &style->light[state_type];
2402 outer_nw = outer_ne = &style->dark[state_type];
2405 case GTK_SHADOW_ETCHED_OUT:
2406 inner_sw = inner_se = &style->bg[state_type];
2407 middle_sw = middle_se = &style->light[state_type];
2408 outer_sw = outer_se = &style->dark[state_type];
2409 inner_nw = inner_ne = &style->bg[state_type];
2410 middle_nw = middle_ne = &style->dark[state_type];
2411 outer_nw = outer_ne = &style->light[state_type];
2421 _cairo_draw_line (cr, inner_sw,
2422 x + 2, y + half_height,
2423 x + half_width, y + height - 2);
2424 _cairo_draw_line (cr, inner_se,
2425 x + half_width, y + height - 2,
2426 x + width - 2, y + half_height);
2427 _cairo_draw_line (cr, middle_sw,
2428 x + 1, y + half_height,
2429 x + half_width, y + height - 1);
2430 _cairo_draw_line (cr, middle_se,
2431 x + half_width, y + height - 1,
2432 x + width - 1, y + half_height);
2433 _cairo_draw_line (cr, outer_sw,
2435 x + half_width, y + height);
2436 _cairo_draw_line (cr, outer_se,
2437 x + half_width, y + height,
2438 x + width, y + half_height);
2440 _cairo_draw_line (cr, inner_nw,
2441 x + 2, y + half_height,
2442 x + half_width, y + 2);
2443 _cairo_draw_line (cr, inner_ne,
2444 x + half_width, y + 2,
2445 x + width - 2, y + half_height);
2446 _cairo_draw_line (cr, middle_nw,
2447 x + 1, y + half_height,
2448 x + half_width, y + 1);
2449 _cairo_draw_line (cr, middle_ne,
2450 x + half_width, y + 1,
2451 x + width - 1, y + half_height);
2452 _cairo_draw_line (cr, outer_nw,
2455 _cairo_draw_line (cr, outer_ne,
2457 x + width, y + half_height);
2462 option_menu_get_props (GtkWidget *widget,
2463 GtkRequisition *indicator_size,
2464 GtkBorder *indicator_spacing)
2466 GtkRequisition *tmp_size = NULL;
2467 GtkBorder *tmp_spacing = NULL;
2471 *indicator_size = *tmp_size;
2472 gtk_requisition_free (tmp_size);
2475 *indicator_size = default_option_indicator_size;
2479 *indicator_spacing = *tmp_spacing;
2480 gtk_border_free (tmp_spacing);
2483 *indicator_spacing = default_option_indicator_spacing;
2487 background_is_solid (GtkStyle *style,
2490 if (style->background[type] == NULL)
2493 return cairo_pattern_get_type (style->background[type]) == CAIRO_PATTERN_TYPE_SOLID;
2497 gtk_default_draw_box (GtkStyle *style,
2499 GtkStateType state_type,
2500 GtkShadowType shadow_type,
2502 const gchar *detail,
2508 GtkStyleContext *context;
2509 GtkStylePrivate *priv;
2510 GtkStateFlags flags = 0;
2513 context = gtk_widget_get_style_context (widget);
2516 priv = GTK_STYLE_GET_PRIVATE (style);
2517 context = priv->context;
2520 gtk_style_context_save (context);
2523 transform_detail_string (detail, context);
2527 case GTK_STATE_ACTIVE:
2528 flags |= GTK_STATE_FLAG_ACTIVE;
2530 case GTK_STATE_PRELIGHT:
2531 flags |= GTK_STATE_FLAG_PRELIGHT;
2533 case GTK_STATE_SELECTED:
2534 flags |= GTK_STATE_FLAG_SELECTED;
2536 case GTK_STATE_INSENSITIVE:
2537 flags |= GTK_STATE_FLAG_INSENSITIVE;
2543 if (shadow_type == GTK_SHADOW_IN)
2544 flags |= GTK_STATE_FLAG_ACTIVE;
2546 gtk_style_context_set_state (context, flags);
2550 if (gtk_style_context_has_class (context, GTK_STYLE_CLASS_PROGRESSBAR))
2551 gtk_render_activity (context, cr, x, y, width, height);
2554 gtk_render_background (context, cr, x, y, width, height);
2555 gtk_render_frame (context, cr, x, y, width, height);
2559 gtk_style_context_restore (context);
2563 get_darkened (const GdkColor *color,
2566 GdkColor src = *color;
2567 GdkColor shaded = *color;
2569 while (darken_count)
2571 _gtk_style_shade (&src, &shaded, 0.93);
2576 return gdk_color_copy (&shaded);
2580 gtk_default_draw_flat_box (GtkStyle *style,
2582 GtkStateType state_type,
2583 GtkShadowType shadow_type,
2585 const gchar *detail,
2591 GtkStyleContext *context;
2592 GtkStylePrivate *priv;
2593 GtkStateFlags flags = 0;
2596 context = gtk_widget_get_style_context (widget);
2599 priv = GTK_STYLE_GET_PRIVATE (style);
2600 context = priv->context;
2603 gtk_style_context_save (context);
2606 transform_detail_string (detail, context);
2610 case GTK_STATE_PRELIGHT:
2611 flags |= GTK_STATE_FLAG_PRELIGHT;
2613 case GTK_STATE_SELECTED:
2614 flags |= GTK_STATE_FLAG_SELECTED;
2616 case GTK_STATE_INSENSITIVE:
2617 flags |= GTK_STATE_FLAG_INSENSITIVE;
2619 case GTK_STATE_ACTIVE:
2620 flags |= GTK_STATE_FLAG_ACTIVE;
2622 case GTK_STATE_FOCUSED:
2623 flags |= GTK_STATE_FLAG_FOCUSED;
2629 gtk_style_context_set_state (context, flags);
2633 gtk_render_background (context, cr,
2640 gtk_style_context_restore (context);
2644 gtk_default_draw_check (GtkStyle *style,
2646 GtkStateType state_type,
2647 GtkShadowType shadow_type,
2649 const gchar *detail,
2655 GtkStyleContext *context;
2656 GtkStylePrivate *priv;
2657 GtkStateFlags flags = 0;
2660 context = gtk_widget_get_style_context (widget);
2663 priv = GTK_STYLE_GET_PRIVATE (style);
2664 context = priv->context;
2667 gtk_style_context_save (context);
2670 transform_detail_string (detail, context);
2674 case GTK_STATE_PRELIGHT:
2675 flags |= GTK_STATE_FLAG_PRELIGHT;
2677 case GTK_STATE_SELECTED:
2678 flags |= GTK_STATE_FLAG_SELECTED;
2680 case GTK_STATE_INSENSITIVE:
2681 flags |= GTK_STATE_FLAG_INSENSITIVE;
2687 if (shadow_type == GTK_SHADOW_IN)
2688 flags |= GTK_STATE_FLAG_ACTIVE;
2689 else if (shadow_type == GTK_SHADOW_ETCHED_IN)
2690 flags |= GTK_STATE_FLAG_INCONSISTENT;
2692 gtk_style_context_set_state (context, flags);
2696 gtk_render_check (context,
2701 gtk_style_context_restore (context);
2705 gtk_default_draw_option (GtkStyle *style,
2707 GtkStateType state_type,
2708 GtkShadowType shadow_type,
2710 const gchar *detail,
2716 GtkStyleContext *context;
2717 GtkStylePrivate *priv;
2718 GtkStateFlags flags = 0;
2721 context = gtk_widget_get_style_context (widget);
2724 priv = GTK_STYLE_GET_PRIVATE (style);
2725 context = priv->context;
2728 gtk_style_context_save (context);
2731 transform_detail_string (detail, context);
2735 case GTK_STATE_PRELIGHT:
2736 flags |= GTK_STATE_FLAG_PRELIGHT;
2738 case GTK_STATE_SELECTED:
2739 flags |= GTK_STATE_FLAG_SELECTED;
2741 case GTK_STATE_INSENSITIVE:
2742 flags |= GTK_STATE_FLAG_INSENSITIVE;
2748 if (shadow_type == GTK_SHADOW_IN)
2749 flags |= GTK_STATE_FLAG_ACTIVE;
2750 else if (shadow_type == GTK_SHADOW_ETCHED_IN)
2751 flags |= GTK_STATE_FLAG_INCONSISTENT;
2753 gtk_style_context_set_state (context, flags);
2756 gtk_render_option (context, cr,
2763 gtk_style_context_restore (context);
2767 gtk_default_draw_tab (GtkStyle *style,
2769 GtkStateType state_type,
2770 GtkShadowType shadow_type,
2772 const gchar *detail,
2778 #define ARROW_SPACE 4
2780 GtkRequisition indicator_size;
2781 GtkBorder indicator_spacing;
2784 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
2786 indicator_size.width += (indicator_size.width % 2) - 1;
2787 arrow_height = indicator_size.width / 2 + 1;
2789 x += (width - indicator_size.width) / 2;
2790 y += (height - (2 * arrow_height + ARROW_SPACE)) / 2;
2792 if (state_type == GTK_STATE_INSENSITIVE)
2794 draw_arrow (cr, &style->white,
2795 GTK_ARROW_UP, x + 1, y + 1,
2796 indicator_size.width, arrow_height);
2798 draw_arrow (cr, &style->white,
2799 GTK_ARROW_DOWN, x + 1, y + arrow_height + ARROW_SPACE + 1,
2800 indicator_size.width, arrow_height);
2803 draw_arrow (cr, &style->fg[state_type],
2805 indicator_size.width, arrow_height);
2808 draw_arrow (cr, &style->fg[state_type],
2809 GTK_ARROW_DOWN, x, y + arrow_height + ARROW_SPACE,
2810 indicator_size.width, arrow_height);
2814 gtk_default_draw_shadow_gap (GtkStyle *style,
2816 GtkStateType state_type,
2817 GtkShadowType shadow_type,
2819 const gchar *detail,
2824 GtkPositionType gap_side,
2828 GtkStyleContext *context;
2829 GtkStylePrivate *priv;
2830 GtkStateFlags flags = 0;
2833 context = gtk_widget_get_style_context (widget);
2836 priv = GTK_STYLE_GET_PRIVATE (style);
2837 context = priv->context;
2840 gtk_style_context_save (context);
2843 transform_detail_string (detail, context);
2847 case GTK_STATE_ACTIVE:
2848 flags |= GTK_STATE_ACTIVE;
2850 case GTK_STATE_PRELIGHT:
2851 flags |= GTK_STATE_FLAG_PRELIGHT;
2853 case GTK_STATE_SELECTED:
2854 flags |= GTK_STATE_FLAG_SELECTED;
2856 case GTK_STATE_INSENSITIVE:
2857 flags |= GTK_STATE_FLAG_INSENSITIVE;
2863 gtk_style_context_set_state (context, flags);
2866 gtk_render_frame_gap (context, cr,
2873 (gdouble) gap_x + gap_width);
2876 gtk_style_context_restore (context);
2880 gtk_default_draw_box_gap (GtkStyle *style,
2882 GtkStateType state_type,
2883 GtkShadowType shadow_type,
2885 const gchar *detail,
2890 GtkPositionType gap_side,
2894 GtkStyleContext *context;
2895 GtkStylePrivate *priv;
2896 GtkStateFlags flags = 0;
2899 context = gtk_widget_get_style_context (widget);
2902 priv = GTK_STYLE_GET_PRIVATE (style);
2903 context = priv->context;
2906 gtk_style_context_save (context);
2909 transform_detail_string (detail, context);
2913 case GTK_STATE_ACTIVE:
2914 flags |= GTK_STATE_ACTIVE;
2916 case GTK_STATE_PRELIGHT:
2917 flags |= GTK_STATE_FLAG_PRELIGHT;
2919 case GTK_STATE_SELECTED:
2920 flags |= GTK_STATE_FLAG_SELECTED;
2922 case GTK_STATE_INSENSITIVE:
2923 flags |= GTK_STATE_FLAG_INSENSITIVE;
2929 gtk_style_context_set_state (context, flags);
2932 gtk_render_background (context, cr,
2938 gtk_render_frame_gap (context, cr,
2945 (gdouble) gap_x + gap_width);
2948 gtk_style_context_restore (context);
2952 gtk_default_draw_extension (GtkStyle *style,
2954 GtkStateType state_type,
2955 GtkShadowType shadow_type,
2957 const gchar *detail,
2962 GtkPositionType gap_side)
2964 GtkStyleContext *context;
2965 GtkStylePrivate *priv;
2966 GtkStateFlags flags = 0;
2969 context = gtk_widget_get_style_context (widget);
2972 priv = GTK_STYLE_GET_PRIVATE (style);
2973 context = priv->context;
2976 gtk_style_context_save (context);
2979 transform_detail_string (detail, context);
2983 case GTK_STATE_ACTIVE:
2984 flags |= GTK_STATE_ACTIVE;
2986 case GTK_STATE_PRELIGHT:
2987 flags |= GTK_STATE_FLAG_PRELIGHT;
2989 case GTK_STATE_SELECTED:
2990 flags |= GTK_STATE_FLAG_SELECTED;
2992 case GTK_STATE_INSENSITIVE:
2993 flags |= GTK_STATE_FLAG_INSENSITIVE;
2999 gtk_style_context_set_state (context, flags);
3003 gtk_render_extension (context, cr,
3011 gtk_style_context_restore (context);
3015 gtk_default_draw_focus (GtkStyle *style,
3017 GtkStateType state_type,
3019 const gchar *detail,
3025 GtkStyleContext *context;
3026 GtkStylePrivate *priv;
3029 context = gtk_widget_get_style_context (widget);
3032 priv = GTK_STYLE_GET_PRIVATE (style);
3033 context = priv->context;
3036 gtk_style_context_save (context);
3039 transform_detail_string (detail, context);
3043 gtk_render_focus (context, cr,
3050 gtk_style_context_restore (context);
3054 gtk_default_draw_slider (GtkStyle *style,
3056 GtkStateType state_type,
3057 GtkShadowType shadow_type,
3059 const gchar *detail,
3064 GtkOrientation orientation)
3066 GtkStyleContext *context;
3067 GtkStylePrivate *priv;
3068 GtkStateFlags flags = 0;
3071 context = gtk_widget_get_style_context (widget);
3074 priv = GTK_STYLE_GET_PRIVATE (style);
3075 context = priv->context;
3078 gtk_style_context_save (context);
3081 transform_detail_string (detail, context);
3085 case GTK_STATE_PRELIGHT:
3086 flags |= GTK_STATE_FLAG_PRELIGHT;
3088 case GTK_STATE_SELECTED:
3089 flags |= GTK_STATE_FLAG_SELECTED;
3091 case GTK_STATE_INSENSITIVE:
3092 flags |= GTK_STATE_FLAG_INSENSITIVE;
3098 gtk_style_context_set_state (context, flags);
3102 gtk_render_slider (context, cr, x, y, width, height, orientation);
3105 gtk_style_context_restore (context);
3109 draw_dot (cairo_t *cr,
3116 size = CLAMP (size, 2, 3);
3120 _cairo_draw_point (cr, light, x, y);
3121 _cairo_draw_point (cr, light, x+1, y+1);
3125 _cairo_draw_point (cr, light, x, y);
3126 _cairo_draw_point (cr, light, x+1, y);
3127 _cairo_draw_point (cr, light, x, y+1);
3128 _cairo_draw_point (cr, dark, x+1, y+2);
3129 _cairo_draw_point (cr, dark, x+2, y+1);
3130 _cairo_draw_point (cr, dark, x+2, y+2);
3135 gtk_default_draw_handle (GtkStyle *style,
3137 GtkStateType state_type,
3138 GtkShadowType shadow_type,
3140 const gchar *detail,
3145 GtkOrientation orientation)
3147 GtkStyleContext *context;
3148 GtkStylePrivate *priv;
3149 GtkStateFlags flags = 0;
3152 context = gtk_widget_get_style_context (widget);
3155 priv = GTK_STYLE_GET_PRIVATE (style);
3156 context = priv->context;
3159 gtk_style_context_save (context);
3162 transform_detail_string (detail, context);
3166 case GTK_STATE_PRELIGHT:
3167 flags |= GTK_STATE_FLAG_PRELIGHT;
3169 case GTK_STATE_SELECTED:
3170 flags |= GTK_STATE_FLAG_SELECTED;
3172 case GTK_STATE_INSENSITIVE:
3173 flags |= GTK_STATE_FLAG_INSENSITIVE;
3179 gtk_style_context_set_state (context, flags);
3183 gtk_render_handle (context, cr,
3190 gtk_style_context_restore (context);
3194 gtk_default_draw_expander (GtkStyle *style,
3196 GtkStateType state_type,
3198 const gchar *detail,
3201 GtkExpanderStyle expander_style)
3203 GtkStyleContext *context;
3204 GtkStylePrivate *priv;
3205 GtkStateFlags flags = 0;
3209 context = gtk_widget_get_style_context (widget);
3212 priv = GTK_STYLE_GET_PRIVATE (style);
3213 context = priv->context;
3216 gtk_style_context_save (context);
3219 transform_detail_string (detail, context);
3221 gtk_style_context_add_class (context, "expander");
3225 case GTK_STATE_PRELIGHT:
3226 flags |= GTK_STATE_FLAG_PRELIGHT;
3228 case GTK_STATE_SELECTED:
3229 flags |= GTK_STATE_FLAG_SELECTED;
3231 case GTK_STATE_INSENSITIVE:
3232 flags |= GTK_STATE_FLAG_INSENSITIVE;
3239 gtk_widget_class_find_style_property (GTK_WIDGET_GET_CLASS (widget),
3241 gtk_widget_style_get (widget, "expander-size", &size, NULL);
3245 if (expander_style == GTK_EXPANDER_EXPANDED)
3246 flags |= GTK_STATE_FLAG_ACTIVE;
3248 gtk_style_context_set_state (context, flags);
3252 gtk_render_expander (context, cr,
3253 (gdouble) x - (size / 2),
3254 (gdouble) y - (size / 2),
3259 gtk_style_context_restore (context);
3263 gtk_default_draw_layout (GtkStyle *style,
3265 GtkStateType state_type,
3268 const gchar *detail,
3271 PangoLayout *layout)
3273 GtkStyleContext *context;
3274 GtkStylePrivate *priv;
3275 GtkStateFlags flags = 0;
3278 context = gtk_widget_get_style_context (widget);
3281 priv = GTK_STYLE_GET_PRIVATE (style);
3282 context = priv->context;
3285 gtk_style_context_save (context);
3288 transform_detail_string (detail, context);
3292 case GTK_STATE_PRELIGHT:
3293 flags |= GTK_STATE_FLAG_PRELIGHT;
3295 case GTK_STATE_SELECTED:
3296 flags |= GTK_STATE_FLAG_SELECTED;
3298 case GTK_STATE_INSENSITIVE:
3299 flags |= GTK_STATE_FLAG_INSENSITIVE;
3305 gtk_style_context_set_state (context, flags);
3309 gtk_render_layout (context, cr,
3315 gtk_style_context_restore (context);
3319 gtk_default_draw_resize_grip (GtkStyle *style,
3321 GtkStateType state_type,
3323 const gchar *detail,
3330 GtkStyleContext *context;
3331 GtkStylePrivate *priv;
3332 GtkStateFlags flags = 0;
3333 GtkJunctionSides sides = 0;
3336 context = gtk_widget_get_style_context (widget);
3339 priv = GTK_STYLE_GET_PRIVATE (style);
3340 context = priv->context;
3343 gtk_style_context_save (context);
3346 transform_detail_string (detail, context);
3348 gtk_style_context_add_class (context, "grip");
3352 case GTK_STATE_PRELIGHT:
3353 flags |= GTK_STATE_FLAG_PRELIGHT;
3355 case GTK_STATE_SELECTED:
3356 flags |= GTK_STATE_FLAG_SELECTED;
3358 case GTK_STATE_INSENSITIVE:
3359 flags |= GTK_STATE_FLAG_INSENSITIVE;
3365 gtk_style_context_set_state (context, flags);
3369 case GDK_WINDOW_EDGE_NORTH_WEST:
3370 sides = GTK_JUNCTION_TOP | GTK_JUNCTION_LEFT;
3372 case GDK_WINDOW_EDGE_NORTH:
3373 sides = GTK_JUNCTION_TOP;
3375 case GDK_WINDOW_EDGE_NORTH_EAST:
3376 sides = GTK_JUNCTION_TOP | GTK_JUNCTION_RIGHT;
3378 case GDK_WINDOW_EDGE_WEST:
3379 sides = GTK_JUNCTION_LEFT;
3381 case GDK_WINDOW_EDGE_EAST:
3382 sides = GTK_JUNCTION_RIGHT;
3384 case GDK_WINDOW_EDGE_SOUTH_WEST:
3385 sides = GTK_JUNCTION_BOTTOM | GTK_JUNCTION_LEFT;
3387 case GDK_WINDOW_EDGE_SOUTH:
3388 sides = GTK_JUNCTION_BOTTOM;
3390 case GDK_WINDOW_EDGE_SOUTH_EAST:
3391 sides = GTK_JUNCTION_BOTTOM | GTK_JUNCTION_RIGHT;
3395 gtk_style_context_set_junction_sides (context, sides);
3399 gtk_render_handle (context, cr,
3406 gtk_style_context_restore (context);
3410 gtk_default_draw_spinner (GtkStyle *style,
3412 GtkStateType state_type,
3414 const gchar *detail,
3429 gtk_style_get (style, GTK_TYPE_SPINNER,
3430 "num-steps", &num_steps,
3432 real_step = step % num_steps;
3434 /* set a clip region for the expose event */
3435 cairo_rectangle (cr, x, y, width, height);
3438 cairo_translate (cr, x, y);
3440 /* draw clip region */
3441 cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
3443 color = &style->fg[state_type];
3446 radius = MIN (width / 2, height / 2);
3447 half = num_steps / 2;
3449 for (i = 0; i < num_steps; i++)
3451 gint inset = 0.7 * radius;
3453 /* transparency is a function of time and intial value */
3454 gdouble t = (gdouble) ((i + num_steps - real_step)
3455 % num_steps) / num_steps;
3459 cairo_set_source_rgba (cr,
3460 color->red / 65535.,
3461 color->green / 65535.,
3462 color->blue / 65535.,
3465 cairo_set_line_width (cr, 2.0);
3467 dx + (radius - inset) * cos (i * G_PI / half),
3468 dy + (radius - inset) * sin (i * G_PI / half));
3470 dx + radius * cos (i * G_PI / half),
3471 dy + radius * sin (i * G_PI / half));
3479 _gtk_style_shade (const GdkColor *a,
3487 red = (gdouble) a->red / 65535.0;
3488 green = (gdouble) a->green / 65535.0;
3489 blue = (gdouble) a->blue / 65535.0;
3491 rgb_to_hls (&red, &green, &blue);
3496 else if (green < 0.0)
3502 else if (blue < 0.0)
3505 hls_to_rgb (&red, &green, &blue);
3507 b->red = red * 65535.0;
3508 b->green = green * 65535.0;
3509 b->blue = blue * 65535.0;
3513 rgb_to_hls (gdouble *r,
3554 l = (max + min) / 2;
3561 s = (max - min) / (max + min);
3563 s = (max - min) / (2 - max - min);
3567 h = (green - blue) / delta;
3568 else if (green == max)
3569 h = 2 + (blue - red) / delta;
3570 else if (blue == max)
3571 h = 4 + (red - green) / delta;
3584 hls_to_rgb (gdouble *h,
3597 if (lightness <= 0.5)
3598 m2 = lightness * (1 + saturation);
3600 m2 = lightness + saturation - lightness * saturation;
3601 m1 = 2 * lightness - m2;
3603 if (saturation == 0)
3618 r = m1 + (m2 - m1) * hue / 60;
3622 r = m1 + (m2 - m1) * (240 - hue) / 60;
3633 g = m1 + (m2 - m1) * hue / 60;
3637 g = m1 + (m2 - m1) * (240 - hue) / 60;
3648 b = m1 + (m2 - m1) * hue / 60;
3652 b = m1 + (m2 - m1) * (240 - hue) / 60;
3665 * @style: a #GtkStyle
3667 * @state_type: a state
3668 * @widget: (allow-none): the widget
3669 * @detail: (allow-none): a style detail
3670 * @x1: the starting x coordinate
3671 * @x2: the ending x coordinate
3672 * @y: the y coordinate
3674 * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @cr
3675 * using the given style and state.
3678 gtk_paint_hline (GtkStyle *style,
3680 GtkStateType state_type,
3682 const gchar *detail,
3687 g_return_if_fail (GTK_IS_STYLE (style));
3688 g_return_if_fail (cr != NULL);
3689 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
3693 GTK_STYLE_GET_CLASS (style)->draw_hline (style, cr, state_type,
3702 * @style: a #GtkStyle
3704 * @state_type: a state
3705 * @widget: (allow-none): the widget
3706 * @detail: (allow-none): a style detail
3707 * @y1_: the starting y coordinate
3708 * @y2_: the ending y coordinate
3709 * @x: the x coordinate
3711 * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @cr
3712 * using the given style and state.
3715 gtk_paint_vline (GtkStyle *style,
3717 GtkStateType state_type,
3719 const gchar *detail,
3724 g_return_if_fail (GTK_IS_STYLE (style));
3725 g_return_if_fail (cr != NULL);
3726 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
3730 GTK_STYLE_GET_CLASS (style)->draw_vline (style, cr, state_type,
3739 * @style: a #GtkStyle
3741 * @state_type: a state
3742 * @shadow_type: type of shadow to draw
3743 * @widget: (allow-none): the widget
3744 * @detail: (allow-none): a style detail
3745 * @x: x origin of the rectangle
3746 * @y: y origin of the rectangle
3747 * @width: width of the rectangle
3748 * @height: width of the rectangle
3750 * Draws a shadow around the given rectangle in @cr
3751 * using the given style and state and shadow type.
3754 gtk_paint_shadow (GtkStyle *style,
3756 GtkStateType state_type,
3757 GtkShadowType shadow_type,
3759 const gchar *detail,
3765 g_return_if_fail (GTK_IS_STYLE (style));
3766 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
3767 g_return_if_fail (cr != NULL);
3768 g_return_if_fail (width >= 0);
3769 g_return_if_fail (height >= 0);
3773 GTK_STYLE_GET_CLASS (style)->draw_shadow (style, cr, state_type, shadow_type,
3775 x, y, width, height);
3782 * @style: a #GtkStyle
3784 * @state_type: a state
3785 * @shadow_type: the type of shadow to draw
3786 * @widget: (allow-none): the widget
3787 * @detail: (allow-none): a style detail
3788 * @arrow_type: the type of arrow to draw
3789 * @fill: %TRUE if the arrow tip should be filled
3790 * @x: x origin of the rectangle to draw the arrow in
3791 * @y: y origin of the rectangle to draw the arrow in
3792 * @width: width of the rectangle to draw the arrow in
3793 * @height: height of the rectangle to draw the arrow in
3795 * Draws an arrow in the given rectangle on @cr using the given
3796 * parameters. @arrow_type determines the direction of the arrow.
3799 gtk_paint_arrow (GtkStyle *style,
3801 GtkStateType state_type,
3802 GtkShadowType shadow_type,
3804 const gchar *detail,
3805 GtkArrowType arrow_type,
3812 g_return_if_fail (GTK_IS_STYLE (style));
3813 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
3814 g_return_if_fail (cr != NULL);
3815 g_return_if_fail (width >= 0);
3816 g_return_if_fail (height >= 0);
3820 GTK_STYLE_GET_CLASS (style)->draw_arrow (style, cr, state_type, shadow_type,
3822 arrow_type, fill, x, y, width, height);
3828 * gtk_paint_diamond:
3829 * @style: a #GtkStyle
3831 * @state_type: a state
3832 * @shadow_type: the type of shadow to draw
3833 * @widget: (allow-none): the widget
3834 * @detail: (allow-none): a style detail
3835 * @x: x origin of the rectangle to draw the diamond in
3836 * @y: y origin of the rectangle to draw the diamond in
3837 * @width: width of the rectangle to draw the diamond in
3838 * @height: height of the rectangle to draw the diamond in
3840 * Draws a diamond in the given rectangle on @window using the given
3844 gtk_paint_diamond (GtkStyle *style,
3846 GtkStateType state_type,
3847 GtkShadowType shadow_type,
3849 const gchar *detail,
3855 g_return_if_fail (GTK_IS_STYLE (style));
3856 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
3857 g_return_if_fail (cr != NULL);
3858 g_return_if_fail (width >= 0);
3859 g_return_if_fail (height >= 0);
3863 GTK_STYLE_GET_CLASS (style)->draw_diamond (style, cr, state_type, shadow_type,
3865 x, y, width, height);
3872 * @style: a #GtkStyle
3874 * @state_type: a state
3875 * @shadow_type: the type of shadow to draw
3876 * @widget: (allow-none): the widget
3877 * @detail: (allow-none): a style detail
3878 * @x: x origin of the box
3879 * @y: y origin of the box
3880 * @width: the width of the box
3881 * @height: the height of the box
3883 * Draws a box on @cr with the given parameters.
3886 gtk_paint_box (GtkStyle *style,
3888 GtkStateType state_type,
3889 GtkShadowType shadow_type,
3891 const gchar *detail,
3897 g_return_if_fail (GTK_IS_STYLE (style));
3898 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
3899 g_return_if_fail (cr != NULL);
3903 GTK_STYLE_GET_CLASS (style)->draw_box (style, cr, state_type, shadow_type,
3905 x, y, width, height);
3911 * gtk_paint_flat_box:
3912 * @style: a #GtkStyle
3914 * @state_type: a state
3915 * @shadow_type: the type of shadow to draw
3916 * @area: (allow-none): clip rectangle, or %NULL if the
3917 * output should not be clipped
3918 * @widget: (allow-none): the widget
3919 * @detail: (allow-none): a style detail
3920 * @x: x origin of the box
3921 * @y: y origin of the box
3922 * @width: the width of the box
3923 * @height: the height of the box
3925 * Draws a flat box on @cr with the given parameters.
3928 gtk_paint_flat_box (GtkStyle *style,
3930 GtkStateType state_type,
3931 GtkShadowType shadow_type,
3933 const gchar *detail,
3939 g_return_if_fail (GTK_IS_STYLE (style));
3940 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
3941 g_return_if_fail (cr != NULL);
3942 g_return_if_fail (width >= 0);
3943 g_return_if_fail (height >= 0);
3947 GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, cr, state_type, shadow_type,
3949 x, y, width, height);
3956 * @style: a #GtkStyle
3958 * @state_type: a state
3959 * @shadow_type: the type of shadow to draw
3960 * @widget: (allow-none): the widget
3961 * @detail: (allow-none): a style detail
3962 * @x: x origin of the rectangle to draw the check in
3963 * @y: y origin of the rectangle to draw the check in
3964 * @width: the width of the rectangle to draw the check in
3965 * @height: the height of the rectangle to draw the check in
3967 * Draws a check button indicator in the given rectangle on @cr with
3968 * the given parameters.
3971 gtk_paint_check (GtkStyle *style,
3973 GtkStateType state_type,
3974 GtkShadowType shadow_type,
3976 const gchar *detail,
3982 g_return_if_fail (GTK_IS_STYLE (style));
3983 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
3984 g_return_if_fail (cr != NULL);
3988 GTK_STYLE_GET_CLASS (style)->draw_check (style, cr, state_type, shadow_type,
3990 x, y, width, height);
3997 * @style: a #GtkStyle
3999 * @state_type: a state
4000 * @shadow_type: the type of shadow to draw
4001 * @widget: (allow-none): the widget
4002 * @detail: (allow-none): a style detail
4003 * @x: x origin of the rectangle to draw the option in
4004 * @y: y origin of the rectangle to draw the option in
4005 * @width: the width of the rectangle to draw the option in
4006 * @height: the height of the rectangle to draw the option in
4008 * Draws a radio button indicator in the given rectangle on @cr with
4009 * the given parameters.
4012 gtk_paint_option (GtkStyle *style,
4014 GtkStateType state_type,
4015 GtkShadowType shadow_type,
4017 const gchar *detail,
4023 g_return_if_fail (GTK_IS_STYLE (style));
4024 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
4025 g_return_if_fail (cr != NULL);
4029 GTK_STYLE_GET_CLASS (style)->draw_option (style, cr, state_type, shadow_type,
4031 x, y, width, height);
4038 * @style: a #GtkStyle
4040 * @state_type: a state
4041 * @shadow_type: the type of shadow to draw
4042 * @widget: (allow-none): the widget
4043 * @detail: (allow-none): a style detail
4044 * @x: x origin of the rectangle to draw the tab in
4045 * @y: y origin of the rectangle to draw the tab in
4046 * @width: the width of the rectangle to draw the tab in
4047 * @height: the height of the rectangle to draw the tab in
4049 * Draws an option menu tab (i.e. the up and down pointing arrows)
4050 * in the given rectangle on @cr using the given parameters.
4053 gtk_paint_tab (GtkStyle *style,
4055 GtkStateType state_type,
4056 GtkShadowType shadow_type,
4058 const gchar *detail,
4064 g_return_if_fail (GTK_IS_STYLE (style));
4065 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
4066 g_return_if_fail (cr != NULL);
4070 GTK_STYLE_GET_CLASS (style)->draw_tab (style, cr, state_type, shadow_type,
4072 x, y, width, height);
4078 * gtk_paint_shadow_gap:
4079 * @style: a #GtkStyle
4081 * @state_type: a state
4082 * @shadow_type: type of shadow to draw
4083 * @widget: (allow-none): the widget
4084 * @detail: (allow-none): a style detail
4085 * @x: x origin of the rectangle
4086 * @y: y origin of the rectangle
4087 * @width: width of the rectangle
4088 * @height: width of the rectangle
4089 * @gap_side: side in which to leave the gap
4090 * @gap_x: starting position of the gap
4091 * @gap_width: width of the gap
4093 * Draws a shadow around the given rectangle in @cr
4094 * using the given style and state and shadow type, leaving a
4098 gtk_paint_shadow_gap (GtkStyle *style,
4100 GtkStateType state_type,
4101 GtkShadowType shadow_type,
4103 const gchar *detail,
4108 GtkPositionType gap_side,
4112 g_return_if_fail (GTK_IS_STYLE (style));
4113 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
4114 g_return_if_fail (cr != NULL);
4115 g_return_if_fail (width >= 0);
4116 g_return_if_fail (height >= 0);
4120 GTK_STYLE_GET_CLASS (style)->draw_shadow_gap (style, cr, state_type, shadow_type,
4122 x, y, width, height, gap_side, gap_x, gap_width);
4128 * gtk_paint_box_gap:
4129 * @style: a #GtkStyle
4131 * @state_type: a state
4132 * @shadow_type: type of shadow to draw
4133 * @widget: (allow-none): the widget
4134 * @detail: (allow-none): a style detail
4135 * @x: x origin of the rectangle
4136 * @y: y origin of the rectangle
4137 * @width: width of the rectangle
4138 * @height: width of the rectangle
4139 * @gap_side: side in which to leave the gap
4140 * @gap_x: starting position of the gap
4141 * @gap_width: width of the gap
4143 * Draws a box in @cr using the given style and state and shadow type,
4144 * leaving a gap in one side.
4147 gtk_paint_box_gap (GtkStyle *style,
4149 GtkStateType state_type,
4150 GtkShadowType shadow_type,
4152 const gchar *detail,
4157 GtkPositionType gap_side,
4161 g_return_if_fail (GTK_IS_STYLE (style));
4162 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
4163 g_return_if_fail (cr != NULL);
4164 g_return_if_fail (width >= 0);
4165 g_return_if_fail (height >= 0);
4169 GTK_STYLE_GET_CLASS (style)->draw_box_gap (style, cr, state_type, shadow_type,
4171 x, y, width, height, gap_side, gap_x, gap_width);
4177 * gtk_paint_extension:
4178 * @style: a #GtkStyle
4180 * @state_type: a state
4181 * @shadow_type: type of shadow to draw
4182 * @widget: (allow-none): the widget
4183 * @detail: (allow-none): a style detail
4184 * @x: x origin of the extension
4185 * @y: y origin of the extension
4186 * @width: width of the extension
4187 * @height: width of the extension
4188 * @gap_side: the side on to which the extension is attached
4190 * Draws an extension, i.e. a notebook tab.
4193 gtk_paint_extension (GtkStyle *style,
4195 GtkStateType state_type,
4196 GtkShadowType shadow_type,
4198 const gchar *detail,
4203 GtkPositionType gap_side)
4205 g_return_if_fail (GTK_IS_STYLE (style));
4206 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
4207 g_return_if_fail (cr != NULL);
4208 g_return_if_fail (width >= 0);
4209 g_return_if_fail (height >= 0);
4213 GTK_STYLE_GET_CLASS (style)->draw_extension (style, cr, state_type, shadow_type,
4215 x, y, width, height, gap_side);
4222 * @style: a #GtkStyle
4224 * @state_type: a state
4225 * @widget: (allow-none): the widget
4226 * @detail: (allow-none): a style detail
4227 * @x: the x origin of the rectangle around which to draw a focus indicator
4228 * @y: the y origin of the rectangle around which to draw a focus indicator
4229 * @width: the width of the rectangle around which to draw a focus indicator
4230 * @height: the height of the rectangle around which to draw a focus indicator
4232 * Draws a focus indicator around the given rectangle on @cr using the
4236 gtk_paint_focus (GtkStyle *style,
4238 GtkStateType state_type,
4240 const gchar *detail,
4246 g_return_if_fail (GTK_IS_STYLE (style));
4247 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
4248 g_return_if_fail (cr != NULL);
4249 g_return_if_fail (width >= 0);
4250 g_return_if_fail (height >= 0);
4254 GTK_STYLE_GET_CLASS (style)->draw_focus (style, cr, state_type,
4256 x, y, width, height);
4263 * @style: a #GtkStyle
4265 * @state_type: a state
4266 * @shadow_type: a shadow
4267 * @widget: (allow-none): the widget
4268 * @detail: (allow-none): a style detail
4269 * @x: the x origin of the rectangle in which to draw a slider
4270 * @y: the y origin of the rectangle in which to draw a slider
4271 * @width: the width of the rectangle in which to draw a slider
4272 * @height: the height of the rectangle in which to draw a slider
4273 * @orientation: the orientation to be used
4275 * Draws a slider in the given rectangle on @cr using the
4276 * given style and orientation.
4279 gtk_paint_slider (GtkStyle *style,
4281 GtkStateType state_type,
4282 GtkShadowType shadow_type,
4284 const gchar *detail,
4289 GtkOrientation orientation)
4291 g_return_if_fail (GTK_IS_STYLE (style));
4292 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
4293 g_return_if_fail (cr != NULL);
4294 g_return_if_fail (width >= 0);
4295 g_return_if_fail (height >= 0);
4299 GTK_STYLE_GET_CLASS (style)->draw_slider (style, cr, state_type, shadow_type,
4301 x, y, width, height, orientation);
4308 * @style: a #GtkStyle
4310 * @state_type: a state
4311 * @shadow_type: type of shadow to draw
4312 * @widget: (allow-none): the widget
4313 * @detail: (allow-none): a style detail
4314 * @x: x origin of the handle
4315 * @y: y origin of the handle
4316 * @width: with of the handle
4317 * @height: height of the handle
4318 * @orientation: the orientation of the handle
4320 * Draws a handle as used in #GtkHandleBox and #GtkPaned.
4323 gtk_paint_handle (GtkStyle *style,
4325 GtkStateType state_type,
4326 GtkShadowType shadow_type,
4328 const gchar *detail,
4333 GtkOrientation orientation)
4335 g_return_if_fail (GTK_IS_STYLE (style));
4336 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
4337 g_return_if_fail (cr != NULL);
4338 g_return_if_fail (width >= 0);
4339 g_return_if_fail (height >= 0);
4343 GTK_STYLE_GET_CLASS (style)->draw_handle (style, cr, state_type, shadow_type,
4345 x, y, width, height, orientation);
4351 * gtk_paint_expander:
4352 * @style: a #GtkStyle
4354 * @state_type: a state
4355 * @widget: (allow-none): the widget
4356 * @detail: (allow-none): a style detail
4357 * @x: the x position to draw the expander at
4358 * @y: the y position to draw the expander at
4359 * @expander_style: the style to draw the expander in; determines
4360 * whether the expander is collapsed, expanded, or in an
4361 * intermediate state.
4363 * Draws an expander as used in #GtkTreeView. @x and @y specify the
4364 * center the expander. The size of the expander is determined by the
4365 * "expander-size" style property of @widget. (If widget is not
4366 * specified or doesn't have an "expander-size" property, an
4367 * unspecified default size will be used, since the caller doesn't
4368 * have sufficient information to position the expander, this is
4369 * likely not useful.) The expander is expander_size pixels tall
4370 * in the collapsed position and expander_size pixels wide in the
4371 * expanded position.
4374 gtk_paint_expander (GtkStyle *style,
4376 GtkStateType state_type,
4378 const gchar *detail,
4381 GtkExpanderStyle expander_style)
4383 g_return_if_fail (GTK_IS_STYLE (style));
4384 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
4385 g_return_if_fail (cr != NULL);
4389 GTK_STYLE_GET_CLASS (style)->draw_expander (style, cr, state_type,
4391 x, y, expander_style);
4398 * @style: a #GtkStyle
4400 * @state_type: a state
4401 * @use_text: whether to use the text or foreground
4402 * graphics context of @style
4403 * @widget: (allow-none): the widget
4404 * @detail: (allow-none): a style detail
4407 * @layout: the layout to draw
4409 * Draws a layout on @cr using the given parameters.
4412 gtk_paint_layout (GtkStyle *style,
4414 GtkStateType state_type,
4417 const gchar *detail,
4420 PangoLayout *layout)
4422 g_return_if_fail (GTK_IS_STYLE (style));
4423 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
4424 g_return_if_fail (cr != NULL);
4428 GTK_STYLE_GET_CLASS (style)->draw_layout (style, cr, state_type, use_text,
4436 * gtk_paint_resize_grip:
4437 * @style: a #GtkStyle
4439 * @state_type: a state
4440 * @widget: (allow-none): the widget
4441 * @detail: (allow-none): a style detail
4442 * @edge: the edge in which to draw the resize grip
4443 * @x: the x origin of the rectangle in which to draw the resize grip
4444 * @y: the y origin of the rectangle in which to draw the resize grip
4445 * @width: the width of the rectangle in which to draw the resize grip
4446 * @height: the height of the rectangle in which to draw the resize grip
4448 * Draws a resize grip in the given rectangle on @cr using the given
4452 gtk_paint_resize_grip (GtkStyle *style,
4454 GtkStateType state_type,
4456 const gchar *detail,
4463 g_return_if_fail (GTK_IS_STYLE (style));
4464 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
4465 g_return_if_fail (cr != NULL);
4469 GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, cr, state_type,
4471 edge, x, y, width, height);
4476 * gtk_paint_spinner:
4477 * @style: a #GtkStyle
4479 * @state_type: a state
4480 * @widget: (allow-none): the widget (may be %NULL)
4481 * @detail: (allow-none): a style detail (may be %NULL)
4482 * @step: the nth step, a value between 0 and #GtkSpinner:num-steps
4483 * @x: the x origin of the rectangle in which to draw the spinner
4484 * @y: the y origin of the rectangle in which to draw the spinner
4485 * @width: the width of the rectangle in which to draw the spinner
4486 * @height: the height of the rectangle in which to draw the spinner
4488 * Draws a spinner on @window using the given parameters.
4491 gtk_paint_spinner (GtkStyle *style,
4493 GtkStateType state_type,
4495 const gchar *detail,
4502 g_return_if_fail (GTK_IS_STYLE (style));
4503 g_return_if_fail (cr != NULL);
4504 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_spinner != NULL);
4508 GTK_STYLE_GET_CLASS (style)->draw_spinner (style, cr, state_type,
4510 step, x, y, width, height);
4518 * Allocates a new #GtkBorder structure and initializes its elements to zero.
4520 * Returns: a new empty #GtkBorder. The newly allocated #GtkBorder should be
4521 * freed with gtk_border_free()
4526 gtk_border_new (void)
4528 return g_slice_new0 (GtkBorder);
4533 * @border_: a #GtkBorder.
4534 * @returns: a copy of @border_.
4536 * Copies a #GtkBorder structure.
4539 gtk_border_copy (const GtkBorder *border)
4541 g_return_val_if_fail (border != NULL, NULL);
4543 return g_slice_dup (GtkBorder, border);
4548 * @border_: a #GtkBorder.
4550 * Frees a #GtkBorder structure.
4553 gtk_border_free (GtkBorder *border)
4555 g_slice_free (GtkBorder, border);
4558 G_DEFINE_BOXED_TYPE (GtkBorder, gtk_border,
4562 typedef struct _CursorInfo CursorInfo;
4572 style_unrealize_cursors (GtkStyle *style)
4576 cursor_info = g_object_get_data (G_OBJECT (style), "gtk-style-cursor-info");
4579 g_free (cursor_info);
4580 g_object_set_data (G_OBJECT (style), I_("gtk-style-cursor-info"), NULL);
4584 static const GdkColor *
4585 get_insertion_cursor_color (GtkWidget *widget,
4586 gboolean is_primary)
4588 CursorInfo *cursor_info;
4590 GdkColor *cursor_color;
4592 style = gtk_widget_get_style (widget);
4594 cursor_info = g_object_get_data (G_OBJECT (style), "gtk-style-cursor-info");
4597 cursor_info = g_new0 (CursorInfo, 1);
4598 g_object_set_data (G_OBJECT (style), I_("gtk-style-cursor-info"), cursor_info);
4599 cursor_info->for_type = G_TYPE_INVALID;
4602 /* We have to keep track of the type because gtk_widget_style_get()
4603 * can return different results when called on the same property and
4604 * same style but for different widgets. :-(. That is,
4605 * GtkEntry::cursor-color = "red" in a style will modify the cursor
4606 * color for entries but not for text view.
4608 if (cursor_info->for_type != G_OBJECT_TYPE (widget))
4610 cursor_info->for_type = G_OBJECT_TYPE (widget);
4612 /* Cursors in text widgets are drawn only in NORMAL state,
4613 * so we can use text[GTK_STATE_NORMAL] as text color here */
4614 gtk_widget_style_get (widget, "cursor-color", &cursor_color, NULL);
4617 cursor_info->primary = *cursor_color;
4618 gdk_color_free (cursor_color);
4622 cursor_info->primary = style->text[GTK_STATE_NORMAL];
4625 gtk_widget_style_get (widget, "secondary-cursor-color", &cursor_color, NULL);
4628 cursor_info->secondary = *cursor_color;
4629 gdk_color_free (cursor_color);
4633 /* text_aa is the average of text and base colors,
4634 * in usual black-on-white case it's grey. */
4635 cursor_info->secondary = style->text_aa[GTK_STATE_NORMAL];
4640 return &cursor_info->primary;
4642 return &cursor_info->secondary;
4646 _gtk_widget_get_cursor_color (GtkWidget *widget,
4649 GdkColor *style_color;
4651 g_return_if_fail (GTK_IS_WIDGET (widget));
4652 g_return_if_fail (color != NULL);
4654 gtk_widget_style_get (widget, "cursor-color", &style_color, NULL);
4658 *color = *style_color;
4659 gdk_color_free (style_color);
4662 *color = gtk_widget_get_style (widget)->text[GTK_STATE_NORMAL];
4666 * gtk_draw_insertion_cursor:
4667 * @widget: a #GtkWidget
4668 * @cr: cairo context to draw to
4669 * @location: location where to draw the cursor (@location->width is ignored)
4670 * @is_primary: if the cursor should be the primary cursor color.
4671 * @direction: whether the cursor is left-to-right or
4672 * right-to-left. Should never be #GTK_TEXT_DIR_NONE
4673 * @draw_arrow: %TRUE to draw a directional arrow on the
4674 * cursor. Should be %FALSE unless the cursor is split.
4676 * Draws a text caret on @cr at @location. This is not a style function
4677 * but merely a convenience function for drawing the standard cursor shape.
4682 gtk_draw_insertion_cursor (GtkWidget *widget,
4684 const GdkRectangle *location,
4685 gboolean is_primary,
4686 GtkTextDirection direction,
4687 gboolean draw_arrow)
4692 gfloat cursor_aspect_ratio;
4695 g_return_if_fail (GTK_IS_WIDGET (widget));
4696 g_return_if_fail (cr != NULL);
4697 g_return_if_fail (location != NULL);
4698 g_return_if_fail (direction != GTK_TEXT_DIR_NONE);
4700 gdk_cairo_set_source_color (cr, get_insertion_cursor_color (widget, is_primary));
4702 /* When changing the shape or size of the cursor here,
4703 * propagate the changes to gtktextview.c:text_window_invalidate_cursors().
4706 gtk_widget_style_get (widget, "cursor-aspect-ratio", &cursor_aspect_ratio, NULL);
4708 stem_width = location->height * cursor_aspect_ratio + 1;
4709 arrow_width = stem_width + 1;
4711 /* put (stem_width % 2) on the proper side of the cursor */
4712 if (direction == GTK_TEXT_DIR_LTR)
4713 offset = stem_width / 2;
4715 offset = stem_width - stem_width / 2;
4717 cairo_rectangle (cr,
4718 location->x - offset, location->y,
4719 stem_width, location->height);
4724 if (direction == GTK_TEXT_DIR_RTL)
4726 x = location->x - offset - 1;
4727 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
4729 cairo_move_to (cr, x, y + 1);
4730 cairo_line_to (cr, x - arrow_width, y + arrow_width);
4731 cairo_line_to (cr, x, y + 2 * arrow_width);
4734 else if (direction == GTK_TEXT_DIR_LTR)
4736 x = location->x + stem_width - offset;
4737 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
4739 cairo_move_to (cr, x, y + 1);
4740 cairo_line_to (cr, x + arrow_width, y + arrow_width);
4741 cairo_line_to (cr, x, y + 2 * arrow_width);