1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
31 #include <gobject/gvaluecollector.h>
32 #include "gtkmarshalers.h"
35 #include "gtkspinbutton.h"
37 #include "gtkwidget.h"
38 #include "gtkthemes.h"
39 #include "gtkiconfactory.h"
40 #include "gtksettings.h" /* _gtk_settings_parse_convert() */
42 #include "gtkspinner.h"
47 * @Short_description: An object that hold style information for widgets
50 * A #GtkStyle object encapsulates the information that provides the look and
51 * feel for a widget. Each #GtkWidget has an associated #GTkStyle object that
52 * is used when rendering that widget. Also, a #GtkStyle holds information for
53 * the five possible widget states though not every widget supports all five
54 * states; see #GtkStateType.
56 * Usually the #GtkStyle for a widget is the same as the default style that is
57 * set by GTK+ and modified the theme engine.
59 * Usually applications should not need to use or modify the #GtkStyle of their
64 #define LIGHTNESS_MULT 1.3
65 #define DARKNESS_MULT 0.7
67 /* --- typedefs & structures --- */
74 #define GTK_STYLE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_STYLE, GtkStylePrivate))
76 typedef struct _GtkStylePrivate GtkStylePrivate;
78 struct _GtkStylePrivate {
82 /* --- prototypes --- */
83 static void gtk_style_finalize (GObject *object);
84 static void gtk_style_realize (GtkStyle *style,
85 GdkColormap *colormap);
86 static void gtk_style_real_realize (GtkStyle *style);
87 static void gtk_style_real_unrealize (GtkStyle *style);
88 static void gtk_style_real_copy (GtkStyle *style,
90 static void gtk_style_real_set_background (GtkStyle *style,
92 GtkStateType state_type);
93 static GtkStyle *gtk_style_real_clone (GtkStyle *style);
94 static void gtk_style_real_init_from_rc (GtkStyle *style,
95 GtkRcStyle *rc_style);
96 static GdkPixbuf *gtk_default_render_icon (GtkStyle *style,
97 const GtkIconSource *source,
98 GtkTextDirection direction,
102 const gchar *detail);
103 static void gtk_default_draw_hline (GtkStyle *style,
105 GtkStateType state_type,
111 static void gtk_default_draw_vline (GtkStyle *style,
113 GtkStateType state_type,
119 static void gtk_default_draw_shadow (GtkStyle *style,
121 GtkStateType state_type,
122 GtkShadowType shadow_type,
129 static void gtk_default_draw_arrow (GtkStyle *style,
131 GtkStateType state_type,
132 GtkShadowType shadow_type,
135 GtkArrowType arrow_type,
141 static void gtk_default_draw_diamond (GtkStyle *style,
143 GtkStateType state_type,
144 GtkShadowType shadow_type,
151 static void gtk_default_draw_box (GtkStyle *style,
153 GtkStateType state_type,
154 GtkShadowType shadow_type,
161 static void gtk_default_draw_flat_box (GtkStyle *style,
163 GtkStateType state_type,
164 GtkShadowType shadow_type,
171 static void gtk_default_draw_check (GtkStyle *style,
173 GtkStateType state_type,
174 GtkShadowType shadow_type,
182 static void gtk_default_draw_option (GtkStyle *style,
184 GtkStateType state_type,
185 GtkShadowType shadow_type,
193 static void gtk_default_draw_tab (GtkStyle *style,
195 GtkStateType state_type,
196 GtkShadowType shadow_type,
204 static void gtk_default_draw_shadow_gap (GtkStyle *style,
206 GtkStateType state_type,
207 GtkShadowType shadow_type,
215 GtkPositionType gap_side,
218 static void gtk_default_draw_box_gap (GtkStyle *style,
220 GtkStateType state_type,
221 GtkShadowType shadow_type,
229 GtkPositionType gap_side,
232 static void gtk_default_draw_extension (GtkStyle *style,
234 GtkStateType state_type,
235 GtkShadowType shadow_type,
243 GtkPositionType gap_side);
244 static void gtk_default_draw_focus (GtkStyle *style,
246 GtkStateType state_type,
254 static void gtk_default_draw_slider (GtkStyle *style,
256 GtkStateType state_type,
257 GtkShadowType shadow_type,
265 GtkOrientation orientation);
266 static void gtk_default_draw_handle (GtkStyle *style,
268 GtkStateType state_type,
269 GtkShadowType shadow_type,
277 GtkOrientation orientation);
278 static void gtk_default_draw_expander (GtkStyle *style,
280 GtkStateType state_type,
286 GtkExpanderStyle expander_style);
287 static void gtk_default_draw_layout (GtkStyle *style,
289 GtkStateType state_type,
296 PangoLayout *layout);
297 static void gtk_default_draw_resize_grip (GtkStyle *style,
299 GtkStateType state_type,
308 static void gtk_default_draw_spinner (GtkStyle *style,
310 GtkStateType state_type,
320 static void rgb_to_hls (gdouble *r,
323 static void hls_to_rgb (gdouble *h,
327 static void style_unrealize_cursors (GtkStyle *style);
330 * Data for default check and radio buttons
333 static const GtkRequisition default_option_indicator_size = { 7, 13 };
334 static const GtkBorder default_option_indicator_spacing = { 7, 5, 2, 2 };
336 #define GTK_GRAY 0xdcdc, 0xdada, 0xd5d5
337 #define GTK_DARK_GRAY 0xc4c4, 0xc2c2, 0xbdbd
338 #define GTK_LIGHT_GRAY 0xeeee, 0xebeb, 0xe7e7
339 #define GTK_WHITE 0xffff, 0xffff, 0xffff
340 #define GTK_BLUE 0x4b4b, 0x6969, 0x8383
341 #define GTK_VERY_DARK_GRAY 0x9c9c, 0x9a9a, 0x9494
342 #define GTK_BLACK 0x0000, 0x0000, 0x0000
343 #define GTK_WEAK_GRAY 0x7530, 0x7530, 0x7530
345 /* --- variables --- */
346 static const GdkColor gtk_default_normal_fg = { 0, GTK_BLACK };
347 static const GdkColor gtk_default_active_fg = { 0, GTK_BLACK };
348 static const GdkColor gtk_default_prelight_fg = { 0, GTK_BLACK };
349 static const GdkColor gtk_default_selected_fg = { 0, GTK_WHITE };
350 static const GdkColor gtk_default_insensitive_fg = { 0, GTK_WEAK_GRAY };
352 static const GdkColor gtk_default_normal_bg = { 0, GTK_GRAY };
353 static const GdkColor gtk_default_active_bg = { 0, GTK_DARK_GRAY };
354 static const GdkColor gtk_default_prelight_bg = { 0, GTK_LIGHT_GRAY };
355 static const GdkColor gtk_default_selected_bg = { 0, GTK_BLUE };
356 static const GdkColor gtk_default_insensitive_bg = { 0, GTK_GRAY };
357 static const GdkColor gtk_default_selected_base = { 0, GTK_BLUE };
358 static const GdkColor gtk_default_active_base = { 0, GTK_VERY_DARK_GRAY };
360 /* --- signals --- */
361 static guint realize_signal = 0;
362 static guint unrealize_signal = 0;
364 G_DEFINE_TYPE (GtkStyle, gtk_style, G_TYPE_OBJECT)
366 /* --- functions --- */
369 * _gtk_style_init_for_settings:
370 * @style: a #GtkStyle
371 * @settings: a #GtkSettings
373 * Initializes the font description in @style according to the default
374 * font name of @settings. This is called for gtk_style_new() with
375 * the settings for the default screen (if any); if we are creating
376 * a style for a particular screen, we then call it again in a
377 * location where we know the correct settings.
378 * The reason for this is that gtk_rc_style_create_style() doesn't
379 * take the screen for an argument.
382 _gtk_style_init_for_settings (GtkStyle *style,
383 GtkSettings *settings)
385 const gchar *font_name = _gtk_rc_context_get_default_font_name (settings);
387 if (style->font_desc)
388 pango_font_description_free (style->font_desc);
390 style->font_desc = pango_font_description_from_string (font_name);
392 if (!pango_font_description_get_family (style->font_desc))
394 g_warning ("Default font does not have a family set");
395 pango_font_description_set_family (style->font_desc, "Sans");
397 if (pango_font_description_get_size (style->font_desc) <= 0)
399 g_warning ("Default font does not have a positive size");
400 pango_font_description_set_size (style->font_desc, 10 * PANGO_SCALE);
405 gtk_style_init (GtkStyle *style)
409 GtkSettings *settings = gtk_settings_get_default ();
412 _gtk_style_init_for_settings (style, settings);
414 style->font_desc = pango_font_description_from_string ("Sans 10");
416 style->attach_count = 0;
417 style->colormap = NULL;
420 style->black.red = 0;
421 style->black.green = 0;
422 style->black.blue = 0;
424 style->white.red = 65535;
425 style->white.green = 65535;
426 style->white.blue = 65535;
428 style->fg[GTK_STATE_NORMAL] = gtk_default_normal_fg;
429 style->fg[GTK_STATE_ACTIVE] = gtk_default_active_fg;
430 style->fg[GTK_STATE_PRELIGHT] = gtk_default_prelight_fg;
431 style->fg[GTK_STATE_SELECTED] = gtk_default_selected_fg;
432 style->fg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
434 style->bg[GTK_STATE_NORMAL] = gtk_default_normal_bg;
435 style->bg[GTK_STATE_ACTIVE] = gtk_default_active_bg;
436 style->bg[GTK_STATE_PRELIGHT] = gtk_default_prelight_bg;
437 style->bg[GTK_STATE_SELECTED] = gtk_default_selected_bg;
438 style->bg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_bg;
440 for (i = 0; i < 4; i++)
442 style->text[i] = style->fg[i];
443 style->base[i] = style->white;
446 style->base[GTK_STATE_SELECTED] = gtk_default_selected_base;
447 style->text[GTK_STATE_SELECTED] = style->white;
448 style->base[GTK_STATE_ACTIVE] = gtk_default_active_base;
449 style->text[GTK_STATE_ACTIVE] = style->white;
450 style->base[GTK_STATE_INSENSITIVE] = gtk_default_prelight_bg;
451 style->text[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
453 for (i = 0; i < 5; i++)
454 style->bg_pixmap[i] = NULL;
456 style->rc_style = NULL;
458 style->xthickness = 2;
459 style->ythickness = 2;
461 style->property_cache = NULL;
465 gtk_style_class_init (GtkStyleClass *klass)
467 GObjectClass *object_class = G_OBJECT_CLASS (klass);
469 object_class->finalize = gtk_style_finalize;
471 klass->clone = gtk_style_real_clone;
472 klass->copy = gtk_style_real_copy;
473 klass->init_from_rc = gtk_style_real_init_from_rc;
474 klass->realize = gtk_style_real_realize;
475 klass->unrealize = gtk_style_real_unrealize;
476 klass->set_background = gtk_style_real_set_background;
477 klass->render_icon = gtk_default_render_icon;
479 klass->draw_hline = gtk_default_draw_hline;
480 klass->draw_vline = gtk_default_draw_vline;
481 klass->draw_shadow = gtk_default_draw_shadow;
482 klass->draw_arrow = gtk_default_draw_arrow;
483 klass->draw_diamond = gtk_default_draw_diamond;
484 klass->draw_box = gtk_default_draw_box;
485 klass->draw_flat_box = gtk_default_draw_flat_box;
486 klass->draw_check = gtk_default_draw_check;
487 klass->draw_option = gtk_default_draw_option;
488 klass->draw_tab = gtk_default_draw_tab;
489 klass->draw_shadow_gap = gtk_default_draw_shadow_gap;
490 klass->draw_box_gap = gtk_default_draw_box_gap;
491 klass->draw_extension = gtk_default_draw_extension;
492 klass->draw_focus = gtk_default_draw_focus;
493 klass->draw_slider = gtk_default_draw_slider;
494 klass->draw_handle = gtk_default_draw_handle;
495 klass->draw_expander = gtk_default_draw_expander;
496 klass->draw_layout = gtk_default_draw_layout;
497 klass->draw_resize_grip = gtk_default_draw_resize_grip;
498 klass->draw_spinner = gtk_default_draw_spinner;
500 g_type_class_add_private (object_class, sizeof (GtkStylePrivate));
504 * @style: the object which received the signal
506 * Emitted when the style has been initialized for a particular
507 * colormap and depth. Connecting to this signal is probably seldom
508 * useful since most of the time applications and widgets only
509 * deal with styles that have been already realized.
513 realize_signal = g_signal_new (I_("realize"),
514 G_TYPE_FROM_CLASS (object_class),
516 G_STRUCT_OFFSET (GtkStyleClass, realize),
518 _gtk_marshal_VOID__VOID,
521 * GtkStyle::unrealize:
522 * @style: the object which received the signal
524 * Emitted when the aspects of the style specific to a particular colormap
525 * and depth are being cleaned up. A connection to this signal can be useful
526 * if a widget wants to cache objects as object data on #GtkStyle.
527 * This signal provides a convenient place to free such cached objects.
531 unrealize_signal = g_signal_new (I_("unrealize"),
532 G_TYPE_FROM_CLASS (object_class),
534 G_STRUCT_OFFSET (GtkStyleClass, unrealize),
536 _gtk_marshal_VOID__VOID,
541 clear_property_cache (GtkStyle *style)
543 if (style->property_cache)
547 for (i = 0; i < style->property_cache->len; i++)
549 PropertyValue *node = &g_array_index (style->property_cache, PropertyValue, i);
551 g_param_spec_unref (node->pspec);
552 g_value_unset (&node->value);
554 g_array_free (style->property_cache, TRUE);
555 style->property_cache = NULL;
560 gtk_style_finalize (GObject *object)
562 GtkStyle *style = GTK_STYLE (object);
563 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
565 g_return_if_fail (style->attach_count == 0);
567 clear_property_cache (style);
569 /* All the styles in the list have the same
570 * style->styles pointer. If we delete the
571 * *first* style from the list, we need to update
572 * the style->styles pointers from all the styles.
573 * Otherwise we simply remove the node from
578 if (style->styles->data != style)
579 style->styles = g_slist_remove (style->styles, style);
582 GSList *tmp_list = style->styles->next;
586 GTK_STYLE (tmp_list->data)->styles = style->styles->next;
587 tmp_list = tmp_list->next;
589 g_slist_free_1 (style->styles);
593 g_slist_foreach (style->icon_factories, (GFunc) g_object_unref, NULL);
594 g_slist_free (style->icon_factories);
596 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_unref, NULL);
597 g_slist_free (priv->color_hashes);
599 pango_font_description_free (style->font_desc);
601 if (style->private_font_desc)
602 pango_font_description_free (style->private_font_desc);
605 g_object_unref (style->rc_style);
607 G_OBJECT_CLASS (gtk_style_parent_class)->finalize (object);
613 * @style: a #GtkStyle
615 * Creates a copy of the passed in #GtkStyle object.
617 * Returns: (transfer full): a copy of @style
620 gtk_style_copy (GtkStyle *style)
624 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
626 new_style = GTK_STYLE_GET_CLASS (style)->clone (style);
627 GTK_STYLE_GET_CLASS (style)->copy (new_style, style);
633 gtk_style_duplicate (GtkStyle *style)
637 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
639 new_style = gtk_style_copy (style);
641 /* All the styles in the list have the same
642 * style->styles pointer. When we insert a new
643 * style, we append it to the list to avoid having
644 * to update the existing ones.
646 style->styles = g_slist_append (style->styles, new_style);
647 new_style->styles = style->styles;
654 * @returns: a new #GtkStyle.
656 * Creates a new #GtkStyle.
663 style = g_object_new (GTK_TYPE_STYLE, NULL);
670 * @style: a #GtkStyle.
671 * @window: a #GdkWindow.
673 * Attaches a style to a window; this process allocates the
674 * colors and creates the GC's for the style - it specializes
675 * it to a particular visual and colormap. The process may
676 * involve the creation of a new style if the style has already
677 * been attached to a window with a different style and colormap.
679 * Since this function may return a new object, you have to use it
680 * in the following way:
681 * <literal>style = gtk_style_attach (style, window)</literal>
683 * Returns: Either @style, or a newly-created #GtkStyle.
684 * If the style is newly created, the style parameter
685 * will be unref'ed, and the new style will have
686 * a reference count belonging to the caller.
689 gtk_style_attach (GtkStyle *style,
693 GtkStyle *new_style = NULL;
694 GdkColormap *colormap;
696 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
697 g_return_val_if_fail (window != NULL, NULL);
699 colormap = gdk_drawable_get_colormap (window);
702 style->styles = g_slist_append (NULL, style);
704 styles = style->styles;
707 new_style = styles->data;
709 if (new_style->colormap == colormap)
713 styles = styles->next;
718 styles = style->styles;
722 new_style = styles->data;
724 if (new_style->attach_count == 0)
726 gtk_style_realize (new_style, colormap);
731 styles = styles->next;
737 new_style = gtk_style_duplicate (style);
738 gtk_style_realize (new_style, colormap);
741 /* A style gets a refcount from being attached */
742 if (new_style->attach_count == 0)
743 g_object_ref (new_style);
745 /* Another refcount belongs to the parent */
746 if (style != new_style)
748 g_object_unref (style);
749 g_object_ref (new_style);
752 new_style->attach_count++;
759 * @style: a #GtkStyle
761 * Detaches a style from a window. If the style is not attached
762 * to any windows anymore, it is unrealized. See gtk_style_attach().
766 gtk_style_detach (GtkStyle *style)
768 g_return_if_fail (GTK_IS_STYLE (style));
769 g_return_if_fail (style->attach_count > 0);
771 style->attach_count -= 1;
772 if (style->attach_count == 0)
774 g_signal_emit (style, unrealize_signal, 0);
776 g_object_unref (style->colormap);
777 style->colormap = NULL;
779 if (style->private_font_desc)
781 pango_font_description_free (style->private_font_desc);
782 style->private_font_desc = NULL;
785 g_object_unref (style);
790 gtk_style_realize (GtkStyle *style,
791 GdkColormap *colormap)
793 style->colormap = g_object_ref (colormap);
794 style->depth = gdk_colormap_get_visual (colormap)->depth;
796 g_signal_emit (style, realize_signal, 0);
800 * gtk_style_lookup_icon_set:
801 * @style: a #GtkStyle
802 * @stock_id: an icon name
804 * Looks up @stock_id in the icon factories associated with @style
805 * and the default icon factory, returning an icon set if found,
808 * Return value: icon set of @stock_id
811 gtk_style_lookup_icon_set (GtkStyle *style,
812 const char *stock_id)
816 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
817 g_return_val_if_fail (stock_id != NULL, NULL);
819 iter = style->icon_factories;
822 GtkIconSet *icon_set = gtk_icon_factory_lookup (GTK_ICON_FACTORY (iter->data),
827 iter = g_slist_next (iter);
830 return gtk_icon_factory_lookup_default (stock_id);
834 * gtk_style_lookup_color:
835 * @style: a #GtkStyle
836 * @color_name: the name of the logical color to look up
837 * @color: the #GdkColor to fill in
839 * Looks up @color_name in the style's logical color mappings,
840 * filling in @color and returning %TRUE if found, otherwise
841 * returning %FALSE. Do not cache the found mapping, because
842 * it depends on the #GtkStyle and might change when a theme
845 * Return value: %TRUE if the mapping was found.
850 gtk_style_lookup_color (GtkStyle *style,
851 const char *color_name,
854 GtkStylePrivate *priv;
857 g_return_val_if_fail (GTK_IS_STYLE (style), FALSE);
858 g_return_val_if_fail (color_name != NULL, FALSE);
859 g_return_val_if_fail (color != NULL, FALSE);
861 priv = GTK_STYLE_GET_PRIVATE (style);
863 for (iter = priv->color_hashes; iter != NULL; iter = iter->next)
865 GHashTable *hash = iter->data;
866 GdkColor *mapping = g_hash_table_lookup (hash, color_name);
870 color->red = mapping->red;
871 color->green = mapping->green;
872 color->blue = mapping->blue;
881 * gtk_style_set_background:
882 * @style: a #GtkStyle
883 * @window: a #GdkWindow
884 * @state_type: a state
886 * Sets the background of @window to the background color or pixmap
887 * specified by @style for the given state.
890 gtk_style_set_background (GtkStyle *style,
892 GtkStateType state_type)
894 g_return_if_fail (GTK_IS_STYLE (style));
895 g_return_if_fail (window != NULL);
897 GTK_STYLE_GET_CLASS (style)->set_background (style, window, state_type);
900 /* Default functions */
902 gtk_style_real_clone (GtkStyle *style)
904 return g_object_new (G_OBJECT_TYPE (style), NULL);
908 gtk_style_real_copy (GtkStyle *style,
911 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
912 GtkStylePrivate *src_priv = GTK_STYLE_GET_PRIVATE (src);
915 for (i = 0; i < 5; i++)
917 style->fg[i] = src->fg[i];
918 style->bg[i] = src->bg[i];
919 style->text[i] = src->text[i];
920 style->base[i] = src->base[i];
922 if (style->bg_pixmap[i])
923 g_object_unref (style->bg_pixmap[i]),
924 style->bg_pixmap[i] = src->bg_pixmap[i];
925 if (style->bg_pixmap[i])
926 g_object_ref (style->bg_pixmap[i]);
929 if (style->font_desc)
930 pango_font_description_free (style->font_desc);
932 style->font_desc = pango_font_description_copy (src->font_desc);
934 style->font_desc = NULL;
936 style->xthickness = src->xthickness;
937 style->ythickness = src->ythickness;
940 g_object_unref (style->rc_style);
941 style->rc_style = src->rc_style;
943 g_object_ref (src->rc_style);
945 g_slist_foreach (style->icon_factories, (GFunc) g_object_unref, NULL);
946 g_slist_free (style->icon_factories);
947 style->icon_factories = g_slist_copy (src->icon_factories);
948 g_slist_foreach (style->icon_factories, (GFunc) g_object_ref, NULL);
950 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_unref, NULL);
951 g_slist_free (priv->color_hashes);
952 priv->color_hashes = g_slist_copy (src_priv->color_hashes);
953 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_ref, NULL);
955 /* don't copy, just clear cache */
956 clear_property_cache (style);
960 gtk_style_real_init_from_rc (GtkStyle *style,
961 GtkRcStyle *rc_style)
963 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
966 /* cache _should_ be still empty */
967 clear_property_cache (style);
969 if (rc_style->font_desc)
970 pango_font_description_merge (style->font_desc, rc_style->font_desc, TRUE);
972 for (i = 0; i < 5; i++)
974 if (rc_style->color_flags[i] & GTK_RC_FG)
975 style->fg[i] = rc_style->fg[i];
976 if (rc_style->color_flags[i] & GTK_RC_BG)
977 style->bg[i] = rc_style->bg[i];
978 if (rc_style->color_flags[i] & GTK_RC_TEXT)
979 style->text[i] = rc_style->text[i];
980 if (rc_style->color_flags[i] & GTK_RC_BASE)
981 style->base[i] = rc_style->base[i];
984 if (rc_style->xthickness >= 0)
985 style->xthickness = rc_style->xthickness;
986 if (rc_style->ythickness >= 0)
987 style->ythickness = rc_style->ythickness;
989 style->icon_factories = g_slist_copy (rc_style->icon_factories);
990 g_slist_foreach (style->icon_factories, (GFunc) g_object_ref, NULL);
992 priv->color_hashes = g_slist_copy (_gtk_rc_style_get_color_hashes (rc_style));
993 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_ref, NULL);
997 style_property_values_cmp (gconstpointer bsearch_node1,
998 gconstpointer bsearch_node2)
1000 const PropertyValue *val1 = bsearch_node1;
1001 const PropertyValue *val2 = bsearch_node2;
1003 if (val1->widget_type == val2->widget_type)
1004 return val1->pspec < val2->pspec ? -1 : val1->pspec == val2->pspec ? 0 : 1;
1006 return val1->widget_type < val2->widget_type ? -1 : 1;
1010 * gtk_style_get_style_property:
1011 * @style: a #GtkStyle
1012 * @widget_type: the #GType of a descendant of #GtkWidget
1013 * @property_name: the name of the style property to get
1014 * @value: a #GValue where the value of the property being
1015 * queried will be stored
1017 * Queries the value of a style property corresponding to a
1018 * widget class is in the given style.
1023 gtk_style_get_style_property (GtkStyle *style,
1025 const gchar *property_name,
1028 GtkWidgetClass *klass;
1030 GtkRcPropertyParser parser;
1031 const GValue *peek_value;
1033 klass = g_type_class_ref (widget_type);
1034 pspec = gtk_widget_class_find_style_property (klass, property_name);
1035 g_type_class_unref (klass);
1039 g_warning ("%s: widget class `%s' has no property named `%s'",
1041 g_type_name (widget_type),
1046 parser = g_param_spec_get_qdata (pspec,
1047 g_quark_from_static_string ("gtk-rc-property-parser"));
1049 peek_value = _gtk_style_peek_property_value (style, widget_type, pspec, parser);
1051 if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec))
1052 g_value_copy (peek_value, value);
1053 else if (g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
1054 g_value_transform (peek_value, value);
1056 g_warning ("can't retrieve style property `%s' of type `%s' as value of type `%s'",
1058 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1059 G_VALUE_TYPE_NAME (value));
1063 * gtk_style_get_valist:
1064 * @style: a #GtkStyle
1065 * @widget_type: the #GType of a descendant of #GtkWidget
1066 * @first_property_name: the name of the first style property to get
1067 * @var_args: a <type>va_list</type> of pairs of property names and
1068 * locations to return the property values, starting with the
1069 * location for @first_property_name.
1071 * Non-vararg variant of gtk_style_get().
1072 * Used primarily by language bindings.
1077 gtk_style_get_valist (GtkStyle *style,
1079 const gchar *first_property_name,
1082 const char *property_name;
1083 GtkWidgetClass *klass;
1085 g_return_if_fail (GTK_IS_STYLE (style));
1087 klass = g_type_class_ref (widget_type);
1089 property_name = first_property_name;
1090 while (property_name)
1093 GtkRcPropertyParser parser;
1094 const GValue *peek_value;
1097 pspec = gtk_widget_class_find_style_property (klass, property_name);
1101 g_warning ("%s: widget class `%s' has no property named `%s'",
1103 g_type_name (widget_type),
1108 parser = g_param_spec_get_qdata (pspec,
1109 g_quark_from_static_string ("gtk-rc-property-parser"));
1111 peek_value = _gtk_style_peek_property_value (style, widget_type, pspec, parser);
1112 G_VALUE_LCOPY (peek_value, var_args, 0, &error);
1115 g_warning ("%s: %s", G_STRLOC, error);
1120 property_name = va_arg (var_args, gchar*);
1123 g_type_class_unref (klass);
1128 * @style: a #GtkStyle
1129 * @widget_type: the #GType of a descendant of #GtkWidget
1130 * @first_property_name: the name of the first style property to get
1131 * @Varargs: pairs of property names and locations to
1132 * return the property values, starting with the location for
1133 * @first_property_name, terminated by %NULL.
1135 * Gets the values of a multiple style properties for @widget_type
1141 gtk_style_get (GtkStyle *style,
1143 const gchar *first_property_name,
1148 va_start (var_args, first_property_name);
1149 gtk_style_get_valist (style, widget_type, first_property_name, var_args);
1154 _gtk_style_peek_property_value (GtkStyle *style,
1157 GtkRcPropertyParser parser)
1159 PropertyValue *pcache, key = { 0, NULL, { 0, } };
1160 const GtkRcProperty *rcprop = NULL;
1163 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1164 g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL);
1165 g_return_val_if_fail (g_type_is_a (pspec->owner_type, GTK_TYPE_WIDGET), NULL);
1166 g_return_val_if_fail (g_type_is_a (widget_type, pspec->owner_type), NULL);
1168 key.widget_type = widget_type;
1171 /* need value cache array */
1172 if (!style->property_cache)
1173 style->property_cache = g_array_new (FALSE, FALSE, sizeof (PropertyValue));
1176 pcache = bsearch (&key,
1177 style->property_cache->data, style->property_cache->len,
1178 sizeof (PropertyValue), style_property_values_cmp);
1180 return &pcache->value;
1184 while (i < style->property_cache->len &&
1185 style_property_values_cmp (&key, &g_array_index (style->property_cache, PropertyValue, i)) >= 0)
1188 g_array_insert_val (style->property_cache, i, key);
1189 pcache = &g_array_index (style->property_cache, PropertyValue, i);
1191 /* cache miss, initialize value type, then set contents */
1192 g_param_spec_ref (pcache->pspec);
1193 g_value_init (&pcache->value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1195 /* value provided by rc style? */
1196 if (style->rc_style)
1198 GQuark prop_quark = g_quark_from_string (pspec->name);
1202 rcprop = _gtk_rc_style_lookup_rc_property (style->rc_style,
1203 g_type_qname (widget_type),
1207 widget_type = g_type_parent (widget_type);
1209 while (g_type_is_a (widget_type, pspec->owner_type));
1212 /* when supplied by rc style, we need to convert */
1213 if (rcprop && !_gtk_settings_parse_convert (parser, &rcprop->value,
1214 pspec, &pcache->value))
1216 gchar *contents = g_strdup_value_contents (&rcprop->value);
1218 g_message ("%s: failed to retrieve property `%s::%s' of type `%s' from rc file value \"%s\" of type `%s'",
1219 rcprop->origin ? rcprop->origin : "(for origin information, set GTK_DEBUG)",
1220 g_type_name (pspec->owner_type), pspec->name,
1221 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1223 G_VALUE_TYPE_NAME (&rcprop->value));
1225 rcprop = NULL; /* needs default */
1228 /* not supplied by rc style (or conversion failed), revert to default */
1230 g_param_value_set_default (pspec, &pcache->value);
1232 return &pcache->value;
1236 load_bg_image (GdkColormap *colormap,
1238 const gchar *filename)
1240 if (strcmp (filename, "<parent>") == 0)
1241 return (GdkPixmap*) GDK_PARENT_RELATIVE;
1247 GdkScreen *screen = gdk_colormap_get_screen (colormap);
1249 pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
1253 pixmap = gdk_pixmap_new (gdk_screen_get_root_window (screen),
1254 gdk_pixbuf_get_width (pixbuf),
1255 gdk_pixbuf_get_height (pixbuf),
1256 gdk_colormap_get_visual (colormap)->depth);
1257 gdk_drawable_set_colormap (pixmap, colormap);
1259 cr = gdk_cairo_create (pixmap);
1261 gdk_cairo_set_source_color (cr, bg_color);
1264 gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
1268 g_object_unref (pixbuf);
1275 gtk_style_real_realize (GtkStyle *style)
1279 for (i = 0; i < 5; i++)
1281 _gtk_style_shade (&style->bg[i], &style->light[i], LIGHTNESS_MULT);
1282 _gtk_style_shade (&style->bg[i], &style->dark[i], DARKNESS_MULT);
1284 style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
1285 style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
1286 style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
1288 style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
1289 style->text_aa[i].green = (style->text[i].green + style->base[i].green) / 2;
1290 style->text_aa[i].blue = (style->text[i].blue + style->base[i].blue) / 2;
1293 style->black.red = 0x0000;
1294 style->black.green = 0x0000;
1295 style->black.blue = 0x0000;
1297 style->white.red = 0xffff;
1298 style->white.green = 0xffff;
1299 style->white.blue = 0xffff;
1301 for (i = 0; i < 5; i++)
1303 if (style->rc_style && style->rc_style->bg_pixmap_name[i])
1304 style->bg_pixmap[i] = load_bg_image (style->colormap,
1306 style->rc_style->bg_pixmap_name[i]);
1311 gtk_style_real_unrealize (GtkStyle *style)
1315 for (i = 0; i < 5; i++)
1317 if (style->bg_pixmap[i] && style->bg_pixmap[i] != (GdkPixmap*) GDK_PARENT_RELATIVE)
1319 g_object_unref (style->bg_pixmap[i]);
1320 style->bg_pixmap[i] = NULL;
1325 style_unrealize_cursors (style);
1329 gtk_style_real_set_background (GtkStyle *style,
1331 GtkStateType state_type)
1334 gint parent_relative;
1336 if (style->bg_pixmap[state_type])
1338 if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
1341 parent_relative = TRUE;
1345 pixmap = style->bg_pixmap[state_type];
1346 parent_relative = FALSE;
1349 gdk_window_set_back_pixmap (window, pixmap, parent_relative);
1352 gdk_window_set_background (window, &style->bg[state_type]);
1356 * gtk_style_render_icon:
1357 * @style: a #GtkStyle
1358 * @source: the #GtkIconSource specifying the icon to render
1359 * @direction: a text direction
1361 * @size: (type int): the size to render the icon at. A size of
1362 * (GtkIconSize)-1 means render at the size of the source and
1364 * @widget: (allow-none): the widget
1365 * @detail: (allow-none): a style detail
1367 * Renders the icon specified by @source at the given @size
1368 * according to the given parameters and returns the result in a
1371 * Return value: (transfer full): a newly-created #GdkPixbuf
1372 * containing the rendered icon
1375 gtk_style_render_icon (GtkStyle *style,
1376 const GtkIconSource *source,
1377 GtkTextDirection direction,
1381 const gchar *detail)
1385 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1386 g_return_val_if_fail (GTK_STYLE_GET_CLASS (style)->render_icon != NULL, NULL);
1388 pixbuf = GTK_STYLE_GET_CLASS (style)->render_icon (style, source, direction, state,
1389 size, widget, detail);
1391 g_return_val_if_fail (pixbuf != NULL, NULL);
1396 /* Default functions */
1399 * gtk_style_apply_default_background:
1405 * @area: (allow-none):
1412 gtk_style_apply_default_background (GtkStyle *style,
1415 GtkStateType state_type,
1423 if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
1425 GdkWindow *parent = gdk_window_get_parent (window);
1426 int x_offset, y_offset;
1430 gdk_window_get_position (window, &x_offset, &y_offset);
1431 cairo_translate (cr, -x_offset, -y_offset);
1432 gtk_style_apply_default_background (style, cr,
1434 x + x_offset, y + y_offset,
1439 gdk_cairo_set_source_color (cr, &style->bg[state_type]);
1441 else if (style->bg_pixmap[state_type])
1443 gdk_cairo_set_source_pixmap (cr, style->bg_pixmap[state_type], 0, 0);
1444 cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
1447 gdk_cairo_set_source_color (cr, &style->bg[state_type]);
1449 cairo_rectangle (cr, x, y, width, height);
1457 scale_or_ref (GdkPixbuf *src,
1461 if (width == gdk_pixbuf_get_width (src) &&
1462 height == gdk_pixbuf_get_height (src))
1464 return g_object_ref (src);
1468 return gdk_pixbuf_scale_simple (src,
1470 GDK_INTERP_BILINEAR);
1475 lookup_icon_size (GtkStyle *style,
1482 GtkSettings *settings;
1484 if (widget && gtk_widget_has_screen (widget))
1486 screen = gtk_widget_get_screen (widget);
1487 settings = gtk_settings_get_for_screen (screen);
1489 else if (style && style->colormap)
1491 screen = gdk_colormap_get_screen (style->colormap);
1492 settings = gtk_settings_get_for_screen (screen);
1496 settings = gtk_settings_get_default ();
1497 GTK_NOTE (MULTIHEAD,
1498 g_warning ("Using the default screen for gtk_default_render_icon()"));
1501 return gtk_icon_size_lookup_for_settings (settings, size, width, height);
1505 gtk_default_render_icon (GtkStyle *style,
1506 const GtkIconSource *source,
1507 GtkTextDirection direction,
1511 const gchar *detail)
1517 GdkPixbuf *base_pixbuf;
1519 /* Oddly, style can be NULL in this function, because
1520 * GtkIconSet can be used without a style and if so
1521 * it uses this function.
1524 base_pixbuf = gtk_icon_source_get_pixbuf (source);
1526 g_return_val_if_fail (base_pixbuf != NULL, NULL);
1528 if (size != (GtkIconSize) -1 && !lookup_icon_size(style, widget, size, &width, &height))
1530 g_warning (G_STRLOC ": invalid icon size '%d'", size);
1534 /* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
1537 if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source))
1538 scaled = scale_or_ref (base_pixbuf, width, height);
1540 scaled = g_object_ref (base_pixbuf);
1542 /* If the state was wildcarded, then generate a state. */
1543 if (gtk_icon_source_get_state_wildcarded (source))
1545 if (state == GTK_STATE_INSENSITIVE)
1547 stated = gdk_pixbuf_copy (scaled);
1549 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
1552 g_object_unref (scaled);
1554 else if (state == GTK_STATE_PRELIGHT)
1556 stated = gdk_pixbuf_copy (scaled);
1558 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
1561 g_object_unref (scaled);
1575 sanitize_size (GdkWindow *window,
1579 if ((*width == -1) && (*height == -1))
1580 gdk_drawable_get_size (window, width, height);
1581 else if (*width == -1)
1582 gdk_drawable_get_size (window, width, NULL);
1583 else if (*height == -1)
1584 gdk_drawable_get_size (window, NULL, height);
1588 _cairo_draw_line (cairo_t *cr,
1597 gdk_cairo_set_source_color (cr, color);
1598 cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
1600 cairo_move_to (cr, x1 + 0.5, y1 + 0.5);
1601 cairo_line_to (cr, x2 + 0.5, y2 + 0.5);
1608 _cairo_draw_rectangle (cairo_t *cr,
1616 gdk_cairo_set_source_color (cr, color);
1620 cairo_rectangle (cr, x, y, width, height);
1625 cairo_rectangle (cr, x + 0.5, y + 0.5, width, height);
1631 _cairo_draw_point (cairo_t *cr,
1636 gdk_cairo_set_source_color (cr, color);
1637 cairo_rectangle (cr, x, y, 1, 1);
1642 gtk_default_draw_hline (GtkStyle *style,
1644 GtkStateType state_type,
1646 const gchar *detail,
1651 gint thickness_light;
1652 gint thickness_dark;
1655 thickness_light = style->ythickness / 2;
1656 thickness_dark = style->ythickness - thickness_light;
1658 cairo_set_line_width (cr, 1.0);
1660 if (detail && !strcmp (detail, "label"))
1662 if (state_type == GTK_STATE_INSENSITIVE)
1663 _cairo_draw_line (cr, &style->white, x1 + 1, y + 1, x2 + 1, y + 1);
1664 _cairo_draw_line (cr, &style->fg[state_type], x1, y, x2, y);
1668 for (i = 0; i < thickness_dark; i++)
1670 _cairo_draw_line (cr, &style->dark[state_type], x1, y + i, x2 - i - 1, y + i);
1671 _cairo_draw_line (cr, &style->light[state_type], x2 - i, y + i, x2, y + i);
1674 y += thickness_dark;
1675 for (i = 0; i < thickness_light; i++)
1677 _cairo_draw_line (cr, &style->dark[state_type], x1, y + i, x1 + thickness_light - i - 1, y + i);
1678 _cairo_draw_line (cr, &style->light[state_type], x1 + thickness_light - i, y + i, x2, y + i);
1685 gtk_default_draw_vline (GtkStyle *style,
1687 GtkStateType state_type,
1689 const gchar *detail,
1694 gint thickness_light;
1695 gint thickness_dark;
1698 thickness_light = style->xthickness / 2;
1699 thickness_dark = style->xthickness - thickness_light;
1701 cairo_set_line_width (cr, 1.0);
1703 for (i = 0; i < thickness_dark; i++)
1705 _cairo_draw_line (cr, &style->dark[state_type],
1706 x + i, y1, x + i, y2 - i - 1);
1707 _cairo_draw_line (cr, &style->light[state_type],
1708 x + i, y2 - i, x + i, y2);
1711 x += thickness_dark;
1712 for (i = 0; i < thickness_light; i++)
1714 _cairo_draw_line (cr, &style->dark[state_type],
1715 x + i, y1, x + i, y1 + thickness_light - i - 1);
1716 _cairo_draw_line (cr, &style->light[state_type],
1717 x + i, y1 + thickness_light - i, x + i, y2);
1722 draw_thin_shadow (GtkStyle *style,
1730 GdkColor *gc1, *gc2;
1732 gc1 = &style->light[state];
1733 gc2 = &style->dark[state];
1735 _cairo_draw_line (cr, gc1,
1736 x, y + height - 1, x + width - 1, y + height - 1);
1737 _cairo_draw_line (cr, gc1,
1738 x + width - 1, y, x + width - 1, y + height - 1);
1740 _cairo_draw_line (cr, gc2,
1741 x, y, x + width - 2, y);
1742 _cairo_draw_line (cr, gc2,
1743 x, y, x, y + height - 2);
1747 draw_spinbutton_shadow (GtkStyle *style,
1750 GtkTextDirection direction,
1757 if (direction == GTK_TEXT_DIR_LTR)
1759 _cairo_draw_line (cr, &style->dark[state],
1760 x, y, x + width - 1, y);
1761 _cairo_draw_line (cr, &style->black,
1762 x, y + 1, x + width - 2, y + 1);
1763 _cairo_draw_line (cr, &style->black,
1764 x + width - 2, y + 2, x + width - 2, y + height - 3);
1765 _cairo_draw_line (cr, &style->light[state],
1766 x + width - 1, y + 1, x + width - 1, y + height - 2);
1767 _cairo_draw_line (cr, &style->light[state],
1768 x, y + height - 1, x + width - 1, y + height - 1);
1769 _cairo_draw_line (cr, &style->bg[state],
1770 x, y + height - 2, x + width - 2, y + height - 2);
1771 _cairo_draw_line (cr, &style->black,
1772 x, y + 2, x, y + height - 3);
1776 _cairo_draw_line (cr, &style->dark[state],
1777 x, y, x + width - 1, y);
1778 _cairo_draw_line (cr, &style->dark[state],
1779 x, y + 1, x, y + height - 1);
1780 _cairo_draw_line (cr, &style->black,
1781 x + 1, y + 1, x + width - 1, y + 1);
1782 _cairo_draw_line (cr, &style->black,
1783 x + 1, y + 2, x + 1, y + height - 2);
1784 _cairo_draw_line (cr, &style->black,
1785 x + width - 1, y + 2, x + width - 1, y + height - 3);
1786 _cairo_draw_line (cr, &style->light[state],
1787 x + 1, y + height - 1, x + width - 1, y + height - 1);
1788 _cairo_draw_line (cr, &style->bg[state],
1789 x + 2, y + height - 2, x + width - 1, y + height - 2);
1794 draw_menu_shadow (GtkStyle *style,
1802 if (style->ythickness > 0)
1804 if (style->ythickness > 1)
1806 _cairo_draw_line (cr, &style->dark[state],
1807 x + 1, y + height - 2,
1808 x + width - 2, y + height - 2);
1809 _cairo_draw_line (cr, &style->black,
1810 x, y + height - 1, x + width - 1, y + height - 1);
1814 _cairo_draw_line (cr, &style->dark[state],
1815 x + 1, y + height - 1, x + width - 1, y + height - 1);
1819 if (style->xthickness > 0)
1821 if (style->xthickness > 1)
1823 _cairo_draw_line (cr, &style->dark[state],
1824 x + width - 2, y + 1,
1825 x + width - 2, y + height - 2);
1827 _cairo_draw_line (cr, &style->black,
1828 x + width - 1, y, x + width - 1, y + height - 1);
1832 _cairo_draw_line (cr, &style->dark[state],
1833 x + width - 1, y + 1, x + width - 1, y + height - 1);
1837 /* Light around top and left */
1839 if (style->ythickness > 0)
1840 _cairo_draw_line (cr, &style->black,
1841 x, y, x + width - 2, y);
1842 if (style->xthickness > 0)
1843 _cairo_draw_line (cr, &style->black,
1844 x, y, x, y + height - 2);
1846 if (style->ythickness > 1)
1847 _cairo_draw_line (cr, &style->light[state],
1848 x + 1, y + 1, x + width - 3, y + 1);
1849 if (style->xthickness > 1)
1850 _cairo_draw_line (cr, &style->light[state],
1851 x + 1, y + 1, x + 1, y + height - 3);
1854 static GtkTextDirection
1855 get_direction (GtkWidget *widget)
1857 GtkTextDirection dir;
1860 dir = gtk_widget_get_direction (widget);
1862 dir = GTK_TEXT_DIR_LTR;
1869 gtk_default_draw_shadow (GtkStyle *style,
1871 GtkStateType state_type,
1872 GtkShadowType shadow_type,
1874 const gchar *detail,
1880 GdkColor *gc1 = NULL;
1881 GdkColor *gc2 = NULL;
1882 gint thickness_light;
1883 gint thickness_dark;
1886 cairo_set_line_width (cr, 1.0);
1888 if (shadow_type == GTK_SHADOW_IN)
1890 if (detail && strcmp (detail, "buttondefault") == 0)
1892 _cairo_draw_rectangle (cr, &style->black, FALSE,
1893 x, y, width - 1, height - 1);
1897 if (detail && strcmp (detail, "trough") == 0)
1899 draw_thin_shadow (style, cr, state_type,
1900 x, y, width, height);
1904 if (GTK_IS_SPIN_BUTTON (widget) &&
1905 detail && strcmp (detail, "spinbutton") == 0)
1907 draw_spinbutton_shadow (style, cr, state_type,
1908 get_direction (widget), x, y, width, height);
1914 if (shadow_type == GTK_SHADOW_OUT && detail && strcmp (detail, "menu") == 0)
1916 draw_menu_shadow (style, cr, state_type, x, y, width, height);
1920 switch (shadow_type)
1922 case GTK_SHADOW_NONE:
1925 case GTK_SHADOW_ETCHED_IN:
1926 gc1 = &style->light[state_type];
1927 gc2 = &style->dark[state_type];
1929 case GTK_SHADOW_OUT:
1930 case GTK_SHADOW_ETCHED_OUT:
1931 gc1 = &style->dark[state_type];
1932 gc2 = &style->light[state_type];
1936 switch (shadow_type)
1938 case GTK_SHADOW_NONE:
1942 /* Light around right and bottom edge */
1944 if (style->ythickness > 0)
1945 _cairo_draw_line (cr, gc1,
1946 x, y + height - 1, x + width - 1, y + height - 1);
1947 if (style->xthickness > 0)
1948 _cairo_draw_line (cr, gc1,
1949 x + width - 1, y, x + width - 1, y + height - 1);
1951 if (style->ythickness > 1)
1952 _cairo_draw_line (cr, &style->bg[state_type],
1953 x + 1, y + height - 2, x + width - 2, y + height - 2);
1954 if (style->xthickness > 1)
1955 _cairo_draw_line (cr, &style->bg[state_type],
1956 x + width - 2, y + 1, x + width - 2, y + height - 2);
1958 /* Dark around left and top */
1960 if (style->ythickness > 1)
1961 _cairo_draw_line (cr, &style->black,
1962 x + 1, y + 1, x + width - 2, y + 1);
1963 if (style->xthickness > 1)
1964 _cairo_draw_line (cr, &style->black,
1965 x + 1, y + 1, x + 1, y + height - 2);
1967 if (style->ythickness > 0)
1968 _cairo_draw_line (cr, gc2,
1969 x, y, x + width - 1, y);
1970 if (style->xthickness > 0)
1971 _cairo_draw_line (cr, gc2,
1972 x, y, x, y + height - 1);
1975 case GTK_SHADOW_OUT:
1976 /* Dark around right and bottom edge */
1978 if (style->ythickness > 0)
1980 if (style->ythickness > 1)
1982 _cairo_draw_line (cr, gc1,
1983 x + 1, y + height - 2, x + width - 2, y + height - 2);
1984 _cairo_draw_line (cr, &style->black,
1985 x, y + height - 1, x + width - 1, y + height - 1);
1989 _cairo_draw_line (cr, gc1,
1990 x + 1, y + height - 1, x + width - 1, y + height - 1);
1994 if (style->xthickness > 0)
1996 if (style->xthickness > 1)
1998 _cairo_draw_line (cr, gc1,
1999 x + width - 2, y + 1, x + width - 2, y + height - 2);
2001 _cairo_draw_line (cr, &style->black,
2002 x + width - 1, y, x + width - 1, y + height - 1);
2006 _cairo_draw_line (cr, gc1,
2007 x + width - 1, y + 1, x + width - 1, y + height - 1);
2011 /* Light around top and left */
2013 if (style->ythickness > 0)
2014 _cairo_draw_line (cr, gc2,
2015 x, y, x + width - 2, y);
2016 if (style->xthickness > 0)
2017 _cairo_draw_line (cr, gc2,
2018 x, y, x, y + height - 2);
2020 if (style->ythickness > 1)
2021 _cairo_draw_line (cr, &style->bg[state_type],
2022 x + 1, y + 1, x + width - 3, y + 1);
2023 if (style->xthickness > 1)
2024 _cairo_draw_line (cr, &style->bg[state_type],
2025 x + 1, y + 1, x + 1, y + height - 3);
2028 case GTK_SHADOW_ETCHED_IN:
2029 case GTK_SHADOW_ETCHED_OUT:
2030 if (style->xthickness > 0)
2032 if (style->xthickness > 1)
2034 thickness_light = 1;
2037 for (i = 0; i < thickness_dark; i++)
2039 _cairo_draw_line (cr, gc1,
2043 y + height - i - 1);
2044 _cairo_draw_line (cr, gc2,
2048 y + height - i - 2);
2051 for (i = 0; i < thickness_light; i++)
2053 _cairo_draw_line (cr, gc1,
2054 x + thickness_dark + i,
2055 y + thickness_dark + i,
2056 x + thickness_dark + i,
2057 y + height - thickness_dark - i - 1);
2058 _cairo_draw_line (cr, gc2,
2059 x + width - thickness_light - i - 1,
2060 y + thickness_dark + i,
2061 x + width - thickness_light - i - 1,
2062 y + height - thickness_light - 1);
2067 _cairo_draw_line (cr,
2068 &style->dark[state_type],
2069 x, y, x, y + height);
2070 _cairo_draw_line (cr,
2071 &style->dark[state_type],
2072 x + width, y, x + width, y + height);
2076 if (style->ythickness > 0)
2078 if (style->ythickness > 1)
2080 thickness_light = 1;
2083 for (i = 0; i < thickness_dark; i++)
2085 _cairo_draw_line (cr, gc1,
2089 y + height - i - 1);
2091 _cairo_draw_line (cr, gc2,
2098 for (i = 0; i < thickness_light; i++)
2100 _cairo_draw_line (cr, gc1,
2101 x + thickness_dark + i,
2102 y + thickness_dark + i,
2103 x + width - thickness_dark - i - 2,
2104 y + thickness_dark + i);
2106 _cairo_draw_line (cr, gc2,
2107 x + thickness_dark + i,
2108 y + height - thickness_light - i - 1,
2109 x + width - thickness_light - 1,
2110 y + height - thickness_light - i - 1);
2115 _cairo_draw_line (cr,
2116 &style->dark[state_type],
2117 x, y, x + width, y);
2118 _cairo_draw_line (cr,
2119 &style->dark[state_type],
2120 x, y + height, x + width, y + height);
2127 if (shadow_type == GTK_SHADOW_IN &&
2128 GTK_IS_SPIN_BUTTON (widget) &&
2129 detail && strcmp (detail, "entry") == 0)
2131 if (get_direction (widget) == GTK_TEXT_DIR_LTR)
2133 _cairo_draw_line (cr,
2134 &style->base[state_type],
2135 x + width - 1, y + 2,
2136 x + width - 1, y + height - 3);
2137 _cairo_draw_line (cr,
2138 &style->base[state_type],
2139 x + width - 2, y + 2,
2140 x + width - 2, y + height - 3);
2142 _cairo_draw_point (cr,
2144 x + width - 1, y + 1);
2145 _cairo_draw_point (cr,
2146 &style->bg[state_type],
2147 x + width - 1, y + height - 2);
2151 _cairo_draw_line (cr,
2152 &style->base[state_type],
2155 _cairo_draw_line (cr,
2156 &style->base[state_type],
2158 x + 1, y + height - 3);
2160 _cairo_draw_point (cr,
2164 _cairo_draw_line (cr,
2165 &style->bg[state_type],
2167 x + 1, y + height - 2);
2168 _cairo_draw_point (cr,
2169 &style->light[state_type],
2176 draw_arrow (cairo_t *cr,
2178 GtkArrowType arrow_type,
2184 gdk_cairo_set_source_color (cr, color);
2187 if (arrow_type == GTK_ARROW_DOWN)
2189 cairo_move_to (cr, x, y);
2190 cairo_line_to (cr, x + width, y);
2191 cairo_line_to (cr, x + width / 2., y + height);
2193 else if (arrow_type == GTK_ARROW_UP)
2195 cairo_move_to (cr, x, y + height);
2196 cairo_line_to (cr, x + width / 2., y);
2197 cairo_line_to (cr, x + width, y + height);
2199 else if (arrow_type == GTK_ARROW_LEFT)
2201 cairo_move_to (cr, x + width, y);
2202 cairo_line_to (cr, x + width, y + height);
2203 cairo_line_to (cr, x, y + height / 2.);
2205 else if (arrow_type == GTK_ARROW_RIGHT)
2207 cairo_move_to (cr, x, y);
2208 cairo_line_to (cr, x + width, y + height / 2.);
2209 cairo_line_to (cr, x, y + height);
2212 cairo_close_path (cr);
2219 calculate_arrow_geometry (GtkArrowType arrow_type,
2231 case GTK_ARROW_DOWN:
2241 if (arrow_type == GTK_ARROW_DOWN)
2243 if (*height % 2 == 1 || h % 2 == 0)
2248 if (*height % 2 == 0 || h % 2 == 0)
2253 case GTK_ARROW_RIGHT:
2254 case GTK_ARROW_LEFT:
2264 if (arrow_type == GTK_ARROW_RIGHT)
2266 if (*width % 2 == 1 || w % 2 == 0)
2271 if (*width % 2 == 0 || w % 2 == 0)
2277 /* should not be reached */
2281 *x += (*width - w) / 2;
2282 *y += (*height - h) / 2;
2288 gtk_default_draw_arrow (GtkStyle *style,
2291 GtkShadowType shadow,
2293 const gchar *detail,
2294 GtkArrowType arrow_type,
2301 calculate_arrow_geometry (arrow_type, &x, &y, &width, &height);
2303 if (detail && strcmp (detail, "menu_scroll_arrow_up") == 0)
2306 if (state == GTK_STATE_INSENSITIVE)
2307 draw_arrow (cr, &style->white, arrow_type,
2308 x + 1, y + 1, width, height);
2309 draw_arrow (cr, &style->fg[state], arrow_type,
2310 x, y, width, height);
2314 gtk_default_draw_diamond (GtkStyle *style,
2316 GtkStateType state_type,
2317 GtkShadowType shadow_type,
2319 const gchar *detail,
2327 GdkColor *outer_nw = NULL;
2328 GdkColor *outer_ne = NULL;
2329 GdkColor *outer_sw = NULL;
2330 GdkColor *outer_se = NULL;
2331 GdkColor *middle_nw = NULL;
2332 GdkColor *middle_ne = NULL;
2333 GdkColor *middle_sw = NULL;
2334 GdkColor *middle_se = NULL;
2335 GdkColor *inner_nw = NULL;
2336 GdkColor *inner_ne = NULL;
2337 GdkColor *inner_sw = NULL;
2338 GdkColor *inner_se = NULL;
2340 half_width = width / 2;
2341 half_height = height / 2;
2343 switch (shadow_type)
2346 inner_sw = inner_se = &style->bg[state_type];
2347 middle_sw = middle_se = &style->light[state_type];
2348 outer_sw = outer_se = &style->light[state_type];
2349 inner_nw = inner_ne = &style->black;
2350 middle_nw = middle_ne = &style->dark[state_type];
2351 outer_nw = outer_ne = &style->dark[state_type];
2354 case GTK_SHADOW_OUT:
2355 inner_sw = inner_se = &style->dark[state_type];
2356 middle_sw = middle_se = &style->dark[state_type];
2357 outer_sw = outer_se = &style->black;
2358 inner_nw = inner_ne = &style->bg[state_type];
2359 middle_nw = middle_ne = &style->light[state_type];
2360 outer_nw = outer_ne = &style->light[state_type];
2363 case GTK_SHADOW_ETCHED_IN:
2364 inner_sw = inner_se = &style->bg[state_type];
2365 middle_sw = middle_se = &style->dark[state_type];
2366 outer_sw = outer_se = &style->light[state_type];
2367 inner_nw = inner_ne = &style->bg[state_type];
2368 middle_nw = middle_ne = &style->light[state_type];
2369 outer_nw = outer_ne = &style->dark[state_type];
2372 case GTK_SHADOW_ETCHED_OUT:
2373 inner_sw = inner_se = &style->bg[state_type];
2374 middle_sw = middle_se = &style->light[state_type];
2375 outer_sw = outer_se = &style->dark[state_type];
2376 inner_nw = inner_ne = &style->bg[state_type];
2377 middle_nw = middle_ne = &style->dark[state_type];
2378 outer_nw = outer_ne = &style->light[state_type];
2388 _cairo_draw_line (cr, inner_sw,
2389 x + 2, y + half_height,
2390 x + half_width, y + height - 2);
2391 _cairo_draw_line (cr, inner_se,
2392 x + half_width, y + height - 2,
2393 x + width - 2, y + half_height);
2394 _cairo_draw_line (cr, middle_sw,
2395 x + 1, y + half_height,
2396 x + half_width, y + height - 1);
2397 _cairo_draw_line (cr, middle_se,
2398 x + half_width, y + height - 1,
2399 x + width - 1, y + half_height);
2400 _cairo_draw_line (cr, outer_sw,
2402 x + half_width, y + height);
2403 _cairo_draw_line (cr, outer_se,
2404 x + half_width, y + height,
2405 x + width, y + half_height);
2407 _cairo_draw_line (cr, inner_nw,
2408 x + 2, y + half_height,
2409 x + half_width, y + 2);
2410 _cairo_draw_line (cr, inner_ne,
2411 x + half_width, y + 2,
2412 x + width - 2, y + half_height);
2413 _cairo_draw_line (cr, middle_nw,
2414 x + 1, y + half_height,
2415 x + half_width, y + 1);
2416 _cairo_draw_line (cr, middle_ne,
2417 x + half_width, y + 1,
2418 x + width - 1, y + half_height);
2419 _cairo_draw_line (cr, outer_nw,
2422 _cairo_draw_line (cr, outer_ne,
2424 x + width, y + half_height);
2429 option_menu_get_props (GtkWidget *widget,
2430 GtkRequisition *indicator_size,
2431 GtkBorder *indicator_spacing)
2433 GtkRequisition *tmp_size = NULL;
2434 GtkBorder *tmp_spacing = NULL;
2438 *indicator_size = *tmp_size;
2439 gtk_requisition_free (tmp_size);
2442 *indicator_size = default_option_indicator_size;
2446 *indicator_spacing = *tmp_spacing;
2447 gtk_border_free (tmp_spacing);
2450 *indicator_spacing = default_option_indicator_spacing;
2454 gtk_default_draw_box (GtkStyle *style,
2456 GtkStateType state_type,
2457 GtkShadowType shadow_type,
2459 const gchar *detail,
2465 gboolean is_spinbutton_box = FALSE;
2467 if (GTK_IS_SPIN_BUTTON (widget) && detail)
2469 if (strcmp (detail, "spinbutton_up") == 0)
2475 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
2480 is_spinbutton_box = TRUE;
2482 else if (strcmp (detail, "spinbutton_down") == 0)
2487 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
2492 is_spinbutton_box = TRUE;
2496 if (!style->bg_pixmap[state_type])
2498 GdkColor *gc = &style->bg[state_type];
2500 if (state_type == GTK_STATE_SELECTED && detail && strcmp (detail, "paned") == 0)
2502 if (widget && !gtk_widget_has_focus (widget))
2503 gc = &style->base[GTK_STATE_ACTIVE];
2506 _cairo_draw_rectangle (cr, gc, TRUE,
2507 x, y, width, height);
2510 gtk_style_apply_default_background (style, cr, gtk_widget_get_window (widget),
2511 state_type, x, y, width, height);
2514 if (is_spinbutton_box)
2519 lower = &style->dark[state_type];
2520 if (shadow_type == GTK_SHADOW_OUT)
2521 upper = &style->light[state_type];
2523 upper = &style->dark[state_type];
2525 _cairo_draw_line (cr, upper, x, y, x + width - 1, y);
2526 _cairo_draw_line (cr, lower, x, y + height - 1, x + width - 1, y + height - 1);
2531 gtk_cairo_paint_shadow (style, cr, state_type, shadow_type, widget, detail,
2532 x, y, width, height);
2534 if (detail && strcmp (detail, "optionmenu") == 0)
2536 GtkRequisition indicator_size;
2537 GtkBorder indicator_spacing;
2540 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
2542 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
2543 vline_x = x + indicator_size.width + indicator_spacing.left + indicator_spacing.right;
2545 vline_x = x + width - (indicator_size.width + indicator_spacing.left + indicator_spacing.right) - style->xthickness;
2547 gtk_cairo_paint_vline (style, cr, state_type, widget,
2549 y + style->ythickness + 1,
2550 y + height - style->ythickness - 3,
2556 get_darkened (const GdkColor *color,
2559 GdkColor src = *color;
2560 GdkColor shaded = *color;
2562 while (darken_count)
2564 _gtk_style_shade (&src, &shaded, 0.93);
2569 return gdk_color_copy (&shaded);
2573 gtk_default_draw_flat_box (GtkStyle *style,
2575 GtkStateType state_type,
2576 GtkShadowType shadow_type,
2578 const gchar *detail,
2585 GdkColor *freeme = NULL;
2587 cairo_set_line_width (cr, 1.0);
2591 int trimmed_len = strlen (detail);
2593 if (g_str_has_prefix (detail, "cell_"))
2595 if (g_str_has_suffix (detail, "_start"))
2597 else if (g_str_has_suffix (detail, "_middle"))
2599 else if (g_str_has_suffix (detail, "_end"))
2603 if (state_type == GTK_STATE_SELECTED)
2605 if (!strcmp ("text", detail))
2606 gc1 = &style->bg[GTK_STATE_SELECTED];
2607 else if (!strncmp ("cell_even", detail, trimmed_len) ||
2608 !strncmp ("cell_odd", detail, trimmed_len) ||
2609 !strncmp ("cell_even_ruled", detail, trimmed_len) ||
2610 !strncmp ("cell_even_ruled_sorted", detail, trimmed_len))
2612 /* This has to be really broken; alex made me do it. -jrb */
2613 if (widget && gtk_widget_has_focus (widget))
2614 gc1 = &style->base[state_type];
2616 gc1 = &style->base[GTK_STATE_ACTIVE];
2618 else if (!strncmp ("cell_odd_ruled", detail, trimmed_len) ||
2619 !strncmp ("cell_odd_ruled_sorted", detail, trimmed_len))
2621 if (widget && gtk_widget_has_focus (widget))
2622 freeme = get_darkened (&style->base[state_type], 1);
2624 freeme = get_darkened (&style->base[GTK_STATE_ACTIVE], 1);
2629 gc1 = &style->bg[state_type];
2634 if (!strcmp ("viewportbin", detail))
2635 gc1 = &style->bg[GTK_STATE_NORMAL];
2636 else if (!strcmp ("entry_bg", detail))
2637 gc1 = &style->base[gtk_widget_get_state (widget)];
2639 /* For trees: even rows are base color, odd rows are a shade of
2640 * the base color, the sort column is a shade of the original color
2644 else if (!strncmp ("cell_even", detail, trimmed_len) ||
2645 !strncmp ("cell_odd", detail, trimmed_len) ||
2646 !strncmp ("cell_even_ruled", detail, trimmed_len))
2648 GdkColor *color = NULL;
2650 gtk_widget_style_get (widget,
2651 "even-row-color", &color,
2656 freeme = get_darkened (color, 0);
2659 gdk_color_free (color);
2662 gc1 = &style->base[state_type];
2664 else if (!strncmp ("cell_odd_ruled", detail, trimmed_len))
2666 GdkColor *color = NULL;
2668 gtk_widget_style_get (widget,
2669 "odd-row-color", &color,
2674 freeme = get_darkened (color, 0);
2677 gdk_color_free (color);
2681 gtk_widget_style_get (widget,
2682 "even-row-color", &color,
2687 freeme = get_darkened (color, 1);
2688 gdk_color_free (color);
2691 freeme = get_darkened (&style->base[state_type], 1);
2695 else if (!strncmp ("cell_even_sorted", detail, trimmed_len) ||
2696 !strncmp ("cell_odd_sorted", detail, trimmed_len) ||
2697 !strncmp ("cell_even_ruled_sorted", detail, trimmed_len))
2699 GdkColor *color = NULL;
2701 if (!strncmp ("cell_odd_sorted", detail, trimmed_len))
2702 gtk_widget_style_get (widget,
2703 "odd-row-color", &color,
2706 gtk_widget_style_get (widget,
2707 "even-row-color", &color,
2712 freeme = get_darkened (color, 1);
2715 gdk_color_free (color);
2719 freeme = get_darkened (&style->base[state_type], 1);
2723 else if (!strncmp ("cell_odd_ruled_sorted", detail, trimmed_len))
2725 GdkColor *color = NULL;
2727 gtk_widget_style_get (widget,
2728 "odd-row-color", &color,
2733 freeme = get_darkened (color, 1);
2736 gdk_color_free (color);
2740 gtk_widget_style_get (widget,
2741 "even-row-color", &color,
2746 freeme = get_darkened (color, 2);
2747 gdk_color_free (color);
2750 freeme = get_darkened (&style->base[state_type], 2);
2755 gc1 = &style->bg[state_type];
2759 gc1 = &style->bg[state_type];
2761 if (!style->bg_pixmap[state_type] || gc1 != &style->bg[state_type])
2763 _cairo_draw_rectangle (cr, gc1, TRUE,
2764 x, y, width, height);
2766 if (detail && !strcmp ("tooltip", detail))
2767 _cairo_draw_rectangle (cr, &style->black, FALSE,
2768 x, y, width - 1, height - 1);
2771 gtk_style_apply_default_background (style, cr, gtk_widget_get_window (widget),
2772 state_type, x, y, width, height);
2775 gdk_color_free (freeme);
2779 gtk_default_draw_check (GtkStyle *style,
2781 GtkStateType state_type,
2782 GtkShadowType shadow_type,
2785 const gchar *detail,
2791 cairo_t *cr = gdk_cairo_create (window);
2792 enum { BUTTON, MENU, CELL } type = BUTTON;
2799 if (strcmp (detail, "cellcheck") == 0)
2801 else if (strcmp (detail, "check") == 0)
2807 gdk_cairo_rectangle (cr, area);
2811 exterior_size = MIN (width, height);
2812 if (exterior_size % 2 == 0) /* Ensure odd */
2815 pad = style->xthickness + MAX (1, (exterior_size - 2 * style->xthickness) / 9);
2816 interior_size = MAX (1, exterior_size - 2 * pad);
2818 if (interior_size < 7)
2821 pad = MAX (0, (exterior_size - interior_size) / 2);
2824 x -= (1 + exterior_size - width) / 2;
2825 y -= (1 + exterior_size - height) / 2;
2832 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
2834 gdk_cairo_set_source_color (cr, &style->text[state_type]);
2836 cairo_set_line_width (cr, 1.0);
2837 cairo_rectangle (cr, x + 0.5, y + 0.5, exterior_size - 1, exterior_size - 1);
2840 gdk_cairo_set_source_color (cr, &style->base[state_type]);
2841 cairo_rectangle (cr, x + 1, y + 1, exterior_size - 2, exterior_size - 2);
2853 gdk_cairo_set_source_color (cr, &style->text[state_type]);
2856 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
2860 if (shadow_type == GTK_SHADOW_IN)
2862 cairo_translate (cr,
2865 cairo_scale (cr, interior_size / 7., interior_size / 7.);
2867 cairo_move_to (cr, 7.0, 0.0);
2868 cairo_line_to (cr, 7.5, 1.0);
2869 cairo_curve_to (cr, 5.3, 2.0,
2872 cairo_curve_to (cr, 3.0, 5.7,
2875 cairo_line_to (cr, 0.2, 3.5);
2876 cairo_curve_to (cr, 1.1, 3.5,
2879 cairo_curve_to (cr, 1.0, 3.9,
2882 cairo_curve_to (cr, 3.5, 3.1,
2888 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
2890 int line_thickness = MAX (1, (3 + interior_size * 2) / 7);
2892 cairo_rectangle (cr,
2894 y + pad + (1 + interior_size - line_thickness) / 2,
2904 gtk_default_draw_option (GtkStyle *style,
2906 GtkStateType state_type,
2907 GtkShadowType shadow_type,
2910 const gchar *detail,
2916 cairo_t *cr = gdk_cairo_create (window);
2917 enum { BUTTON, MENU, CELL } type = BUTTON;
2922 if (strcmp (detail, "radio") == 0)
2924 else if (strcmp (detail, "option") == 0)
2930 gdk_cairo_rectangle (cr, area);
2934 exterior_size = MIN (width, height);
2935 if (exterior_size % 2 == 0) /* Ensure odd */
2938 x -= (1 + exterior_size - width) / 2;
2939 y -= (1 + exterior_size - height) / 2;
2945 gdk_cairo_set_source_color (cr, &style->base[state_type]);
2948 x + exterior_size / 2.,
2949 y + exterior_size / 2.,
2950 (exterior_size - 1) / 2.,
2953 cairo_fill_preserve (cr);
2956 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
2958 gdk_cairo_set_source_color (cr, &style->text[state_type]);
2960 cairo_set_line_width (cr, 1.);
2971 gdk_cairo_set_source_color (cr, &style->text[state_type]);
2976 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
2980 if (shadow_type == GTK_SHADOW_IN)
2982 int pad = style->xthickness + MAX (1, 2 * (exterior_size - 2 * style->xthickness) / 9);
2983 int interior_size = MAX (1, exterior_size - 2 * pad);
2985 if (interior_size < 5)
2988 pad = MAX (0, (exterior_size - interior_size) / 2);
2992 x + pad + interior_size / 2.,
2993 y + pad + interior_size / 2.,
2998 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
3000 int pad = style->xthickness + MAX (1, (exterior_size - 2 * style->xthickness) / 9);
3001 int interior_size = MAX (1, exterior_size - 2 * pad);
3004 if (interior_size < 7)
3007 pad = MAX (0, (exterior_size - interior_size) / 2);
3010 line_thickness = MAX (1, (3 + interior_size * 2) / 7);
3012 cairo_rectangle (cr,
3014 y + pad + (interior_size - line_thickness) / 2.,
3024 gtk_default_draw_tab (GtkStyle *style,
3026 GtkStateType state_type,
3027 GtkShadowType shadow_type,
3030 const gchar *detail,
3036 #define ARROW_SPACE 4
3039 GtkRequisition indicator_size;
3040 GtkBorder indicator_spacing;
3043 cr = gdk_cairo_create (window);
3047 gdk_cairo_rectangle (cr, area);
3051 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
3053 indicator_size.width += (indicator_size.width % 2) - 1;
3054 arrow_height = indicator_size.width / 2 + 1;
3056 x += (width - indicator_size.width) / 2;
3057 y += (height - (2 * arrow_height + ARROW_SPACE)) / 2;
3059 if (state_type == GTK_STATE_INSENSITIVE)
3061 draw_arrow (cr, &style->white,
3062 GTK_ARROW_UP, x + 1, y + 1,
3063 indicator_size.width, arrow_height);
3065 draw_arrow (cr, &style->white,
3066 GTK_ARROW_DOWN, x + 1, y + arrow_height + ARROW_SPACE + 1,
3067 indicator_size.width, arrow_height);
3070 draw_arrow (cr, &style->fg[state_type],
3072 indicator_size.width, arrow_height);
3075 draw_arrow (cr, &style->fg[state_type],
3076 GTK_ARROW_DOWN, x, y + arrow_height + ARROW_SPACE,
3077 indicator_size.width, arrow_height);
3083 gtk_default_draw_shadow_gap (GtkStyle *style,
3085 GtkStateType state_type,
3086 GtkShadowType shadow_type,
3089 const gchar *detail,
3094 GtkPositionType gap_side,
3098 GdkColor *color1 = NULL;
3099 GdkColor *color2 = NULL;
3100 GdkColor *color3 = NULL;
3101 GdkColor *color4 = NULL;
3104 sanitize_size (window, &width, &height);
3106 switch (shadow_type)
3108 case GTK_SHADOW_NONE:
3112 color1 = &style->dark[state_type];
3113 color2 = &style->black;
3114 color3 = &style->bg[state_type];
3115 color4 = &style->light[state_type];
3117 case GTK_SHADOW_ETCHED_IN:
3118 color1 = &style->dark[state_type];
3119 color2 = &style->light[state_type];
3120 color3 = &style->dark[state_type];
3121 color4 = &style->light[state_type];
3123 case GTK_SHADOW_OUT:
3124 color1 = &style->light[state_type];
3125 color2 = &style->bg[state_type];
3126 color3 = &style->dark[state_type];
3127 color4 = &style->black;
3129 case GTK_SHADOW_ETCHED_OUT:
3130 color1 = &style->light[state_type];
3131 color2 = &style->dark[state_type];
3132 color3 = &style->light[state_type];
3133 color4 = &style->dark[state_type];
3137 cr = gdk_cairo_create (window);
3140 gdk_cairo_rectangle (cr, area);
3144 switch (shadow_type)
3146 case GTK_SHADOW_NONE:
3148 case GTK_SHADOW_OUT:
3149 case GTK_SHADOW_ETCHED_IN:
3150 case GTK_SHADOW_ETCHED_OUT:
3154 _cairo_draw_line (cr, color1,
3155 x, y, x, y + height - 1);
3156 _cairo_draw_line (cr, color2,
3157 x + 1, y, x + 1, y + height - 2);
3159 _cairo_draw_line (cr, color3,
3160 x + 1, y + height - 2, x + width - 2, y + height - 2);
3161 _cairo_draw_line (cr, color3,
3162 x + width - 2, y, x + width - 2, y + height - 2);
3163 _cairo_draw_line (cr, color4,
3164 x, y + height - 1, x + width - 1, y + height - 1);
3165 _cairo_draw_line (cr, color4,
3166 x + width - 1, y, x + width - 1, y + height - 1);
3169 _cairo_draw_line (cr, color1,
3170 x, y, x + gap_x - 1, y);
3171 _cairo_draw_line (cr, color2,
3172 x + 1, y + 1, x + gap_x - 1, y + 1);
3173 _cairo_draw_line (cr, color2,
3174 x + gap_x, y, x + gap_x, y);
3176 if ((width - (gap_x + gap_width)) > 0)
3178 _cairo_draw_line (cr, color1,
3179 x + gap_x + gap_width, y, x + width - 2, y);
3180 _cairo_draw_line (cr, color2,
3181 x + gap_x + gap_width, y + 1, x + width - 3, y + 1);
3182 _cairo_draw_line (cr, color2,
3183 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
3186 case GTK_POS_BOTTOM:
3187 _cairo_draw_line (cr, color1,
3188 x, y, x + width - 1, y);
3189 _cairo_draw_line (cr, color1,
3190 x, y, x, y + height - 1);
3191 _cairo_draw_line (cr, color2,
3192 x + 1, y + 1, x + width - 2, y + 1);
3193 _cairo_draw_line (cr, color2,
3194 x + 1, y + 1, x + 1, y + height - 1);
3196 _cairo_draw_line (cr, color3,
3197 x + width - 2, y + 1, x + width - 2, y + height - 1);
3198 _cairo_draw_line (cr, color4,
3199 x + width - 1, y, x + width - 1, y + height - 1);
3202 _cairo_draw_line (cr, color4,
3203 x, y + height - 1, x + gap_x - 1, y + height - 1);
3204 _cairo_draw_line (cr, color3,
3205 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
3206 _cairo_draw_line (cr, color3,
3207 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
3209 if ((width - (gap_x + gap_width)) > 0)
3211 _cairo_draw_line (cr, color4,
3212 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
3213 _cairo_draw_line (cr, color3,
3214 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
3215 _cairo_draw_line (cr, color3,
3216 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
3220 _cairo_draw_line (cr, color1,
3221 x, y, x + width - 1, y);
3222 _cairo_draw_line (cr, color2,
3223 x, y + 1, x + width - 2, y + 1);
3225 _cairo_draw_line (cr, color3,
3226 x, y + height - 2, x + width - 2, y + height - 2);
3227 _cairo_draw_line (cr, color3,
3228 x + width - 2, y + 1, x + width - 2, y + height - 2);
3229 _cairo_draw_line (cr, color4,
3230 x, y + height - 1, x + width - 1, y + height - 1);
3231 _cairo_draw_line (cr, color4,
3232 x + width - 1, y, x + width - 1, y + height - 1);
3235 _cairo_draw_line (cr, color1,
3236 x, y, x, y + gap_x - 1);
3237 _cairo_draw_line (cr, color2,
3238 x + 1, y + 1, x + 1, y + gap_x - 1);
3239 _cairo_draw_line (cr, color2,
3240 x, y + gap_x, x, y + gap_x);
3242 if ((width - (gap_x + gap_width)) > 0)
3244 _cairo_draw_line (cr, color1,
3245 x, y + gap_x + gap_width, x, y + height - 2);
3246 _cairo_draw_line (cr, color2,
3247 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
3248 _cairo_draw_line (cr, color2,
3249 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
3253 _cairo_draw_line (cr, color1,
3254 x, y, x + width - 1, y);
3255 _cairo_draw_line (cr, color1,
3256 x, y, x, y + height - 1);
3257 _cairo_draw_line (cr, color2,
3258 x + 1, y + 1, x + width - 1, y + 1);
3259 _cairo_draw_line (cr, color2,
3260 x + 1, y + 1, x + 1, y + height - 2);
3262 _cairo_draw_line (cr, color3,
3263 x + 1, y + height - 2, x + width - 1, y + height - 2);
3264 _cairo_draw_line (cr, color4,
3265 x, y + height - 1, x + width - 1, y + height - 1);
3268 _cairo_draw_line (cr, color4,
3269 x + width - 1, y, x + width - 1, y + gap_x - 1);
3270 _cairo_draw_line (cr, color3,
3271 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
3272 _cairo_draw_line (cr, color3,
3273 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
3275 if ((width - (gap_x + gap_width)) > 0)
3277 _cairo_draw_line (cr, color4,
3278 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
3279 _cairo_draw_line (cr, color3,
3280 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
3281 _cairo_draw_line (cr, color3,
3282 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
3292 gtk_default_draw_box_gap (GtkStyle *style,
3294 GtkStateType state_type,
3295 GtkShadowType shadow_type,
3298 const gchar *detail,
3303 GtkPositionType gap_side,
3313 sanitize_size (window, &width, &height);
3315 cr = gdk_cairo_create (window);
3318 gdk_cairo_rectangle (cr, area);
3322 gtk_style_apply_default_background (style, cr, window,
3323 state_type, x, y, width, height);
3325 switch (shadow_type)
3327 case GTK_SHADOW_NONE:
3331 color1 = style->dark[state_type];
3332 color2 = style->black;
3333 color3 = style->bg[state_type];
3334 color4 = style->light[state_type];
3336 case GTK_SHADOW_ETCHED_IN:
3337 color1 = style->dark[state_type];
3338 color2 = style->light[state_type];
3339 color3 = style->dark[state_type];
3340 color4 = style->light[state_type];
3342 case GTK_SHADOW_OUT:
3343 color1 = style->light[state_type];
3344 color2 = style->bg[state_type];
3345 color3 = style->dark[state_type];
3346 color4 = style->black;
3348 case GTK_SHADOW_ETCHED_OUT:
3349 color1 = style->light[state_type];
3350 color2 = style->dark[state_type];
3351 color3 = style->light[state_type];
3352 color4 = style->dark[state_type];
3356 cairo_set_line_width (cr, 1.0);
3358 switch (shadow_type)
3360 case GTK_SHADOW_NONE:
3362 case GTK_SHADOW_OUT:
3363 case GTK_SHADOW_ETCHED_IN:
3364 case GTK_SHADOW_ETCHED_OUT:
3368 _cairo_draw_line (cr, &color1,
3369 x, y, x, y + height - 1);
3370 _cairo_draw_line (cr, &color2,
3371 x + 1, y, x + 1, y + height - 2);
3373 _cairo_draw_line (cr, &color3,
3374 x + 1, y + height - 2, x + width - 2, y + height - 2);
3375 _cairo_draw_line (cr, &color3,
3376 x + width - 2, y, x + width - 2, y + height - 2);
3377 _cairo_draw_line (cr, &color4,
3378 x, y + height - 1, x + width - 1, y + height - 1);
3379 _cairo_draw_line (cr, &color4,
3380 x + width - 1, y, x + width - 1, y + height - 1);
3383 _cairo_draw_line (cr, &color1,
3384 x, y, x + gap_x - 1, y);
3385 _cairo_draw_line (cr, &color2,
3386 x + 1, y + 1, x + gap_x - 1, y + 1);
3387 _cairo_draw_line (cr, &color2,
3388 x + gap_x, y, x + gap_x, y);
3390 if ((width - (gap_x + gap_width)) > 0)
3392 _cairo_draw_line (cr, &color1,
3393 x + gap_x + gap_width, y, x + width - 2, y);
3394 _cairo_draw_line (cr, &color2,
3395 x + gap_x + gap_width, y + 1, x + width - 2, y + 1);
3396 _cairo_draw_line (cr, &color2,
3397 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
3400 case GTK_POS_BOTTOM:
3401 _cairo_draw_line (cr, &color1,
3402 x, y, x + width - 1, y);
3403 _cairo_draw_line (cr, &color1,
3404 x, y, x, y + height - 1);
3405 _cairo_draw_line (cr, &color2,
3406 x + 1, y + 1, x + width - 2, y + 1);
3407 _cairo_draw_line (cr, &color2,
3408 x + 1, y + 1, x + 1, y + height - 1);
3410 _cairo_draw_line (cr, &color3,
3411 x + width - 2, y + 1, x + width - 2, y + height - 1);
3412 _cairo_draw_line (cr, &color4,
3413 x + width - 1, y, x + width - 1, y + height - 1);
3416 _cairo_draw_line (cr, &color4,
3417 x, y + height - 1, x + gap_x - 1, y + height - 1);
3418 _cairo_draw_line (cr, &color3,
3419 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
3420 _cairo_draw_line (cr, &color3,
3421 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
3423 if ((width - (gap_x + gap_width)) > 0)
3425 _cairo_draw_line (cr, &color4,
3426 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
3427 _cairo_draw_line (cr, &color3,
3428 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
3429 _cairo_draw_line (cr, &color3,
3430 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
3434 _cairo_draw_line (cr, &color1,
3435 x, y, x + width - 1, y);
3436 _cairo_draw_line (cr, &color2,
3437 x, y + 1, x + width - 2, y + 1);
3439 _cairo_draw_line (cr, &color3,
3440 x, y + height - 2, x + width - 2, y + height - 2);
3441 _cairo_draw_line (cr, &color3,
3442 x + width - 2, y + 1, x + width - 2, y + height - 2);
3443 _cairo_draw_line (cr, &color4,
3444 x, y + height - 1, x + width - 1, y + height - 1);
3445 _cairo_draw_line (cr, &color4,
3446 x + width - 1, y, x + width - 1, y + height - 1);
3449 _cairo_draw_line (cr, &color1,
3450 x, y, x, y + gap_x - 1);
3451 _cairo_draw_line (cr, &color2,
3452 x + 1, y + 1, x + 1, y + gap_x - 1);
3453 _cairo_draw_line (cr, &color2,
3454 x, y + gap_x, x, y + gap_x);
3456 if ((height - (gap_x + gap_width)) > 0)
3458 _cairo_draw_line (cr, &color1,
3459 x, y + gap_x + gap_width, x, y + height - 2);
3460 _cairo_draw_line (cr, &color2,
3461 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
3462 _cairo_draw_line (cr, &color2,
3463 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
3467 _cairo_draw_line (cr, &color1,
3468 x, y, x + width - 1, y);
3469 _cairo_draw_line (cr, &color1,
3470 x, y, x, y + height - 1);
3471 _cairo_draw_line (cr, &color2,
3472 x + 1, y + 1, x + width - 1, y + 1);
3473 _cairo_draw_line (cr, &color2,
3474 x + 1, y + 1, x + 1, y + height - 2);
3476 _cairo_draw_line (cr, &color3,
3477 x + 1, y + height - 2, x + width - 1, y + height - 2);
3478 _cairo_draw_line (cr, &color4,
3479 x, y + height - 1, x + width - 1, y + height - 1);
3482 _cairo_draw_line (cr, &color4,
3483 x + width - 1, y, x + width - 1, y + gap_x - 1);
3484 _cairo_draw_line (cr, &color3,
3485 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
3486 _cairo_draw_line (cr, &color3,
3487 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
3489 if ((height - (gap_x + gap_width)) > 0)
3491 _cairo_draw_line (cr, &color4,
3492 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
3493 _cairo_draw_line (cr, &color3,
3494 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
3495 _cairo_draw_line (cr, &color3,
3496 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
3507 gtk_default_draw_extension (GtkStyle *style,
3509 GtkStateType state_type,
3510 GtkShadowType shadow_type,
3513 const gchar *detail,
3518 GtkPositionType gap_side)
3526 sanitize_size (window, &width, &height);
3528 cr = gdk_cairo_create (window);
3531 gdk_cairo_rectangle (cr, area);
3538 gtk_style_apply_default_background (style, cr, window,
3545 case GTK_POS_BOTTOM:
3546 gtk_style_apply_default_background (style, cr, window,
3554 gtk_style_apply_default_background (style, cr, window,
3562 gtk_style_apply_default_background (style, cr, window,
3571 switch (shadow_type)
3573 case GTK_SHADOW_NONE:
3577 color1 = style->dark[state_type];
3578 color2 = style->black;
3579 color3 = style->bg[state_type];
3580 color4 = style->light[state_type];
3582 case GTK_SHADOW_ETCHED_IN:
3583 color1 = style->dark[state_type];
3584 color2 = style->light[state_type];
3585 color3 = style->dark[state_type];
3586 color4 = style->light[state_type];
3588 case GTK_SHADOW_OUT:
3589 color1 = style->light[state_type];
3590 color2 = style->bg[state_type];
3591 color3 = style->dark[state_type];
3592 color4 = style->black;
3594 case GTK_SHADOW_ETCHED_OUT:
3595 color1 = style->light[state_type];
3596 color2 = style->dark[state_type];
3597 color3 = style->light[state_type];
3598 color4 = style->dark[state_type];
3602 cairo_set_line_width (cr, 1.0);
3604 switch (shadow_type)
3606 case GTK_SHADOW_NONE:
3608 case GTK_SHADOW_OUT:
3609 case GTK_SHADOW_ETCHED_IN:
3610 case GTK_SHADOW_ETCHED_OUT:
3614 _cairo_draw_line (cr, &color1,
3615 x, y, x, y + height - 2);
3616 _cairo_draw_line (cr, &color2,
3617 x + 1, y, x + 1, y + height - 2);
3619 _cairo_draw_line (cr, &color3,
3620 x + 2, y + height - 2, x + width - 2, y + height - 2);
3621 _cairo_draw_line (cr, &color3,
3622 x + width - 2, y, x + width - 2, y + height - 2);
3623 _cairo_draw_line (cr, &color4,
3624 x + 1, y + height - 1, x + width - 2, y + height - 1);
3625 _cairo_draw_line (cr, &color4,
3626 x + width - 1, y, x + width - 1, y + height - 2);
3628 case GTK_POS_BOTTOM:
3629 _cairo_draw_line (cr, &color1,
3630 x + 1, y, x + width - 2, y);
3631 _cairo_draw_line (cr, &color1,
3632 x, y + 1, x, y + height - 1);
3633 _cairo_draw_line (cr, &color2,
3634 x + 1, y + 1, x + width - 2, y + 1);
3635 _cairo_draw_line (cr, &color2,
3636 x + 1, y + 1, x + 1, y + height - 1);
3638 _cairo_draw_line (cr, &color3,
3639 x + width - 2, y + 2, x + width - 2, y + height - 1);
3640 _cairo_draw_line (cr, &color4,
3641 x + width - 1, y + 1, x + width - 1, y + height - 1);
3644 _cairo_draw_line (cr, &color1,
3645 x, y, x + width - 2, y);
3646 _cairo_draw_line (cr, &color2,
3647 x + 1, y + 1, x + width - 2, y + 1);
3649 _cairo_draw_line (cr, &color3,
3650 x, y + height - 2, x + width - 2, y + height - 2);
3651 _cairo_draw_line (cr, &color3,
3652 x + width - 2, y + 2, x + width - 2, y + height - 2);
3653 _cairo_draw_line (cr, &color4,
3654 x, y + height - 1, x + width - 2, y + height - 1);
3655 _cairo_draw_line (cr, &color4,
3656 x + width - 1, y + 1, x + width - 1, y + height - 2);
3659 _cairo_draw_line (cr, &color1,
3660 x + 1, y, x + width - 1, y);
3661 _cairo_draw_line (cr, &color1,
3662 x, y + 1, x, y + height - 2);
3663 _cairo_draw_line (cr, &color2,
3664 x + 1, y + 1, x + width - 1, y + 1);
3665 _cairo_draw_line (cr, &color2,
3666 x + 1, y + 1, x + 1, y + height - 2);
3668 _cairo_draw_line (cr, &color3,
3669 x + 2, y + height - 2, x + width - 1, y + height - 2);
3670 _cairo_draw_line (cr, &color4,
3671 x + 1, y + height - 1, x + width - 1, y + height - 1);
3680 gtk_default_draw_focus (GtkStyle *style,
3682 GtkStateType state_type,
3685 const gchar *detail,
3692 gboolean free_dash_list = FALSE;
3693 gint line_width = 1;
3694 gint8 *dash_list = (gint8 *) "\1\1";
3698 gtk_widget_style_get (widget,
3699 "focus-line-width", &line_width,
3700 "focus-line-pattern", (gchar *)&dash_list,
3703 free_dash_list = TRUE;
3706 if (detail && !strcmp (detail, "add-mode"))
3711 dash_list = (gint8 *) "\4\4";
3712 free_dash_list = FALSE;
3715 sanitize_size (window, &width, &height);
3717 cr = gdk_cairo_create (window);
3719 if (detail && !strcmp (detail, "colorwheel_light"))
3720 cairo_set_source_rgb (cr, 0., 0., 0.);
3721 else if (detail && !strcmp (detail, "colorwheel_dark"))
3722 cairo_set_source_rgb (cr, 1., 1., 1.);
3724 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3726 cairo_set_line_width (cr, line_width);
3730 gint n_dashes = strlen ((const gchar *) dash_list);
3731 gdouble *dashes = g_new (gdouble, n_dashes);
3732 gdouble total_length = 0;
3733 gdouble dash_offset;
3736 for (i = 0; i < n_dashes; i++)
3738 dashes[i] = dash_list[i];
3739 total_length += dash_list[i];
3742 /* The dash offset here aligns the pattern to integer pixels
3743 * by starting the dash at the right side of the left border
3744 * Negative dash offsets in cairo don't work
3745 * (https://bugs.freedesktop.org/show_bug.cgi?id=2729)
3747 dash_offset = - line_width / 2.;
3748 while (dash_offset < 0)
3749 dash_offset += total_length;
3751 cairo_set_dash (cr, dashes, n_dashes, dash_offset);
3757 gdk_cairo_rectangle (cr, area);
3761 cairo_rectangle (cr,
3762 x + line_width / 2.,
3763 y + line_width / 2.,
3765 height - line_width);
3774 gtk_default_draw_slider (GtkStyle *style,
3776 GtkStateType state_type,
3777 GtkShadowType shadow_type,
3780 const gchar *detail,
3785 GtkOrientation orientation)
3787 sanitize_size (window, &width, &height);
3789 gtk_paint_box (style, window, state_type, shadow_type,
3790 area, widget, detail, x, y, width, height);
3793 (strcmp ("hscale", detail) == 0 ||
3794 strcmp ("vscale", detail) == 0))
3796 if (orientation == GTK_ORIENTATION_HORIZONTAL)
3797 gtk_paint_vline (style, window, state_type, area, widget, detail,
3798 y + style->ythickness,
3799 y + height - style->ythickness - 1, x + width / 2);
3801 gtk_paint_hline (style, window, state_type, area, widget, detail,
3802 x + style->xthickness,
3803 x + width - style->xthickness - 1, y + height / 2);
3808 draw_dot (cairo_t *cr,
3815 size = CLAMP (size, 2, 3);
3819 _cairo_draw_point (cr, light, x, y);
3820 _cairo_draw_point (cr, light, x+1, y+1);
3824 _cairo_draw_point (cr, light, x, y);
3825 _cairo_draw_point (cr, light, x+1, y);
3826 _cairo_draw_point (cr, light, x, y+1);
3827 _cairo_draw_point (cr, dark, x+1, y+2);
3828 _cairo_draw_point (cr, dark, x+2, y+1);
3829 _cairo_draw_point (cr, dark, x+2, y+2);
3834 gtk_default_draw_handle (GtkStyle *style,
3836 GtkStateType state_type,
3837 GtkShadowType shadow_type,
3840 const gchar *detail,
3845 GtkOrientation orientation)
3848 gint xthick, ythick;
3849 GdkColor light, dark;
3852 sanitize_size (window, &width, &height);
3854 gtk_paint_box (style, window, state_type, shadow_type, area, widget,
3855 detail, x, y, width, height);
3857 cr = gdk_cairo_create (window);
3860 gdk_cairo_rectangle (cr, area);
3864 if (detail && !strcmp (detail, "paned"))
3866 /* we want to ignore the shadow border in paned widgets */
3870 if (state_type == GTK_STATE_SELECTED && widget && !gtk_widget_has_focus (widget))
3871 _gtk_style_shade (&style->base[GTK_STATE_ACTIVE], &light,
3874 light = style->light[state_type];
3876 dark = style->black;
3880 xthick = style->xthickness;
3881 ythick = style->ythickness;
3883 light = style->light[state_type];
3884 dark = style->dark[state_type];
3887 cairo_rectangle(cr, x + xthick, y + ythick,
3888 width - (xthick * 2), height - (ythick * 2));
3891 if (detail && !strcmp (detail, "paned"))
3893 if (orientation == GTK_ORIENTATION_HORIZONTAL)
3894 for (xx = x + width/2 - 15; xx <= x + width/2 + 15; xx += 5)
3895 draw_dot (cr, &light, &dark, xx, y + height/2 - 1, 3);
3897 for (yy = y + height/2 - 15; yy <= y + height/2 + 15; yy += 5)
3898 draw_dot (cr, &light, &dark, x + width/2 - 1, yy, 3);
3902 for (yy = y + ythick; yy < (y + height - ythick); yy += 3)
3903 for (xx = x + xthick; xx < (x + width - xthick); xx += 6)
3905 draw_dot (cr, &light, &dark, xx, yy, 2);
3906 draw_dot (cr, &light, &dark, xx + 3, yy + 1, 2);
3914 gtk_default_draw_expander (GtkStyle *style,
3916 GtkStateType state_type,
3919 const gchar *detail,
3922 GtkExpanderStyle expander_style)
3924 #define DEFAULT_EXPANDER_SIZE 12
3928 double vertical_overshoot;
3931 double interp; /* interpolation factor for center position */
3932 double x_double_horz, y_double_horz;
3933 double x_double_vert, y_double_vert;
3934 double x_double, y_double;
3937 cairo_t *cr = gdk_cairo_create (window);
3941 gdk_cairo_rectangle (cr, area);
3946 gtk_widget_class_find_style_property (GTK_WIDGET_GET_CLASS (widget),
3949 gtk_widget_style_get (widget,
3950 "expander-size", &expander_size,
3954 expander_size = DEFAULT_EXPANDER_SIZE;
3956 line_width = MAX (1, expander_size/9);
3958 switch (expander_style)
3960 case GTK_EXPANDER_COLLAPSED:
3961 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 180 : 0;
3964 case GTK_EXPANDER_SEMI_COLLAPSED:
3965 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 150 : 30;
3968 case GTK_EXPANDER_SEMI_EXPANDED:
3969 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 120 : 60;
3972 case GTK_EXPANDER_EXPANDED:
3977 g_assert_not_reached ();
3980 /* Compute distance that the stroke extends beyonds the end
3981 * of the triangle we draw.
3983 vertical_overshoot = line_width / 2.0 * (1. / tan (G_PI / 8));
3985 /* For odd line widths, we end the vertical line of the triangle
3986 * at a half pixel, so we round differently.
3988 if (line_width % 2 == 1)
3989 vertical_overshoot = ceil (0.5 + vertical_overshoot) - 0.5;
3991 vertical_overshoot = ceil (vertical_overshoot);
3993 /* Adjust the size of the triangle we draw so that the entire stroke fits
3995 diameter = MAX (3, expander_size - 2 * vertical_overshoot);
3997 /* If the line width is odd, we want the diameter to be even,
3998 * and vice versa, so force the sum to be odd. This relationship
3999 * makes the point of the triangle look right.
4001 diameter -= (1 - (diameter + line_width) % 2);
4003 radius = diameter / 2.;
4005 /* Adjust the center so that the stroke is properly aligned with
4006 * the pixel grid. The center adjustment is different for the
4007 * horizontal and vertical orientations. For intermediate positions
4008 * we interpolate between the two.
4010 x_double_vert = floor (x - (radius + line_width) / 2.) + (radius + line_width) / 2.;
4011 y_double_vert = y - 0.5;
4013 x_double_horz = x - 0.5;
4014 y_double_horz = floor (y - (radius + line_width) / 2.) + (radius + line_width) / 2.;
4016 x_double = x_double_vert * (1 - interp) + x_double_horz * interp;
4017 y_double = y_double_vert * (1 - interp) + y_double_horz * interp;
4019 cairo_translate (cr, x_double, y_double);
4020 cairo_rotate (cr, degrees * G_PI / 180);
4022 cairo_move_to (cr, - radius / 2., - radius);
4023 cairo_line_to (cr, radius / 2., 0);
4024 cairo_line_to (cr, - radius / 2., radius);
4025 cairo_close_path (cr);
4027 cairo_set_line_width (cr, line_width);
4029 if (state_type == GTK_STATE_PRELIGHT)
4030 gdk_cairo_set_source_color (cr,
4031 &style->fg[GTK_STATE_PRELIGHT]);
4032 else if (state_type == GTK_STATE_ACTIVE)
4033 gdk_cairo_set_source_color (cr,
4034 &style->light[GTK_STATE_ACTIVE]);
4036 gdk_cairo_set_source_color (cr,
4037 &style->base[GTK_STATE_NORMAL]);
4039 cairo_fill_preserve (cr);
4041 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
4048 gtk_default_draw_layout (GtkStyle *style,
4050 GtkStateType state_type,
4054 const gchar *detail,
4057 PangoLayout *layout)
4061 const PangoMatrix *matrix;
4063 cr = gdk_cairo_create (window);
4067 gdk_cairo_rectangle (cr, area);
4071 matrix = pango_context_get_matrix (pango_layout_get_context (layout));
4074 cairo_matrix_t cairo_matrix;
4075 PangoMatrix tmp_matrix;
4076 PangoRectangle rect;
4078 cairo_matrix_init (&cairo_matrix,
4079 matrix->xx, matrix->yx,
4080 matrix->xy, matrix->yy,
4081 matrix->x0, matrix->y0);
4083 pango_layout_get_extents (layout, NULL, &rect);
4084 pango_matrix_transform_rectangle (matrix, &rect);
4085 pango_extents_to_pixels (&rect, NULL);
4087 tmp_matrix = *matrix;
4088 cairo_matrix.x0 += x - rect.x;
4089 cairo_matrix.y0 += y - rect.y;
4091 cairo_set_matrix (cr, &cairo_matrix);
4094 cairo_translate (cr, x, y);
4096 cairo_new_path (cr);
4098 if (state_type == GTK_STATE_INSENSITIVE)
4100 gdk_cairo_set_source_color (cr, &style->white);
4101 cairo_move_to (cr, 1, 1);
4102 _gtk_pango_fill_layout (cr, layout);
4103 cairo_new_path (cr);
4106 gc = use_text ? &style->text[state_type] : &style->fg[state_type];
4108 gdk_cairo_set_source_color (cr, gc);
4110 pango_cairo_show_layout (cr, layout);
4116 gtk_default_draw_resize_grip (GtkStyle *style,
4118 GtkStateType state_type,
4121 const gchar *detail,
4131 cr = gdk_cairo_create (window);
4132 cairo_rectangle (cr, x, y, width, height);
4136 gdk_cairo_rectangle (cr, area);
4140 cairo_set_line_width (cr, 1.0);
4145 case GDK_WINDOW_EDGE_NORTH_WEST:
4146 /* make it square */
4149 else if (height < width)
4153 case GDK_WINDOW_EDGE_NORTH:
4157 case GDK_WINDOW_EDGE_NORTH_EAST:
4158 /* make it square, aligning to top right */
4161 else if (height < width)
4163 x += (width - height);
4168 case GDK_WINDOW_EDGE_WEST:
4172 case GDK_WINDOW_EDGE_EAST:
4173 /* aligning to right */
4176 x += (width - height);
4180 case GDK_WINDOW_EDGE_SOUTH_WEST:
4181 /* make it square, aligning to bottom left */
4184 y += (height - width);
4187 else if (height < width)
4191 case GDK_WINDOW_EDGE_SOUTH:
4192 /* align to bottom */
4195 y += (height - width);
4199 case GDK_WINDOW_EDGE_SOUTH_EAST:
4200 /* make it square, aligning to bottom right */
4203 y += (height - width);
4206 else if (height < width)
4208 x += (width - height);
4214 g_assert_not_reached ();
4219 case GDK_WINDOW_EDGE_WEST:
4220 case GDK_WINDOW_EDGE_EAST:
4226 while (xi < x + width)
4228 _cairo_draw_line (cr,
4229 &style->light[state_type],
4234 _cairo_draw_line (cr,
4235 &style->dark[state_type],
4243 case GDK_WINDOW_EDGE_NORTH:
4244 case GDK_WINDOW_EDGE_SOUTH:
4250 while (yi < y + height)
4252 _cairo_draw_line (cr,
4253 &style->light[state_type],
4258 _cairo_draw_line (cr,
4259 &style->dark[state_type],
4267 case GDK_WINDOW_EDGE_NORTH_WEST:
4276 _cairo_draw_line (cr,
4277 &style->dark[state_type],
4284 _cairo_draw_line (cr,
4285 &style->dark[state_type],
4292 _cairo_draw_line (cr,
4293 &style->light[state_type],
4303 case GDK_WINDOW_EDGE_NORTH_EAST:
4310 while (xi < (x + width - 3))
4312 _cairo_draw_line (cr,
4313 &style->light[state_type],
4320 _cairo_draw_line (cr,
4321 &style->dark[state_type],
4328 _cairo_draw_line (cr,
4329 &style->dark[state_type],
4338 case GDK_WINDOW_EDGE_SOUTH_WEST:
4347 _cairo_draw_line (cr,
4348 &style->dark[state_type],
4355 _cairo_draw_line (cr,
4356 &style->dark[state_type],
4363 _cairo_draw_line (cr,
4364 &style->light[state_type],
4374 case GDK_WINDOW_EDGE_SOUTH_EAST:
4381 while (xi < (x + width - 3))
4383 _cairo_draw_line (cr,
4384 &style->light[state_type],
4391 _cairo_draw_line (cr,
4392 &style->dark[state_type],
4399 _cairo_draw_line (cr,
4400 &style->dark[state_type],
4410 g_assert_not_reached ();
4418 gtk_default_draw_spinner (GtkStyle *style,
4420 GtkStateType state_type,
4423 const gchar *detail,
4439 gtk_style_get (style, GTK_TYPE_SPINNER,
4440 "num-steps", &num_steps,
4442 real_step = step % num_steps;
4444 /* get cairo context */
4445 cr = gdk_cairo_create (window);
4447 /* set a clip region for the expose event */
4448 cairo_rectangle (cr, x, y, width, height);
4451 cairo_translate (cr, x, y);
4453 /* draw clip region */
4454 cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
4456 color = &style->fg[state_type];
4459 radius = MIN (width / 2, height / 2);
4460 half = num_steps / 2;
4462 for (i = 0; i < num_steps; i++)
4464 gint inset = 0.7 * radius;
4466 /* transparency is a function of time and intial value */
4467 gdouble t = (gdouble) ((i + num_steps - real_step)
4468 % num_steps) / num_steps;
4472 cairo_set_source_rgba (cr,
4473 color->red / 65535.,
4474 color->green / 65535.,
4475 color->blue / 65535.,
4478 cairo_set_line_width (cr, 2.0);
4480 dx + (radius - inset) * cos (i * G_PI / half),
4481 dy + (radius - inset) * sin (i * G_PI / half));
4483 dx + radius * cos (i * G_PI / half),
4484 dy + radius * sin (i * G_PI / half));
4495 _gtk_style_shade (const GdkColor *a,
4503 red = (gdouble) a->red / 65535.0;
4504 green = (gdouble) a->green / 65535.0;
4505 blue = (gdouble) a->blue / 65535.0;
4507 rgb_to_hls (&red, &green, &blue);
4512 else if (green < 0.0)
4518 else if (blue < 0.0)
4521 hls_to_rgb (&red, &green, &blue);
4523 b->red = red * 65535.0;
4524 b->green = green * 65535.0;
4525 b->blue = blue * 65535.0;
4529 rgb_to_hls (gdouble *r,
4570 l = (max + min) / 2;
4577 s = (max - min) / (max + min);
4579 s = (max - min) / (2 - max - min);
4583 h = (green - blue) / delta;
4584 else if (green == max)
4585 h = 2 + (blue - red) / delta;
4586 else if (blue == max)
4587 h = 4 + (red - green) / delta;
4600 hls_to_rgb (gdouble *h,
4613 if (lightness <= 0.5)
4614 m2 = lightness * (1 + saturation);
4616 m2 = lightness + saturation - lightness * saturation;
4617 m1 = 2 * lightness - m2;
4619 if (saturation == 0)
4634 r = m1 + (m2 - m1) * hue / 60;
4638 r = m1 + (m2 - m1) * (240 - hue) / 60;
4649 g = m1 + (m2 - m1) * hue / 60;
4653 g = m1 + (m2 - m1) * (240 - hue) / 60;
4664 b = m1 + (m2 - m1) * hue / 60;
4668 b = m1 + (m2 - m1) * (240 - hue) / 60;
4680 gtk_style_cairo_create (GdkWindow *window, const GdkRectangle *area)
4684 cr = gdk_cairo_create (window);
4688 gdk_cairo_rectangle (cr, area);
4697 * @style: a #GtkStyle
4698 * @window: a #GdkWindow
4699 * @state_type: a state
4700 * @area: (allow-none): rectangle to which the output is clipped, or %NULL if the
4701 * output should not be clipped
4702 * @widget: (allow-none): the widget
4703 * @detail: (allow-none): a style detail
4704 * @x1: the starting x coordinate
4705 * @x2: the ending x coordinate
4706 * @y: the y coordinate
4708 * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @window
4709 * using the given style and state.
4712 gtk_paint_hline (GtkStyle *style,
4714 GtkStateType state_type,
4715 const GdkRectangle *area,
4717 const gchar *detail,
4724 g_return_if_fail (GTK_IS_STYLE (style));
4725 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
4726 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
4728 cr = gtk_style_cairo_create (window, area);
4730 gtk_cairo_paint_hline (style, cr, state_type,
4738 * gtk_cairo_paint_hline:
4739 * @style: a #GtkStyle
4741 * @state_type: a state
4742 * @widget: (allow-none): the widget
4743 * @detail: (allow-none): a style detail
4744 * @x1: the starting x coordinate
4745 * @x2: the ending x coordinate
4746 * @y: the y coordinate
4748 * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @cr
4749 * using the given style and state.
4752 gtk_cairo_paint_hline (GtkStyle *style,
4754 GtkStateType state_type,
4756 const gchar *detail,
4761 g_return_if_fail (GTK_IS_STYLE (style));
4762 g_return_if_fail (cr != NULL);
4763 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
4767 GTK_STYLE_GET_CLASS (style)->draw_hline (style, cr, state_type,
4776 * @style: a #GtkStyle
4777 * @window: a #GdkWindow
4778 * @state_type: a state
4779 * @area: (allow-none): rectangle to which the output is clipped, or %NULL if the
4780 * output should not be clipped
4781 * @widget: (allow-none): the widget
4782 * @detail: (allow-none): a style detail
4783 * @y1_: the starting y coordinate
4784 * @y2_: the ending y coordinate
4785 * @x: the x coordinate
4787 * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @window
4788 * using the given style and state.
4791 gtk_paint_vline (GtkStyle *style,
4793 GtkStateType state_type,
4794 const GdkRectangle *area,
4796 const gchar *detail,
4803 g_return_if_fail (GTK_IS_STYLE (style));
4804 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
4805 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
4807 cr = gtk_style_cairo_create (window, area);
4809 GTK_STYLE_GET_CLASS (style)->draw_vline (style, cr, state_type,
4817 * gtk_cairo_paint_vline:
4818 * @style: a #GtkStyle
4820 * @state_type: a state
4821 * @widget: (allow-none): the widget
4822 * @detail: (allow-none): a style detail
4823 * @y1_: the starting y coordinate
4824 * @y2_: the ending y coordinate
4825 * @x: the x coordinate
4827 * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @cr
4828 * using the given style and state.
4831 gtk_cairo_paint_vline (GtkStyle *style,
4833 GtkStateType state_type,
4835 const gchar *detail,
4840 g_return_if_fail (GTK_IS_STYLE (style));
4841 g_return_if_fail (cr != NULL);
4842 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
4846 GTK_STYLE_GET_CLASS (style)->draw_vline (style, cr, state_type,
4855 * @style: a #GtkStyle
4856 * @window: a #GdkWindow
4857 * @state_type: a state
4858 * @shadow_type: type of shadow to draw
4859 * @area: (allow-none): clip rectangle or %NULL if the
4860 * output should not be clipped
4861 * @widget: (allow-none): the widget
4862 * @detail: (allow-none): a style detail
4863 * @x: x origin of the rectangle
4864 * @y: y origin of the rectangle
4865 * @width: width of the rectangle
4866 * @height: width of the rectangle
4868 * Draws a shadow around the given rectangle in @window
4869 * using the given style and state and shadow type.
4872 gtk_paint_shadow (GtkStyle *style,
4874 GtkStateType state_type,
4875 GtkShadowType shadow_type,
4876 const GdkRectangle *area,
4878 const gchar *detail,
4886 g_return_if_fail (GTK_IS_STYLE (style));
4887 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
4888 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
4890 sanitize_size (window, &width, &height);
4892 cr = gtk_style_cairo_create (window, area);
4894 gtk_cairo_paint_shadow (style, cr, state_type, shadow_type,
4896 x, y, width, height);
4902 * gtk_cairo_paint_shadow:
4903 * @style: a #GtkStyle
4905 * @state_type: a state
4906 * @shadow_type: type of shadow to draw
4907 * @widget: (allow-none): the widget
4908 * @detail: (allow-none): a style detail
4909 * @x: x origin of the rectangle
4910 * @y: y origin of the rectangle
4911 * @width: width of the rectangle
4912 * @height: width of the rectangle
4914 * Draws a shadow around the given rectangle in @cr
4915 * using the given style and state and shadow type.
4918 gtk_cairo_paint_shadow (GtkStyle *style,
4920 GtkStateType state_type,
4921 GtkShadowType shadow_type,
4923 const gchar *detail,
4929 g_return_if_fail (GTK_IS_STYLE (style));
4930 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
4931 g_return_if_fail (cr != NULL);
4932 g_return_if_fail (width >= 0);
4933 g_return_if_fail (height >= 0);
4937 GTK_STYLE_GET_CLASS (style)->draw_shadow (style, cr, state_type, shadow_type,
4939 x, y, width, height);
4946 * @style: a #GtkStyle
4947 * @window: a #GdkWindow
4948 * @state_type: a state
4949 * @shadow_type: the type of shadow to draw
4950 * @area: (allow-none): clip rectangle, or %NULL if the
4951 * output should not be clipped
4952 * @widget: (allow-none): the widget
4953 * @detail: (allow-none): a style detail
4954 * @arrow_type: the type of arrow to draw
4955 * @fill: %TRUE if the arrow tip should be filled
4956 * @x: x origin of the rectangle to draw the arrow in
4957 * @y: y origin of the rectangle to draw the arrow in
4958 * @width: width of the rectangle to draw the arrow in
4959 * @height: height of the rectangle to draw the arrow in
4961 * Draws an arrow in the given rectangle on @window using the given
4962 * parameters. @arrow_type determines the direction of the arrow.
4965 gtk_paint_arrow (GtkStyle *style,
4967 GtkStateType state_type,
4968 GtkShadowType shadow_type,
4969 const GdkRectangle *area,
4971 const gchar *detail,
4972 GtkArrowType arrow_type,
4981 g_return_if_fail (GTK_IS_STYLE (style));
4982 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
4983 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
4985 sanitize_size (window, &width, &height);
4987 cr = gtk_style_cairo_create (window, area);
4989 gtk_cairo_paint_arrow (style, cr, state_type, shadow_type,
4991 arrow_type, fill, x, y, width, height);
4997 * gtk_cairo_paint_arrow:
4998 * @style: a #GtkStyle
5000 * @state_type: a state
5001 * @shadow_type: the type of shadow to draw
5002 * @widget: (allow-none): the widget
5003 * @detail: (allow-none): a style detail
5004 * @arrow_type: the type of arrow to draw
5005 * @fill: %TRUE if the arrow tip should be filled
5006 * @x: x origin of the rectangle to draw the arrow in
5007 * @y: y origin of the rectangle to draw the arrow in
5008 * @width: width of the rectangle to draw the arrow in
5009 * @height: height of the rectangle to draw the arrow in
5011 * Draws an arrow in the given rectangle on @cr using the given
5012 * parameters. @arrow_type determines the direction of the arrow.
5015 gtk_cairo_paint_arrow (GtkStyle *style,
5017 GtkStateType state_type,
5018 GtkShadowType shadow_type,
5020 const gchar *detail,
5021 GtkArrowType arrow_type,
5028 g_return_if_fail (GTK_IS_STYLE (style));
5029 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
5030 g_return_if_fail (cr != NULL);
5031 g_return_if_fail (width >= 0);
5032 g_return_if_fail (height >= 0);
5036 GTK_STYLE_GET_CLASS (style)->draw_arrow (style, cr, state_type, shadow_type,
5038 arrow_type, fill, x, y, width, height);
5044 * gtk_paint_diamond:
5045 * @style: a #GtkStyle
5046 * @window: a #GdkWindow
5047 * @state_type: a state
5048 * @shadow_type: the type of shadow to draw
5049 * @area: (allow-none): clip rectangle, or %NULL if the
5050 * output should not be clipped
5051 * @widget: (allow-none): the widget
5052 * @detail: (allow-none): a style detail
5053 * @x: x origin of the rectangle to draw the diamond in
5054 * @y: y origin of the rectangle to draw the diamond in
5055 * @width: width of the rectangle to draw the diamond in
5056 * @height: height of the rectangle to draw the diamond in
5058 * Draws a diamond in the given rectangle on @window using the given
5062 gtk_paint_diamond (GtkStyle *style,
5064 GtkStateType state_type,
5065 GtkShadowType shadow_type,
5066 const GdkRectangle *area,
5068 const gchar *detail,
5076 g_return_if_fail (GTK_IS_STYLE (style));
5077 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
5078 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5080 sanitize_size (window, &width, &height);
5082 cr = gtk_style_cairo_create (window, area);
5084 gtk_cairo_paint_diamond (style, cr, state_type, shadow_type,
5086 x, y, width, height);
5092 * gtk_cairo_paint_diamond:
5093 * @style: a #GtkStyle
5095 * @state_type: a state
5096 * @shadow_type: the type of shadow to draw
5097 * @widget: (allow-none): the widget
5098 * @detail: (allow-none): a style detail
5099 * @x: x origin of the rectangle to draw the diamond in
5100 * @y: y origin of the rectangle to draw the diamond in
5101 * @width: width of the rectangle to draw the diamond in
5102 * @height: height of the rectangle to draw the diamond in
5104 * Draws a diamond in the given rectangle on @window using the given
5108 gtk_cairo_paint_diamond (GtkStyle *style,
5110 GtkStateType state_type,
5111 GtkShadowType shadow_type,
5113 const gchar *detail,
5119 g_return_if_fail (GTK_IS_STYLE (style));
5120 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
5121 g_return_if_fail (cr != NULL);
5122 g_return_if_fail (width >= 0);
5123 g_return_if_fail (height >= 0);
5127 GTK_STYLE_GET_CLASS (style)->draw_diamond (style, cr, state_type, shadow_type,
5129 x, y, width, height);
5136 * @style: a #GtkStyle
5137 * @window: a #GdkWindow
5138 * @state_type: a state
5139 * @shadow_type: the type of shadow to draw
5140 * @area: (allow-none): clip rectangle, or %NULL if the
5141 * output should not be clipped
5142 * @widget: (allow-none): the widget
5143 * @detail: (allow-none): a style detail
5144 * @x: x origin of the box
5145 * @y: y origin of the box
5146 * @width: the width of the box
5147 * @height: the height of the box
5149 * Draws a box on @window with the given parameters.
5152 gtk_paint_box (GtkStyle *style,
5154 GtkStateType state_type,
5155 GtkShadowType shadow_type,
5156 const GdkRectangle *area,
5158 const gchar *detail,
5166 g_return_if_fail (GTK_IS_STYLE (style));
5167 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
5168 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5170 sanitize_size (window, &width, &height);
5172 cr = gtk_style_cairo_create (window, area);
5174 gtk_cairo_paint_box (style, cr, state_type, shadow_type,
5176 x, y, width, height);
5182 * gtk_cairo_paint_box:
5183 * @style: a #GtkStyle
5185 * @state_type: a state
5186 * @shadow_type: the type of shadow to draw
5187 * @widget: (allow-none): the widget
5188 * @detail: (allow-none): a style detail
5189 * @x: x origin of the box
5190 * @y: y origin of the box
5191 * @width: the width of the box
5192 * @height: the height of the box
5194 * Draws a box on @cr with the given parameters.
5197 gtk_cairo_paint_box (GtkStyle *style,
5199 GtkStateType state_type,
5200 GtkShadowType shadow_type,
5202 const gchar *detail,
5208 g_return_if_fail (GTK_IS_STYLE (style));
5209 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
5210 g_return_if_fail (cr != NULL);
5214 GTK_STYLE_GET_CLASS (style)->draw_box (style, cr, state_type, shadow_type,
5216 x, y, width, height);
5222 * gtk_paint_flat_box:
5223 * @style: a #GtkStyle
5224 * @window: a #GdkWindow
5225 * @state_type: a state
5226 * @shadow_type: the type of shadow to draw
5227 * @area: (allow-none): clip rectangle, or %NULL if the
5228 * output should not be clipped
5229 * @widget: (allow-none): the widget
5230 * @detail: (allow-none): a style detail
5231 * @x: x origin of the box
5232 * @y: y origin of the box
5233 * @width: the width of the box
5234 * @height: the height of the box
5236 * Draws a flat box on @window with the given parameters.
5239 gtk_paint_flat_box (GtkStyle *style,
5241 GtkStateType state_type,
5242 GtkShadowType shadow_type,
5243 const GdkRectangle *area,
5245 const gchar *detail,
5253 g_return_if_fail (GTK_IS_STYLE (style));
5254 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
5255 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5257 sanitize_size (window, &width, &height);
5259 cr = gtk_style_cairo_create (window, area);
5261 gtk_cairo_paint_flat_box (style, cr, state_type, shadow_type,
5263 x, y, width, height);
5269 * gtk_cairo_paint_flat_box:
5270 * @style: a #GtkStyle
5272 * @state_type: a state
5273 * @shadow_type: the type of shadow to draw
5274 * @area: (allow-none): clip rectangle, or %NULL if the
5275 * output should not be clipped
5276 * @widget: (allow-none): the widget
5277 * @detail: (allow-none): a style detail
5278 * @x: x origin of the box
5279 * @y: y origin of the box
5280 * @width: the width of the box
5281 * @height: the height of the box
5283 * Draws a flat box on @cr with the given parameters.
5286 gtk_cairo_paint_flat_box (GtkStyle *style,
5288 GtkStateType state_type,
5289 GtkShadowType shadow_type,
5291 const gchar *detail,
5297 g_return_if_fail (GTK_IS_STYLE (style));
5298 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
5299 g_return_if_fail (cr != NULL);
5300 g_return_if_fail (width >= 0);
5301 g_return_if_fail (height >= 0);
5305 GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, cr, state_type, shadow_type,
5307 x, y, width, height);
5314 * @style: a #GtkStyle
5315 * @window: a #GdkWindow
5316 * @state_type: a state
5317 * @shadow_type: the type of shadow to draw
5318 * @area: (allow-none): clip rectangle, or %NULL if the
5319 * output should not be clipped
5320 * @widget: (allow-none): the widget
5321 * @detail: (allow-none): a style detail
5322 * @x: x origin of the rectangle to draw the check in
5323 * @y: y origin of the rectangle to draw the check in
5324 * @width: the width of the rectangle to draw the check in
5325 * @height: the height of the rectangle to draw the check in
5327 * Draws a check button indicator in the given rectangle on @window with
5328 * the given parameters.
5331 gtk_paint_check (GtkStyle *style,
5333 GtkStateType state_type,
5334 GtkShadowType shadow_type,
5335 const GdkRectangle *area,
5337 const gchar *detail,
5343 g_return_if_fail (GTK_IS_STYLE (style));
5344 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
5345 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5347 GTK_STYLE_GET_CLASS (style)->draw_check (style, window, state_type, shadow_type,
5348 (GdkRectangle *) area, widget, detail,
5349 x, y, width, height);
5354 * @style: a #GtkStyle
5355 * @window: a #GdkWindow
5356 * @state_type: a state
5357 * @shadow_type: the type of shadow to draw
5358 * @area: (allow-none): clip rectangle, or %NULL if the
5359 * output should not be clipped
5360 * @widget: (allow-none): the widget
5361 * @detail: (allow-none): a style detail
5362 * @x: x origin of the rectangle to draw the option in
5363 * @y: y origin of the rectangle to draw the option in
5364 * @width: the width of the rectangle to draw the option in
5365 * @height: the height of the rectangle to draw the option in
5367 * Draws a radio button indicator in the given rectangle on @window with
5368 * the given parameters.
5371 gtk_paint_option (GtkStyle *style,
5373 GtkStateType state_type,
5374 GtkShadowType shadow_type,
5375 const GdkRectangle *area,
5377 const gchar *detail,
5383 g_return_if_fail (GTK_IS_STYLE (style));
5384 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
5385 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5387 GTK_STYLE_GET_CLASS (style)->draw_option (style, window, state_type, shadow_type,
5388 (GdkRectangle *) area, widget, detail,
5389 x, y, width, height);
5394 * @style: a #GtkStyle
5395 * @window: a #GdkWindow
5396 * @state_type: a state
5397 * @shadow_type: the type of shadow to draw
5398 * @area: (allow-none): clip rectangle, or %NULL if the
5399 * output should not be clipped
5400 * @widget: (allow-none): the widget
5401 * @detail: (allow-none): a style detail
5402 * @x: x origin of the rectangle to draw the tab in
5403 * @y: y origin of the rectangle to draw the tab in
5404 * @width: the width of the rectangle to draw the tab in
5405 * @height: the height of the rectangle to draw the tab in
5407 * Draws an option menu tab (i.e. the up and down pointing arrows)
5408 * in the given rectangle on @window using the given parameters.
5411 gtk_paint_tab (GtkStyle *style,
5413 GtkStateType state_type,
5414 GtkShadowType shadow_type,
5415 const GdkRectangle *area,
5417 const gchar *detail,
5423 g_return_if_fail (GTK_IS_STYLE (style));
5424 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
5425 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5427 GTK_STYLE_GET_CLASS (style)->draw_tab (style, window, state_type, shadow_type,
5428 (GdkRectangle *) area, widget, detail,
5429 x, y, width, height);
5433 * gtk_paint_shadow_gap:
5434 * @style: a #GtkStyle
5435 * @window: a #GdkWindow
5436 * @state_type: a state
5437 * @shadow_type: type of shadow to draw
5438 * @area: (allow-none): clip rectangle, or %NULL if the
5439 * output should not be clipped
5440 * @widget: (allow-none): the widget
5441 * @detail: (allow-none): a style detail
5442 * @x: x origin of the rectangle
5443 * @y: y origin of the rectangle
5444 * @width: width of the rectangle
5445 * @height: width of the rectangle
5446 * @gap_side: side in which to leave the gap
5447 * @gap_x: starting position of the gap
5448 * @gap_width: width of the gap
5450 * Draws a shadow around the given rectangle in @window
5451 * using the given style and state and shadow type, leaving a
5455 gtk_paint_shadow_gap (GtkStyle *style,
5457 GtkStateType state_type,
5458 GtkShadowType shadow_type,
5459 const GdkRectangle *area,
5461 const gchar *detail,
5466 GtkPositionType gap_side,
5470 g_return_if_fail (GTK_IS_STYLE (style));
5471 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
5472 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5474 GTK_STYLE_GET_CLASS (style)->draw_shadow_gap (style, window, state_type, shadow_type,
5475 (GdkRectangle *) area, widget, detail,
5476 x, y, width, height, gap_side, gap_x, gap_width);
5481 * gtk_paint_box_gap:
5482 * @style: a #GtkStyle
5483 * @window: a #GdkWindow
5484 * @state_type: a state
5485 * @shadow_type: type of shadow to draw
5486 * @area: (allow-none): clip rectangle, or %NULL if the
5487 * output should not be clipped
5488 * @widget: (allow-none): the widget
5489 * @detail: (allow-none): a style detail
5490 * @x: x origin of the rectangle
5491 * @y: y origin of the rectangle
5492 * @width: width of the rectangle
5493 * @height: width of the rectangle
5494 * @gap_side: side in which to leave the gap
5495 * @gap_x: starting position of the gap
5496 * @gap_width: width of the gap
5498 * Draws a box in @window using the given style and state and shadow type,
5499 * leaving a gap in one side.
5502 gtk_paint_box_gap (GtkStyle *style,
5504 GtkStateType state_type,
5505 GtkShadowType shadow_type,
5506 const GdkRectangle *area,
5508 const gchar *detail,
5513 GtkPositionType gap_side,
5517 g_return_if_fail (GTK_IS_STYLE (style));
5518 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
5519 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5521 GTK_STYLE_GET_CLASS (style)->draw_box_gap (style, window, state_type, shadow_type,
5522 (GdkRectangle *) area, widget, detail,
5523 x, y, width, height, gap_side, gap_x, gap_width);
5527 * gtk_paint_extension:
5528 * @style: a #GtkStyle
5529 * @window: a #GdkWindow
5530 * @state_type: a state
5531 * @shadow_type: type of shadow to draw
5532 * @area: (allow-none): clip rectangle, or %NULL if the
5533 * output should not be clipped
5534 * @widget: (allow-none): the widget
5535 * @detail: (allow-none): a style detail
5536 * @x: x origin of the extension
5537 * @y: y origin of the extension
5538 * @width: width of the extension
5539 * @height: width of the extension
5540 * @gap_side: the side on to which the extension is attached
5542 * Draws an extension, i.e. a notebook tab.
5545 gtk_paint_extension (GtkStyle *style,
5547 GtkStateType state_type,
5548 GtkShadowType shadow_type,
5549 const GdkRectangle *area,
5551 const gchar *detail,
5556 GtkPositionType gap_side)
5558 g_return_if_fail (GTK_IS_STYLE (style));
5559 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
5560 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5562 GTK_STYLE_GET_CLASS (style)->draw_extension (style, window, state_type, shadow_type,
5563 (GdkRectangle *) area, widget, detail,
5564 x, y, width, height, gap_side);
5569 * @style: a #GtkStyle
5570 * @window: a #GdkWindow
5571 * @state_type: a state
5572 * @area: (allow-none): clip rectangle, or %NULL if the
5573 * output should not be clipped
5574 * @widget: (allow-none): the widget
5575 * @detail: (allow-none): a style detail
5576 * @x: the x origin of the rectangle around which to draw a focus indicator
5577 * @y: the y origin of the rectangle around which to draw a focus indicator
5578 * @width: the width of the rectangle around which to draw a focus indicator
5579 * @height: the height of the rectangle around which to draw a focus indicator
5581 * Draws a focus indicator around the given rectangle on @window using the
5585 gtk_paint_focus (GtkStyle *style,
5587 GtkStateType state_type,
5588 const GdkRectangle *area,
5590 const gchar *detail,
5596 g_return_if_fail (GTK_IS_STYLE (style));
5597 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
5598 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5600 GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, state_type,
5601 (GdkRectangle *) area, widget, detail,
5602 x, y, width, height);
5607 * @style: a #GtkStyle
5608 * @window: a #GdkWindow
5609 * @state_type: a state
5610 * @shadow_type: a shadow
5611 * @area: (allow-none): clip rectangle, or %NULL if the
5612 * output should not be clipped
5613 * @widget: (allow-none): the widget
5614 * @detail: (allow-none): a style detail
5615 * @x: the x origin of the rectangle in which to draw a slider
5616 * @y: the y origin of the rectangle in which to draw a slider
5617 * @width: the width of the rectangle in which to draw a slider
5618 * @height: the height of the rectangle in which to draw a slider
5619 * @orientation: the orientation to be used
5621 * Draws a slider in the given rectangle on @window using the
5622 * given style and orientation.
5625 gtk_paint_slider (GtkStyle *style,
5627 GtkStateType state_type,
5628 GtkShadowType shadow_type,
5629 const GdkRectangle *area,
5631 const gchar *detail,
5636 GtkOrientation orientation)
5638 g_return_if_fail (GTK_IS_STYLE (style));
5639 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
5640 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5642 GTK_STYLE_GET_CLASS (style)->draw_slider (style, window, state_type, shadow_type,
5643 (GdkRectangle *) area, widget, detail,
5644 x, y, width, height, orientation);
5649 * @style: a #GtkStyle
5650 * @window: a #GdkWindow
5651 * @state_type: a state
5652 * @shadow_type: type of shadow to draw
5653 * @area: (allow-none): clip rectangle, or %NULL if the
5654 * output should not be clipped
5655 * @widget: (allow-none): the widget
5656 * @detail: (allow-none): a style detail
5657 * @x: x origin of the handle
5658 * @y: y origin of the handle
5659 * @width: with of the handle
5660 * @height: height of the handle
5661 * @orientation: the orientation of the handle
5663 * Draws a handle as used in #GtkHandleBox and #GtkPaned.
5666 gtk_paint_handle (GtkStyle *style,
5668 GtkStateType state_type,
5669 GtkShadowType shadow_type,
5670 const GdkRectangle *area,
5672 const gchar *detail,
5677 GtkOrientation orientation)
5679 g_return_if_fail (GTK_IS_STYLE (style));
5680 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
5681 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5683 GTK_STYLE_GET_CLASS (style)->draw_handle (style, window, state_type, shadow_type,
5684 (GdkRectangle *) area, widget, detail,
5685 x, y, width, height, orientation);
5689 * gtk_paint_expander:
5690 * @style: a #GtkStyle
5691 * @window: a #GdkWindow
5692 * @state_type: a state
5693 * @area: (allow-none): clip rectangle, or %NULL if the
5694 * output should not be clipped
5695 * @widget: (allow-none): the widget
5696 * @detail: (allow-none): a style detail
5697 * @x: the x position to draw the expander at
5698 * @y: the y position to draw the expander at
5699 * @expander_style: the style to draw the expander in; determines
5700 * whether the expander is collapsed, expanded, or in an
5701 * intermediate state.
5703 * Draws an expander as used in #GtkTreeView. @x and @y specify the
5704 * center the expander. The size of the expander is determined by the
5705 * "expander-size" style property of @widget. (If widget is not
5706 * specified or doesn't have an "expander-size" property, an
5707 * unspecified default size will be used, since the caller doesn't
5708 * have sufficient information to position the expander, this is
5709 * likely not useful.) The expander is expander_size pixels tall
5710 * in the collapsed position and expander_size pixels wide in the
5711 * expanded position.
5714 gtk_paint_expander (GtkStyle *style,
5716 GtkStateType state_type,
5717 const GdkRectangle *area,
5719 const gchar *detail,
5722 GtkExpanderStyle expander_style)
5724 g_return_if_fail (GTK_IS_STYLE (style));
5725 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
5726 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5728 GTK_STYLE_GET_CLASS (style)->draw_expander (style, window, state_type,
5729 (GdkRectangle *) area, widget, detail,
5730 x, y, expander_style);
5735 * @style: a #GtkStyle
5736 * @window: a #GdkWindow
5737 * @state_type: a state
5738 * @use_text: whether to use the text or foreground
5739 * graphics context of @style
5740 * @area: (allow-none): clip rectangle, or %NULL if the
5741 * output should not be clipped
5742 * @widget: (allow-none): the widget
5743 * @detail: (allow-none): a style detail
5746 * @layout: the layout to draw
5748 * Draws a layout on @window using the given parameters.
5751 gtk_paint_layout (GtkStyle *style,
5753 GtkStateType state_type,
5755 const GdkRectangle *area,
5757 const gchar *detail,
5760 PangoLayout *layout)
5762 g_return_if_fail (GTK_IS_STYLE (style));
5763 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
5764 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5766 GTK_STYLE_GET_CLASS (style)->draw_layout (style, window, state_type, use_text,
5767 (GdkRectangle *) area, widget, detail,
5772 * gtk_paint_resize_grip:
5773 * @style: a #GtkStyle
5774 * @window: a #GdkWindow
5775 * @state_type: a state
5776 * @area: (allow-none): clip rectangle, or %NULL if the
5777 * output should not be clipped
5778 * @widget: (allow-none): the widget
5779 * @detail: (allow-none): a style detail
5780 * @edge: the edge in which to draw the resize grip
5781 * @x: the x origin of the rectangle in which to draw the resize grip
5782 * @y: the y origin of the rectangle in which to draw the resize grip
5783 * @width: the width of the rectangle in which to draw the resize grip
5784 * @height: the height of the rectangle in which to draw the resize grip
5786 * Draws a resize grip in the given rectangle on @window using the given
5790 gtk_paint_resize_grip (GtkStyle *style,
5792 GtkStateType state_type,
5793 const GdkRectangle *area,
5795 const gchar *detail,
5803 g_return_if_fail (GTK_IS_STYLE (style));
5804 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
5805 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5807 GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, window, state_type,
5808 (GdkRectangle *) area, widget, detail,
5809 edge, x, y, width, height);
5813 * gtk_paint_spinner:
5814 * @style: a #GtkStyle
5815 * @window: a #GdkWindow
5816 * @state_type: a state
5817 * @area: (allow-none): clip rectangle, or %NULL if the
5818 * output should not be clipped
5819 * @widget: (allow-none): the widget (may be %NULL)
5820 * @detail: (allow-none): a style detail (may be %NULL)
5821 * @step: the nth step, a value between 0 and #GtkSpinner:num-steps
5822 * @x: the x origin of the rectangle in which to draw the spinner
5823 * @y: the y origin of the rectangle in which to draw the spinner
5824 * @width: the width of the rectangle in which to draw the spinner
5825 * @height: the height of the rectangle in which to draw the spinner
5827 * Draws a spinner on @window using the given parameters.
5832 gtk_paint_spinner (GtkStyle *style,
5834 GtkStateType state_type,
5835 const GdkRectangle *area,
5837 const gchar *detail,
5844 g_return_if_fail (GTK_IS_STYLE (style));
5845 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_spinner != NULL);
5846 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5848 GTK_STYLE_GET_CLASS (style)->draw_spinner (style, window, state_type,
5849 (GdkRectangle *)area, widget, detail,
5850 step, x, y, width, height);
5856 * Allocates a new #GtkBorder structure and initializes its elements to zero.
5858 * Returns: a new empty #GtkBorder. The newly allocated #GtkBorder should be
5859 * freed with gtk_border_free()
5864 gtk_border_new (void)
5866 return g_slice_new0 (GtkBorder);
5871 * @border_: a #GtkBorder.
5872 * @returns: a copy of @border_.
5874 * Copies a #GtkBorder structure.
5877 gtk_border_copy (const GtkBorder *border)
5879 g_return_val_if_fail (border != NULL, NULL);
5881 return g_slice_dup (GtkBorder, border);
5886 * @border_: a #GtkBorder.
5888 * Frees a #GtkBorder structure.
5891 gtk_border_free (GtkBorder *border)
5893 g_slice_free (GtkBorder, border);
5896 G_DEFINE_BOXED_TYPE (GtkBorder, gtk_border,
5900 typedef struct _CursorInfo CursorInfo;
5910 style_unrealize_cursors (GtkStyle *style)
5914 cursor_info = g_object_get_data (G_OBJECT (style), "gtk-style-cursor-info");
5917 g_free (cursor_info);
5918 g_object_set_data (G_OBJECT (style), I_("gtk-style-cursor-info"), NULL);
5922 static const GdkColor *
5923 get_insertion_cursor_color (GtkWidget *widget,
5924 gboolean is_primary)
5926 CursorInfo *cursor_info;
5928 GdkColor *cursor_color;
5930 style = gtk_widget_get_style (widget);
5932 cursor_info = g_object_get_data (G_OBJECT (style), "gtk-style-cursor-info");
5935 cursor_info = g_new0 (CursorInfo, 1);
5936 g_object_set_data (G_OBJECT (style), I_("gtk-style-cursor-info"), cursor_info);
5937 cursor_info->for_type = G_TYPE_INVALID;
5940 /* We have to keep track of the type because gtk_widget_style_get()
5941 * can return different results when called on the same property and
5942 * same style but for different widgets. :-(. That is,
5943 * GtkEntry::cursor-color = "red" in a style will modify the cursor
5944 * color for entries but not for text view.
5946 if (cursor_info->for_type != G_OBJECT_TYPE (widget))
5948 cursor_info->for_type = G_OBJECT_TYPE (widget);
5950 /* Cursors in text widgets are drawn only in NORMAL state,
5951 * so we can use text[GTK_STATE_NORMAL] as text color here */
5952 gtk_widget_style_get (widget, "cursor-color", &cursor_color, NULL);
5955 cursor_info->primary = *cursor_color;
5956 gdk_color_free (cursor_color);
5960 cursor_info->primary = style->text[GTK_STATE_NORMAL];
5963 gtk_widget_style_get (widget, "secondary-cursor-color", &cursor_color, NULL);
5966 cursor_info->secondary = *cursor_color;
5967 gdk_color_free (cursor_color);
5971 /* text_aa is the average of text and base colors,
5972 * in usual black-on-white case it's grey. */
5973 cursor_info->secondary = style->text_aa[GTK_STATE_NORMAL];
5978 return &cursor_info->primary;
5980 return &cursor_info->secondary;
5984 _gtk_widget_get_cursor_color (GtkWidget *widget,
5987 GdkColor *style_color;
5989 g_return_if_fail (GTK_IS_WIDGET (widget));
5990 g_return_if_fail (color != NULL);
5992 gtk_widget_style_get (widget, "cursor-color", &style_color, NULL);
5996 *color = *style_color;
5997 gdk_color_free (style_color);
6000 *color = gtk_widget_get_style (widget)->text[GTK_STATE_NORMAL];
6004 draw_insertion_cursor (GtkWidget *widget,
6006 const GdkRectangle *location,
6007 GtkTextDirection direction,
6008 gboolean draw_arrow)
6013 gfloat cursor_aspect_ratio;
6016 /* When changing the shape or size of the cursor here,
6017 * propagate the changes to gtktextview.c:text_window_invalidate_cursors().
6020 gtk_widget_style_get (widget, "cursor-aspect-ratio", &cursor_aspect_ratio, NULL);
6022 stem_width = location->height * cursor_aspect_ratio + 1;
6023 arrow_width = stem_width + 1;
6025 /* put (stem_width % 2) on the proper side of the cursor */
6026 if (direction == GTK_TEXT_DIR_LTR)
6027 offset = stem_width / 2;
6029 offset = stem_width - stem_width / 2;
6031 cairo_rectangle (cr,
6032 location->x - offset, location->y,
6033 stem_width, location->height);
6038 if (direction == GTK_TEXT_DIR_RTL)
6040 x = location->x - offset - 1;
6041 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
6043 cairo_move_to (cr, x, y + 1);
6044 cairo_line_to (cr, x - arrow_width, y + arrow_width);
6045 cairo_line_to (cr, x, y + 2 * arrow_width);
6048 else if (direction == GTK_TEXT_DIR_LTR)
6050 x = location->x + stem_width - offset;
6051 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
6053 cairo_move_to (cr, x, y + 1);
6054 cairo_line_to (cr, x + arrow_width, y + arrow_width);
6055 cairo_line_to (cr, x, y + 2 * arrow_width);
6062 * gtk_draw_insertion_cursor:
6063 * @widget: a #GtkWidget
6064 * @drawable: a #GdkDrawable
6065 * @area: (allow-none): rectangle to which the output is clipped, or %NULL if the
6066 * output should not be clipped
6067 * @location: location where to draw the cursor (@location->width is ignored)
6068 * @is_primary: if the cursor should be the primary cursor color.
6069 * @direction: whether the cursor is left-to-right or
6070 * right-to-left. Should never be #GTK_TEXT_DIR_NONE
6071 * @draw_arrow: %TRUE to draw a directional arrow on the
6072 * cursor. Should be %FALSE unless the cursor is split.
6074 * Draws a text caret on @drawable at @location. This is not a style function
6075 * but merely a convenience function for drawing the standard cursor shape.
6080 gtk_draw_insertion_cursor (GtkWidget *widget,
6081 GdkDrawable *drawable,
6082 const GdkRectangle *area,
6083 const GdkRectangle *location,
6084 gboolean is_primary,
6085 GtkTextDirection direction,
6086 gboolean draw_arrow)
6090 g_return_if_fail (GTK_IS_WIDGET (widget));
6091 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
6092 g_return_if_fail (location != NULL);
6093 g_return_if_fail (direction != GTK_TEXT_DIR_NONE);
6095 cr = gdk_cairo_create (drawable);
6098 gdk_cairo_rectangle (cr, area);
6102 gdk_cairo_set_source_color (cr, get_insertion_cursor_color (widget, is_primary));
6103 draw_insertion_cursor (widget, cr, location, direction, draw_arrow);