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 {
83 /* --- prototypes --- */
84 static void gtk_style_finalize (GObject *object);
85 static void gtk_style_realize (GtkStyle *style,
87 static void gtk_style_real_realize (GtkStyle *style);
88 static void gtk_style_real_unrealize (GtkStyle *style);
89 static void gtk_style_real_copy (GtkStyle *style,
91 static void gtk_style_real_set_background (GtkStyle *style,
93 GtkStateType state_type);
94 static GtkStyle *gtk_style_real_clone (GtkStyle *style);
95 static void gtk_style_real_init_from_rc (GtkStyle *style,
96 GtkRcStyle *rc_style);
97 static GdkPixbuf *gtk_default_render_icon (GtkStyle *style,
98 const GtkIconSource *source,
99 GtkTextDirection direction,
103 const gchar *detail);
104 static void gtk_default_draw_hline (GtkStyle *style,
106 GtkStateType state_type,
112 static void gtk_default_draw_vline (GtkStyle *style,
114 GtkStateType state_type,
120 static void gtk_default_draw_shadow (GtkStyle *style,
122 GtkStateType state_type,
123 GtkShadowType shadow_type,
130 static void gtk_default_draw_arrow (GtkStyle *style,
132 GtkStateType state_type,
133 GtkShadowType shadow_type,
136 GtkArrowType arrow_type,
142 static void gtk_default_draw_diamond (GtkStyle *style,
144 GtkStateType state_type,
145 GtkShadowType shadow_type,
152 static void gtk_default_draw_box (GtkStyle *style,
154 GtkStateType state_type,
155 GtkShadowType shadow_type,
162 static void gtk_default_draw_flat_box (GtkStyle *style,
164 GtkStateType state_type,
165 GtkShadowType shadow_type,
172 static void gtk_default_draw_check (GtkStyle *style,
174 GtkStateType state_type,
175 GtkShadowType shadow_type,
182 static void gtk_default_draw_option (GtkStyle *style,
184 GtkStateType state_type,
185 GtkShadowType shadow_type,
192 static void gtk_default_draw_tab (GtkStyle *style,
194 GtkStateType state_type,
195 GtkShadowType shadow_type,
202 static void gtk_default_draw_shadow_gap (GtkStyle *style,
204 GtkStateType state_type,
205 GtkShadowType shadow_type,
212 GtkPositionType gap_side,
215 static void gtk_default_draw_box_gap (GtkStyle *style,
217 GtkStateType state_type,
218 GtkShadowType shadow_type,
225 GtkPositionType gap_side,
228 static void gtk_default_draw_extension (GtkStyle *style,
230 GtkStateType state_type,
231 GtkShadowType shadow_type,
238 GtkPositionType gap_side);
239 static void gtk_default_draw_focus (GtkStyle *style,
241 GtkStateType state_type,
248 static void gtk_default_draw_slider (GtkStyle *style,
250 GtkStateType state_type,
251 GtkShadowType shadow_type,
258 GtkOrientation orientation);
259 static void gtk_default_draw_handle (GtkStyle *style,
261 GtkStateType state_type,
262 GtkShadowType shadow_type,
269 GtkOrientation orientation);
270 static void gtk_default_draw_expander (GtkStyle *style,
272 GtkStateType state_type,
277 GtkExpanderStyle expander_style);
278 static void gtk_default_draw_layout (GtkStyle *style,
280 GtkStateType state_type,
286 PangoLayout *layout);
287 static void gtk_default_draw_resize_grip (GtkStyle *style,
289 GtkStateType state_type,
297 static void gtk_default_draw_spinner (GtkStyle *style,
299 GtkStateType state_type,
308 static void rgb_to_hls (gdouble *r,
311 static void hls_to_rgb (gdouble *h,
315 static void style_unrealize_cursors (GtkStyle *style);
318 * Data for default check and radio buttons
321 static const GtkRequisition default_option_indicator_size = { 7, 13 };
322 static const GtkBorder default_option_indicator_spacing = { 7, 5, 2, 2 };
324 #define GTK_GRAY 0xdcdc, 0xdada, 0xd5d5
325 #define GTK_DARK_GRAY 0xc4c4, 0xc2c2, 0xbdbd
326 #define GTK_LIGHT_GRAY 0xeeee, 0xebeb, 0xe7e7
327 #define GTK_WHITE 0xffff, 0xffff, 0xffff
328 #define GTK_BLUE 0x4b4b, 0x6969, 0x8383
329 #define GTK_VERY_DARK_GRAY 0x9c9c, 0x9a9a, 0x9494
330 #define GTK_BLACK 0x0000, 0x0000, 0x0000
331 #define GTK_WEAK_GRAY 0x7530, 0x7530, 0x7530
333 /* --- variables --- */
334 static const GdkColor gtk_default_normal_fg = { 0, GTK_BLACK };
335 static const GdkColor gtk_default_active_fg = { 0, GTK_BLACK };
336 static const GdkColor gtk_default_prelight_fg = { 0, GTK_BLACK };
337 static const GdkColor gtk_default_selected_fg = { 0, GTK_WHITE };
338 static const GdkColor gtk_default_insensitive_fg = { 0, GTK_WEAK_GRAY };
340 static const GdkColor gtk_default_normal_bg = { 0, GTK_GRAY };
341 static const GdkColor gtk_default_active_bg = { 0, GTK_DARK_GRAY };
342 static const GdkColor gtk_default_prelight_bg = { 0, GTK_LIGHT_GRAY };
343 static const GdkColor gtk_default_selected_bg = { 0, GTK_BLUE };
344 static const GdkColor gtk_default_insensitive_bg = { 0, GTK_GRAY };
345 static const GdkColor gtk_default_selected_base = { 0, GTK_BLUE };
346 static const GdkColor gtk_default_active_base = { 0, GTK_VERY_DARK_GRAY };
348 /* --- signals --- */
349 static guint realize_signal = 0;
350 static guint unrealize_signal = 0;
352 G_DEFINE_TYPE (GtkStyle, gtk_style, G_TYPE_OBJECT)
354 /* --- functions --- */
357 * _gtk_style_init_for_settings:
358 * @style: a #GtkStyle
359 * @settings: a #GtkSettings
361 * Initializes the font description in @style according to the default
362 * font name of @settings. This is called for gtk_style_new() with
363 * the settings for the default screen (if any); if we are creating
364 * a style for a particular screen, we then call it again in a
365 * location where we know the correct settings.
366 * The reason for this is that gtk_rc_style_create_style() doesn't
367 * take the screen for an argument.
370 _gtk_style_init_for_settings (GtkStyle *style,
371 GtkSettings *settings)
373 const gchar *font_name = _gtk_rc_context_get_default_font_name (settings);
375 if (style->font_desc)
376 pango_font_description_free (style->font_desc);
378 style->font_desc = pango_font_description_from_string (font_name);
380 if (!pango_font_description_get_family (style->font_desc))
382 g_warning ("Default font does not have a family set");
383 pango_font_description_set_family (style->font_desc, "Sans");
385 if (pango_font_description_get_size (style->font_desc) <= 0)
387 g_warning ("Default font does not have a positive size");
388 pango_font_description_set_size (style->font_desc, 10 * PANGO_SCALE);
393 gtk_style_init (GtkStyle *style)
397 GtkSettings *settings = gtk_settings_get_default ();
400 _gtk_style_init_for_settings (style, settings);
402 style->font_desc = pango_font_description_from_string ("Sans 10");
404 style->attach_count = 0;
406 style->black.red = 0;
407 style->black.green = 0;
408 style->black.blue = 0;
410 style->white.red = 65535;
411 style->white.green = 65535;
412 style->white.blue = 65535;
414 style->fg[GTK_STATE_NORMAL] = gtk_default_normal_fg;
415 style->fg[GTK_STATE_ACTIVE] = gtk_default_active_fg;
416 style->fg[GTK_STATE_PRELIGHT] = gtk_default_prelight_fg;
417 style->fg[GTK_STATE_SELECTED] = gtk_default_selected_fg;
418 style->fg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
420 style->bg[GTK_STATE_NORMAL] = gtk_default_normal_bg;
421 style->bg[GTK_STATE_ACTIVE] = gtk_default_active_bg;
422 style->bg[GTK_STATE_PRELIGHT] = gtk_default_prelight_bg;
423 style->bg[GTK_STATE_SELECTED] = gtk_default_selected_bg;
424 style->bg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_bg;
426 for (i = 0; i < 4; i++)
428 style->text[i] = style->fg[i];
429 style->base[i] = style->white;
432 style->base[GTK_STATE_SELECTED] = gtk_default_selected_base;
433 style->text[GTK_STATE_SELECTED] = style->white;
434 style->base[GTK_STATE_ACTIVE] = gtk_default_active_base;
435 style->text[GTK_STATE_ACTIVE] = style->white;
436 style->base[GTK_STATE_INSENSITIVE] = gtk_default_prelight_bg;
437 style->text[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
439 style->rc_style = NULL;
441 style->xthickness = 2;
442 style->ythickness = 2;
444 style->property_cache = NULL;
448 gtk_style_class_init (GtkStyleClass *klass)
450 GObjectClass *object_class = G_OBJECT_CLASS (klass);
452 object_class->finalize = gtk_style_finalize;
454 klass->clone = gtk_style_real_clone;
455 klass->copy = gtk_style_real_copy;
456 klass->init_from_rc = gtk_style_real_init_from_rc;
457 klass->realize = gtk_style_real_realize;
458 klass->unrealize = gtk_style_real_unrealize;
459 klass->set_background = gtk_style_real_set_background;
460 klass->render_icon = gtk_default_render_icon;
462 klass->draw_hline = gtk_default_draw_hline;
463 klass->draw_vline = gtk_default_draw_vline;
464 klass->draw_shadow = gtk_default_draw_shadow;
465 klass->draw_arrow = gtk_default_draw_arrow;
466 klass->draw_diamond = gtk_default_draw_diamond;
467 klass->draw_box = gtk_default_draw_box;
468 klass->draw_flat_box = gtk_default_draw_flat_box;
469 klass->draw_check = gtk_default_draw_check;
470 klass->draw_option = gtk_default_draw_option;
471 klass->draw_tab = gtk_default_draw_tab;
472 klass->draw_shadow_gap = gtk_default_draw_shadow_gap;
473 klass->draw_box_gap = gtk_default_draw_box_gap;
474 klass->draw_extension = gtk_default_draw_extension;
475 klass->draw_focus = gtk_default_draw_focus;
476 klass->draw_slider = gtk_default_draw_slider;
477 klass->draw_handle = gtk_default_draw_handle;
478 klass->draw_expander = gtk_default_draw_expander;
479 klass->draw_layout = gtk_default_draw_layout;
480 klass->draw_resize_grip = gtk_default_draw_resize_grip;
481 klass->draw_spinner = gtk_default_draw_spinner;
483 g_type_class_add_private (object_class, sizeof (GtkStylePrivate));
487 * @style: the object which received the signal
489 * Emitted when the style has been initialized for a particular
490 * visual. Connecting to this signal is probably seldom
491 * useful since most of the time applications and widgets only
492 * deal with styles that have been already realized.
496 realize_signal = g_signal_new (I_("realize"),
497 G_TYPE_FROM_CLASS (object_class),
499 G_STRUCT_OFFSET (GtkStyleClass, realize),
501 _gtk_marshal_VOID__VOID,
504 * GtkStyle::unrealize:
505 * @style: the object which received the signal
507 * Emitted when the aspects of the style specific to a particular visual
508 * is being cleaned up. A connection to this signal can be useful
509 * if a widget wants to cache objects as object data on #GtkStyle.
510 * This signal provides a convenient place to free such cached objects.
514 unrealize_signal = g_signal_new (I_("unrealize"),
515 G_TYPE_FROM_CLASS (object_class),
517 G_STRUCT_OFFSET (GtkStyleClass, unrealize),
519 _gtk_marshal_VOID__VOID,
524 clear_property_cache (GtkStyle *style)
526 if (style->property_cache)
530 for (i = 0; i < style->property_cache->len; i++)
532 PropertyValue *node = &g_array_index (style->property_cache, PropertyValue, i);
534 g_param_spec_unref (node->pspec);
535 g_value_unset (&node->value);
537 g_array_free (style->property_cache, TRUE);
538 style->property_cache = NULL;
543 gtk_style_finalize (GObject *object)
545 GtkStyle *style = GTK_STYLE (object);
546 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
548 g_return_if_fail (style->attach_count == 0);
550 clear_property_cache (style);
552 /* All the styles in the list have the same
553 * style->styles pointer. If we delete the
554 * *first* style from the list, we need to update
555 * the style->styles pointers from all the styles.
556 * Otherwise we simply remove the node from
561 if (style->styles->data != style)
562 style->styles = g_slist_remove (style->styles, style);
565 GSList *tmp_list = style->styles->next;
569 GTK_STYLE (tmp_list->data)->styles = style->styles->next;
570 tmp_list = tmp_list->next;
572 g_slist_free_1 (style->styles);
576 g_slist_foreach (style->icon_factories, (GFunc) g_object_unref, NULL);
577 g_slist_free (style->icon_factories);
579 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_unref, NULL);
580 g_slist_free (priv->color_hashes);
582 pango_font_description_free (style->font_desc);
584 if (style->private_font_desc)
585 pango_font_description_free (style->private_font_desc);
588 g_object_unref (style->rc_style);
590 G_OBJECT_CLASS (gtk_style_parent_class)->finalize (object);
596 * @style: a #GtkStyle
598 * Creates a copy of the passed in #GtkStyle object.
600 * Returns: (transfer full): a copy of @style
603 gtk_style_copy (GtkStyle *style)
607 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
609 new_style = GTK_STYLE_GET_CLASS (style)->clone (style);
610 GTK_STYLE_GET_CLASS (style)->copy (new_style, style);
616 gtk_style_duplicate (GtkStyle *style)
620 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
622 new_style = gtk_style_copy (style);
624 /* All the styles in the list have the same
625 * style->styles pointer. When we insert a new
626 * style, we append it to the list to avoid having
627 * to update the existing ones.
629 style->styles = g_slist_append (style->styles, new_style);
630 new_style->styles = style->styles;
637 * @returns: a new #GtkStyle.
639 * Creates a new #GtkStyle.
646 style = g_object_new (GTK_TYPE_STYLE, NULL);
653 * @style: a #GtkStyle.
654 * @window: a #GdkWindow.
656 * Attaches a style to a window; this process allocates the
657 * colors and creates the GC's for the style - it specializes
658 * it to a particular visual. The process may involve the creation
659 * of a new style if the style has already been attached to a
660 * window with a different style and visual.
662 * Since this function may return a new object, you have to use it
663 * in the following way:
664 * <literal>style = gtk_style_attach (style, window)</literal>
666 * Returns: Either @style, or a newly-created #GtkStyle.
667 * If the style is newly created, the style parameter
668 * will be unref'ed, and the new style will have
669 * a reference count belonging to the caller.
672 gtk_style_attach (GtkStyle *style,
676 GtkStyle *new_style = NULL;
679 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
680 g_return_val_if_fail (window != NULL, NULL);
682 visual = gdk_window_get_visual (window);
685 style->styles = g_slist_append (NULL, style);
687 styles = style->styles;
690 new_style = styles->data;
692 if (new_style->visual == visual)
696 styles = styles->next;
701 styles = style->styles;
705 new_style = styles->data;
707 if (new_style->attach_count == 0)
709 gtk_style_realize (new_style, visual);
714 styles = styles->next;
720 new_style = gtk_style_duplicate (style);
721 gtk_style_realize (new_style, visual);
724 /* A style gets a refcount from being attached */
725 if (new_style->attach_count == 0)
726 g_object_ref (new_style);
728 /* Another refcount belongs to the parent */
729 if (style != new_style)
731 g_object_unref (style);
732 g_object_ref (new_style);
735 new_style->attach_count++;
742 * @style: a #GtkStyle
744 * Detaches a style from a window. If the style is not attached
745 * to any windows anymore, it is unrealized. See gtk_style_attach().
749 gtk_style_detach (GtkStyle *style)
751 g_return_if_fail (GTK_IS_STYLE (style));
752 g_return_if_fail (style->attach_count > 0);
754 style->attach_count -= 1;
755 if (style->attach_count == 0)
757 g_signal_emit (style, unrealize_signal, 0);
759 g_object_unref (style->visual);
760 style->visual = NULL;
762 if (style->private_font_desc)
764 pango_font_description_free (style->private_font_desc);
765 style->private_font_desc = NULL;
768 g_object_unref (style);
773 gtk_style_realize (GtkStyle *style,
776 style->visual = g_object_ref (visual);
778 g_signal_emit (style, realize_signal, 0);
782 * gtk_style_lookup_icon_set:
783 * @style: a #GtkStyle
784 * @stock_id: an icon name
786 * Looks up @stock_id in the icon factories associated with @style
787 * and the default icon factory, returning an icon set if found,
790 * Return value: icon set of @stock_id
793 gtk_style_lookup_icon_set (GtkStyle *style,
794 const char *stock_id)
798 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
799 g_return_val_if_fail (stock_id != NULL, NULL);
801 iter = style->icon_factories;
804 GtkIconSet *icon_set = gtk_icon_factory_lookup (GTK_ICON_FACTORY (iter->data),
809 iter = g_slist_next (iter);
812 return gtk_icon_factory_lookup_default (stock_id);
816 * gtk_style_lookup_color:
817 * @style: a #GtkStyle
818 * @color_name: the name of the logical color to look up
819 * @color: the #GdkColor to fill in
821 * Looks up @color_name in the style's logical color mappings,
822 * filling in @color and returning %TRUE if found, otherwise
823 * returning %FALSE. Do not cache the found mapping, because
824 * it depends on the #GtkStyle and might change when a theme
827 * Return value: %TRUE if the mapping was found.
832 gtk_style_lookup_color (GtkStyle *style,
833 const char *color_name,
836 GtkStylePrivate *priv;
839 g_return_val_if_fail (GTK_IS_STYLE (style), FALSE);
840 g_return_val_if_fail (color_name != NULL, FALSE);
841 g_return_val_if_fail (color != NULL, FALSE);
843 priv = GTK_STYLE_GET_PRIVATE (style);
845 for (iter = priv->color_hashes; iter != NULL; iter = iter->next)
847 GHashTable *hash = iter->data;
848 GdkColor *mapping = g_hash_table_lookup (hash, color_name);
852 color->red = mapping->red;
853 color->green = mapping->green;
854 color->blue = mapping->blue;
863 * gtk_style_set_background:
864 * @style: a #GtkStyle
865 * @window: a #GdkWindow
866 * @state_type: a state
868 * Sets the background of @window to the background color or pixmap
869 * specified by @style for the given state.
872 gtk_style_set_background (GtkStyle *style,
874 GtkStateType state_type)
876 g_return_if_fail (GTK_IS_STYLE (style));
877 g_return_if_fail (window != NULL);
879 GTK_STYLE_GET_CLASS (style)->set_background (style, window, state_type);
882 /* Default functions */
884 gtk_style_real_clone (GtkStyle *style)
886 return g_object_new (G_OBJECT_TYPE (style), NULL);
890 gtk_style_real_copy (GtkStyle *style,
893 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
894 GtkStylePrivate *src_priv = GTK_STYLE_GET_PRIVATE (src);
897 for (i = 0; i < 5; i++)
899 style->fg[i] = src->fg[i];
900 style->bg[i] = src->bg[i];
901 style->text[i] = src->text[i];
902 style->base[i] = src->base[i];
904 if (style->background[i])
905 cairo_pattern_destroy (style->background[i]),
906 style->background[i] = src->background[i];
907 if (style->background[i])
908 cairo_pattern_reference (style->background[i]);
911 if (style->font_desc)
912 pango_font_description_free (style->font_desc);
914 style->font_desc = pango_font_description_copy (src->font_desc);
916 style->font_desc = NULL;
918 style->xthickness = src->xthickness;
919 style->ythickness = src->ythickness;
922 g_object_unref (style->rc_style);
923 style->rc_style = src->rc_style;
925 g_object_ref (src->rc_style);
927 g_slist_foreach (style->icon_factories, (GFunc) g_object_unref, NULL);
928 g_slist_free (style->icon_factories);
929 style->icon_factories = g_slist_copy (src->icon_factories);
930 g_slist_foreach (style->icon_factories, (GFunc) g_object_ref, NULL);
932 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_unref, NULL);
933 g_slist_free (priv->color_hashes);
934 priv->color_hashes = g_slist_copy (src_priv->color_hashes);
935 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_ref, NULL);
937 /* don't copy, just clear cache */
938 clear_property_cache (style);
942 gtk_style_real_init_from_rc (GtkStyle *style,
943 GtkRcStyle *rc_style)
945 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
948 /* cache _should_ be still empty */
949 clear_property_cache (style);
951 if (rc_style->font_desc)
952 pango_font_description_merge (style->font_desc, rc_style->font_desc, TRUE);
954 for (i = 0; i < 5; i++)
956 if (rc_style->color_flags[i] & GTK_RC_FG)
957 style->fg[i] = rc_style->fg[i];
958 if (rc_style->color_flags[i] & GTK_RC_BG)
959 style->bg[i] = rc_style->bg[i];
960 if (rc_style->color_flags[i] & GTK_RC_TEXT)
961 style->text[i] = rc_style->text[i];
962 if (rc_style->color_flags[i] & GTK_RC_BASE)
963 style->base[i] = rc_style->base[i];
966 if (rc_style->xthickness >= 0)
967 style->xthickness = rc_style->xthickness;
968 if (rc_style->ythickness >= 0)
969 style->ythickness = rc_style->ythickness;
971 style->icon_factories = g_slist_copy (rc_style->icon_factories);
972 g_slist_foreach (style->icon_factories, (GFunc) g_object_ref, NULL);
974 priv->color_hashes = g_slist_copy (_gtk_rc_style_get_color_hashes (rc_style));
975 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_ref, NULL);
979 style_property_values_cmp (gconstpointer bsearch_node1,
980 gconstpointer bsearch_node2)
982 const PropertyValue *val1 = bsearch_node1;
983 const PropertyValue *val2 = bsearch_node2;
985 if (val1->widget_type == val2->widget_type)
986 return val1->pspec < val2->pspec ? -1 : val1->pspec == val2->pspec ? 0 : 1;
988 return val1->widget_type < val2->widget_type ? -1 : 1;
992 * gtk_style_get_style_property:
993 * @style: a #GtkStyle
994 * @widget_type: the #GType of a descendant of #GtkWidget
995 * @property_name: the name of the style property to get
996 * @value: a #GValue where the value of the property being
997 * queried will be stored
999 * Queries the value of a style property corresponding to a
1000 * widget class is in the given style.
1005 gtk_style_get_style_property (GtkStyle *style,
1007 const gchar *property_name,
1010 GtkWidgetClass *klass;
1012 GtkRcPropertyParser parser;
1013 const GValue *peek_value;
1015 klass = g_type_class_ref (widget_type);
1016 pspec = gtk_widget_class_find_style_property (klass, property_name);
1017 g_type_class_unref (klass);
1021 g_warning ("%s: widget class `%s' has no property named `%s'",
1023 g_type_name (widget_type),
1028 parser = g_param_spec_get_qdata (pspec,
1029 g_quark_from_static_string ("gtk-rc-property-parser"));
1031 peek_value = _gtk_style_peek_property_value (style, widget_type, pspec, parser);
1033 if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec))
1034 g_value_copy (peek_value, value);
1035 else if (g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
1036 g_value_transform (peek_value, value);
1038 g_warning ("can't retrieve style property `%s' of type `%s' as value of type `%s'",
1040 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1041 G_VALUE_TYPE_NAME (value));
1045 * gtk_style_get_valist:
1046 * @style: a #GtkStyle
1047 * @widget_type: the #GType of a descendant of #GtkWidget
1048 * @first_property_name: the name of the first style property to get
1049 * @var_args: a <type>va_list</type> of pairs of property names and
1050 * locations to return the property values, starting with the
1051 * location for @first_property_name.
1053 * Non-vararg variant of gtk_style_get().
1054 * Used primarily by language bindings.
1059 gtk_style_get_valist (GtkStyle *style,
1061 const gchar *first_property_name,
1064 const char *property_name;
1065 GtkWidgetClass *klass;
1067 g_return_if_fail (GTK_IS_STYLE (style));
1069 klass = g_type_class_ref (widget_type);
1071 property_name = first_property_name;
1072 while (property_name)
1075 GtkRcPropertyParser parser;
1076 const GValue *peek_value;
1079 pspec = gtk_widget_class_find_style_property (klass, property_name);
1083 g_warning ("%s: widget class `%s' has no property named `%s'",
1085 g_type_name (widget_type),
1090 parser = g_param_spec_get_qdata (pspec,
1091 g_quark_from_static_string ("gtk-rc-property-parser"));
1093 peek_value = _gtk_style_peek_property_value (style, widget_type, pspec, parser);
1094 G_VALUE_LCOPY (peek_value, var_args, 0, &error);
1097 g_warning ("%s: %s", G_STRLOC, error);
1102 property_name = va_arg (var_args, gchar*);
1105 g_type_class_unref (klass);
1110 * @style: a #GtkStyle
1111 * @widget_type: the #GType of a descendant of #GtkWidget
1112 * @first_property_name: the name of the first style property to get
1113 * @Varargs: pairs of property names and locations to
1114 * return the property values, starting with the location for
1115 * @first_property_name, terminated by %NULL.
1117 * Gets the values of a multiple style properties for @widget_type
1123 gtk_style_get (GtkStyle *style,
1125 const gchar *first_property_name,
1130 va_start (var_args, first_property_name);
1131 gtk_style_get_valist (style, widget_type, first_property_name, var_args);
1136 _gtk_style_peek_property_value (GtkStyle *style,
1139 GtkRcPropertyParser parser)
1141 PropertyValue *pcache, key = { 0, NULL, { 0, } };
1142 const GtkRcProperty *rcprop = NULL;
1145 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1146 g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL);
1147 g_return_val_if_fail (g_type_is_a (pspec->owner_type, GTK_TYPE_WIDGET), NULL);
1148 g_return_val_if_fail (g_type_is_a (widget_type, pspec->owner_type), NULL);
1150 key.widget_type = widget_type;
1153 /* need value cache array */
1154 if (!style->property_cache)
1155 style->property_cache = g_array_new (FALSE, FALSE, sizeof (PropertyValue));
1158 pcache = bsearch (&key,
1159 style->property_cache->data, style->property_cache->len,
1160 sizeof (PropertyValue), style_property_values_cmp);
1162 return &pcache->value;
1166 while (i < style->property_cache->len &&
1167 style_property_values_cmp (&key, &g_array_index (style->property_cache, PropertyValue, i)) >= 0)
1170 g_array_insert_val (style->property_cache, i, key);
1171 pcache = &g_array_index (style->property_cache, PropertyValue, i);
1173 /* cache miss, initialize value type, then set contents */
1174 g_param_spec_ref (pcache->pspec);
1175 g_value_init (&pcache->value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1177 /* value provided by rc style? */
1178 if (style->rc_style)
1180 GQuark prop_quark = g_quark_from_string (pspec->name);
1184 rcprop = _gtk_rc_style_lookup_rc_property (style->rc_style,
1185 g_type_qname (widget_type),
1189 widget_type = g_type_parent (widget_type);
1191 while (g_type_is_a (widget_type, pspec->owner_type));
1194 /* when supplied by rc style, we need to convert */
1195 if (rcprop && !_gtk_settings_parse_convert (parser, &rcprop->value,
1196 pspec, &pcache->value))
1198 gchar *contents = g_strdup_value_contents (&rcprop->value);
1200 g_message ("%s: failed to retrieve property `%s::%s' of type `%s' from rc file value \"%s\" of type `%s'",
1201 rcprop->origin ? rcprop->origin : "(for origin information, set GTK_DEBUG)",
1202 g_type_name (pspec->owner_type), pspec->name,
1203 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1205 G_VALUE_TYPE_NAME (&rcprop->value));
1207 rcprop = NULL; /* needs default */
1210 /* not supplied by rc style (or conversion failed), revert to default */
1212 g_param_value_set_default (pspec, &pcache->value);
1214 return &pcache->value;
1217 static cairo_pattern_t *
1218 load_background (GdkVisual *visual,
1220 const gchar *filename)
1222 if (filename == NULL)
1224 return cairo_pattern_create_rgb (bg_color->red / 65535.0,
1225 bg_color->green / 65535.0,
1226 bg_color->blue / 65535.0);
1228 if (strcmp (filename, "<parent>") == 0)
1233 cairo_surface_t *surface;
1234 cairo_pattern_t *pattern;
1236 GdkScreen *screen = gdk_visual_get_screen (visual);
1238 pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
1242 surface = gdk_window_create_similar_surface (gdk_screen_get_root_window (screen),
1243 CAIRO_CONTENT_COLOR,
1244 gdk_pixbuf_get_width (pixbuf),
1245 gdk_pixbuf_get_height (pixbuf));
1247 cr = cairo_create (surface);
1249 gdk_cairo_set_source_color (cr, bg_color);
1252 gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
1256 g_object_unref (pixbuf);
1258 pattern = cairo_pattern_create_for_surface (surface);
1260 cairo_surface_destroy (surface);
1267 gtk_style_real_realize (GtkStyle *style)
1271 for (i = 0; i < 5; i++)
1273 _gtk_style_shade (&style->bg[i], &style->light[i], LIGHTNESS_MULT);
1274 _gtk_style_shade (&style->bg[i], &style->dark[i], DARKNESS_MULT);
1276 style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
1277 style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
1278 style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
1280 style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
1281 style->text_aa[i].green = (style->text[i].green + style->base[i].green) / 2;
1282 style->text_aa[i].blue = (style->text[i].blue + style->base[i].blue) / 2;
1285 style->black.red = 0x0000;
1286 style->black.green = 0x0000;
1287 style->black.blue = 0x0000;
1289 style->white.red = 0xffff;
1290 style->white.green = 0xffff;
1291 style->white.blue = 0xffff;
1293 for (i = 0; i < 5; i++)
1295 const char *image_name;
1297 if (style->rc_style)
1298 image_name = style->rc_style->bg_pixmap_name[i];
1302 style->background[i] = load_background (style->visual,
1309 gtk_style_real_unrealize (GtkStyle *style)
1313 for (i = 0; i < 5; i++)
1315 if (style->background[i])
1317 cairo_pattern_destroy (style->background[i]);
1318 style->background[i] = NULL;
1323 style_unrealize_cursors (style);
1327 gtk_style_real_set_background (GtkStyle *style,
1329 GtkStateType state_type)
1331 gdk_window_set_background_pattern (window, style->background[state_type]);
1335 * gtk_style_render_icon:
1336 * @style: a #GtkStyle
1337 * @source: the #GtkIconSource specifying the icon to render
1338 * @direction: a text direction
1340 * @size: (type int): the size to render the icon at. A size of
1341 * (GtkIconSize)-1 means render at the size of the source and
1343 * @widget: (allow-none): the widget
1344 * @detail: (allow-none): a style detail
1346 * Renders the icon specified by @source at the given @size
1347 * according to the given parameters and returns the result in a
1350 * Return value: (transfer full): a newly-created #GdkPixbuf
1351 * containing the rendered icon
1354 gtk_style_render_icon (GtkStyle *style,
1355 const GtkIconSource *source,
1356 GtkTextDirection direction,
1360 const gchar *detail)
1364 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1365 g_return_val_if_fail (GTK_STYLE_GET_CLASS (style)->render_icon != NULL, NULL);
1367 pixbuf = GTK_STYLE_GET_CLASS (style)->render_icon (style, source, direction, state,
1368 size, widget, detail);
1370 g_return_val_if_fail (pixbuf != NULL, NULL);
1375 /* Default functions */
1378 * gtk_style_apply_default_background:
1384 * @area: (allow-none):
1391 gtk_style_apply_default_background (GtkStyle *style,
1394 GtkStateType state_type,
1402 if (style->background[state_type] == NULL)
1404 GdkWindow *parent = gdk_window_get_parent (window);
1405 int x_offset, y_offset;
1409 gdk_window_get_position (window, &x_offset, &y_offset);
1410 cairo_translate (cr, -x_offset, -y_offset);
1411 gtk_style_apply_default_background (style, cr,
1413 x + x_offset, y + y_offset,
1418 gdk_cairo_set_source_color (cr, &style->bg[state_type]);
1421 cairo_set_source (cr, style->background[state_type]);
1423 cairo_rectangle (cr, x, y, width, height);
1431 scale_or_ref (GdkPixbuf *src,
1435 if (width == gdk_pixbuf_get_width (src) &&
1436 height == gdk_pixbuf_get_height (src))
1438 return g_object_ref (src);
1442 return gdk_pixbuf_scale_simple (src,
1444 GDK_INTERP_BILINEAR);
1449 lookup_icon_size (GtkStyle *style,
1456 GtkSettings *settings;
1458 if (widget && gtk_widget_has_screen (widget))
1460 screen = gtk_widget_get_screen (widget);
1461 settings = gtk_settings_get_for_screen (screen);
1463 else if (style && style->visual)
1465 screen = gdk_visual_get_screen (style->visual);
1466 settings = gtk_settings_get_for_screen (screen);
1470 settings = gtk_settings_get_default ();
1471 GTK_NOTE (MULTIHEAD,
1472 g_warning ("Using the default screen for gtk_default_render_icon()"));
1475 return gtk_icon_size_lookup_for_settings (settings, size, width, height);
1479 gtk_default_render_icon (GtkStyle *style,
1480 const GtkIconSource *source,
1481 GtkTextDirection direction,
1485 const gchar *detail)
1491 GdkPixbuf *base_pixbuf;
1493 /* Oddly, style can be NULL in this function, because
1494 * GtkIconSet can be used without a style and if so
1495 * it uses this function.
1498 base_pixbuf = gtk_icon_source_get_pixbuf (source);
1500 g_return_val_if_fail (base_pixbuf != NULL, NULL);
1502 if (size != (GtkIconSize) -1 && !lookup_icon_size(style, widget, size, &width, &height))
1504 g_warning (G_STRLOC ": invalid icon size '%d'", size);
1508 /* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
1511 if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source))
1512 scaled = scale_or_ref (base_pixbuf, width, height);
1514 scaled = g_object_ref (base_pixbuf);
1516 /* If the state was wildcarded, then generate a state. */
1517 if (gtk_icon_source_get_state_wildcarded (source))
1519 if (state == GTK_STATE_INSENSITIVE)
1521 stated = gdk_pixbuf_copy (scaled);
1523 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
1526 g_object_unref (scaled);
1528 else if (state == GTK_STATE_PRELIGHT)
1530 stated = gdk_pixbuf_copy (scaled);
1532 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
1535 g_object_unref (scaled);
1549 _cairo_draw_line (cairo_t *cr,
1558 gdk_cairo_set_source_color (cr, color);
1559 cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
1561 cairo_move_to (cr, x1 + 0.5, y1 + 0.5);
1562 cairo_line_to (cr, x2 + 0.5, y2 + 0.5);
1569 _cairo_draw_rectangle (cairo_t *cr,
1577 gdk_cairo_set_source_color (cr, color);
1581 cairo_rectangle (cr, x, y, width, height);
1586 cairo_rectangle (cr, x + 0.5, y + 0.5, width, height);
1592 _cairo_draw_point (cairo_t *cr,
1597 gdk_cairo_set_source_color (cr, color);
1598 cairo_rectangle (cr, x, y, 1, 1);
1603 gtk_default_draw_hline (GtkStyle *style,
1605 GtkStateType state_type,
1607 const gchar *detail,
1612 gint thickness_light;
1613 gint thickness_dark;
1616 thickness_light = style->ythickness / 2;
1617 thickness_dark = style->ythickness - thickness_light;
1619 cairo_set_line_width (cr, 1.0);
1621 if (detail && !strcmp (detail, "label"))
1623 if (state_type == GTK_STATE_INSENSITIVE)
1624 _cairo_draw_line (cr, &style->white, x1 + 1, y + 1, x2 + 1, y + 1);
1625 _cairo_draw_line (cr, &style->fg[state_type], x1, y, x2, y);
1629 for (i = 0; i < thickness_dark; i++)
1631 _cairo_draw_line (cr, &style->dark[state_type], x1, y + i, x2 - i - 1, y + i);
1632 _cairo_draw_line (cr, &style->light[state_type], x2 - i, y + i, x2, y + i);
1635 y += thickness_dark;
1636 for (i = 0; i < thickness_light; i++)
1638 _cairo_draw_line (cr, &style->dark[state_type], x1, y + i, x1 + thickness_light - i - 1, y + i);
1639 _cairo_draw_line (cr, &style->light[state_type], x1 + thickness_light - i, y + i, x2, y + i);
1646 gtk_default_draw_vline (GtkStyle *style,
1648 GtkStateType state_type,
1650 const gchar *detail,
1655 gint thickness_light;
1656 gint thickness_dark;
1659 thickness_light = style->xthickness / 2;
1660 thickness_dark = style->xthickness - thickness_light;
1662 cairo_set_line_width (cr, 1.0);
1664 for (i = 0; i < thickness_dark; i++)
1666 _cairo_draw_line (cr, &style->dark[state_type],
1667 x + i, y1, x + i, y2 - i - 1);
1668 _cairo_draw_line (cr, &style->light[state_type],
1669 x + i, y2 - i, x + i, y2);
1672 x += thickness_dark;
1673 for (i = 0; i < thickness_light; i++)
1675 _cairo_draw_line (cr, &style->dark[state_type],
1676 x + i, y1, x + i, y1 + thickness_light - i - 1);
1677 _cairo_draw_line (cr, &style->light[state_type],
1678 x + i, y1 + thickness_light - i, x + i, y2);
1683 draw_thin_shadow (GtkStyle *style,
1691 GdkColor *gc1, *gc2;
1693 gc1 = &style->light[state];
1694 gc2 = &style->dark[state];
1696 _cairo_draw_line (cr, gc1,
1697 x, y + height - 1, x + width - 1, y + height - 1);
1698 _cairo_draw_line (cr, gc1,
1699 x + width - 1, y, x + width - 1, y + height - 1);
1701 _cairo_draw_line (cr, gc2,
1702 x, y, x + width - 2, y);
1703 _cairo_draw_line (cr, gc2,
1704 x, y, x, y + height - 2);
1708 draw_spinbutton_shadow (GtkStyle *style,
1711 GtkTextDirection direction,
1718 if (direction == GTK_TEXT_DIR_LTR)
1720 _cairo_draw_line (cr, &style->dark[state],
1721 x, y, x + width - 1, y);
1722 _cairo_draw_line (cr, &style->black,
1723 x, y + 1, x + width - 2, y + 1);
1724 _cairo_draw_line (cr, &style->black,
1725 x + width - 2, y + 2, x + width - 2, y + height - 3);
1726 _cairo_draw_line (cr, &style->light[state],
1727 x + width - 1, y + 1, x + width - 1, y + height - 2);
1728 _cairo_draw_line (cr, &style->light[state],
1729 x, y + height - 1, x + width - 1, y + height - 1);
1730 _cairo_draw_line (cr, &style->bg[state],
1731 x, y + height - 2, x + width - 2, y + height - 2);
1732 _cairo_draw_line (cr, &style->black,
1733 x, y + 2, x, y + height - 3);
1737 _cairo_draw_line (cr, &style->dark[state],
1738 x, y, x + width - 1, y);
1739 _cairo_draw_line (cr, &style->dark[state],
1740 x, y + 1, x, y + height - 1);
1741 _cairo_draw_line (cr, &style->black,
1742 x + 1, y + 1, x + width - 1, y + 1);
1743 _cairo_draw_line (cr, &style->black,
1744 x + 1, y + 2, x + 1, y + height - 2);
1745 _cairo_draw_line (cr, &style->black,
1746 x + width - 1, y + 2, x + width - 1, y + height - 3);
1747 _cairo_draw_line (cr, &style->light[state],
1748 x + 1, y + height - 1, x + width - 1, y + height - 1);
1749 _cairo_draw_line (cr, &style->bg[state],
1750 x + 2, y + height - 2, x + width - 1, y + height - 2);
1755 draw_menu_shadow (GtkStyle *style,
1763 if (style->ythickness > 0)
1765 if (style->ythickness > 1)
1767 _cairo_draw_line (cr, &style->dark[state],
1768 x + 1, y + height - 2,
1769 x + width - 2, y + height - 2);
1770 _cairo_draw_line (cr, &style->black,
1771 x, y + height - 1, x + width - 1, y + height - 1);
1775 _cairo_draw_line (cr, &style->dark[state],
1776 x + 1, y + height - 1, x + width - 1, y + height - 1);
1780 if (style->xthickness > 0)
1782 if (style->xthickness > 1)
1784 _cairo_draw_line (cr, &style->dark[state],
1785 x + width - 2, y + 1,
1786 x + width - 2, y + height - 2);
1788 _cairo_draw_line (cr, &style->black,
1789 x + width - 1, y, x + width - 1, y + height - 1);
1793 _cairo_draw_line (cr, &style->dark[state],
1794 x + width - 1, y + 1, x + width - 1, y + height - 1);
1798 /* Light around top and left */
1800 if (style->ythickness > 0)
1801 _cairo_draw_line (cr, &style->black,
1802 x, y, x + width - 2, y);
1803 if (style->xthickness > 0)
1804 _cairo_draw_line (cr, &style->black,
1805 x, y, x, y + height - 2);
1807 if (style->ythickness > 1)
1808 _cairo_draw_line (cr, &style->light[state],
1809 x + 1, y + 1, x + width - 3, y + 1);
1810 if (style->xthickness > 1)
1811 _cairo_draw_line (cr, &style->light[state],
1812 x + 1, y + 1, x + 1, y + height - 3);
1815 static GtkTextDirection
1816 get_direction (GtkWidget *widget)
1818 GtkTextDirection dir;
1821 dir = gtk_widget_get_direction (widget);
1823 dir = GTK_TEXT_DIR_LTR;
1830 gtk_default_draw_shadow (GtkStyle *style,
1832 GtkStateType state_type,
1833 GtkShadowType shadow_type,
1835 const gchar *detail,
1841 GdkColor *gc1 = NULL;
1842 GdkColor *gc2 = NULL;
1843 gint thickness_light;
1844 gint thickness_dark;
1847 cairo_set_line_width (cr, 1.0);
1849 if (shadow_type == GTK_SHADOW_IN)
1851 if (detail && strcmp (detail, "buttondefault") == 0)
1853 _cairo_draw_rectangle (cr, &style->black, FALSE,
1854 x, y, width - 1, height - 1);
1858 if (detail && strcmp (detail, "trough") == 0)
1860 draw_thin_shadow (style, cr, state_type,
1861 x, y, width, height);
1865 if (GTK_IS_SPIN_BUTTON (widget) &&
1866 detail && strcmp (detail, "spinbutton") == 0)
1868 draw_spinbutton_shadow (style, cr, state_type,
1869 get_direction (widget), x, y, width, height);
1875 if (shadow_type == GTK_SHADOW_OUT && detail && strcmp (detail, "menu") == 0)
1877 draw_menu_shadow (style, cr, state_type, x, y, width, height);
1881 switch (shadow_type)
1883 case GTK_SHADOW_NONE:
1886 case GTK_SHADOW_ETCHED_IN:
1887 gc1 = &style->light[state_type];
1888 gc2 = &style->dark[state_type];
1890 case GTK_SHADOW_OUT:
1891 case GTK_SHADOW_ETCHED_OUT:
1892 gc1 = &style->dark[state_type];
1893 gc2 = &style->light[state_type];
1897 switch (shadow_type)
1899 case GTK_SHADOW_NONE:
1903 /* Light around right and bottom edge */
1905 if (style->ythickness > 0)
1906 _cairo_draw_line (cr, gc1,
1907 x, y + height - 1, x + width - 1, y + height - 1);
1908 if (style->xthickness > 0)
1909 _cairo_draw_line (cr, gc1,
1910 x + width - 1, y, x + width - 1, y + height - 1);
1912 if (style->ythickness > 1)
1913 _cairo_draw_line (cr, &style->bg[state_type],
1914 x + 1, y + height - 2, x + width - 2, y + height - 2);
1915 if (style->xthickness > 1)
1916 _cairo_draw_line (cr, &style->bg[state_type],
1917 x + width - 2, y + 1, x + width - 2, y + height - 2);
1919 /* Dark around left and top */
1921 if (style->ythickness > 1)
1922 _cairo_draw_line (cr, &style->black,
1923 x + 1, y + 1, x + width - 2, y + 1);
1924 if (style->xthickness > 1)
1925 _cairo_draw_line (cr, &style->black,
1926 x + 1, y + 1, x + 1, y + height - 2);
1928 if (style->ythickness > 0)
1929 _cairo_draw_line (cr, gc2,
1930 x, y, x + width - 1, y);
1931 if (style->xthickness > 0)
1932 _cairo_draw_line (cr, gc2,
1933 x, y, x, y + height - 1);
1936 case GTK_SHADOW_OUT:
1937 /* Dark around right and bottom edge */
1939 if (style->ythickness > 0)
1941 if (style->ythickness > 1)
1943 _cairo_draw_line (cr, gc1,
1944 x + 1, y + height - 2, x + width - 2, y + height - 2);
1945 _cairo_draw_line (cr, &style->black,
1946 x, y + height - 1, x + width - 1, y + height - 1);
1950 _cairo_draw_line (cr, gc1,
1951 x + 1, y + height - 1, x + width - 1, y + height - 1);
1955 if (style->xthickness > 0)
1957 if (style->xthickness > 1)
1959 _cairo_draw_line (cr, gc1,
1960 x + width - 2, y + 1, x + width - 2, y + height - 2);
1962 _cairo_draw_line (cr, &style->black,
1963 x + width - 1, y, x + width - 1, y + height - 1);
1967 _cairo_draw_line (cr, gc1,
1968 x + width - 1, y + 1, x + width - 1, y + height - 1);
1972 /* Light around top and left */
1974 if (style->ythickness > 0)
1975 _cairo_draw_line (cr, gc2,
1976 x, y, x + width - 2, y);
1977 if (style->xthickness > 0)
1978 _cairo_draw_line (cr, gc2,
1979 x, y, x, y + height - 2);
1981 if (style->ythickness > 1)
1982 _cairo_draw_line (cr, &style->bg[state_type],
1983 x + 1, y + 1, x + width - 3, y + 1);
1984 if (style->xthickness > 1)
1985 _cairo_draw_line (cr, &style->bg[state_type],
1986 x + 1, y + 1, x + 1, y + height - 3);
1989 case GTK_SHADOW_ETCHED_IN:
1990 case GTK_SHADOW_ETCHED_OUT:
1991 if (style->xthickness > 0)
1993 if (style->xthickness > 1)
1995 thickness_light = 1;
1998 for (i = 0; i < thickness_dark; i++)
2000 _cairo_draw_line (cr, gc1,
2004 y + height - i - 1);
2005 _cairo_draw_line (cr, gc2,
2009 y + height - i - 2);
2012 for (i = 0; i < thickness_light; i++)
2014 _cairo_draw_line (cr, gc1,
2015 x + thickness_dark + i,
2016 y + thickness_dark + i,
2017 x + thickness_dark + i,
2018 y + height - thickness_dark - i - 1);
2019 _cairo_draw_line (cr, gc2,
2020 x + width - thickness_light - i - 1,
2021 y + thickness_dark + i,
2022 x + width - thickness_light - i - 1,
2023 y + height - thickness_light - 1);
2028 _cairo_draw_line (cr,
2029 &style->dark[state_type],
2030 x, y, x, y + height);
2031 _cairo_draw_line (cr,
2032 &style->dark[state_type],
2033 x + width, y, x + width, y + height);
2037 if (style->ythickness > 0)
2039 if (style->ythickness > 1)
2041 thickness_light = 1;
2044 for (i = 0; i < thickness_dark; i++)
2046 _cairo_draw_line (cr, gc1,
2050 y + height - i - 1);
2052 _cairo_draw_line (cr, gc2,
2059 for (i = 0; i < thickness_light; i++)
2061 _cairo_draw_line (cr, gc1,
2062 x + thickness_dark + i,
2063 y + thickness_dark + i,
2064 x + width - thickness_dark - i - 2,
2065 y + thickness_dark + i);
2067 _cairo_draw_line (cr, gc2,
2068 x + thickness_dark + i,
2069 y + height - thickness_light - i - 1,
2070 x + width - thickness_light - 1,
2071 y + height - thickness_light - i - 1);
2076 _cairo_draw_line (cr,
2077 &style->dark[state_type],
2078 x, y, x + width, y);
2079 _cairo_draw_line (cr,
2080 &style->dark[state_type],
2081 x, y + height, x + width, y + height);
2088 if (shadow_type == GTK_SHADOW_IN &&
2089 GTK_IS_SPIN_BUTTON (widget) &&
2090 detail && strcmp (detail, "entry") == 0)
2092 if (get_direction (widget) == GTK_TEXT_DIR_LTR)
2094 _cairo_draw_line (cr,
2095 &style->base[state_type],
2096 x + width - 1, y + 2,
2097 x + width - 1, y + height - 3);
2098 _cairo_draw_line (cr,
2099 &style->base[state_type],
2100 x + width - 2, y + 2,
2101 x + width - 2, y + height - 3);
2103 _cairo_draw_point (cr,
2105 x + width - 1, y + 1);
2106 _cairo_draw_point (cr,
2107 &style->bg[state_type],
2108 x + width - 1, y + height - 2);
2112 _cairo_draw_line (cr,
2113 &style->base[state_type],
2116 _cairo_draw_line (cr,
2117 &style->base[state_type],
2119 x + 1, y + height - 3);
2121 _cairo_draw_point (cr,
2125 _cairo_draw_line (cr,
2126 &style->bg[state_type],
2128 x + 1, y + height - 2);
2129 _cairo_draw_point (cr,
2130 &style->light[state_type],
2137 draw_arrow (cairo_t *cr,
2139 GtkArrowType arrow_type,
2145 gdk_cairo_set_source_color (cr, color);
2148 if (arrow_type == GTK_ARROW_DOWN)
2150 cairo_move_to (cr, x, y);
2151 cairo_line_to (cr, x + width, y);
2152 cairo_line_to (cr, x + width / 2., y + height);
2154 else if (arrow_type == GTK_ARROW_UP)
2156 cairo_move_to (cr, x, y + height);
2157 cairo_line_to (cr, x + width / 2., y);
2158 cairo_line_to (cr, x + width, y + height);
2160 else if (arrow_type == GTK_ARROW_LEFT)
2162 cairo_move_to (cr, x + width, y);
2163 cairo_line_to (cr, x + width, y + height);
2164 cairo_line_to (cr, x, y + height / 2.);
2166 else if (arrow_type == GTK_ARROW_RIGHT)
2168 cairo_move_to (cr, x, y);
2169 cairo_line_to (cr, x + width, y + height / 2.);
2170 cairo_line_to (cr, x, y + height);
2173 cairo_close_path (cr);
2180 calculate_arrow_geometry (GtkArrowType arrow_type,
2192 case GTK_ARROW_DOWN:
2202 if (arrow_type == GTK_ARROW_DOWN)
2204 if (*height % 2 == 1 || h % 2 == 0)
2209 if (*height % 2 == 0 || h % 2 == 0)
2214 case GTK_ARROW_RIGHT:
2215 case GTK_ARROW_LEFT:
2225 if (arrow_type == GTK_ARROW_RIGHT)
2227 if (*width % 2 == 1 || w % 2 == 0)
2232 if (*width % 2 == 0 || w % 2 == 0)
2238 /* should not be reached */
2242 *x += (*width - w) / 2;
2243 *y += (*height - h) / 2;
2249 gtk_default_draw_arrow (GtkStyle *style,
2252 GtkShadowType shadow,
2254 const gchar *detail,
2255 GtkArrowType arrow_type,
2262 calculate_arrow_geometry (arrow_type, &x, &y, &width, &height);
2264 if (detail && strcmp (detail, "menu_scroll_arrow_up") == 0)
2267 if (state == GTK_STATE_INSENSITIVE)
2268 draw_arrow (cr, &style->white, arrow_type,
2269 x + 1, y + 1, width, height);
2270 draw_arrow (cr, &style->fg[state], arrow_type,
2271 x, y, width, height);
2275 gtk_default_draw_diamond (GtkStyle *style,
2277 GtkStateType state_type,
2278 GtkShadowType shadow_type,
2280 const gchar *detail,
2288 GdkColor *outer_nw = NULL;
2289 GdkColor *outer_ne = NULL;
2290 GdkColor *outer_sw = NULL;
2291 GdkColor *outer_se = NULL;
2292 GdkColor *middle_nw = NULL;
2293 GdkColor *middle_ne = NULL;
2294 GdkColor *middle_sw = NULL;
2295 GdkColor *middle_se = NULL;
2296 GdkColor *inner_nw = NULL;
2297 GdkColor *inner_ne = NULL;
2298 GdkColor *inner_sw = NULL;
2299 GdkColor *inner_se = NULL;
2301 half_width = width / 2;
2302 half_height = height / 2;
2304 switch (shadow_type)
2307 inner_sw = inner_se = &style->bg[state_type];
2308 middle_sw = middle_se = &style->light[state_type];
2309 outer_sw = outer_se = &style->light[state_type];
2310 inner_nw = inner_ne = &style->black;
2311 middle_nw = middle_ne = &style->dark[state_type];
2312 outer_nw = outer_ne = &style->dark[state_type];
2315 case GTK_SHADOW_OUT:
2316 inner_sw = inner_se = &style->dark[state_type];
2317 middle_sw = middle_se = &style->dark[state_type];
2318 outer_sw = outer_se = &style->black;
2319 inner_nw = inner_ne = &style->bg[state_type];
2320 middle_nw = middle_ne = &style->light[state_type];
2321 outer_nw = outer_ne = &style->light[state_type];
2324 case GTK_SHADOW_ETCHED_IN:
2325 inner_sw = inner_se = &style->bg[state_type];
2326 middle_sw = middle_se = &style->dark[state_type];
2327 outer_sw = outer_se = &style->light[state_type];
2328 inner_nw = inner_ne = &style->bg[state_type];
2329 middle_nw = middle_ne = &style->light[state_type];
2330 outer_nw = outer_ne = &style->dark[state_type];
2333 case GTK_SHADOW_ETCHED_OUT:
2334 inner_sw = inner_se = &style->bg[state_type];
2335 middle_sw = middle_se = &style->light[state_type];
2336 outer_sw = outer_se = &style->dark[state_type];
2337 inner_nw = inner_ne = &style->bg[state_type];
2338 middle_nw = middle_ne = &style->dark[state_type];
2339 outer_nw = outer_ne = &style->light[state_type];
2349 _cairo_draw_line (cr, inner_sw,
2350 x + 2, y + half_height,
2351 x + half_width, y + height - 2);
2352 _cairo_draw_line (cr, inner_se,
2353 x + half_width, y + height - 2,
2354 x + width - 2, y + half_height);
2355 _cairo_draw_line (cr, middle_sw,
2356 x + 1, y + half_height,
2357 x + half_width, y + height - 1);
2358 _cairo_draw_line (cr, middle_se,
2359 x + half_width, y + height - 1,
2360 x + width - 1, y + half_height);
2361 _cairo_draw_line (cr, outer_sw,
2363 x + half_width, y + height);
2364 _cairo_draw_line (cr, outer_se,
2365 x + half_width, y + height,
2366 x + width, y + half_height);
2368 _cairo_draw_line (cr, inner_nw,
2369 x + 2, y + half_height,
2370 x + half_width, y + 2);
2371 _cairo_draw_line (cr, inner_ne,
2372 x + half_width, y + 2,
2373 x + width - 2, y + half_height);
2374 _cairo_draw_line (cr, middle_nw,
2375 x + 1, y + half_height,
2376 x + half_width, y + 1);
2377 _cairo_draw_line (cr, middle_ne,
2378 x + half_width, y + 1,
2379 x + width - 1, y + half_height);
2380 _cairo_draw_line (cr, outer_nw,
2383 _cairo_draw_line (cr, outer_ne,
2385 x + width, y + half_height);
2390 option_menu_get_props (GtkWidget *widget,
2391 GtkRequisition *indicator_size,
2392 GtkBorder *indicator_spacing)
2394 GtkRequisition *tmp_size = NULL;
2395 GtkBorder *tmp_spacing = NULL;
2399 *indicator_size = *tmp_size;
2400 gtk_requisition_free (tmp_size);
2403 *indicator_size = default_option_indicator_size;
2407 *indicator_spacing = *tmp_spacing;
2408 gtk_border_free (tmp_spacing);
2411 *indicator_spacing = default_option_indicator_spacing;
2415 background_is_solid (GtkStyle *style,
2418 if (style->background[type] == NULL)
2421 return cairo_pattern_get_type (style->background[type]) == CAIRO_PATTERN_TYPE_SOLID;
2425 gtk_default_draw_box (GtkStyle *style,
2427 GtkStateType state_type,
2428 GtkShadowType shadow_type,
2430 const gchar *detail,
2436 gboolean is_spinbutton_box = FALSE;
2438 if (GTK_IS_SPIN_BUTTON (widget) && detail)
2440 if (strcmp (detail, "spinbutton_up") == 0)
2446 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
2451 is_spinbutton_box = TRUE;
2453 else if (strcmp (detail, "spinbutton_down") == 0)
2458 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
2463 is_spinbutton_box = TRUE;
2467 if (background_is_solid (style, state_type))
2469 GdkColor *gc = &style->bg[state_type];
2471 if (state_type == GTK_STATE_SELECTED && detail && strcmp (detail, "paned") == 0)
2473 if (widget && !gtk_widget_has_focus (widget))
2474 gc = &style->base[GTK_STATE_ACTIVE];
2477 _cairo_draw_rectangle (cr, gc, TRUE,
2478 x, y, width, height);
2481 gtk_style_apply_default_background (style, cr, gtk_widget_get_window (widget),
2482 state_type, x, y, width, height);
2485 if (is_spinbutton_box)
2490 lower = &style->dark[state_type];
2491 if (shadow_type == GTK_SHADOW_OUT)
2492 upper = &style->light[state_type];
2494 upper = &style->dark[state_type];
2496 _cairo_draw_line (cr, upper, x, y, x + width - 1, y);
2497 _cairo_draw_line (cr, lower, x, y + height - 1, x + width - 1, y + height - 1);
2502 gtk_paint_shadow (style, cr, state_type, shadow_type, widget, detail,
2503 x, y, width, height);
2505 if (detail && strcmp (detail, "optionmenu") == 0)
2507 GtkRequisition indicator_size;
2508 GtkBorder indicator_spacing;
2511 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
2513 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
2514 vline_x = x + indicator_size.width + indicator_spacing.left + indicator_spacing.right;
2516 vline_x = x + width - (indicator_size.width + indicator_spacing.left + indicator_spacing.right) - style->xthickness;
2518 gtk_paint_vline (style, cr, state_type, widget,
2520 y + style->ythickness + 1,
2521 y + height - style->ythickness - 3,
2527 get_darkened (const GdkColor *color,
2530 GdkColor src = *color;
2531 GdkColor shaded = *color;
2533 while (darken_count)
2535 _gtk_style_shade (&src, &shaded, 0.93);
2540 return gdk_color_copy (&shaded);
2544 gtk_default_draw_flat_box (GtkStyle *style,
2546 GtkStateType state_type,
2547 GtkShadowType shadow_type,
2549 const gchar *detail,
2556 GdkColor *freeme = NULL;
2558 cairo_set_line_width (cr, 1.0);
2562 int trimmed_len = strlen (detail);
2564 if (g_str_has_prefix (detail, "cell_"))
2566 if (g_str_has_suffix (detail, "_start"))
2568 else if (g_str_has_suffix (detail, "_middle"))
2570 else if (g_str_has_suffix (detail, "_end"))
2574 if (state_type == GTK_STATE_SELECTED)
2576 if (!strcmp ("text", detail))
2577 gc1 = &style->bg[GTK_STATE_SELECTED];
2578 else if (!strncmp ("cell_even", detail, trimmed_len) ||
2579 !strncmp ("cell_odd", detail, trimmed_len) ||
2580 !strncmp ("cell_even_ruled", detail, trimmed_len) ||
2581 !strncmp ("cell_even_ruled_sorted", detail, trimmed_len))
2583 /* This has to be really broken; alex made me do it. -jrb */
2584 if (widget && gtk_widget_has_focus (widget))
2585 gc1 = &style->base[state_type];
2587 gc1 = &style->base[GTK_STATE_ACTIVE];
2589 else if (!strncmp ("cell_odd_ruled", detail, trimmed_len) ||
2590 !strncmp ("cell_odd_ruled_sorted", detail, trimmed_len))
2592 if (widget && gtk_widget_has_focus (widget))
2593 freeme = get_darkened (&style->base[state_type], 1);
2595 freeme = get_darkened (&style->base[GTK_STATE_ACTIVE], 1);
2600 gc1 = &style->bg[state_type];
2605 if (!strcmp ("viewportbin", detail))
2606 gc1 = &style->bg[GTK_STATE_NORMAL];
2607 else if (!strcmp ("entry_bg", detail))
2608 gc1 = &style->base[gtk_widget_get_state (widget)];
2610 /* For trees: even rows are base color, odd rows are a shade of
2611 * the base color, the sort column is a shade of the original color
2615 else if (!strncmp ("cell_even", detail, trimmed_len) ||
2616 !strncmp ("cell_odd", detail, trimmed_len) ||
2617 !strncmp ("cell_even_ruled", detail, trimmed_len))
2619 GdkColor *color = NULL;
2621 gtk_widget_style_get (widget,
2622 "even-row-color", &color,
2627 freeme = get_darkened (color, 0);
2630 gdk_color_free (color);
2633 gc1 = &style->base[state_type];
2635 else if (!strncmp ("cell_odd_ruled", detail, trimmed_len))
2637 GdkColor *color = NULL;
2639 gtk_widget_style_get (widget,
2640 "odd-row-color", &color,
2645 freeme = get_darkened (color, 0);
2648 gdk_color_free (color);
2652 gtk_widget_style_get (widget,
2653 "even-row-color", &color,
2658 freeme = get_darkened (color, 1);
2659 gdk_color_free (color);
2662 freeme = get_darkened (&style->base[state_type], 1);
2666 else if (!strncmp ("cell_even_sorted", detail, trimmed_len) ||
2667 !strncmp ("cell_odd_sorted", detail, trimmed_len) ||
2668 !strncmp ("cell_even_ruled_sorted", detail, trimmed_len))
2670 GdkColor *color = NULL;
2672 if (!strncmp ("cell_odd_sorted", detail, trimmed_len))
2673 gtk_widget_style_get (widget,
2674 "odd-row-color", &color,
2677 gtk_widget_style_get (widget,
2678 "even-row-color", &color,
2683 freeme = get_darkened (color, 1);
2686 gdk_color_free (color);
2690 freeme = get_darkened (&style->base[state_type], 1);
2694 else if (!strncmp ("cell_odd_ruled_sorted", detail, trimmed_len))
2696 GdkColor *color = NULL;
2698 gtk_widget_style_get (widget,
2699 "odd-row-color", &color,
2704 freeme = get_darkened (color, 1);
2707 gdk_color_free (color);
2711 gtk_widget_style_get (widget,
2712 "even-row-color", &color,
2717 freeme = get_darkened (color, 2);
2718 gdk_color_free (color);
2721 freeme = get_darkened (&style->base[state_type], 2);
2726 gc1 = &style->bg[state_type];
2730 gc1 = &style->bg[state_type];
2732 if (background_is_solid (style, state_type) || gc1 != &style->bg[state_type])
2734 _cairo_draw_rectangle (cr, gc1, TRUE,
2735 x, y, width, height);
2737 if (detail && !strcmp ("tooltip", detail))
2738 _cairo_draw_rectangle (cr, &style->black, FALSE,
2739 x, y, width - 1, height - 1);
2742 gtk_style_apply_default_background (style, cr, gtk_widget_get_window (widget),
2743 state_type, x, y, width, height);
2746 gdk_color_free (freeme);
2750 gtk_default_draw_check (GtkStyle *style,
2752 GtkStateType state_type,
2753 GtkShadowType shadow_type,
2755 const gchar *detail,
2761 enum { BUTTON, MENU, CELL } type = BUTTON;
2768 if (strcmp (detail, "cellcheck") == 0)
2770 else if (strcmp (detail, "check") == 0)
2774 exterior_size = MIN (width, height);
2775 if (exterior_size % 2 == 0) /* Ensure odd */
2778 pad = style->xthickness + MAX (1, (exterior_size - 2 * style->xthickness) / 9);
2779 interior_size = MAX (1, exterior_size - 2 * pad);
2781 if (interior_size < 7)
2784 pad = MAX (0, (exterior_size - interior_size) / 2);
2787 x -= (1 + exterior_size - width) / 2;
2788 y -= (1 + exterior_size - height) / 2;
2795 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
2797 gdk_cairo_set_source_color (cr, &style->text[state_type]);
2799 cairo_set_line_width (cr, 1.0);
2800 cairo_rectangle (cr, x + 0.5, y + 0.5, exterior_size - 1, exterior_size - 1);
2803 gdk_cairo_set_source_color (cr, &style->base[state_type]);
2804 cairo_rectangle (cr, x + 1, y + 1, exterior_size - 2, exterior_size - 2);
2816 gdk_cairo_set_source_color (cr, &style->text[state_type]);
2819 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
2823 if (shadow_type == GTK_SHADOW_IN)
2825 cairo_translate (cr,
2828 cairo_scale (cr, interior_size / 7., interior_size / 7.);
2830 cairo_move_to (cr, 7.0, 0.0);
2831 cairo_line_to (cr, 7.5, 1.0);
2832 cairo_curve_to (cr, 5.3, 2.0,
2835 cairo_curve_to (cr, 3.0, 5.7,
2838 cairo_line_to (cr, 0.2, 3.5);
2839 cairo_curve_to (cr, 1.1, 3.5,
2842 cairo_curve_to (cr, 1.0, 3.9,
2845 cairo_curve_to (cr, 3.5, 3.1,
2851 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
2853 int line_thickness = MAX (1, (3 + interior_size * 2) / 7);
2855 cairo_rectangle (cr,
2857 y + pad + (1 + interior_size - line_thickness) / 2,
2865 gtk_default_draw_option (GtkStyle *style,
2867 GtkStateType state_type,
2868 GtkShadowType shadow_type,
2870 const gchar *detail,
2876 enum { BUTTON, MENU, CELL } type = BUTTON;
2881 if (strcmp (detail, "radio") == 0)
2883 else if (strcmp (detail, "option") == 0)
2887 exterior_size = MIN (width, height);
2888 if (exterior_size % 2 == 0) /* Ensure odd */
2891 x -= (1 + exterior_size - width) / 2;
2892 y -= (1 + exterior_size - height) / 2;
2898 gdk_cairo_set_source_color (cr, &style->base[state_type]);
2901 x + exterior_size / 2.,
2902 y + exterior_size / 2.,
2903 (exterior_size - 1) / 2.,
2906 cairo_fill_preserve (cr);
2909 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
2911 gdk_cairo_set_source_color (cr, &style->text[state_type]);
2913 cairo_set_line_width (cr, 1.);
2924 gdk_cairo_set_source_color (cr, &style->text[state_type]);
2929 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
2933 if (shadow_type == GTK_SHADOW_IN)
2935 int pad = style->xthickness + MAX (1, 2 * (exterior_size - 2 * style->xthickness) / 9);
2936 int interior_size = MAX (1, exterior_size - 2 * pad);
2938 if (interior_size < 5)
2941 pad = MAX (0, (exterior_size - interior_size) / 2);
2945 x + pad + interior_size / 2.,
2946 y + pad + interior_size / 2.,
2951 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
2953 int pad = style->xthickness + MAX (1, (exterior_size - 2 * style->xthickness) / 9);
2954 int interior_size = MAX (1, exterior_size - 2 * pad);
2957 if (interior_size < 7)
2960 pad = MAX (0, (exterior_size - interior_size) / 2);
2963 line_thickness = MAX (1, (3 + interior_size * 2) / 7);
2965 cairo_rectangle (cr,
2967 y + pad + (interior_size - line_thickness) / 2.,
2975 gtk_default_draw_tab (GtkStyle *style,
2977 GtkStateType state_type,
2978 GtkShadowType shadow_type,
2980 const gchar *detail,
2986 #define ARROW_SPACE 4
2988 GtkRequisition indicator_size;
2989 GtkBorder indicator_spacing;
2992 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
2994 indicator_size.width += (indicator_size.width % 2) - 1;
2995 arrow_height = indicator_size.width / 2 + 1;
2997 x += (width - indicator_size.width) / 2;
2998 y += (height - (2 * arrow_height + ARROW_SPACE)) / 2;
3000 if (state_type == GTK_STATE_INSENSITIVE)
3002 draw_arrow (cr, &style->white,
3003 GTK_ARROW_UP, x + 1, y + 1,
3004 indicator_size.width, arrow_height);
3006 draw_arrow (cr, &style->white,
3007 GTK_ARROW_DOWN, x + 1, y + arrow_height + ARROW_SPACE + 1,
3008 indicator_size.width, arrow_height);
3011 draw_arrow (cr, &style->fg[state_type],
3013 indicator_size.width, arrow_height);
3016 draw_arrow (cr, &style->fg[state_type],
3017 GTK_ARROW_DOWN, x, y + arrow_height + ARROW_SPACE,
3018 indicator_size.width, arrow_height);
3022 gtk_default_draw_shadow_gap (GtkStyle *style,
3024 GtkStateType state_type,
3025 GtkShadowType shadow_type,
3027 const gchar *detail,
3032 GtkPositionType gap_side,
3036 GdkColor *color1 = NULL;
3037 GdkColor *color2 = NULL;
3038 GdkColor *color3 = NULL;
3039 GdkColor *color4 = NULL;
3041 switch (shadow_type)
3043 case GTK_SHADOW_NONE:
3047 color1 = &style->dark[state_type];
3048 color2 = &style->black;
3049 color3 = &style->bg[state_type];
3050 color4 = &style->light[state_type];
3052 case GTK_SHADOW_ETCHED_IN:
3053 color1 = &style->dark[state_type];
3054 color2 = &style->light[state_type];
3055 color3 = &style->dark[state_type];
3056 color4 = &style->light[state_type];
3058 case GTK_SHADOW_OUT:
3059 color1 = &style->light[state_type];
3060 color2 = &style->bg[state_type];
3061 color3 = &style->dark[state_type];
3062 color4 = &style->black;
3064 case GTK_SHADOW_ETCHED_OUT:
3065 color1 = &style->light[state_type];
3066 color2 = &style->dark[state_type];
3067 color3 = &style->light[state_type];
3068 color4 = &style->dark[state_type];
3072 switch (shadow_type)
3074 case GTK_SHADOW_NONE:
3076 case GTK_SHADOW_OUT:
3077 case GTK_SHADOW_ETCHED_IN:
3078 case GTK_SHADOW_ETCHED_OUT:
3082 _cairo_draw_line (cr, color1,
3083 x, y, x, y + height - 1);
3084 _cairo_draw_line (cr, color2,
3085 x + 1, y, x + 1, y + height - 2);
3087 _cairo_draw_line (cr, color3,
3088 x + 1, y + height - 2, x + width - 2, y + height - 2);
3089 _cairo_draw_line (cr, color3,
3090 x + width - 2, y, x + width - 2, y + height - 2);
3091 _cairo_draw_line (cr, color4,
3092 x, y + height - 1, x + width - 1, y + height - 1);
3093 _cairo_draw_line (cr, color4,
3094 x + width - 1, y, x + width - 1, y + height - 1);
3097 _cairo_draw_line (cr, color1,
3098 x, y, x + gap_x - 1, y);
3099 _cairo_draw_line (cr, color2,
3100 x + 1, y + 1, x + gap_x - 1, y + 1);
3101 _cairo_draw_line (cr, color2,
3102 x + gap_x, y, x + gap_x, y);
3104 if ((width - (gap_x + gap_width)) > 0)
3106 _cairo_draw_line (cr, color1,
3107 x + gap_x + gap_width, y, x + width - 2, y);
3108 _cairo_draw_line (cr, color2,
3109 x + gap_x + gap_width, y + 1, x + width - 3, y + 1);
3110 _cairo_draw_line (cr, color2,
3111 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
3114 case GTK_POS_BOTTOM:
3115 _cairo_draw_line (cr, color1,
3116 x, y, x + width - 1, y);
3117 _cairo_draw_line (cr, color1,
3118 x, y, x, y + height - 1);
3119 _cairo_draw_line (cr, color2,
3120 x + 1, y + 1, x + width - 2, y + 1);
3121 _cairo_draw_line (cr, color2,
3122 x + 1, y + 1, x + 1, y + height - 1);
3124 _cairo_draw_line (cr, color3,
3125 x + width - 2, y + 1, x + width - 2, y + height - 1);
3126 _cairo_draw_line (cr, color4,
3127 x + width - 1, y, x + width - 1, y + height - 1);
3130 _cairo_draw_line (cr, color4,
3131 x, y + height - 1, x + gap_x - 1, y + height - 1);
3132 _cairo_draw_line (cr, color3,
3133 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
3134 _cairo_draw_line (cr, color3,
3135 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
3137 if ((width - (gap_x + gap_width)) > 0)
3139 _cairo_draw_line (cr, color4,
3140 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
3141 _cairo_draw_line (cr, color3,
3142 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
3143 _cairo_draw_line (cr, color3,
3144 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
3148 _cairo_draw_line (cr, color1,
3149 x, y, x + width - 1, y);
3150 _cairo_draw_line (cr, color2,
3151 x, y + 1, x + width - 2, y + 1);
3153 _cairo_draw_line (cr, color3,
3154 x, y + height - 2, x + width - 2, y + height - 2);
3155 _cairo_draw_line (cr, color3,
3156 x + width - 2, y + 1, x + width - 2, y + height - 2);
3157 _cairo_draw_line (cr, color4,
3158 x, y + height - 1, x + width - 1, y + height - 1);
3159 _cairo_draw_line (cr, color4,
3160 x + width - 1, y, x + width - 1, y + height - 1);
3163 _cairo_draw_line (cr, color1,
3164 x, y, x, y + gap_x - 1);
3165 _cairo_draw_line (cr, color2,
3166 x + 1, y + 1, x + 1, y + gap_x - 1);
3167 _cairo_draw_line (cr, color2,
3168 x, y + gap_x, x, y + gap_x);
3170 if ((width - (gap_x + gap_width)) > 0)
3172 _cairo_draw_line (cr, color1,
3173 x, y + gap_x + gap_width, x, y + height - 2);
3174 _cairo_draw_line (cr, color2,
3175 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
3176 _cairo_draw_line (cr, color2,
3177 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
3181 _cairo_draw_line (cr, color1,
3182 x, y, x + width - 1, y);
3183 _cairo_draw_line (cr, color1,
3184 x, y, x, y + height - 1);
3185 _cairo_draw_line (cr, color2,
3186 x + 1, y + 1, x + width - 1, y + 1);
3187 _cairo_draw_line (cr, color2,
3188 x + 1, y + 1, x + 1, y + height - 2);
3190 _cairo_draw_line (cr, color3,
3191 x + 1, y + height - 2, x + width - 1, y + height - 2);
3192 _cairo_draw_line (cr, color4,
3193 x, y + height - 1, x + width - 1, y + height - 1);
3196 _cairo_draw_line (cr, color4,
3197 x + width - 1, y, x + width - 1, y + gap_x - 1);
3198 _cairo_draw_line (cr, color3,
3199 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
3200 _cairo_draw_line (cr, color3,
3201 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
3203 if ((width - (gap_x + gap_width)) > 0)
3205 _cairo_draw_line (cr, color4,
3206 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
3207 _cairo_draw_line (cr, color3,
3208 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
3209 _cairo_draw_line (cr, color3,
3210 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
3218 gtk_default_draw_box_gap (GtkStyle *style,
3220 GtkStateType state_type,
3221 GtkShadowType shadow_type,
3223 const gchar *detail,
3228 GtkPositionType gap_side,
3237 gtk_style_apply_default_background (style, cr, gtk_widget_get_window (widget),
3238 state_type, x, y, width, height);
3240 switch (shadow_type)
3242 case GTK_SHADOW_NONE:
3245 color1 = style->dark[state_type];
3246 color2 = style->black;
3247 color3 = style->bg[state_type];
3248 color4 = style->light[state_type];
3250 case GTK_SHADOW_ETCHED_IN:
3251 color1 = style->dark[state_type];
3252 color2 = style->light[state_type];
3253 color3 = style->dark[state_type];
3254 color4 = style->light[state_type];
3256 case GTK_SHADOW_OUT:
3257 color1 = style->light[state_type];
3258 color2 = style->bg[state_type];
3259 color3 = style->dark[state_type];
3260 color4 = style->black;
3262 case GTK_SHADOW_ETCHED_OUT:
3263 color1 = style->light[state_type];
3264 color2 = style->dark[state_type];
3265 color3 = style->light[state_type];
3266 color4 = style->dark[state_type];
3270 cairo_set_line_width (cr, 1.0);
3272 switch (shadow_type)
3274 case GTK_SHADOW_NONE:
3276 case GTK_SHADOW_OUT:
3277 case GTK_SHADOW_ETCHED_IN:
3278 case GTK_SHADOW_ETCHED_OUT:
3282 _cairo_draw_line (cr, &color1,
3283 x, y, x, y + height - 1);
3284 _cairo_draw_line (cr, &color2,
3285 x + 1, y, x + 1, y + height - 2);
3287 _cairo_draw_line (cr, &color3,
3288 x + 1, y + height - 2, x + width - 2, y + height - 2);
3289 _cairo_draw_line (cr, &color3,
3290 x + width - 2, y, x + width - 2, y + height - 2);
3291 _cairo_draw_line (cr, &color4,
3292 x, y + height - 1, x + width - 1, y + height - 1);
3293 _cairo_draw_line (cr, &color4,
3294 x + width - 1, y, x + width - 1, y + height - 1);
3297 _cairo_draw_line (cr, &color1,
3298 x, y, x + gap_x - 1, y);
3299 _cairo_draw_line (cr, &color2,
3300 x + 1, y + 1, x + gap_x - 1, y + 1);
3301 _cairo_draw_line (cr, &color2,
3302 x + gap_x, y, x + gap_x, y);
3304 if ((width - (gap_x + gap_width)) > 0)
3306 _cairo_draw_line (cr, &color1,
3307 x + gap_x + gap_width, y, x + width - 2, y);
3308 _cairo_draw_line (cr, &color2,
3309 x + gap_x + gap_width, y + 1, x + width - 2, y + 1);
3310 _cairo_draw_line (cr, &color2,
3311 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
3314 case GTK_POS_BOTTOM:
3315 _cairo_draw_line (cr, &color1,
3316 x, y, x + width - 1, y);
3317 _cairo_draw_line (cr, &color1,
3318 x, y, x, y + height - 1);
3319 _cairo_draw_line (cr, &color2,
3320 x + 1, y + 1, x + width - 2, y + 1);
3321 _cairo_draw_line (cr, &color2,
3322 x + 1, y + 1, x + 1, y + height - 1);
3324 _cairo_draw_line (cr, &color3,
3325 x + width - 2, y + 1, x + width - 2, y + height - 1);
3326 _cairo_draw_line (cr, &color4,
3327 x + width - 1, y, x + width - 1, y + height - 1);
3330 _cairo_draw_line (cr, &color4,
3331 x, y + height - 1, x + gap_x - 1, y + height - 1);
3332 _cairo_draw_line (cr, &color3,
3333 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
3334 _cairo_draw_line (cr, &color3,
3335 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
3337 if ((width - (gap_x + gap_width)) > 0)
3339 _cairo_draw_line (cr, &color4,
3340 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
3341 _cairo_draw_line (cr, &color3,
3342 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
3343 _cairo_draw_line (cr, &color3,
3344 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
3348 _cairo_draw_line (cr, &color1,
3349 x, y, x + width - 1, y);
3350 _cairo_draw_line (cr, &color2,
3351 x, y + 1, x + width - 2, y + 1);
3353 _cairo_draw_line (cr, &color3,
3354 x, y + height - 2, x + width - 2, y + height - 2);
3355 _cairo_draw_line (cr, &color3,
3356 x + width - 2, y + 1, x + width - 2, y + height - 2);
3357 _cairo_draw_line (cr, &color4,
3358 x, y + height - 1, x + width - 1, y + height - 1);
3359 _cairo_draw_line (cr, &color4,
3360 x + width - 1, y, x + width - 1, y + height - 1);
3363 _cairo_draw_line (cr, &color1,
3364 x, y, x, y + gap_x - 1);
3365 _cairo_draw_line (cr, &color2,
3366 x + 1, y + 1, x + 1, y + gap_x - 1);
3367 _cairo_draw_line (cr, &color2,
3368 x, y + gap_x, x, y + gap_x);
3370 if ((height - (gap_x + gap_width)) > 0)
3372 _cairo_draw_line (cr, &color1,
3373 x, y + gap_x + gap_width, x, y + height - 2);
3374 _cairo_draw_line (cr, &color2,
3375 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
3376 _cairo_draw_line (cr, &color2,
3377 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
3381 _cairo_draw_line (cr, &color1,
3382 x, y, x + width - 1, y);
3383 _cairo_draw_line (cr, &color1,
3384 x, y, x, y + height - 1);
3385 _cairo_draw_line (cr, &color2,
3386 x + 1, y + 1, x + width - 1, y + 1);
3387 _cairo_draw_line (cr, &color2,
3388 x + 1, y + 1, x + 1, y + height - 2);
3390 _cairo_draw_line (cr, &color3,
3391 x + 1, y + height - 2, x + width - 1, y + height - 2);
3392 _cairo_draw_line (cr, &color4,
3393 x, y + height - 1, x + width - 1, y + height - 1);
3396 _cairo_draw_line (cr, &color4,
3397 x + width - 1, y, x + width - 1, y + gap_x - 1);
3398 _cairo_draw_line (cr, &color3,
3399 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
3400 _cairo_draw_line (cr, &color3,
3401 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
3403 if ((height - (gap_x + gap_width)) > 0)
3405 _cairo_draw_line (cr, &color4,
3406 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
3407 _cairo_draw_line (cr, &color3,
3408 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
3409 _cairo_draw_line (cr, &color3,
3410 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
3418 gtk_default_draw_extension (GtkStyle *style,
3420 GtkStateType state_type,
3421 GtkShadowType shadow_type,
3423 const gchar *detail,
3428 GtkPositionType gap_side)
3430 GdkWindow *window = gtk_widget_get_window (widget);
3439 gtk_style_apply_default_background (style, cr, window,
3446 case GTK_POS_BOTTOM:
3447 gtk_style_apply_default_background (style, cr, window,
3455 gtk_style_apply_default_background (style, cr, window,
3463 gtk_style_apply_default_background (style, cr, window,
3472 switch (shadow_type)
3474 case GTK_SHADOW_NONE:
3477 color1 = style->dark[state_type];
3478 color2 = style->black;
3479 color3 = style->bg[state_type];
3480 color4 = style->light[state_type];
3482 case GTK_SHADOW_ETCHED_IN:
3483 color1 = style->dark[state_type];
3484 color2 = style->light[state_type];
3485 color3 = style->dark[state_type];
3486 color4 = style->light[state_type];
3488 case GTK_SHADOW_OUT:
3489 color1 = style->light[state_type];
3490 color2 = style->bg[state_type];
3491 color3 = style->dark[state_type];
3492 color4 = style->black;
3494 case GTK_SHADOW_ETCHED_OUT:
3495 color1 = style->light[state_type];
3496 color2 = style->dark[state_type];
3497 color3 = style->light[state_type];
3498 color4 = style->dark[state_type];
3502 cairo_set_line_width (cr, 1.0);
3504 switch (shadow_type)
3506 case GTK_SHADOW_NONE:
3508 case GTK_SHADOW_OUT:
3509 case GTK_SHADOW_ETCHED_IN:
3510 case GTK_SHADOW_ETCHED_OUT:
3514 _cairo_draw_line (cr, &color1,
3515 x, y, x, y + height - 2);
3516 _cairo_draw_line (cr, &color2,
3517 x + 1, y, x + 1, y + height - 2);
3519 _cairo_draw_line (cr, &color3,
3520 x + 2, y + height - 2, x + width - 2, y + height - 2);
3521 _cairo_draw_line (cr, &color3,
3522 x + width - 2, y, x + width - 2, y + height - 2);
3523 _cairo_draw_line (cr, &color4,
3524 x + 1, y + height - 1, x + width - 2, y + height - 1);
3525 _cairo_draw_line (cr, &color4,
3526 x + width - 1, y, x + width - 1, y + height - 2);
3528 case GTK_POS_BOTTOM:
3529 _cairo_draw_line (cr, &color1,
3530 x + 1, y, x + width - 2, y);
3531 _cairo_draw_line (cr, &color1,
3532 x, y + 1, x, y + height - 1);
3533 _cairo_draw_line (cr, &color2,
3534 x + 1, y + 1, x + width - 2, y + 1);
3535 _cairo_draw_line (cr, &color2,
3536 x + 1, y + 1, x + 1, y + height - 1);
3538 _cairo_draw_line (cr, &color3,
3539 x + width - 2, y + 2, x + width - 2, y + height - 1);
3540 _cairo_draw_line (cr, &color4,
3541 x + width - 1, y + 1, x + width - 1, y + height - 1);
3544 _cairo_draw_line (cr, &color1,
3545 x, y, x + width - 2, y);
3546 _cairo_draw_line (cr, &color2,
3547 x + 1, y + 1, x + width - 2, y + 1);
3549 _cairo_draw_line (cr, &color3,
3550 x, y + height - 2, x + width - 2, y + height - 2);
3551 _cairo_draw_line (cr, &color3,
3552 x + width - 2, y + 2, x + width - 2, y + height - 2);
3553 _cairo_draw_line (cr, &color4,
3554 x, y + height - 1, x + width - 2, y + height - 1);
3555 _cairo_draw_line (cr, &color4,
3556 x + width - 1, y + 1, x + width - 1, y + height - 2);
3559 _cairo_draw_line (cr, &color1,
3560 x + 1, y, x + width - 1, y);
3561 _cairo_draw_line (cr, &color1,
3562 x, y + 1, x, y + height - 2);
3563 _cairo_draw_line (cr, &color2,
3564 x + 1, y + 1, x + width - 1, y + 1);
3565 _cairo_draw_line (cr, &color2,
3566 x + 1, y + 1, x + 1, y + height - 2);
3568 _cairo_draw_line (cr, &color3,
3569 x + 2, y + height - 2, x + width - 1, y + height - 2);
3570 _cairo_draw_line (cr, &color4,
3571 x + 1, y + height - 1, x + width - 1, y + height - 1);
3578 gtk_default_draw_focus (GtkStyle *style,
3580 GtkStateType state_type,
3582 const gchar *detail,
3588 gboolean free_dash_list = FALSE;
3589 gint line_width = 1;
3590 gint8 *dash_list = (gint8 *) "\1\1";
3594 gtk_widget_style_get (widget,
3595 "focus-line-width", &line_width,
3596 "focus-line-pattern", (gchar *)&dash_list,
3599 free_dash_list = TRUE;
3602 if (detail && !strcmp (detail, "add-mode"))
3607 dash_list = (gint8 *) "\4\4";
3608 free_dash_list = FALSE;
3611 if (detail && !strcmp (detail, "colorwheel_light"))
3612 cairo_set_source_rgb (cr, 0., 0., 0.);
3613 else if (detail && !strcmp (detail, "colorwheel_dark"))
3614 cairo_set_source_rgb (cr, 1., 1., 1.);
3616 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3618 cairo_set_line_width (cr, line_width);
3622 gint n_dashes = strlen ((const gchar *) dash_list);
3623 gdouble *dashes = g_new (gdouble, n_dashes);
3624 gdouble total_length = 0;
3625 gdouble dash_offset;
3628 for (i = 0; i < n_dashes; i++)
3630 dashes[i] = dash_list[i];
3631 total_length += dash_list[i];
3634 /* The dash offset here aligns the pattern to integer pixels
3635 * by starting the dash at the right side of the left border
3636 * Negative dash offsets in cairo don't work
3637 * (https://bugs.freedesktop.org/show_bug.cgi?id=2729)
3639 dash_offset = - line_width / 2.;
3640 while (dash_offset < 0)
3641 dash_offset += total_length;
3643 cairo_set_dash (cr, dashes, n_dashes, dash_offset);
3647 cairo_rectangle (cr,
3648 x + line_width / 2.,
3649 y + line_width / 2.,
3651 height - line_width);
3659 gtk_default_draw_slider (GtkStyle *style,
3661 GtkStateType state_type,
3662 GtkShadowType shadow_type,
3664 const gchar *detail,
3669 GtkOrientation orientation)
3671 gtk_paint_box (style, cr, state_type, shadow_type,
3672 widget, detail, x, y, width, height);
3675 (strcmp ("hscale", detail) == 0 ||
3676 strcmp ("vscale", detail) == 0))
3678 if (orientation == GTK_ORIENTATION_HORIZONTAL)
3679 gtk_paint_vline (style, cr, state_type, widget, detail,
3680 y + style->ythickness,
3681 y + height - style->ythickness - 1, x + width / 2);
3683 gtk_paint_hline (style, cr, state_type, widget, detail,
3684 x + style->xthickness,
3685 x + width - style->xthickness - 1, y + height / 2);
3690 draw_dot (cairo_t *cr,
3697 size = CLAMP (size, 2, 3);
3701 _cairo_draw_point (cr, light, x, y);
3702 _cairo_draw_point (cr, light, x+1, y+1);
3706 _cairo_draw_point (cr, light, x, y);
3707 _cairo_draw_point (cr, light, x+1, y);
3708 _cairo_draw_point (cr, light, x, y+1);
3709 _cairo_draw_point (cr, dark, x+1, y+2);
3710 _cairo_draw_point (cr, dark, x+2, y+1);
3711 _cairo_draw_point (cr, dark, x+2, y+2);
3716 gtk_default_draw_handle (GtkStyle *style,
3718 GtkStateType state_type,
3719 GtkShadowType shadow_type,
3721 const gchar *detail,
3726 GtkOrientation orientation)
3729 gint xthick, ythick;
3730 GdkColor light, dark;
3732 gtk_paint_box (style, cr, state_type, shadow_type, widget,
3733 detail, x, y, width, height);
3735 if (detail && !strcmp (detail, "paned"))
3737 /* we want to ignore the shadow border in paned widgets */
3741 if (state_type == GTK_STATE_SELECTED && widget && !gtk_widget_has_focus (widget))
3742 _gtk_style_shade (&style->base[GTK_STATE_ACTIVE], &light,
3745 light = style->light[state_type];
3747 dark = style->black;
3751 xthick = style->xthickness;
3752 ythick = style->ythickness;
3754 light = style->light[state_type];
3755 dark = style->dark[state_type];
3758 cairo_rectangle(cr, x + xthick, y + ythick,
3759 width - (xthick * 2), height - (ythick * 2));
3762 if (detail && !strcmp (detail, "paned"))
3764 if (orientation == GTK_ORIENTATION_HORIZONTAL)
3765 for (xx = x + width/2 - 15; xx <= x + width/2 + 15; xx += 5)
3766 draw_dot (cr, &light, &dark, xx, y + height/2 - 1, 3);
3768 for (yy = y + height/2 - 15; yy <= y + height/2 + 15; yy += 5)
3769 draw_dot (cr, &light, &dark, x + width/2 - 1, yy, 3);
3773 for (yy = y + ythick; yy < (y + height - ythick); yy += 3)
3774 for (xx = x + xthick; xx < (x + width - xthick); xx += 6)
3776 draw_dot (cr, &light, &dark, xx, yy, 2);
3777 draw_dot (cr, &light, &dark, xx + 3, yy + 1, 2);
3783 gtk_default_draw_expander (GtkStyle *style,
3785 GtkStateType state_type,
3787 const gchar *detail,
3790 GtkExpanderStyle expander_style)
3792 #define DEFAULT_EXPANDER_SIZE 12
3796 double vertical_overshoot;
3799 double interp; /* interpolation factor for center position */
3800 double x_double_horz, y_double_horz;
3801 double x_double_vert, y_double_vert;
3802 double x_double, y_double;
3806 gtk_widget_class_find_style_property (GTK_WIDGET_GET_CLASS (widget),
3809 gtk_widget_style_get (widget,
3810 "expander-size", &expander_size,
3814 expander_size = DEFAULT_EXPANDER_SIZE;
3816 line_width = MAX (1, expander_size/9);
3818 switch (expander_style)
3820 case GTK_EXPANDER_COLLAPSED:
3821 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 180 : 0;
3824 case GTK_EXPANDER_SEMI_COLLAPSED:
3825 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 150 : 30;
3828 case GTK_EXPANDER_SEMI_EXPANDED:
3829 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 120 : 60;
3832 case GTK_EXPANDER_EXPANDED:
3837 g_assert_not_reached ();
3840 /* Compute distance that the stroke extends beyonds the end
3841 * of the triangle we draw.
3843 vertical_overshoot = line_width / 2.0 * (1. / tan (G_PI / 8));
3845 /* For odd line widths, we end the vertical line of the triangle
3846 * at a half pixel, so we round differently.
3848 if (line_width % 2 == 1)
3849 vertical_overshoot = ceil (0.5 + vertical_overshoot) - 0.5;
3851 vertical_overshoot = ceil (vertical_overshoot);
3853 /* Adjust the size of the triangle we draw so that the entire stroke fits
3855 diameter = MAX (3, expander_size - 2 * vertical_overshoot);
3857 /* If the line width is odd, we want the diameter to be even,
3858 * and vice versa, so force the sum to be odd. This relationship
3859 * makes the point of the triangle look right.
3861 diameter -= (1 - (diameter + line_width) % 2);
3863 radius = diameter / 2.;
3865 /* Adjust the center so that the stroke is properly aligned with
3866 * the pixel grid. The center adjustment is different for the
3867 * horizontal and vertical orientations. For intermediate positions
3868 * we interpolate between the two.
3870 x_double_vert = floor (x - (radius + line_width) / 2.) + (radius + line_width) / 2.;
3871 y_double_vert = y - 0.5;
3873 x_double_horz = x - 0.5;
3874 y_double_horz = floor (y - (radius + line_width) / 2.) + (radius + line_width) / 2.;
3876 x_double = x_double_vert * (1 - interp) + x_double_horz * interp;
3877 y_double = y_double_vert * (1 - interp) + y_double_horz * interp;
3879 cairo_translate (cr, x_double, y_double);
3880 cairo_rotate (cr, degrees * G_PI / 180);
3882 cairo_move_to (cr, - radius / 2., - radius);
3883 cairo_line_to (cr, radius / 2., 0);
3884 cairo_line_to (cr, - radius / 2., radius);
3885 cairo_close_path (cr);
3887 cairo_set_line_width (cr, line_width);
3889 if (state_type == GTK_STATE_PRELIGHT)
3890 gdk_cairo_set_source_color (cr,
3891 &style->fg[GTK_STATE_PRELIGHT]);
3892 else if (state_type == GTK_STATE_ACTIVE)
3893 gdk_cairo_set_source_color (cr,
3894 &style->light[GTK_STATE_ACTIVE]);
3896 gdk_cairo_set_source_color (cr,
3897 &style->base[GTK_STATE_NORMAL]);
3899 cairo_fill_preserve (cr);
3901 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3906 gtk_default_draw_layout (GtkStyle *style,
3908 GtkStateType state_type,
3911 const gchar *detail,
3914 PangoLayout *layout)
3917 const PangoMatrix *matrix;
3919 matrix = pango_context_get_matrix (pango_layout_get_context (layout));
3922 cairo_matrix_t cairo_matrix;
3923 PangoMatrix tmp_matrix;
3924 PangoRectangle rect;
3926 cairo_matrix_init (&cairo_matrix,
3927 matrix->xx, matrix->yx,
3928 matrix->xy, matrix->yy,
3929 matrix->x0, matrix->y0);
3931 pango_layout_get_extents (layout, NULL, &rect);
3932 pango_matrix_transform_rectangle (matrix, &rect);
3933 pango_extents_to_pixels (&rect, NULL);
3935 tmp_matrix = *matrix;
3936 cairo_matrix.x0 += x - rect.x;
3937 cairo_matrix.y0 += y - rect.y;
3939 cairo_set_matrix (cr, &cairo_matrix);
3942 cairo_translate (cr, x, y);
3944 cairo_new_path (cr);
3946 if (state_type == GTK_STATE_INSENSITIVE)
3948 gdk_cairo_set_source_color (cr, &style->white);
3949 cairo_move_to (cr, 1, 1);
3950 _gtk_pango_fill_layout (cr, layout);
3951 cairo_new_path (cr);
3954 gc = use_text ? &style->text[state_type] : &style->fg[state_type];
3956 gdk_cairo_set_source_color (cr, gc);
3958 pango_cairo_show_layout (cr, layout);
3962 gtk_default_draw_resize_grip (GtkStyle *style,
3964 GtkStateType state_type,
3966 const gchar *detail,
3975 cairo_rectangle (cr, x, y, width, height);
3978 cairo_set_line_width (cr, 1.0);
3983 case GDK_WINDOW_EDGE_NORTH_WEST:
3984 /* make it square */
3987 else if (height < width)
3991 case GDK_WINDOW_EDGE_NORTH:
3995 case GDK_WINDOW_EDGE_NORTH_EAST:
3996 /* make it square, aligning to top right */
3999 else if (height < width)
4001 x += (width - height);
4006 case GDK_WINDOW_EDGE_WEST:
4010 case GDK_WINDOW_EDGE_EAST:
4011 /* aligning to right */
4014 x += (width - height);
4018 case GDK_WINDOW_EDGE_SOUTH_WEST:
4019 /* make it square, aligning to bottom left */
4022 y += (height - width);
4025 else if (height < width)
4029 case GDK_WINDOW_EDGE_SOUTH:
4030 /* align to bottom */
4033 y += (height - width);
4037 case GDK_WINDOW_EDGE_SOUTH_EAST:
4038 /* make it square, aligning to bottom right */
4041 y += (height - width);
4044 else if (height < width)
4046 x += (width - height);
4052 g_assert_not_reached ();
4057 case GDK_WINDOW_EDGE_WEST:
4058 case GDK_WINDOW_EDGE_EAST:
4064 while (xi < x + width)
4066 _cairo_draw_line (cr,
4067 &style->light[state_type],
4072 _cairo_draw_line (cr,
4073 &style->dark[state_type],
4081 case GDK_WINDOW_EDGE_NORTH:
4082 case GDK_WINDOW_EDGE_SOUTH:
4088 while (yi < y + height)
4090 _cairo_draw_line (cr,
4091 &style->light[state_type],
4096 _cairo_draw_line (cr,
4097 &style->dark[state_type],
4105 case GDK_WINDOW_EDGE_NORTH_WEST:
4114 _cairo_draw_line (cr,
4115 &style->dark[state_type],
4122 _cairo_draw_line (cr,
4123 &style->dark[state_type],
4130 _cairo_draw_line (cr,
4131 &style->light[state_type],
4141 case GDK_WINDOW_EDGE_NORTH_EAST:
4148 while (xi < (x + width - 3))
4150 _cairo_draw_line (cr,
4151 &style->light[state_type],
4158 _cairo_draw_line (cr,
4159 &style->dark[state_type],
4166 _cairo_draw_line (cr,
4167 &style->dark[state_type],
4176 case GDK_WINDOW_EDGE_SOUTH_WEST:
4185 _cairo_draw_line (cr,
4186 &style->dark[state_type],
4193 _cairo_draw_line (cr,
4194 &style->dark[state_type],
4201 _cairo_draw_line (cr,
4202 &style->light[state_type],
4212 case GDK_WINDOW_EDGE_SOUTH_EAST:
4219 while (xi < (x + width - 3))
4221 _cairo_draw_line (cr,
4222 &style->light[state_type],
4229 _cairo_draw_line (cr,
4230 &style->dark[state_type],
4237 _cairo_draw_line (cr,
4238 &style->dark[state_type],
4248 g_assert_not_reached ();
4254 gtk_default_draw_spinner (GtkStyle *style,
4256 GtkStateType state_type,
4258 const gchar *detail,
4273 gtk_style_get (style, GTK_TYPE_SPINNER,
4274 "num-steps", &num_steps,
4276 real_step = step % num_steps;
4278 /* set a clip region for the expose event */
4279 cairo_rectangle (cr, x, y, width, height);
4282 cairo_translate (cr, x, y);
4284 /* draw clip region */
4285 cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
4287 color = &style->fg[state_type];
4290 radius = MIN (width / 2, height / 2);
4291 half = num_steps / 2;
4293 for (i = 0; i < num_steps; i++)
4295 gint inset = 0.7 * radius;
4297 /* transparency is a function of time and intial value */
4298 gdouble t = (gdouble) ((i + num_steps - real_step)
4299 % num_steps) / num_steps;
4303 cairo_set_source_rgba (cr,
4304 color->red / 65535.,
4305 color->green / 65535.,
4306 color->blue / 65535.,
4309 cairo_set_line_width (cr, 2.0);
4311 dx + (radius - inset) * cos (i * G_PI / half),
4312 dy + (radius - inset) * sin (i * G_PI / half));
4314 dx + radius * cos (i * G_PI / half),
4315 dy + radius * sin (i * G_PI / half));
4323 _gtk_style_shade (const GdkColor *a,
4331 red = (gdouble) a->red / 65535.0;
4332 green = (gdouble) a->green / 65535.0;
4333 blue = (gdouble) a->blue / 65535.0;
4335 rgb_to_hls (&red, &green, &blue);
4340 else if (green < 0.0)
4346 else if (blue < 0.0)
4349 hls_to_rgb (&red, &green, &blue);
4351 b->red = red * 65535.0;
4352 b->green = green * 65535.0;
4353 b->blue = blue * 65535.0;
4357 rgb_to_hls (gdouble *r,
4398 l = (max + min) / 2;
4405 s = (max - min) / (max + min);
4407 s = (max - min) / (2 - max - min);
4411 h = (green - blue) / delta;
4412 else if (green == max)
4413 h = 2 + (blue - red) / delta;
4414 else if (blue == max)
4415 h = 4 + (red - green) / delta;
4428 hls_to_rgb (gdouble *h,
4441 if (lightness <= 0.5)
4442 m2 = lightness * (1 + saturation);
4444 m2 = lightness + saturation - lightness * saturation;
4445 m1 = 2 * lightness - m2;
4447 if (saturation == 0)
4462 r = m1 + (m2 - m1) * hue / 60;
4466 r = m1 + (m2 - m1) * (240 - hue) / 60;
4477 g = m1 + (m2 - m1) * hue / 60;
4481 g = m1 + (m2 - m1) * (240 - hue) / 60;
4492 b = m1 + (m2 - m1) * hue / 60;
4496 b = m1 + (m2 - m1) * (240 - hue) / 60;
4509 * @style: a #GtkStyle
4511 * @state_type: a state
4512 * @widget: (allow-none): the widget
4513 * @detail: (allow-none): a style detail
4514 * @x1: the starting x coordinate
4515 * @x2: the ending x coordinate
4516 * @y: the y coordinate
4518 * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @cr
4519 * using the given style and state.
4522 gtk_paint_hline (GtkStyle *style,
4524 GtkStateType state_type,
4526 const gchar *detail,
4531 g_return_if_fail (GTK_IS_STYLE (style));
4532 g_return_if_fail (cr != NULL);
4533 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
4537 GTK_STYLE_GET_CLASS (style)->draw_hline (style, cr, state_type,
4546 * @style: a #GtkStyle
4548 * @state_type: a state
4549 * @widget: (allow-none): the widget
4550 * @detail: (allow-none): a style detail
4551 * @y1_: the starting y coordinate
4552 * @y2_: the ending y coordinate
4553 * @x: the x coordinate
4555 * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @cr
4556 * using the given style and state.
4559 gtk_paint_vline (GtkStyle *style,
4561 GtkStateType state_type,
4563 const gchar *detail,
4568 g_return_if_fail (GTK_IS_STYLE (style));
4569 g_return_if_fail (cr != NULL);
4570 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
4574 GTK_STYLE_GET_CLASS (style)->draw_vline (style, cr, state_type,
4583 * @style: a #GtkStyle
4585 * @state_type: a state
4586 * @shadow_type: type of shadow to draw
4587 * @widget: (allow-none): the widget
4588 * @detail: (allow-none): a style detail
4589 * @x: x origin of the rectangle
4590 * @y: y origin of the rectangle
4591 * @width: width of the rectangle
4592 * @height: width of the rectangle
4594 * Draws a shadow around the given rectangle in @cr
4595 * using the given style and state and shadow type.
4598 gtk_paint_shadow (GtkStyle *style,
4600 GtkStateType state_type,
4601 GtkShadowType shadow_type,
4603 const gchar *detail,
4609 g_return_if_fail (GTK_IS_STYLE (style));
4610 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
4611 g_return_if_fail (cr != NULL);
4612 g_return_if_fail (width >= 0);
4613 g_return_if_fail (height >= 0);
4617 GTK_STYLE_GET_CLASS (style)->draw_shadow (style, cr, state_type, shadow_type,
4619 x, y, width, height);
4626 * @style: a #GtkStyle
4628 * @state_type: a state
4629 * @shadow_type: the type of shadow to draw
4630 * @widget: (allow-none): the widget
4631 * @detail: (allow-none): a style detail
4632 * @arrow_type: the type of arrow to draw
4633 * @fill: %TRUE if the arrow tip should be filled
4634 * @x: x origin of the rectangle to draw the arrow in
4635 * @y: y origin of the rectangle to draw the arrow in
4636 * @width: width of the rectangle to draw the arrow in
4637 * @height: height of the rectangle to draw the arrow in
4639 * Draws an arrow in the given rectangle on @cr using the given
4640 * parameters. @arrow_type determines the direction of the arrow.
4643 gtk_paint_arrow (GtkStyle *style,
4645 GtkStateType state_type,
4646 GtkShadowType shadow_type,
4648 const gchar *detail,
4649 GtkArrowType arrow_type,
4656 g_return_if_fail (GTK_IS_STYLE (style));
4657 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
4658 g_return_if_fail (cr != NULL);
4659 g_return_if_fail (width >= 0);
4660 g_return_if_fail (height >= 0);
4664 GTK_STYLE_GET_CLASS (style)->draw_arrow (style, cr, state_type, shadow_type,
4666 arrow_type, fill, x, y, width, height);
4672 * gtk_paint_diamond:
4673 * @style: a #GtkStyle
4675 * @state_type: a state
4676 * @shadow_type: the type of shadow to draw
4677 * @widget: (allow-none): the widget
4678 * @detail: (allow-none): a style detail
4679 * @x: x origin of the rectangle to draw the diamond in
4680 * @y: y origin of the rectangle to draw the diamond in
4681 * @width: width of the rectangle to draw the diamond in
4682 * @height: height of the rectangle to draw the diamond in
4684 * Draws a diamond in the given rectangle on @window using the given
4688 gtk_paint_diamond (GtkStyle *style,
4690 GtkStateType state_type,
4691 GtkShadowType shadow_type,
4693 const gchar *detail,
4699 g_return_if_fail (GTK_IS_STYLE (style));
4700 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
4701 g_return_if_fail (cr != NULL);
4702 g_return_if_fail (width >= 0);
4703 g_return_if_fail (height >= 0);
4707 GTK_STYLE_GET_CLASS (style)->draw_diamond (style, cr, state_type, shadow_type,
4709 x, y, width, height);
4716 * @style: a #GtkStyle
4718 * @state_type: a state
4719 * @shadow_type: the type of shadow to draw
4720 * @widget: (allow-none): the widget
4721 * @detail: (allow-none): a style detail
4722 * @x: x origin of the box
4723 * @y: y origin of the box
4724 * @width: the width of the box
4725 * @height: the height of the box
4727 * Draws a box on @cr with the given parameters.
4730 gtk_paint_box (GtkStyle *style,
4732 GtkStateType state_type,
4733 GtkShadowType shadow_type,
4735 const gchar *detail,
4741 g_return_if_fail (GTK_IS_STYLE (style));
4742 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
4743 g_return_if_fail (cr != NULL);
4747 GTK_STYLE_GET_CLASS (style)->draw_box (style, cr, state_type, shadow_type,
4749 x, y, width, height);
4755 * gtk_paint_flat_box:
4756 * @style: a #GtkStyle
4758 * @state_type: a state
4759 * @shadow_type: the type of shadow to draw
4760 * @area: (allow-none): clip rectangle, or %NULL if the
4761 * output should not be clipped
4762 * @widget: (allow-none): the widget
4763 * @detail: (allow-none): a style detail
4764 * @x: x origin of the box
4765 * @y: y origin of the box
4766 * @width: the width of the box
4767 * @height: the height of the box
4769 * Draws a flat box on @cr with the given parameters.
4772 gtk_paint_flat_box (GtkStyle *style,
4774 GtkStateType state_type,
4775 GtkShadowType shadow_type,
4777 const gchar *detail,
4783 g_return_if_fail (GTK_IS_STYLE (style));
4784 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
4785 g_return_if_fail (cr != NULL);
4786 g_return_if_fail (width >= 0);
4787 g_return_if_fail (height >= 0);
4791 GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, cr, state_type, shadow_type,
4793 x, y, width, height);
4800 * @style: a #GtkStyle
4802 * @state_type: a state
4803 * @shadow_type: the type of shadow to draw
4804 * @widget: (allow-none): the widget
4805 * @detail: (allow-none): a style detail
4806 * @x: x origin of the rectangle to draw the check in
4807 * @y: y origin of the rectangle to draw the check in
4808 * @width: the width of the rectangle to draw the check in
4809 * @height: the height of the rectangle to draw the check in
4811 * Draws a check button indicator in the given rectangle on @cr with
4812 * the given parameters.
4815 gtk_paint_check (GtkStyle *style,
4817 GtkStateType state_type,
4818 GtkShadowType shadow_type,
4820 const gchar *detail,
4826 g_return_if_fail (GTK_IS_STYLE (style));
4827 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
4828 g_return_if_fail (cr != NULL);
4832 GTK_STYLE_GET_CLASS (style)->draw_check (style, cr, state_type, shadow_type,
4834 x, y, width, height);
4841 * @style: a #GtkStyle
4843 * @state_type: a state
4844 * @shadow_type: the type of shadow to draw
4845 * @widget: (allow-none): the widget
4846 * @detail: (allow-none): a style detail
4847 * @x: x origin of the rectangle to draw the option in
4848 * @y: y origin of the rectangle to draw the option in
4849 * @width: the width of the rectangle to draw the option in
4850 * @height: the height of the rectangle to draw the option in
4852 * Draws a radio button indicator in the given rectangle on @cr with
4853 * the given parameters.
4856 gtk_paint_option (GtkStyle *style,
4858 GtkStateType state_type,
4859 GtkShadowType shadow_type,
4861 const gchar *detail,
4867 g_return_if_fail (GTK_IS_STYLE (style));
4868 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
4869 g_return_if_fail (cr != NULL);
4873 GTK_STYLE_GET_CLASS (style)->draw_option (style, cr, state_type, shadow_type,
4875 x, y, width, height);
4882 * @style: a #GtkStyle
4884 * @state_type: a state
4885 * @shadow_type: the type of shadow to draw
4886 * @widget: (allow-none): the widget
4887 * @detail: (allow-none): a style detail
4888 * @x: x origin of the rectangle to draw the tab in
4889 * @y: y origin of the rectangle to draw the tab in
4890 * @width: the width of the rectangle to draw the tab in
4891 * @height: the height of the rectangle to draw the tab in
4893 * Draws an option menu tab (i.e. the up and down pointing arrows)
4894 * in the given rectangle on @cr using the given parameters.
4897 gtk_paint_tab (GtkStyle *style,
4899 GtkStateType state_type,
4900 GtkShadowType shadow_type,
4902 const gchar *detail,
4908 g_return_if_fail (GTK_IS_STYLE (style));
4909 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
4910 g_return_if_fail (cr != NULL);
4914 GTK_STYLE_GET_CLASS (style)->draw_tab (style, cr, state_type, shadow_type,
4916 x, y, width, height);
4922 * gtk_paint_shadow_gap:
4923 * @style: a #GtkStyle
4925 * @state_type: a state
4926 * @shadow_type: type of shadow to draw
4927 * @widget: (allow-none): the widget
4928 * @detail: (allow-none): a style detail
4929 * @x: x origin of the rectangle
4930 * @y: y origin of the rectangle
4931 * @width: width of the rectangle
4932 * @height: width of the rectangle
4933 * @gap_side: side in which to leave the gap
4934 * @gap_x: starting position of the gap
4935 * @gap_width: width of the gap
4937 * Draws a shadow around the given rectangle in @cr
4938 * using the given style and state and shadow type, leaving a
4942 gtk_paint_shadow_gap (GtkStyle *style,
4944 GtkStateType state_type,
4945 GtkShadowType shadow_type,
4947 const gchar *detail,
4952 GtkPositionType gap_side,
4956 g_return_if_fail (GTK_IS_STYLE (style));
4957 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
4958 g_return_if_fail (cr != NULL);
4959 g_return_if_fail (width >= 0);
4960 g_return_if_fail (height >= 0);
4964 GTK_STYLE_GET_CLASS (style)->draw_shadow_gap (style, cr, state_type, shadow_type,
4966 x, y, width, height, gap_side, gap_x, gap_width);
4972 * gtk_paint_box_gap:
4973 * @style: a #GtkStyle
4975 * @state_type: a state
4976 * @shadow_type: type of shadow to draw
4977 * @widget: (allow-none): the widget
4978 * @detail: (allow-none): a style detail
4979 * @x: x origin of the rectangle
4980 * @y: y origin of the rectangle
4981 * @width: width of the rectangle
4982 * @height: width of the rectangle
4983 * @gap_side: side in which to leave the gap
4984 * @gap_x: starting position of the gap
4985 * @gap_width: width of the gap
4987 * Draws a box in @cr using the given style and state and shadow type,
4988 * leaving a gap in one side.
4991 gtk_paint_box_gap (GtkStyle *style,
4993 GtkStateType state_type,
4994 GtkShadowType shadow_type,
4996 const gchar *detail,
5001 GtkPositionType gap_side,
5005 g_return_if_fail (GTK_IS_STYLE (style));
5006 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
5007 g_return_if_fail (cr != NULL);
5008 g_return_if_fail (width >= 0);
5009 g_return_if_fail (height >= 0);
5013 GTK_STYLE_GET_CLASS (style)->draw_box_gap (style, cr, state_type, shadow_type,
5015 x, y, width, height, gap_side, gap_x, gap_width);
5021 * gtk_paint_extension:
5022 * @style: a #GtkStyle
5024 * @state_type: a state
5025 * @shadow_type: type of shadow to draw
5026 * @widget: (allow-none): the widget
5027 * @detail: (allow-none): a style detail
5028 * @x: x origin of the extension
5029 * @y: y origin of the extension
5030 * @width: width of the extension
5031 * @height: width of the extension
5032 * @gap_side: the side on to which the extension is attached
5034 * Draws an extension, i.e. a notebook tab.
5037 gtk_paint_extension (GtkStyle *style,
5039 GtkStateType state_type,
5040 GtkShadowType shadow_type,
5042 const gchar *detail,
5047 GtkPositionType gap_side)
5049 g_return_if_fail (GTK_IS_STYLE (style));
5050 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
5051 g_return_if_fail (cr != NULL);
5052 g_return_if_fail (width >= 0);
5053 g_return_if_fail (height >= 0);
5057 GTK_STYLE_GET_CLASS (style)->draw_extension (style, cr, state_type, shadow_type,
5059 x, y, width, height, gap_side);
5066 * @style: a #GtkStyle
5068 * @state_type: a state
5069 * @widget: (allow-none): the widget
5070 * @detail: (allow-none): a style detail
5071 * @x: the x origin of the rectangle around which to draw a focus indicator
5072 * @y: the y origin of the rectangle around which to draw a focus indicator
5073 * @width: the width of the rectangle around which to draw a focus indicator
5074 * @height: the height of the rectangle around which to draw a focus indicator
5076 * Draws a focus indicator around the given rectangle on @cr using the
5080 gtk_paint_focus (GtkStyle *style,
5082 GtkStateType state_type,
5084 const gchar *detail,
5090 g_return_if_fail (GTK_IS_STYLE (style));
5091 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
5092 g_return_if_fail (cr != NULL);
5093 g_return_if_fail (width >= 0);
5094 g_return_if_fail (height >= 0);
5098 GTK_STYLE_GET_CLASS (style)->draw_focus (style, cr, state_type,
5100 x, y, width, height);
5107 * @style: a #GtkStyle
5109 * @state_type: a state
5110 * @shadow_type: a shadow
5111 * @widget: (allow-none): the widget
5112 * @detail: (allow-none): a style detail
5113 * @x: the x origin of the rectangle in which to draw a slider
5114 * @y: the y origin of the rectangle in which to draw a slider
5115 * @width: the width of the rectangle in which to draw a slider
5116 * @height: the height of the rectangle in which to draw a slider
5117 * @orientation: the orientation to be used
5119 * Draws a slider in the given rectangle on @cr using the
5120 * given style and orientation.
5123 gtk_paint_slider (GtkStyle *style,
5125 GtkStateType state_type,
5126 GtkShadowType shadow_type,
5128 const gchar *detail,
5133 GtkOrientation orientation)
5135 g_return_if_fail (GTK_IS_STYLE (style));
5136 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
5137 g_return_if_fail (cr != NULL);
5138 g_return_if_fail (width >= 0);
5139 g_return_if_fail (height >= 0);
5143 GTK_STYLE_GET_CLASS (style)->draw_slider (style, cr, state_type, shadow_type,
5145 x, y, width, height, orientation);
5152 * @style: a #GtkStyle
5154 * @state_type: a state
5155 * @shadow_type: type of shadow to draw
5156 * @widget: (allow-none): the widget
5157 * @detail: (allow-none): a style detail
5158 * @x: x origin of the handle
5159 * @y: y origin of the handle
5160 * @width: with of the handle
5161 * @height: height of the handle
5162 * @orientation: the orientation of the handle
5164 * Draws a handle as used in #GtkHandleBox and #GtkPaned.
5167 gtk_paint_handle (GtkStyle *style,
5169 GtkStateType state_type,
5170 GtkShadowType shadow_type,
5172 const gchar *detail,
5177 GtkOrientation orientation)
5179 g_return_if_fail (GTK_IS_STYLE (style));
5180 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
5181 g_return_if_fail (cr != NULL);
5182 g_return_if_fail (width >= 0);
5183 g_return_if_fail (height >= 0);
5187 GTK_STYLE_GET_CLASS (style)->draw_handle (style, cr, state_type, shadow_type,
5189 x, y, width, height, orientation);
5195 * gtk_paint_expander:
5196 * @style: a #GtkStyle
5198 * @state_type: a state
5199 * @widget: (allow-none): the widget
5200 * @detail: (allow-none): a style detail
5201 * @x: the x position to draw the expander at
5202 * @y: the y position to draw the expander at
5203 * @expander_style: the style to draw the expander in; determines
5204 * whether the expander is collapsed, expanded, or in an
5205 * intermediate state.
5207 * Draws an expander as used in #GtkTreeView. @x and @y specify the
5208 * center the expander. The size of the expander is determined by the
5209 * "expander-size" style property of @widget. (If widget is not
5210 * specified or doesn't have an "expander-size" property, an
5211 * unspecified default size will be used, since the caller doesn't
5212 * have sufficient information to position the expander, this is
5213 * likely not useful.) The expander is expander_size pixels tall
5214 * in the collapsed position and expander_size pixels wide in the
5215 * expanded position.
5218 gtk_paint_expander (GtkStyle *style,
5220 GtkStateType state_type,
5222 const gchar *detail,
5225 GtkExpanderStyle expander_style)
5227 g_return_if_fail (GTK_IS_STYLE (style));
5228 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
5229 g_return_if_fail (cr != NULL);
5233 GTK_STYLE_GET_CLASS (style)->draw_expander (style, cr, state_type,
5235 x, y, expander_style);
5242 * @style: a #GtkStyle
5244 * @state_type: a state
5245 * @use_text: whether to use the text or foreground
5246 * graphics context of @style
5247 * @widget: (allow-none): the widget
5248 * @detail: (allow-none): a style detail
5251 * @layout: the layout to draw
5253 * Draws a layout on @cr using the given parameters.
5256 gtk_paint_layout (GtkStyle *style,
5258 GtkStateType state_type,
5261 const gchar *detail,
5264 PangoLayout *layout)
5266 g_return_if_fail (GTK_IS_STYLE (style));
5267 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
5268 g_return_if_fail (cr != NULL);
5272 GTK_STYLE_GET_CLASS (style)->draw_layout (style, cr, state_type, use_text,
5280 * gtk_paint_resize_grip:
5281 * @style: a #GtkStyle
5283 * @state_type: a state
5284 * @widget: (allow-none): the widget
5285 * @detail: (allow-none): a style detail
5286 * @edge: the edge in which to draw the resize grip
5287 * @x: the x origin of the rectangle in which to draw the resize grip
5288 * @y: the y origin of the rectangle in which to draw the resize grip
5289 * @width: the width of the rectangle in which to draw the resize grip
5290 * @height: the height of the rectangle in which to draw the resize grip
5292 * Draws a resize grip in the given rectangle on @cr using the given
5296 gtk_paint_resize_grip (GtkStyle *style,
5298 GtkStateType state_type,
5300 const gchar *detail,
5307 g_return_if_fail (GTK_IS_STYLE (style));
5308 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
5309 g_return_if_fail (cr != NULL);
5313 GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, cr, state_type,
5315 edge, x, y, width, height);
5320 * gtk_paint_spinner:
5321 * @style: a #GtkStyle
5323 * @state_type: a state
5324 * @widget: (allow-none): the widget (may be %NULL)
5325 * @detail: (allow-none): a style detail (may be %NULL)
5326 * @step: the nth step, a value between 0 and #GtkSpinner:num-steps
5327 * @x: the x origin of the rectangle in which to draw the spinner
5328 * @y: the y origin of the rectangle in which to draw the spinner
5329 * @width: the width of the rectangle in which to draw the spinner
5330 * @height: the height of the rectangle in which to draw the spinner
5332 * Draws a spinner on @window using the given parameters.
5335 gtk_paint_spinner (GtkStyle *style,
5337 GtkStateType state_type,
5339 const gchar *detail,
5346 g_return_if_fail (GTK_IS_STYLE (style));
5347 g_return_if_fail (cr != NULL);
5348 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_spinner != NULL);
5352 GTK_STYLE_GET_CLASS (style)->draw_spinner (style, cr, state_type,
5354 step, x, y, width, height);
5362 * Allocates a new #GtkBorder structure and initializes its elements to zero.
5364 * Returns: a new empty #GtkBorder. The newly allocated #GtkBorder should be
5365 * freed with gtk_border_free()
5370 gtk_border_new (void)
5372 return g_slice_new0 (GtkBorder);
5377 * @border_: a #GtkBorder.
5378 * @returns: a copy of @border_.
5380 * Copies a #GtkBorder structure.
5383 gtk_border_copy (const GtkBorder *border)
5385 g_return_val_if_fail (border != NULL, NULL);
5387 return g_slice_dup (GtkBorder, border);
5392 * @border_: a #GtkBorder.
5394 * Frees a #GtkBorder structure.
5397 gtk_border_free (GtkBorder *border)
5399 g_slice_free (GtkBorder, border);
5402 G_DEFINE_BOXED_TYPE (GtkBorder, gtk_border,
5406 typedef struct _CursorInfo CursorInfo;
5416 style_unrealize_cursors (GtkStyle *style)
5420 cursor_info = g_object_get_data (G_OBJECT (style), "gtk-style-cursor-info");
5423 g_free (cursor_info);
5424 g_object_set_data (G_OBJECT (style), I_("gtk-style-cursor-info"), NULL);
5428 static const GdkColor *
5429 get_insertion_cursor_color (GtkWidget *widget,
5430 gboolean is_primary)
5432 CursorInfo *cursor_info;
5434 GdkColor *cursor_color;
5436 style = gtk_widget_get_style (widget);
5438 cursor_info = g_object_get_data (G_OBJECT (style), "gtk-style-cursor-info");
5441 cursor_info = g_new0 (CursorInfo, 1);
5442 g_object_set_data (G_OBJECT (style), I_("gtk-style-cursor-info"), cursor_info);
5443 cursor_info->for_type = G_TYPE_INVALID;
5446 /* We have to keep track of the type because gtk_widget_style_get()
5447 * can return different results when called on the same property and
5448 * same style but for different widgets. :-(. That is,
5449 * GtkEntry::cursor-color = "red" in a style will modify the cursor
5450 * color for entries but not for text view.
5452 if (cursor_info->for_type != G_OBJECT_TYPE (widget))
5454 cursor_info->for_type = G_OBJECT_TYPE (widget);
5456 /* Cursors in text widgets are drawn only in NORMAL state,
5457 * so we can use text[GTK_STATE_NORMAL] as text color here */
5458 gtk_widget_style_get (widget, "cursor-color", &cursor_color, NULL);
5461 cursor_info->primary = *cursor_color;
5462 gdk_color_free (cursor_color);
5466 cursor_info->primary = style->text[GTK_STATE_NORMAL];
5469 gtk_widget_style_get (widget, "secondary-cursor-color", &cursor_color, NULL);
5472 cursor_info->secondary = *cursor_color;
5473 gdk_color_free (cursor_color);
5477 /* text_aa is the average of text and base colors,
5478 * in usual black-on-white case it's grey. */
5479 cursor_info->secondary = style->text_aa[GTK_STATE_NORMAL];
5484 return &cursor_info->primary;
5486 return &cursor_info->secondary;
5490 _gtk_widget_get_cursor_color (GtkWidget *widget,
5493 GdkColor *style_color;
5495 g_return_if_fail (GTK_IS_WIDGET (widget));
5496 g_return_if_fail (color != NULL);
5498 gtk_widget_style_get (widget, "cursor-color", &style_color, NULL);
5502 *color = *style_color;
5503 gdk_color_free (style_color);
5506 *color = gtk_widget_get_style (widget)->text[GTK_STATE_NORMAL];
5510 * gtk_draw_insertion_cursor:
5511 * @widget: a #GtkWidget
5512 * @cr: cairo context to draw to
5513 * @location: location where to draw the cursor (@location->width is ignored)
5514 * @is_primary: if the cursor should be the primary cursor color.
5515 * @direction: whether the cursor is left-to-right or
5516 * right-to-left. Should never be #GTK_TEXT_DIR_NONE
5517 * @draw_arrow: %TRUE to draw a directional arrow on the
5518 * cursor. Should be %FALSE unless the cursor is split.
5520 * Draws a text caret on @cr at @location. This is not a style function
5521 * but merely a convenience function for drawing the standard cursor shape.
5526 gtk_draw_insertion_cursor (GtkWidget *widget,
5528 const GdkRectangle *location,
5529 gboolean is_primary,
5530 GtkTextDirection direction,
5531 gboolean draw_arrow)
5536 gfloat cursor_aspect_ratio;
5539 g_return_if_fail (GTK_IS_WIDGET (widget));
5540 g_return_if_fail (cr != NULL);
5541 g_return_if_fail (location != NULL);
5542 g_return_if_fail (direction != GTK_TEXT_DIR_NONE);
5544 gdk_cairo_set_source_color (cr, get_insertion_cursor_color (widget, is_primary));
5546 /* When changing the shape or size of the cursor here,
5547 * propagate the changes to gtktextview.c:text_window_invalidate_cursors().
5550 gtk_widget_style_get (widget, "cursor-aspect-ratio", &cursor_aspect_ratio, NULL);
5552 stem_width = location->height * cursor_aspect_ratio + 1;
5553 arrow_width = stem_width + 1;
5555 /* put (stem_width % 2) on the proper side of the cursor */
5556 if (direction == GTK_TEXT_DIR_LTR)
5557 offset = stem_width / 2;
5559 offset = stem_width - stem_width / 2;
5561 cairo_rectangle (cr,
5562 location->x - offset, location->y,
5563 stem_width, location->height);
5568 if (direction == GTK_TEXT_DIR_RTL)
5570 x = location->x - offset - 1;
5571 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
5573 cairo_move_to (cr, x, y + 1);
5574 cairo_line_to (cr, x - arrow_width, y + arrow_width);
5575 cairo_line_to (cr, x, y + 2 * arrow_width);
5578 else if (direction == GTK_TEXT_DIR_LTR)
5580 x = location->x + stem_width - offset;
5581 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
5583 cairo_move_to (cr, x, y + 1);
5584 cairo_line_to (cr, x + arrow_width, y + arrow_width);
5585 cairo_line_to (cr, x, y + 2 * arrow_width);