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;
89 /* --- prototypes --- */
90 static void gtk_style_finalize (GObject *object);
91 static void gtk_style_constructed (GObject *object);
92 static void gtk_style_set_property (GObject *object,
97 static void gtk_style_realize (GtkStyle *style,
99 static void gtk_style_real_realize (GtkStyle *style);
100 static void gtk_style_real_unrealize (GtkStyle *style);
101 static void gtk_style_real_copy (GtkStyle *style,
103 static void gtk_style_real_set_background (GtkStyle *style,
105 GtkStateType state_type);
106 static GtkStyle *gtk_style_real_clone (GtkStyle *style);
107 static void gtk_style_real_init_from_rc (GtkStyle *style,
108 GtkRcStyle *rc_style);
109 static GdkPixbuf *gtk_default_render_icon (GtkStyle *style,
110 const GtkIconSource *source,
111 GtkTextDirection direction,
115 const gchar *detail);
116 static void gtk_default_draw_hline (GtkStyle *style,
118 GtkStateType state_type,
124 static void gtk_default_draw_vline (GtkStyle *style,
126 GtkStateType state_type,
132 static void gtk_default_draw_shadow (GtkStyle *style,
134 GtkStateType state_type,
135 GtkShadowType shadow_type,
142 static void gtk_default_draw_arrow (GtkStyle *style,
144 GtkStateType state_type,
145 GtkShadowType shadow_type,
148 GtkArrowType arrow_type,
154 static void gtk_default_draw_diamond (GtkStyle *style,
156 GtkStateType state_type,
157 GtkShadowType shadow_type,
164 static void gtk_default_draw_box (GtkStyle *style,
166 GtkStateType state_type,
167 GtkShadowType shadow_type,
174 static void gtk_default_draw_flat_box (GtkStyle *style,
176 GtkStateType state_type,
177 GtkShadowType shadow_type,
184 static void gtk_default_draw_check (GtkStyle *style,
186 GtkStateType state_type,
187 GtkShadowType shadow_type,
194 static void gtk_default_draw_option (GtkStyle *style,
196 GtkStateType state_type,
197 GtkShadowType shadow_type,
204 static void gtk_default_draw_tab (GtkStyle *style,
206 GtkStateType state_type,
207 GtkShadowType shadow_type,
214 static void gtk_default_draw_shadow_gap (GtkStyle *style,
216 GtkStateType state_type,
217 GtkShadowType shadow_type,
224 GtkPositionType gap_side,
227 static void gtk_default_draw_box_gap (GtkStyle *style,
229 GtkStateType state_type,
230 GtkShadowType shadow_type,
237 GtkPositionType gap_side,
240 static void gtk_default_draw_extension (GtkStyle *style,
242 GtkStateType state_type,
243 GtkShadowType shadow_type,
250 GtkPositionType gap_side);
251 static void gtk_default_draw_focus (GtkStyle *style,
253 GtkStateType state_type,
260 static void gtk_default_draw_slider (GtkStyle *style,
262 GtkStateType state_type,
263 GtkShadowType shadow_type,
270 GtkOrientation orientation);
271 static void gtk_default_draw_handle (GtkStyle *style,
273 GtkStateType state_type,
274 GtkShadowType shadow_type,
281 GtkOrientation orientation);
282 static void gtk_default_draw_expander (GtkStyle *style,
284 GtkStateType state_type,
289 GtkExpanderStyle expander_style);
290 static void gtk_default_draw_layout (GtkStyle *style,
292 GtkStateType state_type,
298 PangoLayout *layout);
299 static void gtk_default_draw_resize_grip (GtkStyle *style,
301 GtkStateType state_type,
309 static void gtk_default_draw_spinner (GtkStyle *style,
311 GtkStateType state_type,
320 static void rgb_to_hls (gdouble *r,
323 static void hls_to_rgb (gdouble *h,
327 static void style_unrealize_cursors (GtkStyle *style);
330 * Data for default check and radio buttons
333 static const GtkRequisition default_option_indicator_size = { 7, 13 };
334 static const GtkBorder default_option_indicator_spacing = { 7, 5, 2, 2 };
336 #define GTK_GRAY 0xdcdc, 0xdada, 0xd5d5
337 #define GTK_DARK_GRAY 0xc4c4, 0xc2c2, 0xbdbd
338 #define GTK_LIGHT_GRAY 0xeeee, 0xebeb, 0xe7e7
339 #define GTK_WHITE 0xffff, 0xffff, 0xffff
340 #define GTK_BLUE 0x4b4b, 0x6969, 0x8383
341 #define GTK_VERY_DARK_GRAY 0x9c9c, 0x9a9a, 0x9494
342 #define GTK_BLACK 0x0000, 0x0000, 0x0000
343 #define GTK_WEAK_GRAY 0x7530, 0x7530, 0x7530
345 /* --- variables --- */
346 static const GdkColor gtk_default_normal_fg = { 0, GTK_BLACK };
347 static const GdkColor gtk_default_active_fg = { 0, GTK_BLACK };
348 static const GdkColor gtk_default_prelight_fg = { 0, GTK_BLACK };
349 static const GdkColor gtk_default_selected_fg = { 0, GTK_WHITE };
350 static const GdkColor gtk_default_insensitive_fg = { 0, GTK_WEAK_GRAY };
352 static const GdkColor gtk_default_normal_bg = { 0, GTK_GRAY };
353 static const GdkColor gtk_default_active_bg = { 0, GTK_DARK_GRAY };
354 static const GdkColor gtk_default_prelight_bg = { 0, GTK_LIGHT_GRAY };
355 static const GdkColor gtk_default_selected_bg = { 0, GTK_BLUE };
356 static const GdkColor gtk_default_insensitive_bg = { 0, GTK_GRAY };
357 static const GdkColor gtk_default_selected_base = { 0, GTK_BLUE };
358 static const GdkColor gtk_default_active_base = { 0, GTK_VERY_DARK_GRAY };
360 /* --- signals --- */
361 static guint realize_signal = 0;
362 static guint unrealize_signal = 0;
364 G_DEFINE_TYPE (GtkStyle, gtk_style, G_TYPE_OBJECT)
366 /* --- functions --- */
369 * _gtk_style_init_for_settings:
370 * @style: a #GtkStyle
371 * @settings: a #GtkSettings
373 * Initializes the font description in @style according to the default
374 * font name of @settings. This is called for gtk_style_new() with
375 * the settings for the default screen (if any); if we are creating
376 * a style for a particular screen, we then call it again in a
377 * location where we know the correct settings.
378 * The reason for this is that gtk_rc_style_create_style() doesn't
379 * take the screen for an argument.
382 _gtk_style_init_for_settings (GtkStyle *style,
383 GtkSettings *settings)
385 const gchar *font_name = _gtk_rc_context_get_default_font_name (settings);
387 if (style->font_desc)
388 pango_font_description_free (style->font_desc);
390 style->font_desc = pango_font_description_from_string (font_name);
392 if (!pango_font_description_get_family (style->font_desc))
394 g_warning ("Default font does not have a family set");
395 pango_font_description_set_family (style->font_desc, "Sans");
397 if (pango_font_description_get_size (style->font_desc) <= 0)
399 g_warning ("Default font does not have a positive size");
400 pango_font_description_set_size (style->font_desc, 10 * PANGO_SCALE);
405 gtk_style_init (GtkStyle *style)
409 GtkSettings *settings = gtk_settings_get_default ();
412 _gtk_style_init_for_settings (style, settings);
414 style->font_desc = pango_font_description_from_string ("Sans 10");
416 style->attach_count = 0;
418 style->black.red = 0;
419 style->black.green = 0;
420 style->black.blue = 0;
422 style->white.red = 65535;
423 style->white.green = 65535;
424 style->white.blue = 65535;
426 style->fg[GTK_STATE_NORMAL] = gtk_default_normal_fg;
427 style->fg[GTK_STATE_ACTIVE] = gtk_default_active_fg;
428 style->fg[GTK_STATE_PRELIGHT] = gtk_default_prelight_fg;
429 style->fg[GTK_STATE_SELECTED] = gtk_default_selected_fg;
430 style->fg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
432 style->bg[GTK_STATE_NORMAL] = gtk_default_normal_bg;
433 style->bg[GTK_STATE_ACTIVE] = gtk_default_active_bg;
434 style->bg[GTK_STATE_PRELIGHT] = gtk_default_prelight_bg;
435 style->bg[GTK_STATE_SELECTED] = gtk_default_selected_bg;
436 style->bg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_bg;
438 for (i = 0; i < 4; i++)
440 style->text[i] = style->fg[i];
441 style->base[i] = style->white;
444 style->base[GTK_STATE_SELECTED] = gtk_default_selected_base;
445 style->text[GTK_STATE_SELECTED] = style->white;
446 style->base[GTK_STATE_ACTIVE] = gtk_default_active_base;
447 style->text[GTK_STATE_ACTIVE] = style->white;
448 style->base[GTK_STATE_INSENSITIVE] = gtk_default_prelight_bg;
449 style->text[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
451 style->rc_style = NULL;
453 style->xthickness = 2;
454 style->ythickness = 2;
456 style->property_cache = NULL;
460 gtk_style_class_init (GtkStyleClass *klass)
462 GObjectClass *object_class = G_OBJECT_CLASS (klass);
464 object_class->finalize = gtk_style_finalize;
465 object_class->set_property = gtk_style_set_property;
466 object_class->constructed = gtk_style_constructed;
468 klass->clone = gtk_style_real_clone;
469 klass->copy = gtk_style_real_copy;
470 klass->init_from_rc = gtk_style_real_init_from_rc;
471 klass->realize = gtk_style_real_realize;
472 klass->unrealize = gtk_style_real_unrealize;
473 klass->set_background = gtk_style_real_set_background;
474 klass->render_icon = gtk_default_render_icon;
476 klass->draw_hline = gtk_default_draw_hline;
477 klass->draw_vline = gtk_default_draw_vline;
478 klass->draw_shadow = gtk_default_draw_shadow;
479 klass->draw_arrow = gtk_default_draw_arrow;
480 klass->draw_diamond = gtk_default_draw_diamond;
481 klass->draw_box = gtk_default_draw_box;
482 klass->draw_flat_box = gtk_default_draw_flat_box;
483 klass->draw_check = gtk_default_draw_check;
484 klass->draw_option = gtk_default_draw_option;
485 klass->draw_tab = gtk_default_draw_tab;
486 klass->draw_shadow_gap = gtk_default_draw_shadow_gap;
487 klass->draw_box_gap = gtk_default_draw_box_gap;
488 klass->draw_extension = gtk_default_draw_extension;
489 klass->draw_focus = gtk_default_draw_focus;
490 klass->draw_slider = gtk_default_draw_slider;
491 klass->draw_handle = gtk_default_draw_handle;
492 klass->draw_expander = gtk_default_draw_expander;
493 klass->draw_layout = gtk_default_draw_layout;
494 klass->draw_resize_grip = gtk_default_draw_resize_grip;
495 klass->draw_spinner = gtk_default_draw_spinner;
497 g_type_class_add_private (object_class, sizeof (GtkStylePrivate));
499 g_object_class_install_property (object_class,
501 g_param_spec_object ("context",
503 P_("GtkStyleContext to get style from"),
504 GTK_TYPE_STYLE_CONTEXT,
505 G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE));
509 * @style: the object which received the signal
511 * Emitted when the style has been initialized for a particular
512 * visual. Connecting to this signal is probably seldom
513 * useful since most of the time applications and widgets only
514 * deal with styles that have been already realized.
518 realize_signal = g_signal_new (I_("realize"),
519 G_TYPE_FROM_CLASS (object_class),
521 G_STRUCT_OFFSET (GtkStyleClass, realize),
523 _gtk_marshal_VOID__VOID,
526 * GtkStyle::unrealize:
527 * @style: the object which received the signal
529 * Emitted when the aspects of the style specific to a particular visual
530 * is being cleaned up. A connection to this signal can be useful
531 * if a widget wants to cache objects as object data on #GtkStyle.
532 * This signal provides a convenient place to free such cached objects.
536 unrealize_signal = g_signal_new (I_("unrealize"),
537 G_TYPE_FROM_CLASS (object_class),
539 G_STRUCT_OFFSET (GtkStyleClass, unrealize),
541 _gtk_marshal_VOID__VOID,
546 clear_property_cache (GtkStyle *style)
548 if (style->property_cache)
552 for (i = 0; i < style->property_cache->len; i++)
554 PropertyValue *node = &g_array_index (style->property_cache, PropertyValue, i);
556 g_param_spec_unref (node->pspec);
557 g_value_unset (&node->value);
559 g_array_free (style->property_cache, TRUE);
560 style->property_cache = NULL;
565 gtk_style_finalize (GObject *object)
567 GtkStyle *style = GTK_STYLE (object);
568 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
570 g_return_if_fail (style->attach_count == 0);
572 clear_property_cache (style);
574 /* All the styles in the list have the same
575 * style->styles pointer. If we delete the
576 * *first* style from the list, we need to update
577 * the style->styles pointers from all the styles.
578 * Otherwise we simply remove the node from
583 if (style->styles->data != style)
584 style->styles = g_slist_remove (style->styles, style);
587 GSList *tmp_list = style->styles->next;
591 GTK_STYLE (tmp_list->data)->styles = style->styles->next;
592 tmp_list = tmp_list->next;
594 g_slist_free_1 (style->styles);
598 g_slist_foreach (style->icon_factories, (GFunc) g_object_unref, NULL);
599 g_slist_free (style->icon_factories);
601 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_unref, NULL);
602 g_slist_free (priv->color_hashes);
604 pango_font_description_free (style->font_desc);
606 if (style->private_font_desc)
607 pango_font_description_free (style->private_font_desc);
610 g_object_unref (style->rc_style);
613 g_object_unref (priv->context);
615 G_OBJECT_CLASS (gtk_style_parent_class)->finalize (object);
619 gtk_style_set_property (GObject *object,
624 GtkStylePrivate *priv;
626 priv = GTK_STYLE_GET_PRIVATE (object);
631 priv->context = g_value_dup_object (value);
634 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
640 set_color (GtkStyle *style,
641 GtkStyleContext *context,
645 GdkColor *color = NULL;
650 gtk_style_context_get (context, state,
651 "background-color", &color,
654 style->bg[state] = *color;
657 gtk_style_context_get (context, state,
658 "foreground-color", &color,
661 style->fg[state] = *color;
664 gtk_style_context_get (context, state,
665 "text-color", &color,
668 style->text[state] = *color;
671 gtk_style_context_get (context, state,
672 "base-color", &color,
675 style->base[state] = *color;
680 gdk_color_free (color);
684 gtk_style_update_from_context (GtkStyle *style)
686 GtkStylePrivate *priv;
690 priv = GTK_STYLE_GET_PRIVATE (style);
692 for (state = GTK_STATE_NORMAL; state <= GTK_STATE_INSENSITIVE; state++)
694 set_color (style, priv->context, state, GTK_RC_BG);
695 set_color (style, priv->context, state, GTK_RC_FG);
696 set_color (style, priv->context, state, GTK_RC_BASE);
697 set_color (style, priv->context, state, GTK_RC_TEXT);
700 if (style->font_desc)
701 pango_font_description_free (style->font_desc);
703 gtk_style_context_get (priv->context, state,
704 "font", &style->font_desc,
710 style->xthickness = padding->left;
711 style->ythickness = padding->top;
713 gtk_border_free (padding);
718 gtk_style_constructed (GObject *object)
720 GtkStylePrivate *priv;
722 priv = GTK_STYLE_GET_PRIVATE (object);
726 gtk_style_update_from_context (GTK_STYLE (object));
728 /* FIXME: Listen to context changes */
734 * @style: a #GtkStyle
736 * Creates a copy of the passed in #GtkStyle object.
738 * Returns: (transfer full): a copy of @style
741 gtk_style_copy (GtkStyle *style)
745 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
747 new_style = GTK_STYLE_GET_CLASS (style)->clone (style);
748 GTK_STYLE_GET_CLASS (style)->copy (new_style, style);
754 gtk_style_duplicate (GtkStyle *style)
758 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
760 new_style = gtk_style_copy (style);
762 /* All the styles in the list have the same
763 * style->styles pointer. When we insert a new
764 * style, we append it to the list to avoid having
765 * to update the existing ones.
767 style->styles = g_slist_append (style->styles, new_style);
768 new_style->styles = style->styles;
775 * @returns: a new #GtkStyle.
777 * Creates a new #GtkStyle.
784 style = g_object_new (GTK_TYPE_STYLE, NULL);
790 gtk_style_has_context (GtkStyle *style)
792 GtkStylePrivate *priv;
794 priv = GTK_STYLE_GET_PRIVATE (style);
796 return priv->context != NULL;
801 * @style: a #GtkStyle.
802 * @window: a #GdkWindow.
804 * Attaches a style to a window; this process allocates the
805 * colors and creates the GC's for the style - it specializes
806 * it to a particular visual. The process may involve the creation
807 * of a new style if the style has already been attached to a
808 * window with a different style and visual.
810 * Since this function may return a new object, you have to use it
811 * in the following way:
812 * <literal>style = gtk_style_attach (style, window)</literal>
814 * Returns: Either @style, or a newly-created #GtkStyle.
815 * If the style is newly created, the style parameter
816 * will be unref'ed, and the new style will have
817 * a reference count belonging to the caller.
820 gtk_style_attach (GtkStyle *style,
824 GtkStyle *new_style = NULL;
827 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
828 g_return_val_if_fail (window != NULL, NULL);
830 visual = gdk_window_get_visual (window);
833 style->styles = g_slist_append (NULL, style);
835 styles = style->styles;
838 new_style = styles->data;
840 if (new_style->visual == visual)
844 styles = styles->next;
849 styles = style->styles;
853 new_style = styles->data;
855 if (new_style->attach_count == 0)
857 gtk_style_realize (new_style, visual);
862 styles = styles->next;
868 new_style = gtk_style_duplicate (style);
869 gtk_style_realize (new_style, visual);
872 /* A style gets a refcount from being attached */
873 if (new_style->attach_count == 0)
874 g_object_ref (new_style);
876 /* Another refcount belongs to the parent */
877 if (style != new_style)
879 g_object_unref (style);
880 g_object_ref (new_style);
883 new_style->attach_count++;
890 * @style: a #GtkStyle
892 * Detaches a style from a window. If the style is not attached
893 * to any windows anymore, it is unrealized. See gtk_style_attach().
897 gtk_style_detach (GtkStyle *style)
899 g_return_if_fail (GTK_IS_STYLE (style));
900 g_return_if_fail (style->attach_count > 0);
902 style->attach_count -= 1;
903 if (style->attach_count == 0)
905 g_signal_emit (style, unrealize_signal, 0);
907 g_object_unref (style->visual);
908 style->visual = NULL;
910 if (style->private_font_desc)
912 pango_font_description_free (style->private_font_desc);
913 style->private_font_desc = NULL;
916 g_object_unref (style);
921 gtk_style_realize (GtkStyle *style,
924 style->visual = g_object_ref (visual);
926 g_signal_emit (style, realize_signal, 0);
930 * gtk_style_lookup_icon_set:
931 * @style: a #GtkStyle
932 * @stock_id: an icon name
934 * Looks up @stock_id in the icon factories associated with @style
935 * and the default icon factory, returning an icon set if found,
938 * Return value: icon set of @stock_id
941 gtk_style_lookup_icon_set (GtkStyle *style,
942 const char *stock_id)
944 GtkStylePrivate *priv;
946 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
947 g_return_val_if_fail (stock_id != NULL, NULL);
949 priv = GTK_STYLE_GET_PRIVATE (style);
951 return gtk_style_context_lookup_icon_set (priv->context, stock_id);
955 * gtk_style_lookup_color:
956 * @style: a #GtkStyle
957 * @color_name: the name of the logical color to look up
958 * @color: the #GdkColor to fill in
960 * Looks up @color_name in the style's logical color mappings,
961 * filling in @color and returning %TRUE if found, otherwise
962 * returning %FALSE. Do not cache the found mapping, because
963 * it depends on the #GtkStyle and might change when a theme
966 * Return value: %TRUE if the mapping was found.
971 gtk_style_lookup_color (GtkStyle *style,
972 const char *color_name,
975 GtkStylePrivate *priv;
977 g_return_val_if_fail (GTK_IS_STYLE (style), FALSE);
978 g_return_val_if_fail (color_name != NULL, FALSE);
979 g_return_val_if_fail (color != NULL, FALSE);
981 priv = GTK_STYLE_GET_PRIVATE (style);
986 return gtk_style_context_lookup_color (priv->context, color_name, color);
990 * gtk_style_set_background:
991 * @style: a #GtkStyle
992 * @window: a #GdkWindow
993 * @state_type: a state
995 * Sets the background of @window to the background color or pixmap
996 * specified by @style for the given state.
999 gtk_style_set_background (GtkStyle *style,
1001 GtkStateType state_type)
1003 g_return_if_fail (GTK_IS_STYLE (style));
1004 g_return_if_fail (window != NULL);
1006 GTK_STYLE_GET_CLASS (style)->set_background (style, window, state_type);
1009 /* Default functions */
1011 gtk_style_real_clone (GtkStyle *style)
1013 GtkStylePrivate *priv;
1015 priv = GTK_STYLE_GET_PRIVATE (style);
1017 return g_object_new (G_OBJECT_TYPE (style),
1018 "context", priv->context,
1023 gtk_style_real_copy (GtkStyle *style,
1026 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
1027 GtkStylePrivate *src_priv = GTK_STYLE_GET_PRIVATE (src);
1030 for (i = 0; i < 5; i++)
1032 style->fg[i] = src->fg[i];
1033 style->bg[i] = src->bg[i];
1034 style->text[i] = src->text[i];
1035 style->base[i] = src->base[i];
1037 if (style->background[i])
1038 cairo_pattern_destroy (style->background[i]),
1039 style->background[i] = src->background[i];
1040 if (style->background[i])
1041 cairo_pattern_reference (style->background[i]);
1044 if (style->font_desc)
1045 pango_font_description_free (style->font_desc);
1047 style->font_desc = pango_font_description_copy (src->font_desc);
1049 style->font_desc = NULL;
1051 style->xthickness = src->xthickness;
1052 style->ythickness = src->ythickness;
1054 if (style->rc_style)
1055 g_object_unref (style->rc_style);
1056 style->rc_style = src->rc_style;
1058 g_object_ref (src->rc_style);
1060 g_slist_foreach (style->icon_factories, (GFunc) g_object_unref, NULL);
1061 g_slist_free (style->icon_factories);
1062 style->icon_factories = g_slist_copy (src->icon_factories);
1063 g_slist_foreach (style->icon_factories, (GFunc) g_object_ref, NULL);
1065 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_unref, NULL);
1066 g_slist_free (priv->color_hashes);
1067 priv->color_hashes = g_slist_copy (src_priv->color_hashes);
1068 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_ref, NULL);
1070 /* don't copy, just clear cache */
1071 clear_property_cache (style);
1075 gtk_style_real_init_from_rc (GtkStyle *style,
1076 GtkRcStyle *rc_style)
1078 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
1081 /* cache _should_ be still empty */
1082 clear_property_cache (style);
1084 if (rc_style->font_desc)
1085 pango_font_description_merge (style->font_desc, rc_style->font_desc, TRUE);
1087 for (i = 0; i < 5; i++)
1089 if (rc_style->color_flags[i] & GTK_RC_FG)
1090 style->fg[i] = rc_style->fg[i];
1091 if (rc_style->color_flags[i] & GTK_RC_BG)
1092 style->bg[i] = rc_style->bg[i];
1093 if (rc_style->color_flags[i] & GTK_RC_TEXT)
1094 style->text[i] = rc_style->text[i];
1095 if (rc_style->color_flags[i] & GTK_RC_BASE)
1096 style->base[i] = rc_style->base[i];
1099 if (rc_style->xthickness >= 0)
1100 style->xthickness = rc_style->xthickness;
1101 if (rc_style->ythickness >= 0)
1102 style->ythickness = rc_style->ythickness;
1104 style->icon_factories = g_slist_copy (rc_style->icon_factories);
1105 g_slist_foreach (style->icon_factories, (GFunc) g_object_ref, NULL);
1107 priv->color_hashes = g_slist_copy (_gtk_rc_style_get_color_hashes (rc_style));
1108 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_ref, NULL);
1112 style_property_values_cmp (gconstpointer bsearch_node1,
1113 gconstpointer bsearch_node2)
1115 const PropertyValue *val1 = bsearch_node1;
1116 const PropertyValue *val2 = bsearch_node2;
1118 if (val1->widget_type == val2->widget_type)
1119 return val1->pspec < val2->pspec ? -1 : val1->pspec == val2->pspec ? 0 : 1;
1121 return val1->widget_type < val2->widget_type ? -1 : 1;
1125 * gtk_style_get_style_property:
1126 * @style: a #GtkStyle
1127 * @widget_type: the #GType of a descendant of #GtkWidget
1128 * @property_name: the name of the style property to get
1129 * @value: a #GValue where the value of the property being
1130 * queried will be stored
1132 * Queries the value of a style property corresponding to a
1133 * widget class is in the given style.
1138 gtk_style_get_style_property (GtkStyle *style,
1140 const gchar *property_name,
1143 GtkWidgetClass *klass;
1145 GtkRcPropertyParser parser;
1146 const GValue *peek_value;
1148 klass = g_type_class_ref (widget_type);
1149 pspec = gtk_widget_class_find_style_property (klass, property_name);
1150 g_type_class_unref (klass);
1154 g_warning ("%s: widget class `%s' has no property named `%s'",
1156 g_type_name (widget_type),
1161 parser = g_param_spec_get_qdata (pspec,
1162 g_quark_from_static_string ("gtk-rc-property-parser"));
1164 peek_value = _gtk_style_peek_property_value (style, widget_type, pspec, parser);
1166 if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec))
1167 g_value_copy (peek_value, value);
1168 else if (g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
1169 g_value_transform (peek_value, value);
1171 g_warning ("can't retrieve style property `%s' of type `%s' as value of type `%s'",
1173 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1174 G_VALUE_TYPE_NAME (value));
1178 * gtk_style_get_valist:
1179 * @style: a #GtkStyle
1180 * @widget_type: the #GType of a descendant of #GtkWidget
1181 * @first_property_name: the name of the first style property to get
1182 * @var_args: a <type>va_list</type> of pairs of property names and
1183 * locations to return the property values, starting with the
1184 * location for @first_property_name.
1186 * Non-vararg variant of gtk_style_get().
1187 * Used primarily by language bindings.
1192 gtk_style_get_valist (GtkStyle *style,
1194 const gchar *first_property_name,
1197 const char *property_name;
1198 GtkWidgetClass *klass;
1200 g_return_if_fail (GTK_IS_STYLE (style));
1202 klass = g_type_class_ref (widget_type);
1204 property_name = first_property_name;
1205 while (property_name)
1208 GtkRcPropertyParser parser;
1209 const GValue *peek_value;
1212 pspec = gtk_widget_class_find_style_property (klass, property_name);
1216 g_warning ("%s: widget class `%s' has no property named `%s'",
1218 g_type_name (widget_type),
1223 parser = g_param_spec_get_qdata (pspec,
1224 g_quark_from_static_string ("gtk-rc-property-parser"));
1226 peek_value = _gtk_style_peek_property_value (style, widget_type, pspec, parser);
1227 G_VALUE_LCOPY (peek_value, var_args, 0, &error);
1230 g_warning ("%s: %s", G_STRLOC, error);
1235 property_name = va_arg (var_args, gchar*);
1238 g_type_class_unref (klass);
1243 * @style: a #GtkStyle
1244 * @widget_type: the #GType of a descendant of #GtkWidget
1245 * @first_property_name: the name of the first style property to get
1246 * @Varargs: pairs of property names and locations to
1247 * return the property values, starting with the location for
1248 * @first_property_name, terminated by %NULL.
1250 * Gets the values of a multiple style properties for @widget_type
1256 gtk_style_get (GtkStyle *style,
1258 const gchar *first_property_name,
1263 va_start (var_args, first_property_name);
1264 gtk_style_get_valist (style, widget_type, first_property_name, var_args);
1269 _gtk_style_peek_property_value (GtkStyle *style,
1272 GtkRcPropertyParser parser)
1274 PropertyValue *pcache, key = { 0, NULL, { 0, } };
1275 const GtkRcProperty *rcprop = NULL;
1278 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1279 g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL);
1280 g_return_val_if_fail (g_type_is_a (pspec->owner_type, GTK_TYPE_WIDGET), NULL);
1281 g_return_val_if_fail (g_type_is_a (widget_type, pspec->owner_type), NULL);
1283 key.widget_type = widget_type;
1286 /* need value cache array */
1287 if (!style->property_cache)
1288 style->property_cache = g_array_new (FALSE, FALSE, sizeof (PropertyValue));
1291 pcache = bsearch (&key,
1292 style->property_cache->data, style->property_cache->len,
1293 sizeof (PropertyValue), style_property_values_cmp);
1295 return &pcache->value;
1299 while (i < style->property_cache->len &&
1300 style_property_values_cmp (&key, &g_array_index (style->property_cache, PropertyValue, i)) >= 0)
1303 g_array_insert_val (style->property_cache, i, key);
1304 pcache = &g_array_index (style->property_cache, PropertyValue, i);
1306 /* cache miss, initialize value type, then set contents */
1307 g_param_spec_ref (pcache->pspec);
1308 g_value_init (&pcache->value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1310 /* value provided by rc style? */
1311 if (style->rc_style)
1313 GQuark prop_quark = g_quark_from_string (pspec->name);
1317 rcprop = _gtk_rc_style_lookup_rc_property (style->rc_style,
1318 g_type_qname (widget_type),
1322 widget_type = g_type_parent (widget_type);
1324 while (g_type_is_a (widget_type, pspec->owner_type));
1327 /* when supplied by rc style, we need to convert */
1328 if (rcprop && !_gtk_settings_parse_convert (parser, &rcprop->value,
1329 pspec, &pcache->value))
1331 gchar *contents = g_strdup_value_contents (&rcprop->value);
1333 g_message ("%s: failed to retrieve property `%s::%s' of type `%s' from rc file value \"%s\" of type `%s'",
1334 rcprop->origin ? rcprop->origin : "(for origin information, set GTK_DEBUG)",
1335 g_type_name (pspec->owner_type), pspec->name,
1336 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1338 G_VALUE_TYPE_NAME (&rcprop->value));
1340 rcprop = NULL; /* needs default */
1343 /* not supplied by rc style (or conversion failed), revert to default */
1345 g_param_value_set_default (pspec, &pcache->value);
1347 return &pcache->value;
1350 static cairo_pattern_t *
1351 load_background (GdkVisual *visual,
1353 const gchar *filename)
1355 if (filename == NULL)
1357 return cairo_pattern_create_rgb (bg_color->red / 65535.0,
1358 bg_color->green / 65535.0,
1359 bg_color->blue / 65535.0);
1361 if (strcmp (filename, "<parent>") == 0)
1366 cairo_surface_t *surface;
1367 cairo_pattern_t *pattern;
1369 GdkScreen *screen = gdk_visual_get_screen (visual);
1371 pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
1375 surface = gdk_window_create_similar_surface (gdk_screen_get_root_window (screen),
1376 CAIRO_CONTENT_COLOR,
1377 gdk_pixbuf_get_width (pixbuf),
1378 gdk_pixbuf_get_height (pixbuf));
1380 cr = cairo_create (surface);
1382 gdk_cairo_set_source_color (cr, bg_color);
1385 gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
1389 g_object_unref (pixbuf);
1391 pattern = cairo_pattern_create_for_surface (surface);
1393 cairo_surface_destroy (surface);
1400 gtk_style_real_realize (GtkStyle *style)
1404 for (i = 0; i < 5; i++)
1406 _gtk_style_shade (&style->bg[i], &style->light[i], LIGHTNESS_MULT);
1407 _gtk_style_shade (&style->bg[i], &style->dark[i], DARKNESS_MULT);
1409 style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
1410 style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
1411 style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
1413 style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
1414 style->text_aa[i].green = (style->text[i].green + style->base[i].green) / 2;
1415 style->text_aa[i].blue = (style->text[i].blue + style->base[i].blue) / 2;
1418 style->black.red = 0x0000;
1419 style->black.green = 0x0000;
1420 style->black.blue = 0x0000;
1422 style->white.red = 0xffff;
1423 style->white.green = 0xffff;
1424 style->white.blue = 0xffff;
1426 for (i = 0; i < 5; i++)
1428 const char *image_name;
1430 if (style->rc_style)
1431 image_name = style->rc_style->bg_pixmap_name[i];
1435 style->background[i] = load_background (style->visual,
1442 gtk_style_real_unrealize (GtkStyle *style)
1446 for (i = 0; i < 5; i++)
1448 if (style->background[i])
1450 cairo_pattern_destroy (style->background[i]);
1451 style->background[i] = NULL;
1456 style_unrealize_cursors (style);
1460 gtk_style_real_set_background (GtkStyle *style,
1462 GtkStateType state_type)
1464 gdk_window_set_background_pattern (window, style->background[state_type]);
1468 * gtk_style_render_icon:
1469 * @style: a #GtkStyle
1470 * @source: the #GtkIconSource specifying the icon to render
1471 * @direction: a text direction
1473 * @size: (type int): the size to render the icon at. A size of
1474 * (GtkIconSize)-1 means render at the size of the source and
1476 * @widget: (allow-none): the widget
1477 * @detail: (allow-none): a style detail
1479 * Renders the icon specified by @source at the given @size
1480 * according to the given parameters and returns the result in a
1483 * Return value: (transfer full): a newly-created #GdkPixbuf
1484 * containing the rendered icon
1487 gtk_style_render_icon (GtkStyle *style,
1488 const GtkIconSource *source,
1489 GtkTextDirection direction,
1493 const gchar *detail)
1497 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1498 g_return_val_if_fail (GTK_STYLE_GET_CLASS (style)->render_icon != NULL, NULL);
1500 pixbuf = GTK_STYLE_GET_CLASS (style)->render_icon (style, source, direction, state,
1501 size, widget, detail);
1503 g_return_val_if_fail (pixbuf != NULL, NULL);
1508 /* Default functions */
1511 * gtk_style_apply_default_background:
1517 * @area: (allow-none):
1524 gtk_style_apply_default_background (GtkStyle *style,
1527 GtkStateType state_type,
1535 if (style->background[state_type] == NULL)
1537 GdkWindow *parent = gdk_window_get_parent (window);
1538 int x_offset, y_offset;
1542 gdk_window_get_position (window, &x_offset, &y_offset);
1543 cairo_translate (cr, -x_offset, -y_offset);
1544 gtk_style_apply_default_background (style, cr,
1546 x + x_offset, y + y_offset,
1551 gdk_cairo_set_source_color (cr, &style->bg[state_type]);
1554 cairo_set_source (cr, style->background[state_type]);
1556 cairo_rectangle (cr, x, y, width, height);
1564 scale_or_ref (GdkPixbuf *src,
1568 if (width == gdk_pixbuf_get_width (src) &&
1569 height == gdk_pixbuf_get_height (src))
1571 return g_object_ref (src);
1575 return gdk_pixbuf_scale_simple (src,
1577 GDK_INTERP_BILINEAR);
1582 lookup_icon_size (GtkStyle *style,
1589 GtkSettings *settings;
1591 if (widget && gtk_widget_has_screen (widget))
1593 screen = gtk_widget_get_screen (widget);
1594 settings = gtk_settings_get_for_screen (screen);
1596 else if (style && style->visual)
1598 screen = gdk_visual_get_screen (style->visual);
1599 settings = gtk_settings_get_for_screen (screen);
1603 settings = gtk_settings_get_default ();
1604 GTK_NOTE (MULTIHEAD,
1605 g_warning ("Using the default screen for gtk_default_render_icon()"));
1608 return gtk_icon_size_lookup_for_settings (settings, size, width, height);
1612 gtk_default_render_icon (GtkStyle *style,
1613 const GtkIconSource *source,
1614 GtkTextDirection direction,
1618 const gchar *detail)
1624 GdkPixbuf *base_pixbuf;
1626 /* Oddly, style can be NULL in this function, because
1627 * GtkIconSet can be used without a style and if so
1628 * it uses this function.
1631 base_pixbuf = gtk_icon_source_get_pixbuf (source);
1633 g_return_val_if_fail (base_pixbuf != NULL, NULL);
1635 if (size != (GtkIconSize) -1 && !lookup_icon_size(style, widget, size, &width, &height))
1637 g_warning (G_STRLOC ": invalid icon size '%d'", size);
1641 /* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
1644 if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source))
1645 scaled = scale_or_ref (base_pixbuf, width, height);
1647 scaled = g_object_ref (base_pixbuf);
1649 /* If the state was wildcarded, then generate a state. */
1650 if (gtk_icon_source_get_state_wildcarded (source))
1652 if (state == GTK_STATE_INSENSITIVE)
1654 stated = gdk_pixbuf_copy (scaled);
1656 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
1659 g_object_unref (scaled);
1661 else if (state == GTK_STATE_PRELIGHT)
1663 stated = gdk_pixbuf_copy (scaled);
1665 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
1668 g_object_unref (scaled);
1682 _cairo_draw_line (cairo_t *cr,
1691 gdk_cairo_set_source_color (cr, color);
1692 cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
1694 cairo_move_to (cr, x1 + 0.5, y1 + 0.5);
1695 cairo_line_to (cr, x2 + 0.5, y2 + 0.5);
1702 _cairo_draw_rectangle (cairo_t *cr,
1710 gdk_cairo_set_source_color (cr, color);
1714 cairo_rectangle (cr, x, y, width, height);
1719 cairo_rectangle (cr, x + 0.5, y + 0.5, width, height);
1725 _cairo_draw_point (cairo_t *cr,
1730 gdk_cairo_set_source_color (cr, color);
1731 cairo_rectangle (cr, x, y, 1, 1);
1736 transform_detail_string (const gchar *detail,
1737 GtkStyleContext *context)
1742 if (strcmp (detail, "arrow") == 0)
1743 gtk_style_context_add_class (context, "arrow");
1744 else if (strcmp (detail, "button") == 0)
1745 gtk_style_context_add_class (context, "button");
1746 else if (strcmp (detail, "buttondefault") == 0)
1748 gtk_style_context_add_class (context, "button");
1749 gtk_style_context_add_class (context, "default");
1751 else if (strcmp (detail, "calendar") == 0)
1752 gtk_style_context_add_class (context, "calendar");
1753 else if (strcmp (detail, "cellcheck") == 0)
1755 gtk_style_context_add_class (context, "cell");
1756 gtk_style_context_add_class (context, "check");
1758 else if (strcmp (detail, "cellradio") == 0)
1760 gtk_style_context_add_class (context, "cell");
1761 gtk_style_context_add_class (context, "radio");
1763 else if (strcmp (detail, "checkbutton") == 0)
1764 gtk_style_context_add_class (context, "check");
1765 else if (strcmp (detail, "check") == 0)
1767 gtk_style_context_add_class (context, "check");
1768 gtk_style_context_add_class (context, "menu");
1770 else if (strcmp (detail, "option") == 0)
1772 gtk_style_context_add_class (context, "radio");
1773 gtk_style_context_add_class (context, "menu");
1775 else if (strcmp (detail, "entry") == 0 ||
1776 strcmp (detail, "entry_bg") == 0)
1777 gtk_style_context_add_class (context, "entry");
1778 else if (strcmp (detail, "expander") == 0)
1779 gtk_style_context_add_class (context, "expander");
1780 else if (strcmp (detail, "tooltip") == 0)
1781 gtk_style_context_add_class (context, "tooltip");
1782 else if (strcmp (detail, "frame") == 0)
1783 gtk_style_context_add_class (context, "frame");
1784 else if (strcmp (detail, "scrolled_window") == 0)
1785 gtk_style_context_add_class (context, "scrolled-window");
1786 else if (strcmp (detail, "viewport") == 0 ||
1787 strcmp (detail, "viewportbin") == 0)
1788 gtk_style_context_add_class (context, "viewport");
1789 else if (strcmp (detail, "trough") == 0)
1791 gtk_style_context_add_class (context, "scrollbar");
1792 gtk_style_context_add_class (context, "trough");
1794 else if (strcmp (detail, "spinbutton") == 0)
1795 gtk_style_context_add_class (context, "spinbutton");
1796 else if (strcmp (detail, "spinbutton_up") == 0)
1798 gtk_style_context_add_class (context, "spinbutton");
1799 gtk_style_context_add_class (context, "button");
1800 gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
1802 else if (strcmp (detail, "spinbutton_down") == 0)
1804 gtk_style_context_add_class (context, "spinbutton");
1805 gtk_style_context_add_class (context, "button");
1806 gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
1808 else if (g_str_has_prefix (detail, "cell_"))
1810 GtkRegionFlags row, col;
1811 gboolean ruled = FALSE;
1815 tokens = g_strsplit (detail, "_", -1);
1821 if (strcmp (tokens[i], "even") == 0)
1822 row |= GTK_REGION_EVEN;
1823 else if (strcmp (tokens[i], "odd") == 0)
1824 row |= GTK_REGION_ODD;
1825 else if (strcmp (tokens[i], "start") == 0)
1826 col |= GTK_REGION_FIRST;
1827 else if (strcmp (tokens[i], "end") == 0)
1828 col |= GTK_REGION_LAST;
1829 else if (strcmp (tokens[i], "ruled") == 0)
1831 else if (strcmp (tokens[i], "sorted") == 0)
1832 col |= GTK_REGION_SORTED;
1838 row &= ~(GTK_REGION_EVEN | GTK_REGION_ODD);
1840 gtk_style_context_add_class (context, "cell");
1841 gtk_style_context_add_region (context, "row", row);
1842 gtk_style_context_add_region (context, "column", col);
1844 g_strfreev (tokens);
1849 gtk_default_draw_hline (GtkStyle *style,
1851 GtkStateType state_type,
1853 const gchar *detail,
1858 GtkStyleContext *context;
1859 GtkStylePrivate *priv;
1862 context = gtk_widget_get_style_context (widget);
1865 priv = GTK_STYLE_GET_PRIVATE (style);
1866 context = priv->context;
1869 gtk_style_context_save (context);
1872 transform_detail_string (detail, context);
1876 gtk_render_line (context, cr,
1881 gtk_style_context_restore (context);
1886 gtk_default_draw_vline (GtkStyle *style,
1888 GtkStateType state_type,
1890 const gchar *detail,
1895 GtkStyleContext *context;
1896 GtkStylePrivate *priv;
1899 context = gtk_widget_get_style_context (widget);
1902 priv = GTK_STYLE_GET_PRIVATE (style);
1903 context = priv->context;
1906 gtk_style_context_save (context);
1909 transform_detail_string (detail, context);
1913 gtk_render_line (context, cr,
1917 gtk_style_context_restore (context);
1921 draw_thin_shadow (GtkStyle *style,
1929 GdkColor *gc1, *gc2;
1931 gc1 = &style->light[state];
1932 gc2 = &style->dark[state];
1934 _cairo_draw_line (cr, gc1,
1935 x, y + height - 1, x + width - 1, y + height - 1);
1936 _cairo_draw_line (cr, gc1,
1937 x + width - 1, y, x + width - 1, y + height - 1);
1939 _cairo_draw_line (cr, gc2,
1940 x, y, x + width - 2, y);
1941 _cairo_draw_line (cr, gc2,
1942 x, y, x, y + height - 2);
1946 draw_spinbutton_shadow (GtkStyle *style,
1949 GtkTextDirection direction,
1956 if (direction == GTK_TEXT_DIR_LTR)
1958 _cairo_draw_line (cr, &style->dark[state],
1959 x, y, x + width - 1, y);
1960 _cairo_draw_line (cr, &style->black,
1961 x, y + 1, x + width - 2, y + 1);
1962 _cairo_draw_line (cr, &style->black,
1963 x + width - 2, y + 2, x + width - 2, y + height - 3);
1964 _cairo_draw_line (cr, &style->light[state],
1965 x + width - 1, y + 1, x + width - 1, y + height - 2);
1966 _cairo_draw_line (cr, &style->light[state],
1967 x, y + height - 1, x + width - 1, y + height - 1);
1968 _cairo_draw_line (cr, &style->bg[state],
1969 x, y + height - 2, x + width - 2, y + height - 2);
1970 _cairo_draw_line (cr, &style->black,
1971 x, y + 2, x, y + height - 3);
1975 _cairo_draw_line (cr, &style->dark[state],
1976 x, y, x + width - 1, y);
1977 _cairo_draw_line (cr, &style->dark[state],
1978 x, y + 1, x, y + height - 1);
1979 _cairo_draw_line (cr, &style->black,
1980 x + 1, y + 1, x + width - 1, y + 1);
1981 _cairo_draw_line (cr, &style->black,
1982 x + 1, y + 2, x + 1, y + height - 2);
1983 _cairo_draw_line (cr, &style->black,
1984 x + width - 1, y + 2, x + width - 1, y + height - 3);
1985 _cairo_draw_line (cr, &style->light[state],
1986 x + 1, y + height - 1, x + width - 1, y + height - 1);
1987 _cairo_draw_line (cr, &style->bg[state],
1988 x + 2, y + height - 2, x + width - 1, y + height - 2);
1993 draw_menu_shadow (GtkStyle *style,
2001 if (style->ythickness > 0)
2003 if (style->ythickness > 1)
2005 _cairo_draw_line (cr, &style->dark[state],
2006 x + 1, y + height - 2,
2007 x + width - 2, y + height - 2);
2008 _cairo_draw_line (cr, &style->black,
2009 x, y + height - 1, x + width - 1, y + height - 1);
2013 _cairo_draw_line (cr, &style->dark[state],
2014 x + 1, y + height - 1, x + width - 1, y + height - 1);
2018 if (style->xthickness > 0)
2020 if (style->xthickness > 1)
2022 _cairo_draw_line (cr, &style->dark[state],
2023 x + width - 2, y + 1,
2024 x + width - 2, y + height - 2);
2026 _cairo_draw_line (cr, &style->black,
2027 x + width - 1, y, x + width - 1, y + height - 1);
2031 _cairo_draw_line (cr, &style->dark[state],
2032 x + width - 1, y + 1, x + width - 1, y + height - 1);
2036 /* Light around top and left */
2038 if (style->ythickness > 0)
2039 _cairo_draw_line (cr, &style->black,
2040 x, y, x + width - 2, y);
2041 if (style->xthickness > 0)
2042 _cairo_draw_line (cr, &style->black,
2043 x, y, x, y + height - 2);
2045 if (style->ythickness > 1)
2046 _cairo_draw_line (cr, &style->light[state],
2047 x + 1, y + 1, x + width - 3, y + 1);
2048 if (style->xthickness > 1)
2049 _cairo_draw_line (cr, &style->light[state],
2050 x + 1, y + 1, x + 1, y + height - 3);
2053 static GtkTextDirection
2054 get_direction (GtkWidget *widget)
2056 GtkTextDirection dir;
2059 dir = gtk_widget_get_direction (widget);
2061 dir = GTK_TEXT_DIR_LTR;
2068 gtk_default_draw_shadow (GtkStyle *style,
2070 GtkStateType state_type,
2071 GtkShadowType shadow_type,
2073 const gchar *detail,
2079 GtkStyleContext *context;
2080 GtkStylePrivate *priv;
2083 context = gtk_widget_get_style_context (widget);
2086 priv = GTK_STYLE_GET_PRIVATE (style);
2087 context = priv->context;
2090 gtk_style_context_save (context);
2093 transform_detail_string (detail, context);
2097 gtk_render_frame (context, cr,
2104 gtk_style_context_restore (context);
2108 draw_arrow (cairo_t *cr,
2110 GtkArrowType arrow_type,
2116 gdk_cairo_set_source_color (cr, color);
2119 if (arrow_type == GTK_ARROW_DOWN)
2121 cairo_move_to (cr, x, y);
2122 cairo_line_to (cr, x + width, y);
2123 cairo_line_to (cr, x + width / 2., y + height);
2125 else if (arrow_type == GTK_ARROW_UP)
2127 cairo_move_to (cr, x, y + height);
2128 cairo_line_to (cr, x + width / 2., y);
2129 cairo_line_to (cr, x + width, y + height);
2131 else if (arrow_type == GTK_ARROW_LEFT)
2133 cairo_move_to (cr, x + width, y);
2134 cairo_line_to (cr, x + width, y + height);
2135 cairo_line_to (cr, x, y + height / 2.);
2137 else if (arrow_type == GTK_ARROW_RIGHT)
2139 cairo_move_to (cr, x, y);
2140 cairo_line_to (cr, x + width, y + height / 2.);
2141 cairo_line_to (cr, x, y + height);
2144 cairo_close_path (cr);
2151 calculate_arrow_geometry (GtkArrowType arrow_type,
2163 case GTK_ARROW_DOWN:
2173 if (arrow_type == GTK_ARROW_DOWN)
2175 if (*height % 2 == 1 || h % 2 == 0)
2180 if (*height % 2 == 0 || h % 2 == 0)
2185 case GTK_ARROW_RIGHT:
2186 case GTK_ARROW_LEFT:
2196 if (arrow_type == GTK_ARROW_RIGHT)
2198 if (*width % 2 == 1 || w % 2 == 0)
2203 if (*width % 2 == 0 || w % 2 == 0)
2209 /* should not be reached */
2213 *x += (*width - w) / 2;
2214 *y += (*height - h) / 2;
2220 gtk_default_draw_arrow (GtkStyle *style,
2223 GtkShadowType shadow,
2225 const gchar *detail,
2226 GtkArrowType arrow_type,
2233 GtkStyleContext *context;
2234 GtkStylePrivate *priv;
2235 GtkStateFlags flags = 0;
2236 gdouble angle, size;
2238 if (arrow_type == GTK_ARROW_NONE)
2242 context = gtk_widget_get_style_context (widget);
2245 priv = GTK_STYLE_GET_PRIVATE (style);
2246 context = priv->context;
2249 gtk_style_context_save (context);
2252 transform_detail_string (detail, context);
2260 case GTK_ARROW_RIGHT:
2264 case GTK_ARROW_DOWN:
2268 case GTK_ARROW_LEFT:
2269 angle = 3 * (G_PI / 2);
2273 g_assert_not_reached ();
2278 case GTK_STATE_PRELIGHT:
2279 flags |= GTK_STATE_FLAG_PRELIGHT;
2281 case GTK_STATE_SELECTED:
2282 flags |= GTK_STATE_FLAG_SELECTED;
2284 case GTK_STATE_INSENSITIVE:
2285 flags |= GTK_STATE_FLAG_INSENSITIVE;
2287 case GTK_STATE_ACTIVE:
2288 flags |= GTK_STATE_FLAG_ACTIVE;
2294 gtk_style_context_set_state (context, flags);
2298 gtk_render_arrow (context,
2305 gtk_style_context_restore (context);
2309 gtk_default_draw_diamond (GtkStyle *style,
2311 GtkStateType state_type,
2312 GtkShadowType shadow_type,
2314 const gchar *detail,
2322 GdkColor *outer_nw = NULL;
2323 GdkColor *outer_ne = NULL;
2324 GdkColor *outer_sw = NULL;
2325 GdkColor *outer_se = NULL;
2326 GdkColor *middle_nw = NULL;
2327 GdkColor *middle_ne = NULL;
2328 GdkColor *middle_sw = NULL;
2329 GdkColor *middle_se = NULL;
2330 GdkColor *inner_nw = NULL;
2331 GdkColor *inner_ne = NULL;
2332 GdkColor *inner_sw = NULL;
2333 GdkColor *inner_se = NULL;
2335 half_width = width / 2;
2336 half_height = height / 2;
2338 switch (shadow_type)
2341 inner_sw = inner_se = &style->bg[state_type];
2342 middle_sw = middle_se = &style->light[state_type];
2343 outer_sw = outer_se = &style->light[state_type];
2344 inner_nw = inner_ne = &style->black;
2345 middle_nw = middle_ne = &style->dark[state_type];
2346 outer_nw = outer_ne = &style->dark[state_type];
2349 case GTK_SHADOW_OUT:
2350 inner_sw = inner_se = &style->dark[state_type];
2351 middle_sw = middle_se = &style->dark[state_type];
2352 outer_sw = outer_se = &style->black;
2353 inner_nw = inner_ne = &style->bg[state_type];
2354 middle_nw = middle_ne = &style->light[state_type];
2355 outer_nw = outer_ne = &style->light[state_type];
2358 case GTK_SHADOW_ETCHED_IN:
2359 inner_sw = inner_se = &style->bg[state_type];
2360 middle_sw = middle_se = &style->dark[state_type];
2361 outer_sw = outer_se = &style->light[state_type];
2362 inner_nw = inner_ne = &style->bg[state_type];
2363 middle_nw = middle_ne = &style->light[state_type];
2364 outer_nw = outer_ne = &style->dark[state_type];
2367 case GTK_SHADOW_ETCHED_OUT:
2368 inner_sw = inner_se = &style->bg[state_type];
2369 middle_sw = middle_se = &style->light[state_type];
2370 outer_sw = outer_se = &style->dark[state_type];
2371 inner_nw = inner_ne = &style->bg[state_type];
2372 middle_nw = middle_ne = &style->dark[state_type];
2373 outer_nw = outer_ne = &style->light[state_type];
2383 _cairo_draw_line (cr, inner_sw,
2384 x + 2, y + half_height,
2385 x + half_width, y + height - 2);
2386 _cairo_draw_line (cr, inner_se,
2387 x + half_width, y + height - 2,
2388 x + width - 2, y + half_height);
2389 _cairo_draw_line (cr, middle_sw,
2390 x + 1, y + half_height,
2391 x + half_width, y + height - 1);
2392 _cairo_draw_line (cr, middle_se,
2393 x + half_width, y + height - 1,
2394 x + width - 1, y + half_height);
2395 _cairo_draw_line (cr, outer_sw,
2397 x + half_width, y + height);
2398 _cairo_draw_line (cr, outer_se,
2399 x + half_width, y + height,
2400 x + width, y + half_height);
2402 _cairo_draw_line (cr, inner_nw,
2403 x + 2, y + half_height,
2404 x + half_width, y + 2);
2405 _cairo_draw_line (cr, inner_ne,
2406 x + half_width, y + 2,
2407 x + width - 2, y + half_height);
2408 _cairo_draw_line (cr, middle_nw,
2409 x + 1, y + half_height,
2410 x + half_width, y + 1);
2411 _cairo_draw_line (cr, middle_ne,
2412 x + half_width, y + 1,
2413 x + width - 1, y + half_height);
2414 _cairo_draw_line (cr, outer_nw,
2417 _cairo_draw_line (cr, outer_ne,
2419 x + width, y + half_height);
2424 option_menu_get_props (GtkWidget *widget,
2425 GtkRequisition *indicator_size,
2426 GtkBorder *indicator_spacing)
2428 GtkRequisition *tmp_size = NULL;
2429 GtkBorder *tmp_spacing = NULL;
2433 *indicator_size = *tmp_size;
2434 gtk_requisition_free (tmp_size);
2437 *indicator_size = default_option_indicator_size;
2441 *indicator_spacing = *tmp_spacing;
2442 gtk_border_free (tmp_spacing);
2445 *indicator_spacing = default_option_indicator_spacing;
2449 background_is_solid (GtkStyle *style,
2452 if (style->background[type] == NULL)
2455 return cairo_pattern_get_type (style->background[type]) == CAIRO_PATTERN_TYPE_SOLID;
2459 gtk_default_draw_box (GtkStyle *style,
2461 GtkStateType state_type,
2462 GtkShadowType shadow_type,
2464 const gchar *detail,
2470 GtkStyleContext *context;
2471 GtkStylePrivate *priv;
2472 GtkStateFlags flags = 0;
2475 context = gtk_widget_get_style_context (widget);
2478 priv = GTK_STYLE_GET_PRIVATE (style);
2479 context = priv->context;
2482 gtk_style_context_save (context);
2485 transform_detail_string (detail, context);
2489 case GTK_STATE_ACTIVE:
2490 flags |= GTK_STATE_FLAG_ACTIVE;
2492 case GTK_STATE_PRELIGHT:
2493 flags |= GTK_STATE_FLAG_PRELIGHT;
2495 case GTK_STATE_SELECTED:
2496 flags |= GTK_STATE_FLAG_SELECTED;
2498 case GTK_STATE_INSENSITIVE:
2499 flags |= GTK_STATE_FLAG_INSENSITIVE;
2505 if (shadow_type == GTK_SHADOW_IN)
2506 flags |= GTK_STATE_FLAG_ACTIVE;
2508 gtk_style_context_set_state (context, flags);
2512 gtk_render_background (context, cr, x, y, width, height);
2513 gtk_render_frame (context, cr, x, y, width, height);
2516 gtk_style_context_restore (context);
2520 get_darkened (const GdkColor *color,
2523 GdkColor src = *color;
2524 GdkColor shaded = *color;
2526 while (darken_count)
2528 _gtk_style_shade (&src, &shaded, 0.93);
2533 return gdk_color_copy (&shaded);
2537 gtk_default_draw_flat_box (GtkStyle *style,
2539 GtkStateType state_type,
2540 GtkShadowType shadow_type,
2542 const gchar *detail,
2548 GtkStyleContext *context;
2549 GtkStylePrivate *priv;
2550 GtkStateFlags flags = 0;
2553 context = gtk_widget_get_style_context (widget);
2556 priv = GTK_STYLE_GET_PRIVATE (style);
2557 context = priv->context;
2560 gtk_style_context_save (context);
2563 transform_detail_string (detail, context);
2567 case GTK_STATE_PRELIGHT:
2568 flags |= GTK_STATE_FLAG_PRELIGHT;
2570 case GTK_STATE_SELECTED:
2571 flags |= GTK_STATE_FLAG_SELECTED;
2573 case GTK_STATE_INSENSITIVE:
2574 flags |= GTK_STATE_FLAG_INSENSITIVE;
2580 gtk_style_context_set_state (context, flags);
2584 gtk_render_background (context, cr,
2591 gtk_style_context_restore (context);
2595 gtk_default_draw_check (GtkStyle *style,
2597 GtkStateType state_type,
2598 GtkShadowType shadow_type,
2600 const gchar *detail,
2606 GtkStyleContext *context;
2607 GtkStylePrivate *priv;
2608 GtkStateFlags flags = 0;
2611 context = gtk_widget_get_style_context (widget);
2614 priv = GTK_STYLE_GET_PRIVATE (style);
2615 context = priv->context;
2618 gtk_style_context_save (context);
2621 transform_detail_string (detail, context);
2625 case GTK_STATE_PRELIGHT:
2626 flags |= GTK_STATE_FLAG_PRELIGHT;
2628 case GTK_STATE_SELECTED:
2629 flags |= GTK_STATE_FLAG_SELECTED;
2631 case GTK_STATE_INSENSITIVE:
2632 flags |= GTK_STATE_FLAG_INSENSITIVE;
2638 if (shadow_type == GTK_SHADOW_IN)
2639 flags |= GTK_STATE_FLAG_ACTIVE;
2640 else if (shadow_type == GTK_SHADOW_ETCHED_IN)
2641 flags |= GTK_STATE_FLAG_INCONSISTENT;
2643 gtk_style_context_set_state (context, flags);
2647 gtk_render_check (context,
2652 gtk_style_context_restore (context);
2656 gtk_default_draw_option (GtkStyle *style,
2658 GtkStateType state_type,
2659 GtkShadowType shadow_type,
2661 const gchar *detail,
2667 GtkStyleContext *context;
2668 GtkStylePrivate *priv;
2669 GtkStateFlags flags = 0;
2672 context = gtk_widget_get_style_context (widget);
2675 priv = GTK_STYLE_GET_PRIVATE (style);
2676 context = priv->context;
2679 gtk_style_context_save (context);
2682 transform_detail_string (detail, context);
2686 case GTK_STATE_PRELIGHT:
2687 flags |= GTK_STATE_FLAG_PRELIGHT;
2689 case GTK_STATE_SELECTED:
2690 flags |= GTK_STATE_FLAG_SELECTED;
2692 case GTK_STATE_INSENSITIVE:
2693 flags |= GTK_STATE_FLAG_INSENSITIVE;
2699 if (shadow_type == GTK_SHADOW_IN)
2700 flags |= GTK_STATE_FLAG_ACTIVE;
2701 else if (shadow_type == GTK_SHADOW_ETCHED_IN)
2702 flags |= GTK_STATE_FLAG_INCONSISTENT;
2704 gtk_style_context_set_state (context, flags);
2707 gtk_render_option (context, cr,
2714 gtk_style_context_restore (context);
2718 gtk_default_draw_tab (GtkStyle *style,
2720 GtkStateType state_type,
2721 GtkShadowType shadow_type,
2723 const gchar *detail,
2729 #define ARROW_SPACE 4
2731 GtkRequisition indicator_size;
2732 GtkBorder indicator_spacing;
2735 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
2737 indicator_size.width += (indicator_size.width % 2) - 1;
2738 arrow_height = indicator_size.width / 2 + 1;
2740 x += (width - indicator_size.width) / 2;
2741 y += (height - (2 * arrow_height + ARROW_SPACE)) / 2;
2743 if (state_type == GTK_STATE_INSENSITIVE)
2745 draw_arrow (cr, &style->white,
2746 GTK_ARROW_UP, x + 1, y + 1,
2747 indicator_size.width, arrow_height);
2749 draw_arrow (cr, &style->white,
2750 GTK_ARROW_DOWN, x + 1, y + arrow_height + ARROW_SPACE + 1,
2751 indicator_size.width, arrow_height);
2754 draw_arrow (cr, &style->fg[state_type],
2756 indicator_size.width, arrow_height);
2759 draw_arrow (cr, &style->fg[state_type],
2760 GTK_ARROW_DOWN, x, y + arrow_height + ARROW_SPACE,
2761 indicator_size.width, arrow_height);
2765 gtk_default_draw_shadow_gap (GtkStyle *style,
2767 GtkStateType state_type,
2768 GtkShadowType shadow_type,
2770 const gchar *detail,
2775 GtkPositionType gap_side,
2779 GtkStyleContext *context;
2780 GtkStylePrivate *priv;
2781 GtkStateFlags flags = 0;
2784 context = gtk_widget_get_style_context (widget);
2787 priv = GTK_STYLE_GET_PRIVATE (style);
2788 context = priv->context;
2791 gtk_style_context_save (context);
2794 transform_detail_string (detail, context);
2798 case GTK_STATE_ACTIVE:
2799 flags |= GTK_STATE_ACTIVE;
2801 case GTK_STATE_PRELIGHT:
2802 flags |= GTK_STATE_FLAG_PRELIGHT;
2804 case GTK_STATE_SELECTED:
2805 flags |= GTK_STATE_FLAG_SELECTED;
2807 case GTK_STATE_INSENSITIVE:
2808 flags |= GTK_STATE_FLAG_INSENSITIVE;
2814 gtk_style_context_set_state (context, flags);
2817 gtk_render_frame_gap (context, cr,
2824 (gdouble) gap_x + gap_width);
2827 gtk_style_context_restore (context);
2831 gtk_default_draw_box_gap (GtkStyle *style,
2833 GtkStateType state_type,
2834 GtkShadowType shadow_type,
2836 const gchar *detail,
2841 GtkPositionType gap_side,
2845 GtkStyleContext *context;
2846 GtkStylePrivate *priv;
2847 GtkStateFlags flags = 0;
2850 context = gtk_widget_get_style_context (widget);
2853 priv = GTK_STYLE_GET_PRIVATE (style);
2854 context = priv->context;
2857 gtk_style_context_save (context);
2860 transform_detail_string (detail, context);
2864 case GTK_STATE_ACTIVE:
2865 flags |= GTK_STATE_ACTIVE;
2867 case GTK_STATE_PRELIGHT:
2868 flags |= GTK_STATE_FLAG_PRELIGHT;
2870 case GTK_STATE_SELECTED:
2871 flags |= GTK_STATE_FLAG_SELECTED;
2873 case GTK_STATE_INSENSITIVE:
2874 flags |= GTK_STATE_FLAG_INSENSITIVE;
2880 gtk_style_context_set_state (context, flags);
2883 gtk_render_background (context, cr,
2889 gtk_render_frame_gap (context, cr,
2896 (gdouble) gap_x + gap_width);
2899 gtk_style_context_restore (context);
2903 gtk_default_draw_extension (GtkStyle *style,
2905 GtkStateType state_type,
2906 GtkShadowType shadow_type,
2908 const gchar *detail,
2913 GtkPositionType gap_side)
2915 GtkStyleContext *context;
2916 GtkStylePrivate *priv;
2917 GtkStateFlags flags = 0;
2920 context = gtk_widget_get_style_context (widget);
2923 priv = GTK_STYLE_GET_PRIVATE (style);
2924 context = priv->context;
2927 gtk_style_context_save (context);
2930 transform_detail_string (detail, context);
2934 case GTK_STATE_ACTIVE:
2935 flags |= GTK_STATE_ACTIVE;
2937 case GTK_STATE_PRELIGHT:
2938 flags |= GTK_STATE_FLAG_PRELIGHT;
2940 case GTK_STATE_SELECTED:
2941 flags |= GTK_STATE_FLAG_SELECTED;
2943 case GTK_STATE_INSENSITIVE:
2944 flags |= GTK_STATE_FLAG_INSENSITIVE;
2950 gtk_style_context_set_state (context, flags);
2954 gtk_render_extension (context, cr,
2962 gtk_style_context_restore (context);
2966 gtk_default_draw_focus (GtkStyle *style,
2968 GtkStateType state_type,
2970 const gchar *detail,
2976 GtkStyleContext *context;
2977 GtkStylePrivate *priv;
2980 context = gtk_widget_get_style_context (widget);
2983 priv = GTK_STYLE_GET_PRIVATE (style);
2984 context = priv->context;
2987 gtk_style_context_save (context);
2990 transform_detail_string (detail, context);
2994 gtk_render_focus (context, cr,
3001 gtk_style_context_restore (context);
3005 gtk_default_draw_slider (GtkStyle *style,
3007 GtkStateType state_type,
3008 GtkShadowType shadow_type,
3010 const gchar *detail,
3015 GtkOrientation orientation)
3017 GtkStyleContext *context;
3018 GtkStylePrivate *priv;
3019 GtkStateFlags flags = 0;
3022 context = gtk_widget_get_style_context (widget);
3025 priv = GTK_STYLE_GET_PRIVATE (style);
3026 context = priv->context;
3029 gtk_style_context_save (context);
3032 transform_detail_string (detail, context);
3036 case GTK_STATE_PRELIGHT:
3037 flags |= GTK_STATE_FLAG_PRELIGHT;
3039 case GTK_STATE_SELECTED:
3040 flags |= GTK_STATE_FLAG_SELECTED;
3042 case GTK_STATE_INSENSITIVE:
3043 flags |= GTK_STATE_FLAG_INSENSITIVE;
3049 gtk_style_context_set_state (context, flags);
3053 gtk_render_slider (context, cr, x, y, width, height, orientation);
3056 gtk_style_context_restore (context);
3060 draw_dot (cairo_t *cr,
3067 size = CLAMP (size, 2, 3);
3071 _cairo_draw_point (cr, light, x, y);
3072 _cairo_draw_point (cr, light, x+1, y+1);
3076 _cairo_draw_point (cr, light, x, y);
3077 _cairo_draw_point (cr, light, x+1, y);
3078 _cairo_draw_point (cr, light, x, y+1);
3079 _cairo_draw_point (cr, dark, x+1, y+2);
3080 _cairo_draw_point (cr, dark, x+2, y+1);
3081 _cairo_draw_point (cr, dark, x+2, y+2);
3086 gtk_default_draw_handle (GtkStyle *style,
3088 GtkStateType state_type,
3089 GtkShadowType shadow_type,
3091 const gchar *detail,
3096 GtkOrientation orientation)
3098 GtkStyleContext *context;
3099 GtkStylePrivate *priv;
3100 GtkStateFlags flags = 0;
3103 context = gtk_widget_get_style_context (widget);
3106 priv = GTK_STYLE_GET_PRIVATE (style);
3107 context = priv->context;
3110 gtk_style_context_save (context);
3113 transform_detail_string (detail, context);
3117 case GTK_STATE_PRELIGHT:
3118 flags |= GTK_STATE_FLAG_PRELIGHT;
3120 case GTK_STATE_SELECTED:
3121 flags |= GTK_STATE_FLAG_SELECTED;
3123 case GTK_STATE_INSENSITIVE:
3124 flags |= GTK_STATE_FLAG_INSENSITIVE;
3130 gtk_style_context_set_state (context, flags);
3134 gtk_render_handle (context, cr,
3141 gtk_style_context_restore (context);
3145 gtk_default_draw_expander (GtkStyle *style,
3147 GtkStateType state_type,
3149 const gchar *detail,
3152 GtkExpanderStyle expander_style)
3154 GtkStyleContext *context;
3155 GtkStylePrivate *priv;
3156 GtkStateFlags flags = 0;
3160 context = gtk_widget_get_style_context (widget);
3163 priv = GTK_STYLE_GET_PRIVATE (style);
3164 context = priv->context;
3167 gtk_style_context_save (context);
3170 transform_detail_string (detail, context);
3174 case GTK_STATE_PRELIGHT:
3175 flags |= GTK_STATE_FLAG_PRELIGHT;
3177 case GTK_STATE_SELECTED:
3178 flags |= GTK_STATE_FLAG_SELECTED;
3180 case GTK_STATE_INSENSITIVE:
3181 flags |= GTK_STATE_FLAG_INSENSITIVE;
3188 gtk_widget_style_get (widget, "expander-size", &size, NULL);
3192 if (expander_style == GTK_EXPANDER_EXPANDED)
3193 flags |= GTK_STATE_FLAG_ACTIVE;
3195 gtk_style_context_set_state (context, flags);
3199 gtk_render_expander (context, cr,
3200 (gdouble) x - (size / 2),
3201 (gdouble) y - (size / 2),
3206 gtk_style_context_restore (context);
3210 gtk_default_draw_layout (GtkStyle *style,
3212 GtkStateType state_type,
3215 const gchar *detail,
3218 PangoLayout *layout)
3220 GtkStyleContext *context;
3221 GtkStylePrivate *priv;
3222 GtkStateFlags flags = 0;
3225 context = gtk_widget_get_style_context (widget);
3228 priv = GTK_STYLE_GET_PRIVATE (style);
3229 context = priv->context;
3232 gtk_style_context_save (context);
3235 transform_detail_string (detail, context);
3239 case GTK_STATE_PRELIGHT:
3240 flags |= GTK_STATE_FLAG_PRELIGHT;
3242 case GTK_STATE_SELECTED:
3243 flags |= GTK_STATE_FLAG_SELECTED;
3245 case GTK_STATE_INSENSITIVE:
3246 flags |= GTK_STATE_FLAG_INSENSITIVE;
3252 gtk_style_context_set_state (context, flags);
3256 gtk_render_layout (context, cr,
3262 gtk_style_context_restore (context);
3266 gtk_default_draw_resize_grip (GtkStyle *style,
3268 GtkStateType state_type,
3270 const gchar *detail,
3279 cairo_rectangle (cr, x, y, width, height);
3282 cairo_set_line_width (cr, 1.0);
3287 case GDK_WINDOW_EDGE_NORTH_WEST:
3288 /* make it square */
3291 else if (height < width)
3295 case GDK_WINDOW_EDGE_NORTH:
3299 case GDK_WINDOW_EDGE_NORTH_EAST:
3300 /* make it square, aligning to top right */
3303 else if (height < width)
3305 x += (width - height);
3310 case GDK_WINDOW_EDGE_WEST:
3314 case GDK_WINDOW_EDGE_EAST:
3315 /* aligning to right */
3318 x += (width - height);
3322 case GDK_WINDOW_EDGE_SOUTH_WEST:
3323 /* make it square, aligning to bottom left */
3326 y += (height - width);
3329 else if (height < width)
3333 case GDK_WINDOW_EDGE_SOUTH:
3334 /* align to bottom */
3337 y += (height - width);
3341 case GDK_WINDOW_EDGE_SOUTH_EAST:
3342 /* make it square, aligning to bottom right */
3345 y += (height - width);
3348 else if (height < width)
3350 x += (width - height);
3356 g_assert_not_reached ();
3361 case GDK_WINDOW_EDGE_WEST:
3362 case GDK_WINDOW_EDGE_EAST:
3368 while (xi < x + width)
3370 _cairo_draw_line (cr,
3371 &style->light[state_type],
3376 _cairo_draw_line (cr,
3377 &style->dark[state_type],
3385 case GDK_WINDOW_EDGE_NORTH:
3386 case GDK_WINDOW_EDGE_SOUTH:
3392 while (yi < y + height)
3394 _cairo_draw_line (cr,
3395 &style->light[state_type],
3400 _cairo_draw_line (cr,
3401 &style->dark[state_type],
3409 case GDK_WINDOW_EDGE_NORTH_WEST:
3418 _cairo_draw_line (cr,
3419 &style->dark[state_type],
3426 _cairo_draw_line (cr,
3427 &style->dark[state_type],
3434 _cairo_draw_line (cr,
3435 &style->light[state_type],
3445 case GDK_WINDOW_EDGE_NORTH_EAST:
3452 while (xi < (x + width - 3))
3454 _cairo_draw_line (cr,
3455 &style->light[state_type],
3462 _cairo_draw_line (cr,
3463 &style->dark[state_type],
3470 _cairo_draw_line (cr,
3471 &style->dark[state_type],
3480 case GDK_WINDOW_EDGE_SOUTH_WEST:
3489 _cairo_draw_line (cr,
3490 &style->dark[state_type],
3497 _cairo_draw_line (cr,
3498 &style->dark[state_type],
3505 _cairo_draw_line (cr,
3506 &style->light[state_type],
3516 case GDK_WINDOW_EDGE_SOUTH_EAST:
3523 while (xi < (x + width - 3))
3525 _cairo_draw_line (cr,
3526 &style->light[state_type],
3533 _cairo_draw_line (cr,
3534 &style->dark[state_type],
3541 _cairo_draw_line (cr,
3542 &style->dark[state_type],
3552 g_assert_not_reached ();
3558 gtk_default_draw_spinner (GtkStyle *style,
3560 GtkStateType state_type,
3562 const gchar *detail,
3577 gtk_style_get (style, GTK_TYPE_SPINNER,
3578 "num-steps", &num_steps,
3580 real_step = step % num_steps;
3582 /* set a clip region for the expose event */
3583 cairo_rectangle (cr, x, y, width, height);
3586 cairo_translate (cr, x, y);
3588 /* draw clip region */
3589 cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
3591 color = &style->fg[state_type];
3594 radius = MIN (width / 2, height / 2);
3595 half = num_steps / 2;
3597 for (i = 0; i < num_steps; i++)
3599 gint inset = 0.7 * radius;
3601 /* transparency is a function of time and intial value */
3602 gdouble t = (gdouble) ((i + num_steps - real_step)
3603 % num_steps) / num_steps;
3607 cairo_set_source_rgba (cr,
3608 color->red / 65535.,
3609 color->green / 65535.,
3610 color->blue / 65535.,
3613 cairo_set_line_width (cr, 2.0);
3615 dx + (radius - inset) * cos (i * G_PI / half),
3616 dy + (radius - inset) * sin (i * G_PI / half));
3618 dx + radius * cos (i * G_PI / half),
3619 dy + radius * sin (i * G_PI / half));
3627 _gtk_style_shade (const GdkColor *a,
3635 red = (gdouble) a->red / 65535.0;
3636 green = (gdouble) a->green / 65535.0;
3637 blue = (gdouble) a->blue / 65535.0;
3639 rgb_to_hls (&red, &green, &blue);
3644 else if (green < 0.0)
3650 else if (blue < 0.0)
3653 hls_to_rgb (&red, &green, &blue);
3655 b->red = red * 65535.0;
3656 b->green = green * 65535.0;
3657 b->blue = blue * 65535.0;
3661 rgb_to_hls (gdouble *r,
3702 l = (max + min) / 2;
3709 s = (max - min) / (max + min);
3711 s = (max - min) / (2 - max - min);
3715 h = (green - blue) / delta;
3716 else if (green == max)
3717 h = 2 + (blue - red) / delta;
3718 else if (blue == max)
3719 h = 4 + (red - green) / delta;
3732 hls_to_rgb (gdouble *h,
3745 if (lightness <= 0.5)
3746 m2 = lightness * (1 + saturation);
3748 m2 = lightness + saturation - lightness * saturation;
3749 m1 = 2 * lightness - m2;
3751 if (saturation == 0)
3766 r = m1 + (m2 - m1) * hue / 60;
3770 r = m1 + (m2 - m1) * (240 - hue) / 60;
3781 g = m1 + (m2 - m1) * hue / 60;
3785 g = m1 + (m2 - m1) * (240 - hue) / 60;
3796 b = m1 + (m2 - m1) * hue / 60;
3800 b = m1 + (m2 - m1) * (240 - hue) / 60;
3813 * @style: a #GtkStyle
3815 * @state_type: a state
3816 * @widget: (allow-none): the widget
3817 * @detail: (allow-none): a style detail
3818 * @x1: the starting x coordinate
3819 * @x2: the ending x coordinate
3820 * @y: the y coordinate
3822 * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @cr
3823 * using the given style and state.
3826 gtk_paint_hline (GtkStyle *style,
3828 GtkStateType state_type,
3830 const gchar *detail,
3835 g_return_if_fail (GTK_IS_STYLE (style));
3836 g_return_if_fail (cr != NULL);
3837 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
3841 GTK_STYLE_GET_CLASS (style)->draw_hline (style, cr, state_type,
3850 * @style: a #GtkStyle
3852 * @state_type: a state
3853 * @widget: (allow-none): the widget
3854 * @detail: (allow-none): a style detail
3855 * @y1_: the starting y coordinate
3856 * @y2_: the ending y coordinate
3857 * @x: the x coordinate
3859 * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @cr
3860 * using the given style and state.
3863 gtk_paint_vline (GtkStyle *style,
3865 GtkStateType state_type,
3867 const gchar *detail,
3872 g_return_if_fail (GTK_IS_STYLE (style));
3873 g_return_if_fail (cr != NULL);
3874 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
3878 GTK_STYLE_GET_CLASS (style)->draw_vline (style, cr, state_type,
3887 * @style: a #GtkStyle
3889 * @state_type: a state
3890 * @shadow_type: type of shadow to draw
3891 * @widget: (allow-none): the widget
3892 * @detail: (allow-none): a style detail
3893 * @x: x origin of the rectangle
3894 * @y: y origin of the rectangle
3895 * @width: width of the rectangle
3896 * @height: width of the rectangle
3898 * Draws a shadow around the given rectangle in @cr
3899 * using the given style and state and shadow type.
3902 gtk_paint_shadow (GtkStyle *style,
3904 GtkStateType state_type,
3905 GtkShadowType shadow_type,
3907 const gchar *detail,
3913 g_return_if_fail (GTK_IS_STYLE (style));
3914 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
3915 g_return_if_fail (cr != NULL);
3916 g_return_if_fail (width >= 0);
3917 g_return_if_fail (height >= 0);
3921 GTK_STYLE_GET_CLASS (style)->draw_shadow (style, cr, state_type, shadow_type,
3923 x, y, width, height);
3930 * @style: a #GtkStyle
3932 * @state_type: a state
3933 * @shadow_type: the type of shadow to draw
3934 * @widget: (allow-none): the widget
3935 * @detail: (allow-none): a style detail
3936 * @arrow_type: the type of arrow to draw
3937 * @fill: %TRUE if the arrow tip should be filled
3938 * @x: x origin of the rectangle to draw the arrow in
3939 * @y: y origin of the rectangle to draw the arrow in
3940 * @width: width of the rectangle to draw the arrow in
3941 * @height: height of the rectangle to draw the arrow in
3943 * Draws an arrow in the given rectangle on @cr using the given
3944 * parameters. @arrow_type determines the direction of the arrow.
3947 gtk_paint_arrow (GtkStyle *style,
3949 GtkStateType state_type,
3950 GtkShadowType shadow_type,
3952 const gchar *detail,
3953 GtkArrowType arrow_type,
3960 g_return_if_fail (GTK_IS_STYLE (style));
3961 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
3962 g_return_if_fail (cr != NULL);
3963 g_return_if_fail (width >= 0);
3964 g_return_if_fail (height >= 0);
3968 GTK_STYLE_GET_CLASS (style)->draw_arrow (style, cr, state_type, shadow_type,
3970 arrow_type, fill, x, y, width, height);
3976 * gtk_paint_diamond:
3977 * @style: a #GtkStyle
3979 * @state_type: a state
3980 * @shadow_type: the type of shadow to draw
3981 * @widget: (allow-none): the widget
3982 * @detail: (allow-none): a style detail
3983 * @x: x origin of the rectangle to draw the diamond in
3984 * @y: y origin of the rectangle to draw the diamond in
3985 * @width: width of the rectangle to draw the diamond in
3986 * @height: height of the rectangle to draw the diamond in
3988 * Draws a diamond in the given rectangle on @window using the given
3992 gtk_paint_diamond (GtkStyle *style,
3994 GtkStateType state_type,
3995 GtkShadowType shadow_type,
3997 const gchar *detail,
4003 g_return_if_fail (GTK_IS_STYLE (style));
4004 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
4005 g_return_if_fail (cr != NULL);
4006 g_return_if_fail (width >= 0);
4007 g_return_if_fail (height >= 0);
4011 GTK_STYLE_GET_CLASS (style)->draw_diamond (style, cr, state_type, shadow_type,
4013 x, y, width, height);
4020 * @style: a #GtkStyle
4022 * @state_type: a state
4023 * @shadow_type: the type of shadow to draw
4024 * @widget: (allow-none): the widget
4025 * @detail: (allow-none): a style detail
4026 * @x: x origin of the box
4027 * @y: y origin of the box
4028 * @width: the width of the box
4029 * @height: the height of the box
4031 * Draws a box on @cr with the given parameters.
4034 gtk_paint_box (GtkStyle *style,
4036 GtkStateType state_type,
4037 GtkShadowType shadow_type,
4039 const gchar *detail,
4045 g_return_if_fail (GTK_IS_STYLE (style));
4046 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
4047 g_return_if_fail (cr != NULL);
4051 GTK_STYLE_GET_CLASS (style)->draw_box (style, cr, state_type, shadow_type,
4053 x, y, width, height);
4059 * gtk_paint_flat_box:
4060 * @style: a #GtkStyle
4062 * @state_type: a state
4063 * @shadow_type: the type of shadow to draw
4064 * @area: (allow-none): clip rectangle, or %NULL if the
4065 * output should not be clipped
4066 * @widget: (allow-none): the widget
4067 * @detail: (allow-none): a style detail
4068 * @x: x origin of the box
4069 * @y: y origin of the box
4070 * @width: the width of the box
4071 * @height: the height of the box
4073 * Draws a flat box on @cr with the given parameters.
4076 gtk_paint_flat_box (GtkStyle *style,
4078 GtkStateType state_type,
4079 GtkShadowType shadow_type,
4081 const gchar *detail,
4087 g_return_if_fail (GTK_IS_STYLE (style));
4088 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
4089 g_return_if_fail (cr != NULL);
4090 g_return_if_fail (width >= 0);
4091 g_return_if_fail (height >= 0);
4095 GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, cr, state_type, shadow_type,
4097 x, y, width, height);
4104 * @style: a #GtkStyle
4106 * @state_type: a state
4107 * @shadow_type: the type of shadow to draw
4108 * @widget: (allow-none): the widget
4109 * @detail: (allow-none): a style detail
4110 * @x: x origin of the rectangle to draw the check in
4111 * @y: y origin of the rectangle to draw the check in
4112 * @width: the width of the rectangle to draw the check in
4113 * @height: the height of the rectangle to draw the check in
4115 * Draws a check button indicator in the given rectangle on @cr with
4116 * the given parameters.
4119 gtk_paint_check (GtkStyle *style,
4121 GtkStateType state_type,
4122 GtkShadowType shadow_type,
4124 const gchar *detail,
4130 g_return_if_fail (GTK_IS_STYLE (style));
4131 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
4132 g_return_if_fail (cr != NULL);
4136 GTK_STYLE_GET_CLASS (style)->draw_check (style, cr, state_type, shadow_type,
4138 x, y, width, height);
4145 * @style: a #GtkStyle
4147 * @state_type: a state
4148 * @shadow_type: the type of shadow to draw
4149 * @widget: (allow-none): the widget
4150 * @detail: (allow-none): a style detail
4151 * @x: x origin of the rectangle to draw the option in
4152 * @y: y origin of the rectangle to draw the option in
4153 * @width: the width of the rectangle to draw the option in
4154 * @height: the height of the rectangle to draw the option in
4156 * Draws a radio button indicator in the given rectangle on @cr with
4157 * the given parameters.
4160 gtk_paint_option (GtkStyle *style,
4162 GtkStateType state_type,
4163 GtkShadowType shadow_type,
4165 const gchar *detail,
4171 g_return_if_fail (GTK_IS_STYLE (style));
4172 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
4173 g_return_if_fail (cr != NULL);
4177 GTK_STYLE_GET_CLASS (style)->draw_option (style, cr, state_type, shadow_type,
4179 x, y, width, height);
4186 * @style: a #GtkStyle
4188 * @state_type: a state
4189 * @shadow_type: the type of shadow to draw
4190 * @widget: (allow-none): the widget
4191 * @detail: (allow-none): a style detail
4192 * @x: x origin of the rectangle to draw the tab in
4193 * @y: y origin of the rectangle to draw the tab in
4194 * @width: the width of the rectangle to draw the tab in
4195 * @height: the height of the rectangle to draw the tab in
4197 * Draws an option menu tab (i.e. the up and down pointing arrows)
4198 * in the given rectangle on @cr using the given parameters.
4201 gtk_paint_tab (GtkStyle *style,
4203 GtkStateType state_type,
4204 GtkShadowType shadow_type,
4206 const gchar *detail,
4212 g_return_if_fail (GTK_IS_STYLE (style));
4213 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
4214 g_return_if_fail (cr != NULL);
4218 GTK_STYLE_GET_CLASS (style)->draw_tab (style, cr, state_type, shadow_type,
4220 x, y, width, height);
4226 * gtk_paint_shadow_gap:
4227 * @style: a #GtkStyle
4229 * @state_type: a state
4230 * @shadow_type: type of shadow to draw
4231 * @widget: (allow-none): the widget
4232 * @detail: (allow-none): a style detail
4233 * @x: x origin of the rectangle
4234 * @y: y origin of the rectangle
4235 * @width: width of the rectangle
4236 * @height: width of the rectangle
4237 * @gap_side: side in which to leave the gap
4238 * @gap_x: starting position of the gap
4239 * @gap_width: width of the gap
4241 * Draws a shadow around the given rectangle in @cr
4242 * using the given style and state and shadow type, leaving a
4246 gtk_paint_shadow_gap (GtkStyle *style,
4248 GtkStateType state_type,
4249 GtkShadowType shadow_type,
4251 const gchar *detail,
4256 GtkPositionType gap_side,
4260 g_return_if_fail (GTK_IS_STYLE (style));
4261 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
4262 g_return_if_fail (cr != NULL);
4263 g_return_if_fail (width >= 0);
4264 g_return_if_fail (height >= 0);
4268 GTK_STYLE_GET_CLASS (style)->draw_shadow_gap (style, cr, state_type, shadow_type,
4270 x, y, width, height, gap_side, gap_x, gap_width);
4276 * gtk_paint_box_gap:
4277 * @style: a #GtkStyle
4279 * @state_type: a state
4280 * @shadow_type: type of shadow to draw
4281 * @widget: (allow-none): the widget
4282 * @detail: (allow-none): a style detail
4283 * @x: x origin of the rectangle
4284 * @y: y origin of the rectangle
4285 * @width: width of the rectangle
4286 * @height: width of the rectangle
4287 * @gap_side: side in which to leave the gap
4288 * @gap_x: starting position of the gap
4289 * @gap_width: width of the gap
4291 * Draws a box in @cr using the given style and state and shadow type,
4292 * leaving a gap in one side.
4295 gtk_paint_box_gap (GtkStyle *style,
4297 GtkStateType state_type,
4298 GtkShadowType shadow_type,
4300 const gchar *detail,
4305 GtkPositionType gap_side,
4309 g_return_if_fail (GTK_IS_STYLE (style));
4310 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
4311 g_return_if_fail (cr != NULL);
4312 g_return_if_fail (width >= 0);
4313 g_return_if_fail (height >= 0);
4317 GTK_STYLE_GET_CLASS (style)->draw_box_gap (style, cr, state_type, shadow_type,
4319 x, y, width, height, gap_side, gap_x, gap_width);
4325 * gtk_paint_extension:
4326 * @style: a #GtkStyle
4328 * @state_type: a state
4329 * @shadow_type: type of shadow to draw
4330 * @widget: (allow-none): the widget
4331 * @detail: (allow-none): a style detail
4332 * @x: x origin of the extension
4333 * @y: y origin of the extension
4334 * @width: width of the extension
4335 * @height: width of the extension
4336 * @gap_side: the side on to which the extension is attached
4338 * Draws an extension, i.e. a notebook tab.
4341 gtk_paint_extension (GtkStyle *style,
4343 GtkStateType state_type,
4344 GtkShadowType shadow_type,
4346 const gchar *detail,
4351 GtkPositionType gap_side)
4353 g_return_if_fail (GTK_IS_STYLE (style));
4354 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
4355 g_return_if_fail (cr != NULL);
4356 g_return_if_fail (width >= 0);
4357 g_return_if_fail (height >= 0);
4361 GTK_STYLE_GET_CLASS (style)->draw_extension (style, cr, state_type, shadow_type,
4363 x, y, width, height, gap_side);
4370 * @style: a #GtkStyle
4372 * @state_type: a state
4373 * @widget: (allow-none): the widget
4374 * @detail: (allow-none): a style detail
4375 * @x: the x origin of the rectangle around which to draw a focus indicator
4376 * @y: the y origin of the rectangle around which to draw a focus indicator
4377 * @width: the width of the rectangle around which to draw a focus indicator
4378 * @height: the height of the rectangle around which to draw a focus indicator
4380 * Draws a focus indicator around the given rectangle on @cr using the
4384 gtk_paint_focus (GtkStyle *style,
4386 GtkStateType state_type,
4388 const gchar *detail,
4394 g_return_if_fail (GTK_IS_STYLE (style));
4395 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
4396 g_return_if_fail (cr != NULL);
4397 g_return_if_fail (width >= 0);
4398 g_return_if_fail (height >= 0);
4402 GTK_STYLE_GET_CLASS (style)->draw_focus (style, cr, state_type,
4404 x, y, width, height);
4411 * @style: a #GtkStyle
4413 * @state_type: a state
4414 * @shadow_type: a shadow
4415 * @widget: (allow-none): the widget
4416 * @detail: (allow-none): a style detail
4417 * @x: the x origin of the rectangle in which to draw a slider
4418 * @y: the y origin of the rectangle in which to draw a slider
4419 * @width: the width of the rectangle in which to draw a slider
4420 * @height: the height of the rectangle in which to draw a slider
4421 * @orientation: the orientation to be used
4423 * Draws a slider in the given rectangle on @cr using the
4424 * given style and orientation.
4427 gtk_paint_slider (GtkStyle *style,
4429 GtkStateType state_type,
4430 GtkShadowType shadow_type,
4432 const gchar *detail,
4437 GtkOrientation orientation)
4439 g_return_if_fail (GTK_IS_STYLE (style));
4440 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
4441 g_return_if_fail (cr != NULL);
4442 g_return_if_fail (width >= 0);
4443 g_return_if_fail (height >= 0);
4447 GTK_STYLE_GET_CLASS (style)->draw_slider (style, cr, state_type, shadow_type,
4449 x, y, width, height, orientation);
4456 * @style: a #GtkStyle
4458 * @state_type: a state
4459 * @shadow_type: type of shadow to draw
4460 * @widget: (allow-none): the widget
4461 * @detail: (allow-none): a style detail
4462 * @x: x origin of the handle
4463 * @y: y origin of the handle
4464 * @width: with of the handle
4465 * @height: height of the handle
4466 * @orientation: the orientation of the handle
4468 * Draws a handle as used in #GtkHandleBox and #GtkPaned.
4471 gtk_paint_handle (GtkStyle *style,
4473 GtkStateType state_type,
4474 GtkShadowType shadow_type,
4476 const gchar *detail,
4481 GtkOrientation orientation)
4483 g_return_if_fail (GTK_IS_STYLE (style));
4484 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
4485 g_return_if_fail (cr != NULL);
4486 g_return_if_fail (width >= 0);
4487 g_return_if_fail (height >= 0);
4491 GTK_STYLE_GET_CLASS (style)->draw_handle (style, cr, state_type, shadow_type,
4493 x, y, width, height, orientation);
4499 * gtk_paint_expander:
4500 * @style: a #GtkStyle
4502 * @state_type: a state
4503 * @widget: (allow-none): the widget
4504 * @detail: (allow-none): a style detail
4505 * @x: the x position to draw the expander at
4506 * @y: the y position to draw the expander at
4507 * @expander_style: the style to draw the expander in; determines
4508 * whether the expander is collapsed, expanded, or in an
4509 * intermediate state.
4511 * Draws an expander as used in #GtkTreeView. @x and @y specify the
4512 * center the expander. The size of the expander is determined by the
4513 * "expander-size" style property of @widget. (If widget is not
4514 * specified or doesn't have an "expander-size" property, an
4515 * unspecified default size will be used, since the caller doesn't
4516 * have sufficient information to position the expander, this is
4517 * likely not useful.) The expander is expander_size pixels tall
4518 * in the collapsed position and expander_size pixels wide in the
4519 * expanded position.
4522 gtk_paint_expander (GtkStyle *style,
4524 GtkStateType state_type,
4526 const gchar *detail,
4529 GtkExpanderStyle expander_style)
4531 g_return_if_fail (GTK_IS_STYLE (style));
4532 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
4533 g_return_if_fail (cr != NULL);
4537 GTK_STYLE_GET_CLASS (style)->draw_expander (style, cr, state_type,
4539 x, y, expander_style);
4546 * @style: a #GtkStyle
4548 * @state_type: a state
4549 * @use_text: whether to use the text or foreground
4550 * graphics context of @style
4551 * @widget: (allow-none): the widget
4552 * @detail: (allow-none): a style detail
4555 * @layout: the layout to draw
4557 * Draws a layout on @cr using the given parameters.
4560 gtk_paint_layout (GtkStyle *style,
4562 GtkStateType state_type,
4565 const gchar *detail,
4568 PangoLayout *layout)
4570 g_return_if_fail (GTK_IS_STYLE (style));
4571 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
4572 g_return_if_fail (cr != NULL);
4576 GTK_STYLE_GET_CLASS (style)->draw_layout (style, cr, state_type, use_text,
4584 * gtk_paint_resize_grip:
4585 * @style: a #GtkStyle
4587 * @state_type: a state
4588 * @widget: (allow-none): the widget
4589 * @detail: (allow-none): a style detail
4590 * @edge: the edge in which to draw the resize grip
4591 * @x: the x origin of the rectangle in which to draw the resize grip
4592 * @y: the y origin of the rectangle in which to draw the resize grip
4593 * @width: the width of the rectangle in which to draw the resize grip
4594 * @height: the height of the rectangle in which to draw the resize grip
4596 * Draws a resize grip in the given rectangle on @cr using the given
4600 gtk_paint_resize_grip (GtkStyle *style,
4602 GtkStateType state_type,
4604 const gchar *detail,
4611 g_return_if_fail (GTK_IS_STYLE (style));
4612 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
4613 g_return_if_fail (cr != NULL);
4617 GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, cr, state_type,
4619 edge, x, y, width, height);
4624 * gtk_paint_spinner:
4625 * @style: a #GtkStyle
4627 * @state_type: a state
4628 * @widget: (allow-none): the widget (may be %NULL)
4629 * @detail: (allow-none): a style detail (may be %NULL)
4630 * @step: the nth step, a value between 0 and #GtkSpinner:num-steps
4631 * @x: the x origin of the rectangle in which to draw the spinner
4632 * @y: the y origin of the rectangle in which to draw the spinner
4633 * @width: the width of the rectangle in which to draw the spinner
4634 * @height: the height of the rectangle in which to draw the spinner
4636 * Draws a spinner on @window using the given parameters.
4639 gtk_paint_spinner (GtkStyle *style,
4641 GtkStateType state_type,
4643 const gchar *detail,
4650 g_return_if_fail (GTK_IS_STYLE (style));
4651 g_return_if_fail (cr != NULL);
4652 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_spinner != NULL);
4656 GTK_STYLE_GET_CLASS (style)->draw_spinner (style, cr, state_type,
4658 step, x, y, width, height);
4666 * Allocates a new #GtkBorder structure and initializes its elements to zero.
4668 * Returns: a new empty #GtkBorder. The newly allocated #GtkBorder should be
4669 * freed with gtk_border_free()
4674 gtk_border_new (void)
4676 return g_slice_new0 (GtkBorder);
4681 * @border_: a #GtkBorder.
4682 * @returns: a copy of @border_.
4684 * Copies a #GtkBorder structure.
4687 gtk_border_copy (const GtkBorder *border)
4689 g_return_val_if_fail (border != NULL, NULL);
4691 return g_slice_dup (GtkBorder, border);
4696 * @border_: a #GtkBorder.
4698 * Frees a #GtkBorder structure.
4701 gtk_border_free (GtkBorder *border)
4703 g_slice_free (GtkBorder, border);
4706 G_DEFINE_BOXED_TYPE (GtkBorder, gtk_border,
4710 typedef struct _CursorInfo CursorInfo;
4720 style_unrealize_cursors (GtkStyle *style)
4724 cursor_info = g_object_get_data (G_OBJECT (style), "gtk-style-cursor-info");
4727 g_free (cursor_info);
4728 g_object_set_data (G_OBJECT (style), I_("gtk-style-cursor-info"), NULL);
4732 static const GdkColor *
4733 get_insertion_cursor_color (GtkWidget *widget,
4734 gboolean is_primary)
4736 CursorInfo *cursor_info;
4738 GdkColor *cursor_color;
4740 style = gtk_widget_get_style (widget);
4742 cursor_info = g_object_get_data (G_OBJECT (style), "gtk-style-cursor-info");
4745 cursor_info = g_new0 (CursorInfo, 1);
4746 g_object_set_data (G_OBJECT (style), I_("gtk-style-cursor-info"), cursor_info);
4747 cursor_info->for_type = G_TYPE_INVALID;
4750 /* We have to keep track of the type because gtk_widget_style_get()
4751 * can return different results when called on the same property and
4752 * same style but for different widgets. :-(. That is,
4753 * GtkEntry::cursor-color = "red" in a style will modify the cursor
4754 * color for entries but not for text view.
4756 if (cursor_info->for_type != G_OBJECT_TYPE (widget))
4758 cursor_info->for_type = G_OBJECT_TYPE (widget);
4760 /* Cursors in text widgets are drawn only in NORMAL state,
4761 * so we can use text[GTK_STATE_NORMAL] as text color here */
4762 gtk_widget_style_get (widget, "cursor-color", &cursor_color, NULL);
4765 cursor_info->primary = *cursor_color;
4766 gdk_color_free (cursor_color);
4770 cursor_info->primary = style->text[GTK_STATE_NORMAL];
4773 gtk_widget_style_get (widget, "secondary-cursor-color", &cursor_color, NULL);
4776 cursor_info->secondary = *cursor_color;
4777 gdk_color_free (cursor_color);
4781 /* text_aa is the average of text and base colors,
4782 * in usual black-on-white case it's grey. */
4783 cursor_info->secondary = style->text_aa[GTK_STATE_NORMAL];
4788 return &cursor_info->primary;
4790 return &cursor_info->secondary;
4794 _gtk_widget_get_cursor_color (GtkWidget *widget,
4797 GdkColor *style_color;
4799 g_return_if_fail (GTK_IS_WIDGET (widget));
4800 g_return_if_fail (color != NULL);
4802 gtk_widget_style_get (widget, "cursor-color", &style_color, NULL);
4806 *color = *style_color;
4807 gdk_color_free (style_color);
4810 *color = gtk_widget_get_style (widget)->text[GTK_STATE_NORMAL];
4814 * gtk_draw_insertion_cursor:
4815 * @widget: a #GtkWidget
4816 * @cr: cairo context to draw to
4817 * @location: location where to draw the cursor (@location->width is ignored)
4818 * @is_primary: if the cursor should be the primary cursor color.
4819 * @direction: whether the cursor is left-to-right or
4820 * right-to-left. Should never be #GTK_TEXT_DIR_NONE
4821 * @draw_arrow: %TRUE to draw a directional arrow on the
4822 * cursor. Should be %FALSE unless the cursor is split.
4824 * Draws a text caret on @cr at @location. This is not a style function
4825 * but merely a convenience function for drawing the standard cursor shape.
4830 gtk_draw_insertion_cursor (GtkWidget *widget,
4832 const GdkRectangle *location,
4833 gboolean is_primary,
4834 GtkTextDirection direction,
4835 gboolean draw_arrow)
4840 gfloat cursor_aspect_ratio;
4843 g_return_if_fail (GTK_IS_WIDGET (widget));
4844 g_return_if_fail (cr != NULL);
4845 g_return_if_fail (location != NULL);
4846 g_return_if_fail (direction != GTK_TEXT_DIR_NONE);
4848 gdk_cairo_set_source_color (cr, get_insertion_cursor_color (widget, is_primary));
4850 /* When changing the shape or size of the cursor here,
4851 * propagate the changes to gtktextview.c:text_window_invalidate_cursors().
4854 gtk_widget_style_get (widget, "cursor-aspect-ratio", &cursor_aspect_ratio, NULL);
4856 stem_width = location->height * cursor_aspect_ratio + 1;
4857 arrow_width = stem_width + 1;
4859 /* put (stem_width % 2) on the proper side of the cursor */
4860 if (direction == GTK_TEXT_DIR_LTR)
4861 offset = stem_width / 2;
4863 offset = stem_width - stem_width / 2;
4865 cairo_rectangle (cr,
4866 location->x - offset, location->y,
4867 stem_width, location->height);
4872 if (direction == GTK_TEXT_DIR_RTL)
4874 x = location->x - offset - 1;
4875 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
4877 cairo_move_to (cr, x, y + 1);
4878 cairo_line_to (cr, x - arrow_width, y + arrow_width);
4879 cairo_line_to (cr, x, y + 2 * arrow_width);
4882 else if (direction == GTK_TEXT_DIR_LTR)
4884 x = location->x + stem_width - offset;
4885 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
4887 cairo_move_to (cr, x, y + 1);
4888 cairo_line_to (cr, x + arrow_width, y + arrow_width);
4889 cairo_line_to (cr, x, y + 2 * arrow_width);