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"
34 #include "gtkspinbutton.h"
36 #include "gtkwidget.h"
37 #include "gtkthemes.h"
38 #include "gtkiconfactory.h"
39 #include "gtksettings.h" /* _gtk_settings_parse_convert() */
41 #include "gtkspinner.h"
46 * @Short_description: An object that hold style information for widgets
49 * A #GtkStyle object encapsulates the information that provides the look and
50 * feel for a widget. Each #GtkWidget has an associated #GTkStyle object that
51 * is used when rendering that widget. Also, a #GtkStyle holds information for
52 * the five possible widget states though not every widget supports all five
53 * states; see #GtkStateType.
55 * Usually the #GtkStyle for a widget is the same as the default style that is
56 * set by GTK+ and modified the theme engine.
58 * Usually applications should not need to use or modify the #GtkStyle of their
63 #define LIGHTNESS_MULT 1.3
64 #define DARKNESS_MULT 0.7
66 /* --- typedefs & structures --- */
73 #define GTK_STYLE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_STYLE, GtkStylePrivate))
75 typedef struct _GtkStylePrivate GtkStylePrivate;
77 struct _GtkStylePrivate {
81 /* --- prototypes --- */
82 static void gtk_style_finalize (GObject *object);
83 static void gtk_style_realize (GtkStyle *style,
84 GdkColormap *colormap);
85 static void gtk_style_real_realize (GtkStyle *style);
86 static void gtk_style_real_unrealize (GtkStyle *style);
87 static void gtk_style_real_copy (GtkStyle *style,
89 static void gtk_style_real_set_background (GtkStyle *style,
91 GtkStateType state_type);
92 static GtkStyle *gtk_style_real_clone (GtkStyle *style);
93 static void gtk_style_real_init_from_rc (GtkStyle *style,
94 GtkRcStyle *rc_style);
95 static GdkPixbuf *gtk_default_render_icon (GtkStyle *style,
96 const GtkIconSource *source,
97 GtkTextDirection direction,
101 const gchar *detail);
102 static void gtk_default_draw_hline (GtkStyle *style,
104 GtkStateType state_type,
111 static void gtk_default_draw_vline (GtkStyle *style,
113 GtkStateType state_type,
120 static void gtk_default_draw_shadow (GtkStyle *style,
122 GtkStateType state_type,
123 GtkShadowType shadow_type,
131 static void gtk_default_draw_arrow (GtkStyle *style,
133 GtkStateType state_type,
134 GtkShadowType shadow_type,
138 GtkArrowType arrow_type,
144 static void gtk_default_draw_diamond (GtkStyle *style,
146 GtkStateType state_type,
147 GtkShadowType shadow_type,
155 static void gtk_default_draw_box (GtkStyle *style,
157 GtkStateType state_type,
158 GtkShadowType shadow_type,
166 static void gtk_default_draw_flat_box (GtkStyle *style,
168 GtkStateType state_type,
169 GtkShadowType shadow_type,
177 static void gtk_default_draw_check (GtkStyle *style,
179 GtkStateType state_type,
180 GtkShadowType shadow_type,
188 static void gtk_default_draw_option (GtkStyle *style,
190 GtkStateType state_type,
191 GtkShadowType shadow_type,
199 static void gtk_default_draw_tab (GtkStyle *style,
201 GtkStateType state_type,
202 GtkShadowType shadow_type,
210 static void gtk_default_draw_shadow_gap (GtkStyle *style,
212 GtkStateType state_type,
213 GtkShadowType shadow_type,
221 GtkPositionType gap_side,
224 static void gtk_default_draw_box_gap (GtkStyle *style,
226 GtkStateType state_type,
227 GtkShadowType shadow_type,
235 GtkPositionType gap_side,
238 static void gtk_default_draw_extension (GtkStyle *style,
240 GtkStateType state_type,
241 GtkShadowType shadow_type,
249 GtkPositionType gap_side);
250 static void gtk_default_draw_focus (GtkStyle *style,
252 GtkStateType state_type,
260 static void gtk_default_draw_slider (GtkStyle *style,
262 GtkStateType state_type,
263 GtkShadowType shadow_type,
271 GtkOrientation orientation);
272 static void gtk_default_draw_handle (GtkStyle *style,
274 GtkStateType state_type,
275 GtkShadowType shadow_type,
283 GtkOrientation orientation);
284 static void gtk_default_draw_expander (GtkStyle *style,
286 GtkStateType state_type,
292 GtkExpanderStyle expander_style);
293 static void gtk_default_draw_layout (GtkStyle *style,
295 GtkStateType state_type,
302 PangoLayout *layout);
303 static void gtk_default_draw_resize_grip (GtkStyle *style,
305 GtkStateType state_type,
314 static void gtk_default_draw_spinner (GtkStyle *style,
316 GtkStateType state_type,
326 static void rgb_to_hls (gdouble *r,
329 static void hls_to_rgb (gdouble *h,
333 static void style_unrealize_cursors (GtkStyle *style);
336 * Data for default check and radio buttons
339 static const GtkRequisition default_option_indicator_size = { 7, 13 };
340 static const GtkBorder default_option_indicator_spacing = { 7, 5, 2, 2 };
342 #define GTK_GRAY 0xdcdc, 0xdada, 0xd5d5
343 #define GTK_DARK_GRAY 0xc4c4, 0xc2c2, 0xbdbd
344 #define GTK_LIGHT_GRAY 0xeeee, 0xebeb, 0xe7e7
345 #define GTK_WHITE 0xffff, 0xffff, 0xffff
346 #define GTK_BLUE 0x4b4b, 0x6969, 0x8383
347 #define GTK_VERY_DARK_GRAY 0x9c9c, 0x9a9a, 0x9494
348 #define GTK_BLACK 0x0000, 0x0000, 0x0000
349 #define GTK_WEAK_GRAY 0x7530, 0x7530, 0x7530
351 /* --- variables --- */
352 static const GdkColor gtk_default_normal_fg = { 0, GTK_BLACK };
353 static const GdkColor gtk_default_active_fg = { 0, GTK_BLACK };
354 static const GdkColor gtk_default_prelight_fg = { 0, GTK_BLACK };
355 static const GdkColor gtk_default_selected_fg = { 0, GTK_WHITE };
356 static const GdkColor gtk_default_insensitive_fg = { 0, GTK_WEAK_GRAY };
358 static const GdkColor gtk_default_normal_bg = { 0, GTK_GRAY };
359 static const GdkColor gtk_default_active_bg = { 0, GTK_DARK_GRAY };
360 static const GdkColor gtk_default_prelight_bg = { 0, GTK_LIGHT_GRAY };
361 static const GdkColor gtk_default_selected_bg = { 0, GTK_BLUE };
362 static const GdkColor gtk_default_insensitive_bg = { 0, GTK_GRAY };
363 static const GdkColor gtk_default_selected_base = { 0, GTK_BLUE };
364 static const GdkColor gtk_default_active_base = { 0, GTK_VERY_DARK_GRAY };
366 /* --- signals --- */
367 static guint realize_signal = 0;
368 static guint unrealize_signal = 0;
370 G_DEFINE_TYPE (GtkStyle, gtk_style, G_TYPE_OBJECT)
372 /* --- functions --- */
375 * _gtk_style_init_for_settings:
376 * @style: a #GtkStyle
377 * @settings: a #GtkSettings
379 * Initializes the font description in @style according to the default
380 * font name of @settings. This is called for gtk_style_new() with
381 * the settings for the default screen (if any); if we are creating
382 * a style for a particular screen, we then call it again in a
383 * location where we know the correct settings.
384 * The reason for this is that gtk_rc_style_create_style() doesn't
385 * take the screen for an argument.
388 _gtk_style_init_for_settings (GtkStyle *style,
389 GtkSettings *settings)
391 const gchar *font_name = _gtk_rc_context_get_default_font_name (settings);
393 if (style->font_desc)
394 pango_font_description_free (style->font_desc);
396 style->font_desc = pango_font_description_from_string (font_name);
398 if (!pango_font_description_get_family (style->font_desc))
400 g_warning ("Default font does not have a family set");
401 pango_font_description_set_family (style->font_desc, "Sans");
403 if (pango_font_description_get_size (style->font_desc) <= 0)
405 g_warning ("Default font does not have a positive size");
406 pango_font_description_set_size (style->font_desc, 10 * PANGO_SCALE);
411 gtk_style_init (GtkStyle *style)
415 GtkSettings *settings = gtk_settings_get_default ();
418 _gtk_style_init_for_settings (style, settings);
420 style->font_desc = pango_font_description_from_string ("Sans 10");
422 style->attach_count = 0;
423 style->colormap = NULL;
426 style->black.red = 0;
427 style->black.green = 0;
428 style->black.blue = 0;
430 style->white.red = 65535;
431 style->white.green = 65535;
432 style->white.blue = 65535;
434 style->fg[GTK_STATE_NORMAL] = gtk_default_normal_fg;
435 style->fg[GTK_STATE_ACTIVE] = gtk_default_active_fg;
436 style->fg[GTK_STATE_PRELIGHT] = gtk_default_prelight_fg;
437 style->fg[GTK_STATE_SELECTED] = gtk_default_selected_fg;
438 style->fg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
440 style->bg[GTK_STATE_NORMAL] = gtk_default_normal_bg;
441 style->bg[GTK_STATE_ACTIVE] = gtk_default_active_bg;
442 style->bg[GTK_STATE_PRELIGHT] = gtk_default_prelight_bg;
443 style->bg[GTK_STATE_SELECTED] = gtk_default_selected_bg;
444 style->bg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_bg;
446 for (i = 0; i < 4; i++)
448 style->text[i] = style->fg[i];
449 style->base[i] = style->white;
452 style->base[GTK_STATE_SELECTED] = gtk_default_selected_base;
453 style->text[GTK_STATE_SELECTED] = style->white;
454 style->base[GTK_STATE_ACTIVE] = gtk_default_active_base;
455 style->text[GTK_STATE_ACTIVE] = style->white;
456 style->base[GTK_STATE_INSENSITIVE] = gtk_default_prelight_bg;
457 style->text[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
459 for (i = 0; i < 5; i++)
460 style->bg_pixmap[i] = NULL;
462 style->rc_style = NULL;
464 style->xthickness = 2;
465 style->ythickness = 2;
467 style->property_cache = NULL;
471 gtk_style_class_init (GtkStyleClass *klass)
473 GObjectClass *object_class = G_OBJECT_CLASS (klass);
475 object_class->finalize = gtk_style_finalize;
477 klass->clone = gtk_style_real_clone;
478 klass->copy = gtk_style_real_copy;
479 klass->init_from_rc = gtk_style_real_init_from_rc;
480 klass->realize = gtk_style_real_realize;
481 klass->unrealize = gtk_style_real_unrealize;
482 klass->set_background = gtk_style_real_set_background;
483 klass->render_icon = gtk_default_render_icon;
485 klass->draw_hline = gtk_default_draw_hline;
486 klass->draw_vline = gtk_default_draw_vline;
487 klass->draw_shadow = gtk_default_draw_shadow;
488 klass->draw_arrow = gtk_default_draw_arrow;
489 klass->draw_diamond = gtk_default_draw_diamond;
490 klass->draw_box = gtk_default_draw_box;
491 klass->draw_flat_box = gtk_default_draw_flat_box;
492 klass->draw_check = gtk_default_draw_check;
493 klass->draw_option = gtk_default_draw_option;
494 klass->draw_tab = gtk_default_draw_tab;
495 klass->draw_shadow_gap = gtk_default_draw_shadow_gap;
496 klass->draw_box_gap = gtk_default_draw_box_gap;
497 klass->draw_extension = gtk_default_draw_extension;
498 klass->draw_focus = gtk_default_draw_focus;
499 klass->draw_slider = gtk_default_draw_slider;
500 klass->draw_handle = gtk_default_draw_handle;
501 klass->draw_expander = gtk_default_draw_expander;
502 klass->draw_layout = gtk_default_draw_layout;
503 klass->draw_resize_grip = gtk_default_draw_resize_grip;
504 klass->draw_spinner = gtk_default_draw_spinner;
506 g_type_class_add_private (object_class, sizeof (GtkStylePrivate));
510 * @style: the object which received the signal
512 * Emitted when the style has been initialized for a particular
513 * colormap and depth. Connecting to this signal is probably seldom
514 * useful since most of the time applications and widgets only
515 * deal with styles that have been already realized.
519 realize_signal = g_signal_new (I_("realize"),
520 G_TYPE_FROM_CLASS (object_class),
522 G_STRUCT_OFFSET (GtkStyleClass, realize),
524 _gtk_marshal_VOID__VOID,
527 * GtkStyle::unrealize:
528 * @style: the object which received the signal
530 * Emitted when the aspects of the style specific to a particular colormap
531 * and depth are being cleaned up. A connection to this signal can be useful
532 * if a widget wants to cache objects as object data on #GtkStyle.
533 * This signal provides a convenient place to free such cached objects.
537 unrealize_signal = g_signal_new (I_("unrealize"),
538 G_TYPE_FROM_CLASS (object_class),
540 G_STRUCT_OFFSET (GtkStyleClass, unrealize),
542 _gtk_marshal_VOID__VOID,
547 clear_property_cache (GtkStyle *style)
549 if (style->property_cache)
553 for (i = 0; i < style->property_cache->len; i++)
555 PropertyValue *node = &g_array_index (style->property_cache, PropertyValue, i);
557 g_param_spec_unref (node->pspec);
558 g_value_unset (&node->value);
560 g_array_free (style->property_cache, TRUE);
561 style->property_cache = NULL;
566 gtk_style_finalize (GObject *object)
568 GtkStyle *style = GTK_STYLE (object);
569 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
571 g_return_if_fail (style->attach_count == 0);
573 clear_property_cache (style);
575 /* All the styles in the list have the same
576 * style->styles pointer. If we delete the
577 * *first* style from the list, we need to update
578 * the style->styles pointers from all the styles.
579 * Otherwise we simply remove the node from
584 if (style->styles->data != style)
585 style->styles = g_slist_remove (style->styles, style);
588 GSList *tmp_list = style->styles->next;
592 GTK_STYLE (tmp_list->data)->styles = style->styles->next;
593 tmp_list = tmp_list->next;
595 g_slist_free_1 (style->styles);
599 g_slist_foreach (style->icon_factories, (GFunc) g_object_unref, NULL);
600 g_slist_free (style->icon_factories);
602 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_unref, NULL);
603 g_slist_free (priv->color_hashes);
605 pango_font_description_free (style->font_desc);
607 if (style->private_font_desc)
608 pango_font_description_free (style->private_font_desc);
611 g_object_unref (style->rc_style);
613 G_OBJECT_CLASS (gtk_style_parent_class)->finalize (object);
619 * @style: a #GtkStyle
621 * Creates a copy of the passed in #GtkStyle object.
623 * Returns: a copy of @style
626 gtk_style_copy (GtkStyle *style)
630 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
632 new_style = GTK_STYLE_GET_CLASS (style)->clone (style);
633 GTK_STYLE_GET_CLASS (style)->copy (new_style, style);
639 gtk_style_duplicate (GtkStyle *style)
643 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
645 new_style = gtk_style_copy (style);
647 /* All the styles in the list have the same
648 * style->styles pointer. When we insert a new
649 * style, we append it to the list to avoid having
650 * to update the existing ones.
652 style->styles = g_slist_append (style->styles, new_style);
653 new_style->styles = style->styles;
660 * @returns: a new #GtkStyle.
662 * Creates a new #GtkStyle.
669 style = g_object_new (GTK_TYPE_STYLE, NULL);
676 * @style: a #GtkStyle.
677 * @window: a #GdkWindow.
679 * Attaches a style to a window; this process allocates the
680 * colors and creates the GC's for the style - it specializes
681 * it to a particular visual and colormap. The process may
682 * involve the creation of a new style if the style has already
683 * been attached to a window with a different style and colormap.
685 * Since this function may return a new object, you have to use it
686 * in the following way:
687 * <literal>style = gtk_style_attach (style, window)</literal>
689 * Returns: Either @style, or a newly-created #GtkStyle.
690 * If the style is newly created, the style parameter
691 * will be unref'ed, and the new style will have
692 * a reference count belonging to the caller.
695 gtk_style_attach (GtkStyle *style,
699 GtkStyle *new_style = NULL;
700 GdkColormap *colormap;
702 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
703 g_return_val_if_fail (window != NULL, NULL);
705 colormap = gdk_drawable_get_colormap (window);
708 style->styles = g_slist_append (NULL, style);
710 styles = style->styles;
713 new_style = styles->data;
715 if (new_style->colormap == colormap)
719 styles = styles->next;
724 styles = style->styles;
728 new_style = styles->data;
730 if (new_style->attach_count == 0)
732 gtk_style_realize (new_style, colormap);
737 styles = styles->next;
743 new_style = gtk_style_duplicate (style);
744 gtk_style_realize (new_style, colormap);
747 /* A style gets a refcount from being attached */
748 if (new_style->attach_count == 0)
749 g_object_ref (new_style);
751 /* Another refcount belongs to the parent */
752 if (style != new_style)
754 g_object_unref (style);
755 g_object_ref (new_style);
758 new_style->attach_count++;
765 * @style: a #GtkStyle
767 * Detaches a style from a window. If the style is not attached
768 * to any windows anymore, it is unrealized. See gtk_style_attach().
772 gtk_style_detach (GtkStyle *style)
774 g_return_if_fail (GTK_IS_STYLE (style));
775 g_return_if_fail (style->attach_count > 0);
777 style->attach_count -= 1;
778 if (style->attach_count == 0)
780 g_signal_emit (style, unrealize_signal, 0);
782 g_object_unref (style->colormap);
783 style->colormap = NULL;
785 if (style->private_font_desc)
787 pango_font_description_free (style->private_font_desc);
788 style->private_font_desc = NULL;
791 g_object_unref (style);
796 gtk_style_realize (GtkStyle *style,
797 GdkColormap *colormap)
799 style->colormap = g_object_ref (colormap);
800 style->depth = gdk_colormap_get_visual (colormap)->depth;
802 g_signal_emit (style, realize_signal, 0);
806 * gtk_style_lookup_icon_set:
807 * @style: a #GtkStyle
808 * @stock_id: an icon name
810 * Looks up @stock_id in the icon factories associated with @style
811 * and the default icon factory, returning an icon set if found,
814 * Return value: icon set of @stock_id
817 gtk_style_lookup_icon_set (GtkStyle *style,
818 const char *stock_id)
822 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
823 g_return_val_if_fail (stock_id != NULL, NULL);
825 iter = style->icon_factories;
828 GtkIconSet *icon_set = gtk_icon_factory_lookup (GTK_ICON_FACTORY (iter->data),
833 iter = g_slist_next (iter);
836 return gtk_icon_factory_lookup_default (stock_id);
840 * gtk_style_lookup_color:
841 * @style: a #GtkStyle
842 * @color_name: the name of the logical color to look up
843 * @color: the #GdkColor to fill in
845 * Looks up @color_name in the style's logical color mappings,
846 * filling in @color and returning %TRUE if found, otherwise
847 * returning %FALSE. Do not cache the found mapping, because
848 * it depends on the #GtkStyle and might change when a theme
851 * Return value: %TRUE if the mapping was found.
856 gtk_style_lookup_color (GtkStyle *style,
857 const char *color_name,
860 GtkStylePrivate *priv;
863 g_return_val_if_fail (GTK_IS_STYLE (style), FALSE);
864 g_return_val_if_fail (color_name != NULL, FALSE);
865 g_return_val_if_fail (color != NULL, FALSE);
867 priv = GTK_STYLE_GET_PRIVATE (style);
869 for (iter = priv->color_hashes; iter != NULL; iter = iter->next)
871 GHashTable *hash = iter->data;
872 GdkColor *mapping = g_hash_table_lookup (hash, color_name);
876 color->red = mapping->red;
877 color->green = mapping->green;
878 color->blue = mapping->blue;
887 * gtk_style_set_background:
888 * @style: a #GtkStyle
889 * @window: a #GdkWindow
890 * @state_type: a state
892 * Sets the background of @window to the background color or pixmap
893 * specified by @style for the given state.
896 gtk_style_set_background (GtkStyle *style,
898 GtkStateType state_type)
900 g_return_if_fail (GTK_IS_STYLE (style));
901 g_return_if_fail (window != NULL);
903 GTK_STYLE_GET_CLASS (style)->set_background (style, window, state_type);
906 /* Default functions */
908 gtk_style_real_clone (GtkStyle *style)
910 return g_object_new (G_OBJECT_TYPE (style), NULL);
914 gtk_style_real_copy (GtkStyle *style,
917 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
918 GtkStylePrivate *src_priv = GTK_STYLE_GET_PRIVATE (src);
921 for (i = 0; i < 5; i++)
923 style->fg[i] = src->fg[i];
924 style->bg[i] = src->bg[i];
925 style->text[i] = src->text[i];
926 style->base[i] = src->base[i];
928 if (style->bg_pixmap[i])
929 g_object_unref (style->bg_pixmap[i]),
930 style->bg_pixmap[i] = src->bg_pixmap[i];
931 if (style->bg_pixmap[i])
932 g_object_ref (style->bg_pixmap[i]);
935 if (style->font_desc)
936 pango_font_description_free (style->font_desc);
938 style->font_desc = pango_font_description_copy (src->font_desc);
940 style->font_desc = NULL;
942 style->xthickness = src->xthickness;
943 style->ythickness = src->ythickness;
946 g_object_unref (style->rc_style);
947 style->rc_style = src->rc_style;
949 g_object_ref (src->rc_style);
951 g_slist_foreach (style->icon_factories, (GFunc) g_object_unref, NULL);
952 g_slist_free (style->icon_factories);
953 style->icon_factories = g_slist_copy (src->icon_factories);
954 g_slist_foreach (style->icon_factories, (GFunc) g_object_ref, NULL);
956 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_unref, NULL);
957 g_slist_free (priv->color_hashes);
958 priv->color_hashes = g_slist_copy (src_priv->color_hashes);
959 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_ref, NULL);
961 /* don't copy, just clear cache */
962 clear_property_cache (style);
966 gtk_style_real_init_from_rc (GtkStyle *style,
967 GtkRcStyle *rc_style)
969 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
972 /* cache _should_ be still empty */
973 clear_property_cache (style);
975 if (rc_style->font_desc)
976 pango_font_description_merge (style->font_desc, rc_style->font_desc, TRUE);
978 for (i = 0; i < 5; i++)
980 if (rc_style->color_flags[i] & GTK_RC_FG)
981 style->fg[i] = rc_style->fg[i];
982 if (rc_style->color_flags[i] & GTK_RC_BG)
983 style->bg[i] = rc_style->bg[i];
984 if (rc_style->color_flags[i] & GTK_RC_TEXT)
985 style->text[i] = rc_style->text[i];
986 if (rc_style->color_flags[i] & GTK_RC_BASE)
987 style->base[i] = rc_style->base[i];
990 if (rc_style->xthickness >= 0)
991 style->xthickness = rc_style->xthickness;
992 if (rc_style->ythickness >= 0)
993 style->ythickness = rc_style->ythickness;
995 style->icon_factories = g_slist_copy (rc_style->icon_factories);
996 g_slist_foreach (style->icon_factories, (GFunc) g_object_ref, NULL);
998 priv->color_hashes = g_slist_copy (_gtk_rc_style_get_color_hashes (rc_style));
999 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_ref, NULL);
1003 style_property_values_cmp (gconstpointer bsearch_node1,
1004 gconstpointer bsearch_node2)
1006 const PropertyValue *val1 = bsearch_node1;
1007 const PropertyValue *val2 = bsearch_node2;
1009 if (val1->widget_type == val2->widget_type)
1010 return val1->pspec < val2->pspec ? -1 : val1->pspec == val2->pspec ? 0 : 1;
1012 return val1->widget_type < val2->widget_type ? -1 : 1;
1016 * gtk_style_get_style_property:
1017 * @style: a #GtkStyle
1018 * @widget_type: the #GType of a descendant of #GtkWidget
1019 * @property_name: the name of the style property to get
1020 * @value: a #GValue where the value of the property being
1021 * queried will be stored
1023 * Queries the value of a style property corresponding to a
1024 * widget class is in the given style.
1029 gtk_style_get_style_property (GtkStyle *style,
1031 const gchar *property_name,
1034 GtkWidgetClass *klass;
1036 GtkRcPropertyParser parser;
1037 const GValue *peek_value;
1039 klass = g_type_class_ref (widget_type);
1040 pspec = gtk_widget_class_find_style_property (klass, property_name);
1041 g_type_class_unref (klass);
1045 g_warning ("%s: widget class `%s' has no property named `%s'",
1047 g_type_name (widget_type),
1052 parser = g_param_spec_get_qdata (pspec,
1053 g_quark_from_static_string ("gtk-rc-property-parser"));
1055 peek_value = _gtk_style_peek_property_value (style, widget_type, pspec, parser);
1057 if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec))
1058 g_value_copy (peek_value, value);
1059 else if (g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
1060 g_value_transform (peek_value, value);
1062 g_warning ("can't retrieve style property `%s' of type `%s' as value of type `%s'",
1064 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1065 G_VALUE_TYPE_NAME (value));
1069 * gtk_style_get_valist:
1070 * @style: a #GtkStyle
1071 * @widget_type: the #GType of a descendant of #GtkWidget
1072 * @first_property_name: the name of the first style property to get
1073 * @var_args: a <type>va_list</type> of pairs of property names and
1074 * locations to return the property values, starting with the
1075 * location for @first_property_name.
1077 * Non-vararg variant of gtk_style_get().
1078 * Used primarily by language bindings.
1083 gtk_style_get_valist (GtkStyle *style,
1085 const gchar *first_property_name,
1088 const char *property_name;
1089 GtkWidgetClass *klass;
1091 g_return_if_fail (GTK_IS_STYLE (style));
1093 klass = g_type_class_ref (widget_type);
1095 property_name = first_property_name;
1096 while (property_name)
1099 GtkRcPropertyParser parser;
1100 const GValue *peek_value;
1103 pspec = gtk_widget_class_find_style_property (klass, property_name);
1107 g_warning ("%s: widget class `%s' has no property named `%s'",
1109 g_type_name (widget_type),
1114 parser = g_param_spec_get_qdata (pspec,
1115 g_quark_from_static_string ("gtk-rc-property-parser"));
1117 peek_value = _gtk_style_peek_property_value (style, widget_type, pspec, parser);
1118 G_VALUE_LCOPY (peek_value, var_args, 0, &error);
1121 g_warning ("%s: %s", G_STRLOC, error);
1126 property_name = va_arg (var_args, gchar*);
1129 g_type_class_unref (klass);
1134 * @style: a #GtkStyle
1135 * @widget_type: the #GType of a descendant of #GtkWidget
1136 * @first_property_name: the name of the first style property to get
1137 * @Varargs: pairs of property names and locations to
1138 * return the property values, starting with the location for
1139 * @first_property_name, terminated by %NULL.
1141 * Gets the values of a multiple style properties for @widget_type
1147 gtk_style_get (GtkStyle *style,
1149 const gchar *first_property_name,
1154 va_start (var_args, first_property_name);
1155 gtk_style_get_valist (style, widget_type, first_property_name, var_args);
1160 _gtk_style_peek_property_value (GtkStyle *style,
1163 GtkRcPropertyParser parser)
1165 PropertyValue *pcache, key = { 0, NULL, { 0, } };
1166 const GtkRcProperty *rcprop = NULL;
1169 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1170 g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL);
1171 g_return_val_if_fail (g_type_is_a (pspec->owner_type, GTK_TYPE_WIDGET), NULL);
1172 g_return_val_if_fail (g_type_is_a (widget_type, pspec->owner_type), NULL);
1174 key.widget_type = widget_type;
1177 /* need value cache array */
1178 if (!style->property_cache)
1179 style->property_cache = g_array_new (FALSE, FALSE, sizeof (PropertyValue));
1182 pcache = bsearch (&key,
1183 style->property_cache->data, style->property_cache->len,
1184 sizeof (PropertyValue), style_property_values_cmp);
1186 return &pcache->value;
1190 while (i < style->property_cache->len &&
1191 style_property_values_cmp (&key, &g_array_index (style->property_cache, PropertyValue, i)) >= 0)
1194 g_array_insert_val (style->property_cache, i, key);
1195 pcache = &g_array_index (style->property_cache, PropertyValue, i);
1197 /* cache miss, initialize value type, then set contents */
1198 g_param_spec_ref (pcache->pspec);
1199 g_value_init (&pcache->value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1201 /* value provided by rc style? */
1202 if (style->rc_style)
1204 GQuark prop_quark = g_quark_from_string (pspec->name);
1208 rcprop = _gtk_rc_style_lookup_rc_property (style->rc_style,
1209 g_type_qname (widget_type),
1213 widget_type = g_type_parent (widget_type);
1215 while (g_type_is_a (widget_type, pspec->owner_type));
1218 /* when supplied by rc style, we need to convert */
1219 if (rcprop && !_gtk_settings_parse_convert (parser, &rcprop->value,
1220 pspec, &pcache->value))
1222 gchar *contents = g_strdup_value_contents (&rcprop->value);
1224 g_message ("%s: failed to retrieve property `%s::%s' of type `%s' from rc file value \"%s\" of type `%s'",
1225 rcprop->origin ? rcprop->origin : "(for origin information, set GTK_DEBUG)",
1226 g_type_name (pspec->owner_type), pspec->name,
1227 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1229 G_VALUE_TYPE_NAME (&rcprop->value));
1231 rcprop = NULL; /* needs default */
1234 /* not supplied by rc style (or conversion failed), revert to default */
1236 g_param_value_set_default (pspec, &pcache->value);
1238 return &pcache->value;
1242 load_bg_image (GdkColormap *colormap,
1244 const gchar *filename)
1246 if (strcmp (filename, "<parent>") == 0)
1247 return (GdkPixmap*) GDK_PARENT_RELATIVE;
1250 return gdk_pixmap_colormap_create_from_xpm (NULL, colormap, NULL,
1257 gtk_style_real_realize (GtkStyle *style)
1261 for (i = 0; i < 5; i++)
1263 _gtk_style_shade (&style->bg[i], &style->light[i], LIGHTNESS_MULT);
1264 _gtk_style_shade (&style->bg[i], &style->dark[i], DARKNESS_MULT);
1266 style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
1267 style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
1268 style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
1270 style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
1271 style->text_aa[i].green = (style->text[i].green + style->base[i].green) / 2;
1272 style->text_aa[i].blue = (style->text[i].blue + style->base[i].blue) / 2;
1275 style->black.red = 0x0000;
1276 style->black.green = 0x0000;
1277 style->black.blue = 0x0000;
1278 gdk_colormap_alloc_color (style->colormap, &style->black, FALSE, TRUE);
1280 style->white.red = 0xffff;
1281 style->white.green = 0xffff;
1282 style->white.blue = 0xffff;
1283 gdk_colormap_alloc_color (style->colormap, &style->white, FALSE, TRUE);
1285 for (i = 0; i < 5; i++)
1287 if (style->rc_style && style->rc_style->bg_pixmap_name[i])
1288 style->bg_pixmap[i] = load_bg_image (style->colormap,
1290 style->rc_style->bg_pixmap_name[i]);
1292 if (!gdk_colormap_alloc_color (style->colormap, &style->fg[i], FALSE, TRUE))
1293 g_warning ("unable to allocate color: ( %d %d %d )",
1294 style->fg[i].red, style->fg[i].green, style->fg[i].blue);
1295 if (!gdk_colormap_alloc_color (style->colormap, &style->bg[i], FALSE, TRUE))
1296 g_warning ("unable to allocate color: ( %d %d %d )",
1297 style->bg[i].red, style->bg[i].green, style->bg[i].blue);
1298 if (!gdk_colormap_alloc_color (style->colormap, &style->light[i], FALSE, TRUE))
1299 g_warning ("unable to allocate color: ( %d %d %d )",
1300 style->light[i].red, style->light[i].green, style->light[i].blue);
1301 if (!gdk_colormap_alloc_color (style->colormap, &style->dark[i], FALSE, TRUE))
1302 g_warning ("unable to allocate color: ( %d %d %d )",
1303 style->dark[i].red, style->dark[i].green, style->dark[i].blue);
1304 if (!gdk_colormap_alloc_color (style->colormap, &style->mid[i], FALSE, TRUE))
1305 g_warning ("unable to allocate color: ( %d %d %d )",
1306 style->mid[i].red, style->mid[i].green, style->mid[i].blue);
1307 if (!gdk_colormap_alloc_color (style->colormap, &style->text[i], FALSE, TRUE))
1308 g_warning ("unable to allocate color: ( %d %d %d )",
1309 style->text[i].red, style->text[i].green, style->text[i].blue);
1310 if (!gdk_colormap_alloc_color (style->colormap, &style->base[i], FALSE, TRUE))
1311 g_warning ("unable to allocate color: ( %d %d %d )",
1312 style->base[i].red, style->base[i].green, style->base[i].blue);
1313 if (!gdk_colormap_alloc_color (style->colormap, &style->text_aa[i], FALSE, TRUE))
1314 g_warning ("unable to allocate color: ( %d %d %d )",
1315 style->text_aa[i].red, style->text_aa[i].green, style->text_aa[i].blue);
1320 gtk_style_real_unrealize (GtkStyle *style)
1324 for (i = 0; i < 5; i++)
1326 if (style->bg_pixmap[i] && style->bg_pixmap[i] != (GdkPixmap*) GDK_PARENT_RELATIVE)
1328 g_object_unref (style->bg_pixmap[i]);
1329 style->bg_pixmap[i] = NULL;
1334 gdk_colormap_free_colors (style->colormap, style->fg, 5);
1335 gdk_colormap_free_colors (style->colormap, style->bg, 5);
1336 gdk_colormap_free_colors (style->colormap, style->light, 5);
1337 gdk_colormap_free_colors (style->colormap, style->dark, 5);
1338 gdk_colormap_free_colors (style->colormap, style->mid, 5);
1339 gdk_colormap_free_colors (style->colormap, style->text, 5);
1340 gdk_colormap_free_colors (style->colormap, style->base, 5);
1341 gdk_colormap_free_colors (style->colormap, style->text_aa, 5);
1343 style_unrealize_cursors (style);
1347 gtk_style_real_set_background (GtkStyle *style,
1349 GtkStateType state_type)
1352 gint parent_relative;
1354 if (style->bg_pixmap[state_type])
1356 if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
1359 parent_relative = TRUE;
1363 pixmap = style->bg_pixmap[state_type];
1364 parent_relative = FALSE;
1367 gdk_window_set_back_pixmap (window, pixmap, parent_relative);
1370 gdk_window_set_background (window, &style->bg[state_type]);
1374 * gtk_style_render_icon:
1375 * @style: a #GtkStyle
1376 * @source: the #GtkIconSource specifying the icon to render
1377 * @direction: a text direction
1379 * @size: (type int) the size to render the icon at. A size of
1380 * (GtkIconSize)-1 means render at the size of the source and
1382 * @widget: (allow-none): the widget
1383 * @detail: (allow-none): a style detail
1384 * @returns: a newly-created #GdkPixbuf containing the rendered icon
1386 * Renders the icon specified by @source at the given @size
1387 * according to the given parameters and returns the result in a
1391 gtk_style_render_icon (GtkStyle *style,
1392 const GtkIconSource *source,
1393 GtkTextDirection direction,
1397 const gchar *detail)
1401 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1402 g_return_val_if_fail (GTK_STYLE_GET_CLASS (style)->render_icon != NULL, NULL);
1404 pixbuf = GTK_STYLE_GET_CLASS (style)->render_icon (style, source, direction, state,
1405 size, widget, detail);
1407 g_return_val_if_fail (pixbuf != NULL, NULL);
1412 /* Default functions */
1415 * gtk_style_apply_default_background:
1420 * @area: (allow-none):
1427 gtk_style_apply_default_background (GtkStyle *style,
1430 GtkStateType state_type,
1431 const GdkRectangle *area,
1437 GdkRectangle new_rect, old_rect;
1443 old_rect.width = width;
1444 old_rect.height = height;
1446 if (!gdk_rectangle_intersect (area, &old_rect, &new_rect))
1453 new_rect.width = width;
1454 new_rect.height = height;
1457 if (!style->bg_pixmap[state_type] ||
1458 GDK_IS_PIXMAP (window) ||
1459 (!set_bg && style->bg_pixmap[state_type] != (GdkPixmap*) GDK_PARENT_RELATIVE))
1461 cairo_t *cr = gdk_cairo_create (window);
1463 if (style->bg_pixmap[state_type])
1465 gdk_cairo_set_source_pixmap (cr, style->bg_pixmap[state_type], 0, 0);
1466 cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
1469 gdk_cairo_set_source_color (cr, &style->bg[state_type]);
1471 gdk_cairo_rectangle (cr, &new_rect);
1480 if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
1481 gdk_window_set_back_pixmap (window, NULL, TRUE);
1483 gdk_window_set_back_pixmap (window, style->bg_pixmap[state_type], FALSE);
1486 gdk_window_clear_area (window,
1487 new_rect.x, new_rect.y,
1488 new_rect.width, new_rect.height);
1493 scale_or_ref (GdkPixbuf *src,
1497 if (width == gdk_pixbuf_get_width (src) &&
1498 height == gdk_pixbuf_get_height (src))
1500 return g_object_ref (src);
1504 return gdk_pixbuf_scale_simple (src,
1506 GDK_INTERP_BILINEAR);
1511 lookup_icon_size (GtkStyle *style,
1518 GtkSettings *settings;
1520 if (widget && gtk_widget_has_screen (widget))
1522 screen = gtk_widget_get_screen (widget);
1523 settings = gtk_settings_get_for_screen (screen);
1525 else if (style && style->colormap)
1527 screen = gdk_colormap_get_screen (style->colormap);
1528 settings = gtk_settings_get_for_screen (screen);
1532 settings = gtk_settings_get_default ();
1533 GTK_NOTE (MULTIHEAD,
1534 g_warning ("Using the default screen for gtk_default_render_icon()"));
1537 return gtk_icon_size_lookup_for_settings (settings, size, width, height);
1541 gtk_default_render_icon (GtkStyle *style,
1542 const GtkIconSource *source,
1543 GtkTextDirection direction,
1547 const gchar *detail)
1553 GdkPixbuf *base_pixbuf;
1555 /* Oddly, style can be NULL in this function, because
1556 * GtkIconSet can be used without a style and if so
1557 * it uses this function.
1560 base_pixbuf = gtk_icon_source_get_pixbuf (source);
1562 g_return_val_if_fail (base_pixbuf != NULL, NULL);
1564 if (size != (GtkIconSize) -1 && !lookup_icon_size(style, widget, size, &width, &height))
1566 g_warning (G_STRLOC ": invalid icon size '%d'", size);
1570 /* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
1573 if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source))
1574 scaled = scale_or_ref (base_pixbuf, width, height);
1576 scaled = g_object_ref (base_pixbuf);
1578 /* If the state was wildcarded, then generate a state. */
1579 if (gtk_icon_source_get_state_wildcarded (source))
1581 if (state == GTK_STATE_INSENSITIVE)
1583 stated = gdk_pixbuf_copy (scaled);
1585 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
1588 g_object_unref (scaled);
1590 else if (state == GTK_STATE_PRELIGHT)
1592 stated = gdk_pixbuf_copy (scaled);
1594 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
1597 g_object_unref (scaled);
1611 sanitize_size (GdkWindow *window,
1615 if ((*width == -1) && (*height == -1))
1616 gdk_drawable_get_size (window, width, height);
1617 else if (*width == -1)
1618 gdk_drawable_get_size (window, width, NULL);
1619 else if (*height == -1)
1620 gdk_drawable_get_size (window, NULL, height);
1624 _cairo_draw_line (cairo_t *cr,
1633 gdk_cairo_set_source_color (cr, color);
1634 cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
1636 cairo_move_to (cr, x1 + 0.5, y1 + 0.5);
1637 cairo_line_to (cr, x2 + 0.5, y2 + 0.5);
1644 _cairo_draw_rectangle (cairo_t *cr,
1652 gdk_cairo_set_source_color (cr, color);
1656 cairo_rectangle (cr, x, y, width, height);
1661 cairo_rectangle (cr, x + 0.5, y + 0.5, width, height);
1667 _cairo_draw_point (cairo_t *cr,
1672 gdk_cairo_set_source_color (cr, color);
1673 cairo_rectangle (cr, x, y, 1, 1);
1678 gtk_default_draw_hline (GtkStyle *style,
1680 GtkStateType state_type,
1683 const gchar *detail,
1689 gint thickness_light;
1690 gint thickness_dark;
1693 thickness_light = style->ythickness / 2;
1694 thickness_dark = style->ythickness - thickness_light;
1696 cr = gdk_cairo_create (window);
1697 cairo_set_line_width (cr, 1.0);
1701 gdk_cairo_rectangle (cr, area);
1705 if (detail && !strcmp (detail, "label"))
1707 if (state_type == GTK_STATE_INSENSITIVE)
1708 _cairo_draw_line (cr, &style->white, x1 + 1, y + 1, x2 + 1, y + 1);
1709 _cairo_draw_line (cr, &style->fg[state_type], x1, y, x2, y);
1713 for (i = 0; i < thickness_dark; i++)
1715 _cairo_draw_line (cr, &style->dark[state_type], x1, y + i, x2 - i - 1, y + i);
1716 _cairo_draw_line (cr, &style->light[state_type], x2 - i, y + i, x2, y + i);
1719 y += thickness_dark;
1720 for (i = 0; i < thickness_light; i++)
1722 _cairo_draw_line (cr, &style->dark[state_type], x1, y + i, x1 + thickness_light - i - 1, y + i);
1723 _cairo_draw_line (cr, &style->light[state_type], x1 + thickness_light - i, y + i, x2, y + i);
1732 gtk_default_draw_vline (GtkStyle *style,
1734 GtkStateType state_type,
1737 const gchar *detail,
1743 gint thickness_light;
1744 gint thickness_dark;
1747 thickness_light = style->xthickness / 2;
1748 thickness_dark = style->xthickness - thickness_light;
1750 cr = gdk_cairo_create (window);
1751 cairo_set_line_width (cr, 1.0);
1755 gdk_cairo_rectangle (cr, area);
1759 for (i = 0; i < thickness_dark; i++)
1761 _cairo_draw_line (cr, &style->dark[state_type],
1762 x + i, y1, x + i, y2 - i - 1);
1763 _cairo_draw_line (cr, &style->light[state_type],
1764 x + i, y2 - i, x + i, y2);
1767 x += thickness_dark;
1768 for (i = 0; i < thickness_light; i++)
1770 _cairo_draw_line (cr, &style->dark[state_type],
1771 x + i, y1, x + i, y1 + thickness_light - i - 1);
1772 _cairo_draw_line (cr, &style->light[state_type],
1773 x + i, y1 + thickness_light - i, x + i, y2);
1780 draw_thin_shadow (GtkStyle *style,
1789 GdkColor *gc1, *gc2;
1791 gc1 = &style->light[state];
1792 gc2 = &style->dark[state];
1794 _cairo_draw_line (cr, gc1,
1795 x, y + height - 1, x + width - 1, y + height - 1);
1796 _cairo_draw_line (cr, gc1,
1797 x + width - 1, y, x + width - 1, y + height - 1);
1799 _cairo_draw_line (cr, gc2,
1800 x, y, x + width - 2, y);
1801 _cairo_draw_line (cr, gc2,
1802 x, y, x, y + height - 2);
1806 draw_spinbutton_shadow (GtkStyle *style,
1809 GtkTextDirection direction,
1817 if (direction == GTK_TEXT_DIR_LTR)
1819 _cairo_draw_line (cr, &style->dark[state],
1820 x, y, x + width - 1, y);
1821 _cairo_draw_line (cr, &style->black,
1822 x, y + 1, x + width - 2, y + 1);
1823 _cairo_draw_line (cr, &style->black,
1824 x + width - 2, y + 2, x + width - 2, y + height - 3);
1825 _cairo_draw_line (cr, &style->light[state],
1826 x + width - 1, y + 1, x + width - 1, y + height - 2);
1827 _cairo_draw_line (cr, &style->light[state],
1828 x, y + height - 1, x + width - 1, y + height - 1);
1829 _cairo_draw_line (cr, &style->bg[state],
1830 x, y + height - 2, x + width - 2, y + height - 2);
1831 _cairo_draw_line (cr, &style->black,
1832 x, y + 2, x, y + height - 3);
1836 _cairo_draw_line (cr, &style->dark[state],
1837 x, y, x + width - 1, y);
1838 _cairo_draw_line (cr, &style->dark[state],
1839 x, y + 1, x, y + height - 1);
1840 _cairo_draw_line (cr, &style->black,
1841 x + 1, y + 1, x + width - 1, y + 1);
1842 _cairo_draw_line (cr, &style->black,
1843 x + 1, y + 2, x + 1, y + height - 2);
1844 _cairo_draw_line (cr, &style->black,
1845 x + width - 1, y + 2, x + width - 1, y + height - 3);
1846 _cairo_draw_line (cr, &style->light[state],
1847 x + 1, y + height - 1, x + width - 1, y + height - 1);
1848 _cairo_draw_line (cr, &style->bg[state],
1849 x + 2, y + height - 2, x + width - 1, y + height - 2);
1854 draw_menu_shadow (GtkStyle *style,
1863 if (style->ythickness > 0)
1865 if (style->ythickness > 1)
1867 _cairo_draw_line (cr, &style->dark[state],
1868 x + 1, y + height - 2,
1869 x + width - 2, y + height - 2);
1870 _cairo_draw_line (cr, &style->black,
1871 x, y + height - 1, x + width - 1, y + height - 1);
1875 _cairo_draw_line (cr, &style->dark[state],
1876 x + 1, y + height - 1, x + width - 1, y + height - 1);
1880 if (style->xthickness > 0)
1882 if (style->xthickness > 1)
1884 _cairo_draw_line (cr, &style->dark[state],
1885 x + width - 2, y + 1,
1886 x + width - 2, y + height - 2);
1888 _cairo_draw_line (cr, &style->black,
1889 x + width - 1, y, x + width - 1, y + height - 1);
1893 _cairo_draw_line (cr, &style->dark[state],
1894 x + width - 1, y + 1, x + width - 1, y + height - 1);
1898 /* Light around top and left */
1900 if (style->ythickness > 0)
1901 _cairo_draw_line (cr, &style->black,
1902 x, y, x + width - 2, y);
1903 if (style->xthickness > 0)
1904 _cairo_draw_line (cr, &style->black,
1905 x, y, x, y + height - 2);
1907 if (style->ythickness > 1)
1908 _cairo_draw_line (cr, &style->light[state],
1909 x + 1, y + 1, x + width - 3, y + 1);
1910 if (style->xthickness > 1)
1911 _cairo_draw_line (cr, &style->light[state],
1912 x + 1, y + 1, x + 1, y + height - 3);
1915 static GtkTextDirection
1916 get_direction (GtkWidget *widget)
1918 GtkTextDirection dir;
1921 dir = gtk_widget_get_direction (widget);
1923 dir = GTK_TEXT_DIR_LTR;
1930 gtk_default_draw_shadow (GtkStyle *style,
1932 GtkStateType state_type,
1933 GtkShadowType shadow_type,
1936 const gchar *detail,
1943 GdkColor *gc1 = NULL;
1944 GdkColor *gc2 = NULL;
1945 gint thickness_light;
1946 gint thickness_dark;
1949 sanitize_size (window, &width, &height);
1951 cr = gdk_cairo_create (window);
1952 cairo_set_line_width (cr, 1.0);
1956 gdk_cairo_rectangle (cr, area);
1960 if (shadow_type == GTK_SHADOW_IN)
1962 if (detail && strcmp (detail, "buttondefault") == 0)
1964 _cairo_draw_rectangle (cr, &style->black, FALSE,
1965 x, y, width - 1, height - 1);
1970 if (detail && strcmp (detail, "trough") == 0)
1972 draw_thin_shadow (style, cr, state_type, area,
1973 x, y, width, height);
1978 if (GTK_IS_SPIN_BUTTON (widget) &&
1979 detail && strcmp (detail, "spinbutton") == 0)
1981 draw_spinbutton_shadow (style, cr, state_type,
1982 get_direction (widget), area, x, y, width, height);
1988 if (shadow_type == GTK_SHADOW_OUT && detail && strcmp (detail, "menu") == 0)
1990 draw_menu_shadow (style, cr, state_type, area, x, y, width, height);
1995 switch (shadow_type)
1997 case GTK_SHADOW_NONE:
2000 case GTK_SHADOW_ETCHED_IN:
2001 gc1 = &style->light[state_type];
2002 gc2 = &style->dark[state_type];
2004 case GTK_SHADOW_OUT:
2005 case GTK_SHADOW_ETCHED_OUT:
2006 gc1 = &style->dark[state_type];
2007 gc2 = &style->light[state_type];
2011 switch (shadow_type)
2013 case GTK_SHADOW_NONE:
2017 /* Light around right and bottom edge */
2019 if (style->ythickness > 0)
2020 _cairo_draw_line (cr, gc1,
2021 x, y + height - 1, x + width - 1, y + height - 1);
2022 if (style->xthickness > 0)
2023 _cairo_draw_line (cr, gc1,
2024 x + width - 1, y, x + width - 1, y + height - 1);
2026 if (style->ythickness > 1)
2027 _cairo_draw_line (cr, &style->bg[state_type],
2028 x + 1, y + height - 2, x + width - 2, y + height - 2);
2029 if (style->xthickness > 1)
2030 _cairo_draw_line (cr, &style->bg[state_type],
2031 x + width - 2, y + 1, x + width - 2, y + height - 2);
2033 /* Dark around left and top */
2035 if (style->ythickness > 1)
2036 _cairo_draw_line (cr, &style->black,
2037 x + 1, y + 1, x + width - 2, y + 1);
2038 if (style->xthickness > 1)
2039 _cairo_draw_line (cr, &style->black,
2040 x + 1, y + 1, x + 1, y + height - 2);
2042 if (style->ythickness > 0)
2043 _cairo_draw_line (cr, gc2,
2044 x, y, x + width - 1, y);
2045 if (style->xthickness > 0)
2046 _cairo_draw_line (cr, gc2,
2047 x, y, x, y + height - 1);
2050 case GTK_SHADOW_OUT:
2051 /* Dark around right and bottom edge */
2053 if (style->ythickness > 0)
2055 if (style->ythickness > 1)
2057 _cairo_draw_line (cr, gc1,
2058 x + 1, y + height - 2, x + width - 2, y + height - 2);
2059 _cairo_draw_line (cr, &style->black,
2060 x, y + height - 1, x + width - 1, y + height - 1);
2064 _cairo_draw_line (cr, gc1,
2065 x + 1, y + height - 1, x + width - 1, y + height - 1);
2069 if (style->xthickness > 0)
2071 if (style->xthickness > 1)
2073 _cairo_draw_line (cr, gc1,
2074 x + width - 2, y + 1, x + width - 2, y + height - 2);
2076 _cairo_draw_line (cr, &style->black,
2077 x + width - 1, y, x + width - 1, y + height - 1);
2081 _cairo_draw_line (cr, gc1,
2082 x + width - 1, y + 1, x + width - 1, y + height - 1);
2086 /* Light around top and left */
2088 if (style->ythickness > 0)
2089 _cairo_draw_line (cr, gc2,
2090 x, y, x + width - 2, y);
2091 if (style->xthickness > 0)
2092 _cairo_draw_line (cr, gc2,
2093 x, y, x, y + height - 2);
2095 if (style->ythickness > 1)
2096 _cairo_draw_line (cr, &style->bg[state_type],
2097 x + 1, y + 1, x + width - 3, y + 1);
2098 if (style->xthickness > 1)
2099 _cairo_draw_line (cr, &style->bg[state_type],
2100 x + 1, y + 1, x + 1, y + height - 3);
2103 case GTK_SHADOW_ETCHED_IN:
2104 case GTK_SHADOW_ETCHED_OUT:
2105 if (style->xthickness > 0)
2107 if (style->xthickness > 1)
2109 thickness_light = 1;
2112 for (i = 0; i < thickness_dark; i++)
2114 _cairo_draw_line (cr, gc1,
2118 y + height - i - 1);
2119 _cairo_draw_line (cr, gc2,
2123 y + height - i - 2);
2126 for (i = 0; i < thickness_light; i++)
2128 _cairo_draw_line (cr, gc1,
2129 x + thickness_dark + i,
2130 y + thickness_dark + i,
2131 x + thickness_dark + i,
2132 y + height - thickness_dark - i - 1);
2133 _cairo_draw_line (cr, gc2,
2134 x + width - thickness_light - i - 1,
2135 y + thickness_dark + i,
2136 x + width - thickness_light - i - 1,
2137 y + height - thickness_light - 1);
2142 _cairo_draw_line (cr,
2143 &style->dark[state_type],
2144 x, y, x, y + height);
2145 _cairo_draw_line (cr,
2146 &style->dark[state_type],
2147 x + width, y, x + width, y + height);
2151 if (style->ythickness > 0)
2153 if (style->ythickness > 1)
2155 thickness_light = 1;
2158 for (i = 0; i < thickness_dark; i++)
2160 _cairo_draw_line (cr, gc1,
2164 y + height - i - 1);
2166 _cairo_draw_line (cr, gc2,
2173 for (i = 0; i < thickness_light; i++)
2175 _cairo_draw_line (cr, gc1,
2176 x + thickness_dark + i,
2177 y + thickness_dark + i,
2178 x + width - thickness_dark - i - 2,
2179 y + thickness_dark + i);
2181 _cairo_draw_line (cr, gc2,
2182 x + thickness_dark + i,
2183 y + height - thickness_light - i - 1,
2184 x + width - thickness_light - 1,
2185 y + height - thickness_light - i - 1);
2190 _cairo_draw_line (cr,
2191 &style->dark[state_type],
2192 x, y, x + width, y);
2193 _cairo_draw_line (cr,
2194 &style->dark[state_type],
2195 x, y + height, x + width, y + height);
2202 if (shadow_type == GTK_SHADOW_IN &&
2203 GTK_IS_SPIN_BUTTON (widget) &&
2204 detail && strcmp (detail, "entry") == 0)
2206 if (get_direction (widget) == GTK_TEXT_DIR_LTR)
2208 _cairo_draw_line (cr,
2209 &style->base[state_type],
2210 x + width - 1, y + 2,
2211 x + width - 1, y + height - 3);
2212 _cairo_draw_line (cr,
2213 &style->base[state_type],
2214 x + width - 2, y + 2,
2215 x + width - 2, y + height - 3);
2217 _cairo_draw_point (cr,
2219 x + width - 1, y + 1);
2220 _cairo_draw_point (cr,
2221 &style->bg[state_type],
2222 x + width - 1, y + height - 2);
2226 _cairo_draw_line (cr,
2227 &style->base[state_type],
2230 _cairo_draw_line (cr,
2231 &style->base[state_type],
2233 x + 1, y + height - 3);
2235 _cairo_draw_point (cr,
2239 _cairo_draw_line (cr,
2240 &style->bg[state_type],
2242 x + 1, y + height - 2);
2243 _cairo_draw_point (cr,
2244 &style->light[state_type],
2254 draw_arrow (cairo_t *cr,
2256 GtkArrowType arrow_type,
2262 gdk_cairo_set_source_color (cr, color);
2265 if (arrow_type == GTK_ARROW_DOWN)
2267 cairo_move_to (cr, x, y);
2268 cairo_line_to (cr, x + width, y);
2269 cairo_line_to (cr, x + width / 2., y + height);
2271 else if (arrow_type == GTK_ARROW_UP)
2273 cairo_move_to (cr, x, y + height);
2274 cairo_line_to (cr, x + width / 2., y);
2275 cairo_line_to (cr, x + width, y + height);
2277 else if (arrow_type == GTK_ARROW_LEFT)
2279 cairo_move_to (cr, x + width, y);
2280 cairo_line_to (cr, x + width, y + height);
2281 cairo_line_to (cr, x, y + height / 2.);
2283 else if (arrow_type == GTK_ARROW_RIGHT)
2285 cairo_move_to (cr, x, y);
2286 cairo_line_to (cr, x + width, y + height / 2.);
2287 cairo_line_to (cr, x, y + height);
2290 cairo_close_path (cr);
2297 calculate_arrow_geometry (GtkArrowType arrow_type,
2309 case GTK_ARROW_DOWN:
2319 if (arrow_type == GTK_ARROW_DOWN)
2321 if (*height % 2 == 1 || h % 2 == 0)
2326 if (*height % 2 == 0 || h % 2 == 0)
2331 case GTK_ARROW_RIGHT:
2332 case GTK_ARROW_LEFT:
2342 if (arrow_type == GTK_ARROW_RIGHT)
2344 if (*width % 2 == 1 || w % 2 == 0)
2349 if (*width % 2 == 0 || w % 2 == 0)
2355 /* should not be reached */
2359 *x += (*width - w) / 2;
2360 *y += (*height - h) / 2;
2366 gtk_default_draw_arrow (GtkStyle *style,
2369 GtkShadowType shadow,
2372 const gchar *detail,
2373 GtkArrowType arrow_type,
2382 sanitize_size (window, &width, &height);
2384 calculate_arrow_geometry (arrow_type, &x, &y, &width, &height);
2386 if (detail && strcmp (detail, "menu_scroll_arrow_up") == 0)
2389 cr = gdk_cairo_create (window);
2393 gdk_cairo_rectangle (cr, area);
2397 if (state == GTK_STATE_INSENSITIVE)
2398 draw_arrow (cr, &style->white, arrow_type,
2399 x + 1, y + 1, width, height);
2400 draw_arrow (cr, &style->fg[state], arrow_type,
2401 x, y, width, height);
2407 gtk_default_draw_diamond (GtkStyle *style,
2409 GtkStateType state_type,
2410 GtkShadowType shadow_type,
2413 const gchar *detail,
2421 GdkColor *outer_nw = NULL;
2422 GdkColor *outer_ne = NULL;
2423 GdkColor *outer_sw = NULL;
2424 GdkColor *outer_se = NULL;
2425 GdkColor *middle_nw = NULL;
2426 GdkColor *middle_ne = NULL;
2427 GdkColor *middle_sw = NULL;
2428 GdkColor *middle_se = NULL;
2429 GdkColor *inner_nw = NULL;
2430 GdkColor *inner_ne = NULL;
2431 GdkColor *inner_sw = NULL;
2432 GdkColor *inner_se = NULL;
2435 sanitize_size (window, &width, &height);
2437 half_width = width / 2;
2438 half_height = height / 2;
2440 switch (shadow_type)
2443 inner_sw = inner_se = &style->bg[state_type];
2444 middle_sw = middle_se = &style->light[state_type];
2445 outer_sw = outer_se = &style->light[state_type];
2446 inner_nw = inner_ne = &style->black;
2447 middle_nw = middle_ne = &style->dark[state_type];
2448 outer_nw = outer_ne = &style->dark[state_type];
2451 case GTK_SHADOW_OUT:
2452 inner_sw = inner_se = &style->dark[state_type];
2453 middle_sw = middle_se = &style->dark[state_type];
2454 outer_sw = outer_se = &style->black;
2455 inner_nw = inner_ne = &style->bg[state_type];
2456 middle_nw = middle_ne = &style->light[state_type];
2457 outer_nw = outer_ne = &style->light[state_type];
2460 case GTK_SHADOW_ETCHED_IN:
2461 inner_sw = inner_se = &style->bg[state_type];
2462 middle_sw = middle_se = &style->dark[state_type];
2463 outer_sw = outer_se = &style->light[state_type];
2464 inner_nw = inner_ne = &style->bg[state_type];
2465 middle_nw = middle_ne = &style->light[state_type];
2466 outer_nw = outer_ne = &style->dark[state_type];
2469 case GTK_SHADOW_ETCHED_OUT:
2470 inner_sw = inner_se = &style->bg[state_type];
2471 middle_sw = middle_se = &style->light[state_type];
2472 outer_sw = outer_se = &style->dark[state_type];
2473 inner_nw = inner_ne = &style->bg[state_type];
2474 middle_nw = middle_ne = &style->dark[state_type];
2475 outer_nw = outer_ne = &style->light[state_type];
2483 cr = gdk_cairo_create (window);
2486 gdk_cairo_rectangle (cr, area);
2492 _cairo_draw_line (cr, inner_sw,
2493 x + 2, y + half_height,
2494 x + half_width, y + height - 2);
2495 _cairo_draw_line (cr, inner_se,
2496 x + half_width, y + height - 2,
2497 x + width - 2, y + half_height);
2498 _cairo_draw_line (cr, middle_sw,
2499 x + 1, y + half_height,
2500 x + half_width, y + height - 1);
2501 _cairo_draw_line (cr, middle_se,
2502 x + half_width, y + height - 1,
2503 x + width - 1, y + half_height);
2504 _cairo_draw_line (cr, outer_sw,
2506 x + half_width, y + height);
2507 _cairo_draw_line (cr, outer_se,
2508 x + half_width, y + height,
2509 x + width, y + half_height);
2511 _cairo_draw_line (cr, inner_nw,
2512 x + 2, y + half_height,
2513 x + half_width, y + 2);
2514 _cairo_draw_line (cr, inner_ne,
2515 x + half_width, y + 2,
2516 x + width - 2, y + half_height);
2517 _cairo_draw_line (cr, middle_nw,
2518 x + 1, y + half_height,
2519 x + half_width, y + 1);
2520 _cairo_draw_line (cr, middle_ne,
2521 x + half_width, y + 1,
2522 x + width - 1, y + half_height);
2523 _cairo_draw_line (cr, outer_nw,
2526 _cairo_draw_line (cr, outer_ne,
2528 x + width, y + half_height);
2535 option_menu_get_props (GtkWidget *widget,
2536 GtkRequisition *indicator_size,
2537 GtkBorder *indicator_spacing)
2539 GtkRequisition *tmp_size = NULL;
2540 GtkBorder *tmp_spacing = NULL;
2544 *indicator_size = *tmp_size;
2545 gtk_requisition_free (tmp_size);
2548 *indicator_size = default_option_indicator_size;
2552 *indicator_spacing = *tmp_spacing;
2553 gtk_border_free (tmp_spacing);
2556 *indicator_spacing = default_option_indicator_spacing;
2560 gtk_default_draw_box (GtkStyle *style,
2562 GtkStateType state_type,
2563 GtkShadowType shadow_type,
2566 const gchar *detail,
2572 gboolean is_spinbutton_box = FALSE;
2574 sanitize_size (window, &width, &height);
2576 if (GTK_IS_SPIN_BUTTON (widget) && detail)
2578 if (strcmp (detail, "spinbutton_up") == 0)
2584 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
2589 is_spinbutton_box = TRUE;
2591 else if (strcmp (detail, "spinbutton_down") == 0)
2596 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
2601 is_spinbutton_box = TRUE;
2605 if (!style->bg_pixmap[state_type] ||
2606 GDK_IS_PIXMAP (window))
2609 GdkColor *gc = &style->bg[state_type];
2611 cr = gdk_cairo_create (window);
2613 if (state_type == GTK_STATE_SELECTED && detail && strcmp (detail, "paned") == 0)
2615 if (widget && !gtk_widget_has_focus (widget))
2616 gc = &style->base[GTK_STATE_ACTIVE];
2621 gdk_cairo_rectangle (cr, area);
2625 _cairo_draw_rectangle (cr, gc, TRUE,
2626 x, y, width, height);
2630 gtk_style_apply_default_background (style, window,
2631 widget && gtk_widget_get_has_window (widget),
2632 state_type, area, x, y, width, height);
2634 if (is_spinbutton_box)
2640 cr = gdk_cairo_create (window);
2642 lower = &style->dark[state_type];
2643 if (shadow_type == GTK_SHADOW_OUT)
2644 upper = &style->light[state_type];
2646 upper = &style->dark[state_type];
2650 gdk_cairo_rectangle (cr, area);
2654 _cairo_draw_line (cr, upper, x, y, x + width - 1, y);
2655 _cairo_draw_line (cr, lower, x, y + height - 1, x + width - 1, y + height - 1);
2661 gtk_paint_shadow (style, window, state_type, shadow_type, area, widget, detail,
2662 x, y, width, height);
2664 if (detail && strcmp (detail, "optionmenu") == 0)
2666 GtkRequisition indicator_size;
2667 GtkBorder indicator_spacing;
2670 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
2672 sanitize_size (window, &width, &height);
2674 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
2675 vline_x = x + indicator_size.width + indicator_spacing.left + indicator_spacing.right;
2677 vline_x = x + width - (indicator_size.width + indicator_spacing.left + indicator_spacing.right) - style->xthickness;
2679 gtk_paint_vline (style, window, state_type, area, widget,
2681 y + style->ythickness + 1,
2682 y + height - style->ythickness - 3,
2688 get_darkened (const GdkColor *color,
2691 GdkColor src = *color;
2692 GdkColor shaded = *color;
2694 while (darken_count)
2696 _gtk_style_shade (&src, &shaded, 0.93);
2701 return gdk_color_copy (&shaded);
2705 gtk_default_draw_flat_box (GtkStyle *style,
2707 GtkStateType state_type,
2708 GtkShadowType shadow_type,
2711 const gchar *detail,
2718 GdkColor *freeme = NULL;
2720 sanitize_size (window, &width, &height);
2724 if (state_type == GTK_STATE_SELECTED)
2726 if (!strcmp ("text", detail))
2727 gc1 = &style->bg[GTK_STATE_SELECTED];
2728 else if (!strcmp ("cell_even", detail) ||
2729 !strcmp ("cell_odd", detail) ||
2730 !strcmp ("cell_even_ruled", detail) ||
2731 !strcmp ("cell_even_ruled_sorted", detail))
2733 /* This has to be really broken; alex made me do it. -jrb */
2734 if (widget && gtk_widget_has_focus (widget))
2735 gc1 = &style->base[state_type];
2737 gc1 = &style->base[GTK_STATE_ACTIVE];
2739 else if (!strcmp ("cell_odd_ruled", detail) ||
2740 !strcmp ("cell_odd_ruled_sorted", detail))
2742 if (widget && gtk_widget_has_focus (widget))
2743 freeme = get_darkened (&style->base[state_type], 1);
2745 freeme = get_darkened (&style->base[GTK_STATE_ACTIVE], 1);
2750 gc1 = &style->bg[state_type];
2755 if (!strcmp ("viewportbin", detail))
2756 gc1 = &style->bg[GTK_STATE_NORMAL];
2757 else if (!strcmp ("entry_bg", detail))
2758 gc1 = &style->base[state_type];
2760 /* For trees: even rows are base color, odd rows are a shade of
2761 * the base color, the sort column is a shade of the original color
2765 else if (!strcmp ("cell_even", detail) ||
2766 !strcmp ("cell_odd", detail) ||
2767 !strcmp ("cell_even_ruled", detail))
2769 GdkColor *color = NULL;
2771 gtk_widget_style_get (widget,
2772 "even-row-color", &color,
2777 freeme = get_darkened (color, 0);
2780 gdk_color_free (color);
2783 gc1 = &style->base[state_type];
2785 else if (!strcmp ("cell_odd_ruled", detail))
2787 GdkColor *color = NULL;
2789 gtk_widget_style_get (widget,
2790 "odd-row-color", &color,
2795 freeme = get_darkened (color, 0);
2798 gdk_color_free (color);
2802 gtk_widget_style_get (widget,
2803 "even-row-color", &color,
2808 freeme = get_darkened (color, 1);
2809 gdk_color_free (color);
2812 freeme = get_darkened (&style->base[state_type], 1);
2816 else if (!strcmp ("cell_even_sorted", detail) ||
2817 !strcmp ("cell_odd_sorted", detail) ||
2818 !strcmp ("cell_even_ruled_sorted", detail))
2820 GdkColor *color = NULL;
2822 if (!strcmp ("cell_odd_sorted", detail))
2823 gtk_widget_style_get (widget,
2824 "odd-row-color", &color,
2827 gtk_widget_style_get (widget,
2828 "even-row-color", &color,
2833 freeme = get_darkened (color, 1);
2836 gdk_color_free (color);
2840 freeme = get_darkened (&style->base[state_type], 1);
2844 else if (!strcmp ("cell_odd_ruled_sorted", detail))
2846 GdkColor *color = NULL;
2848 gtk_widget_style_get (widget,
2849 "odd-row-color", &color,
2854 freeme = get_darkened (color, 1);
2857 gdk_color_free (color);
2861 gtk_widget_style_get (widget,
2862 "even-row-color", &color,
2867 freeme = get_darkened (color, 2);
2868 gdk_color_free (color);
2871 freeme = get_darkened (&style->base[state_type], 2);
2876 gc1 = &style->bg[state_type];
2880 gc1 = &style->bg[state_type];
2882 if (!style->bg_pixmap[state_type] || gc1 != &style->bg[state_type] ||
2883 GDK_IS_PIXMAP (window))
2887 cr = gdk_cairo_create (window);
2888 cairo_set_line_width (cr, 1.0);
2892 gdk_cairo_rectangle (cr, area);
2896 _cairo_draw_rectangle (cr, gc1, TRUE,
2897 x, y, width, height);
2899 if (detail && !strcmp ("tooltip", detail))
2900 _cairo_draw_rectangle (cr, &style->black, FALSE,
2901 x, y, width - 1, height - 1);
2906 gtk_style_apply_default_background (style, window,
2907 widget && gtk_widget_get_has_window (widget),
2908 state_type, area, x, y, width, height);
2912 gdk_color_free (freeme);
2916 gtk_default_draw_check (GtkStyle *style,
2918 GtkStateType state_type,
2919 GtkShadowType shadow_type,
2922 const gchar *detail,
2928 cairo_t *cr = gdk_cairo_create (window);
2929 enum { BUTTON, MENU, CELL } type = BUTTON;
2936 if (strcmp (detail, "cellcheck") == 0)
2938 else if (strcmp (detail, "check") == 0)
2944 gdk_cairo_rectangle (cr, area);
2948 exterior_size = MIN (width, height);
2949 if (exterior_size % 2 == 0) /* Ensure odd */
2952 pad = style->xthickness + MAX (1, (exterior_size - 2 * style->xthickness) / 9);
2953 interior_size = MAX (1, exterior_size - 2 * pad);
2955 if (interior_size < 7)
2958 pad = MAX (0, (exterior_size - interior_size) / 2);
2961 x -= (1 + exterior_size - width) / 2;
2962 y -= (1 + exterior_size - height) / 2;
2969 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
2971 gdk_cairo_set_source_color (cr, &style->text[state_type]);
2973 cairo_set_line_width (cr, 1.0);
2974 cairo_rectangle (cr, x + 0.5, y + 0.5, exterior_size - 1, exterior_size - 1);
2977 gdk_cairo_set_source_color (cr, &style->base[state_type]);
2978 cairo_rectangle (cr, x + 1, y + 1, exterior_size - 2, exterior_size - 2);
2990 gdk_cairo_set_source_color (cr, &style->text[state_type]);
2993 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
2997 if (shadow_type == GTK_SHADOW_IN)
2999 cairo_translate (cr,
3002 cairo_scale (cr, interior_size / 7., interior_size / 7.);
3004 cairo_move_to (cr, 7.0, 0.0);
3005 cairo_line_to (cr, 7.5, 1.0);
3006 cairo_curve_to (cr, 5.3, 2.0,
3009 cairo_curve_to (cr, 3.0, 5.7,
3012 cairo_line_to (cr, 0.2, 3.5);
3013 cairo_curve_to (cr, 1.1, 3.5,
3016 cairo_curve_to (cr, 1.0, 3.9,
3019 cairo_curve_to (cr, 3.5, 3.1,
3025 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
3027 int line_thickness = MAX (1, (3 + interior_size * 2) / 7);
3029 cairo_rectangle (cr,
3031 y + pad + (1 + interior_size - line_thickness) / 2,
3041 gtk_default_draw_option (GtkStyle *style,
3043 GtkStateType state_type,
3044 GtkShadowType shadow_type,
3047 const gchar *detail,
3053 cairo_t *cr = gdk_cairo_create (window);
3054 enum { BUTTON, MENU, CELL } type = BUTTON;
3059 if (strcmp (detail, "radio") == 0)
3061 else if (strcmp (detail, "option") == 0)
3067 gdk_cairo_rectangle (cr, area);
3071 exterior_size = MIN (width, height);
3072 if (exterior_size % 2 == 0) /* Ensure odd */
3075 x -= (1 + exterior_size - width) / 2;
3076 y -= (1 + exterior_size - height) / 2;
3082 gdk_cairo_set_source_color (cr, &style->base[state_type]);
3085 x + exterior_size / 2.,
3086 y + exterior_size / 2.,
3087 (exterior_size - 1) / 2.,
3090 cairo_fill_preserve (cr);
3093 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3095 gdk_cairo_set_source_color (cr, &style->text[state_type]);
3097 cairo_set_line_width (cr, 1.);
3108 gdk_cairo_set_source_color (cr, &style->text[state_type]);
3113 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3117 if (shadow_type == GTK_SHADOW_IN)
3119 int pad = style->xthickness + MAX (1, 2 * (exterior_size - 2 * style->xthickness) / 9);
3120 int interior_size = MAX (1, exterior_size - 2 * pad);
3122 if (interior_size < 5)
3125 pad = MAX (0, (exterior_size - interior_size) / 2);
3129 x + pad + interior_size / 2.,
3130 y + pad + interior_size / 2.,
3135 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
3137 int pad = style->xthickness + MAX (1, (exterior_size - 2 * style->xthickness) / 9);
3138 int interior_size = MAX (1, exterior_size - 2 * pad);
3141 if (interior_size < 7)
3144 pad = MAX (0, (exterior_size - interior_size) / 2);
3147 line_thickness = MAX (1, (3 + interior_size * 2) / 7);
3149 cairo_rectangle (cr,
3151 y + pad + (interior_size - line_thickness) / 2.,
3161 gtk_default_draw_tab (GtkStyle *style,
3163 GtkStateType state_type,
3164 GtkShadowType shadow_type,
3167 const gchar *detail,
3173 #define ARROW_SPACE 4
3176 GtkRequisition indicator_size;
3177 GtkBorder indicator_spacing;
3180 cr = gdk_cairo_create (window);
3184 gdk_cairo_rectangle (cr, area);
3188 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
3190 indicator_size.width += (indicator_size.width % 2) - 1;
3191 arrow_height = indicator_size.width / 2 + 1;
3193 x += (width - indicator_size.width) / 2;
3194 y += (height - (2 * arrow_height + ARROW_SPACE)) / 2;
3196 if (state_type == GTK_STATE_INSENSITIVE)
3198 draw_arrow (cr, &style->white,
3199 GTK_ARROW_UP, x + 1, y + 1,
3200 indicator_size.width, arrow_height);
3202 draw_arrow (cr, &style->white,
3203 GTK_ARROW_DOWN, x + 1, y + arrow_height + ARROW_SPACE + 1,
3204 indicator_size.width, arrow_height);
3207 draw_arrow (cr, &style->fg[state_type],
3209 indicator_size.width, arrow_height);
3212 draw_arrow (cr, &style->fg[state_type],
3213 GTK_ARROW_DOWN, x, y + arrow_height + ARROW_SPACE,
3214 indicator_size.width, arrow_height);
3220 gtk_default_draw_shadow_gap (GtkStyle *style,
3222 GtkStateType state_type,
3223 GtkShadowType shadow_type,
3226 const gchar *detail,
3231 GtkPositionType gap_side,
3235 GdkColor *color1 = NULL;
3236 GdkColor *color2 = NULL;
3237 GdkColor *color3 = NULL;
3238 GdkColor *color4 = NULL;
3241 sanitize_size (window, &width, &height);
3243 switch (shadow_type)
3245 case GTK_SHADOW_NONE:
3249 color1 = &style->dark[state_type];
3250 color2 = &style->black;
3251 color3 = &style->bg[state_type];
3252 color4 = &style->light[state_type];
3254 case GTK_SHADOW_ETCHED_IN:
3255 color1 = &style->dark[state_type];
3256 color2 = &style->light[state_type];
3257 color3 = &style->dark[state_type];
3258 color4 = &style->light[state_type];
3260 case GTK_SHADOW_OUT:
3261 color1 = &style->light[state_type];
3262 color2 = &style->bg[state_type];
3263 color3 = &style->dark[state_type];
3264 color4 = &style->black;
3266 case GTK_SHADOW_ETCHED_OUT:
3267 color1 = &style->light[state_type];
3268 color2 = &style->dark[state_type];
3269 color3 = &style->light[state_type];
3270 color4 = &style->dark[state_type];
3274 cr = gdk_cairo_create (window);
3277 gdk_cairo_rectangle (cr, area);
3281 switch (shadow_type)
3283 case GTK_SHADOW_NONE:
3285 case GTK_SHADOW_OUT:
3286 case GTK_SHADOW_ETCHED_IN:
3287 case GTK_SHADOW_ETCHED_OUT:
3291 _cairo_draw_line (cr, color1,
3292 x, y, x, y + height - 1);
3293 _cairo_draw_line (cr, color2,
3294 x + 1, y, x + 1, y + height - 2);
3296 _cairo_draw_line (cr, color3,
3297 x + 1, y + height - 2, x + width - 2, y + height - 2);
3298 _cairo_draw_line (cr, color3,
3299 x + width - 2, y, x + width - 2, y + height - 2);
3300 _cairo_draw_line (cr, color4,
3301 x, y + height - 1, x + width - 1, y + height - 1);
3302 _cairo_draw_line (cr, color4,
3303 x + width - 1, y, x + width - 1, y + height - 1);
3306 _cairo_draw_line (cr, color1,
3307 x, y, x + gap_x - 1, y);
3308 _cairo_draw_line (cr, color2,
3309 x + 1, y + 1, x + gap_x - 1, y + 1);
3310 _cairo_draw_line (cr, color2,
3311 x + gap_x, y, x + gap_x, y);
3313 if ((width - (gap_x + gap_width)) > 0)
3315 _cairo_draw_line (cr, color1,
3316 x + gap_x + gap_width, y, x + width - 2, y);
3317 _cairo_draw_line (cr, color2,
3318 x + gap_x + gap_width, y + 1, x + width - 3, y + 1);
3319 _cairo_draw_line (cr, color2,
3320 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
3323 case GTK_POS_BOTTOM:
3324 _cairo_draw_line (cr, color1,
3325 x, y, x + width - 1, y);
3326 _cairo_draw_line (cr, color1,
3327 x, y, x, y + height - 1);
3328 _cairo_draw_line (cr, color2,
3329 x + 1, y + 1, x + width - 2, y + 1);
3330 _cairo_draw_line (cr, color2,
3331 x + 1, y + 1, x + 1, y + height - 1);
3333 _cairo_draw_line (cr, color3,
3334 x + width - 2, y + 1, x + width - 2, y + height - 1);
3335 _cairo_draw_line (cr, color4,
3336 x + width - 1, y, x + width - 1, y + height - 1);
3339 _cairo_draw_line (cr, color4,
3340 x, y + height - 1, x + gap_x - 1, y + height - 1);
3341 _cairo_draw_line (cr, color3,
3342 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
3343 _cairo_draw_line (cr, color3,
3344 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
3346 if ((width - (gap_x + gap_width)) > 0)
3348 _cairo_draw_line (cr, color4,
3349 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
3350 _cairo_draw_line (cr, color3,
3351 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
3352 _cairo_draw_line (cr, color3,
3353 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
3357 _cairo_draw_line (cr, color1,
3358 x, y, x + width - 1, y);
3359 _cairo_draw_line (cr, color2,
3360 x, y + 1, x + width - 2, y + 1);
3362 _cairo_draw_line (cr, color3,
3363 x, y + height - 2, x + width - 2, y + height - 2);
3364 _cairo_draw_line (cr, color3,
3365 x + width - 2, y + 1, x + width - 2, y + height - 2);
3366 _cairo_draw_line (cr, color4,
3367 x, y + height - 1, x + width - 1, y + height - 1);
3368 _cairo_draw_line (cr, color4,
3369 x + width - 1, y, x + width - 1, y + height - 1);
3372 _cairo_draw_line (cr, color1,
3373 x, y, x, y + gap_x - 1);
3374 _cairo_draw_line (cr, color2,
3375 x + 1, y + 1, x + 1, y + gap_x - 1);
3376 _cairo_draw_line (cr, color2,
3377 x, y + gap_x, x, y + gap_x);
3379 if ((width - (gap_x + gap_width)) > 0)
3381 _cairo_draw_line (cr, color1,
3382 x, y + gap_x + gap_width, x, y + height - 2);
3383 _cairo_draw_line (cr, color2,
3384 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
3385 _cairo_draw_line (cr, color2,
3386 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
3390 _cairo_draw_line (cr, color1,
3391 x, y, x + width - 1, y);
3392 _cairo_draw_line (cr, color1,
3393 x, y, x, y + height - 1);
3394 _cairo_draw_line (cr, color2,
3395 x + 1, y + 1, x + width - 1, y + 1);
3396 _cairo_draw_line (cr, color2,
3397 x + 1, y + 1, x + 1, y + height - 2);
3399 _cairo_draw_line (cr, color3,
3400 x + 1, y + height - 2, x + width - 1, y + height - 2);
3401 _cairo_draw_line (cr, color4,
3402 x, y + height - 1, x + width - 1, y + height - 1);
3405 _cairo_draw_line (cr, color4,
3406 x + width - 1, y, x + width - 1, y + gap_x - 1);
3407 _cairo_draw_line (cr, color3,
3408 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
3409 _cairo_draw_line (cr, color3,
3410 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
3412 if ((width - (gap_x + gap_width)) > 0)
3414 _cairo_draw_line (cr, color4,
3415 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
3416 _cairo_draw_line (cr, color3,
3417 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
3418 _cairo_draw_line (cr, color3,
3419 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
3429 gtk_default_draw_box_gap (GtkStyle *style,
3431 GtkStateType state_type,
3432 GtkShadowType shadow_type,
3435 const gchar *detail,
3440 GtkPositionType gap_side,
3450 sanitize_size (window, &width, &height);
3452 gtk_style_apply_default_background (style, window,
3453 widget && gtk_widget_get_has_window (widget),
3454 state_type, area, x, y, width, height);
3456 cr = gdk_cairo_create (window);
3459 gdk_cairo_rectangle (cr, area);
3463 switch (shadow_type)
3465 case GTK_SHADOW_NONE:
3469 color1 = style->dark[state_type];
3470 color2 = style->black;
3471 color3 = style->bg[state_type];
3472 color4 = style->light[state_type];
3474 case GTK_SHADOW_ETCHED_IN:
3475 color1 = style->dark[state_type];
3476 color2 = style->light[state_type];
3477 color3 = style->dark[state_type];
3478 color4 = style->light[state_type];
3480 case GTK_SHADOW_OUT:
3481 color1 = style->light[state_type];
3482 color2 = style->bg[state_type];
3483 color3 = style->dark[state_type];
3484 color4 = style->black;
3486 case GTK_SHADOW_ETCHED_OUT:
3487 color1 = style->light[state_type];
3488 color2 = style->dark[state_type];
3489 color3 = style->light[state_type];
3490 color4 = style->dark[state_type];
3494 cairo_set_line_width (cr, 1.0);
3496 switch (shadow_type)
3498 case GTK_SHADOW_NONE:
3500 case GTK_SHADOW_OUT:
3501 case GTK_SHADOW_ETCHED_IN:
3502 case GTK_SHADOW_ETCHED_OUT:
3506 _cairo_draw_line (cr, &color1,
3507 x, y, x, y + height - 1);
3508 _cairo_draw_line (cr, &color2,
3509 x + 1, y, x + 1, y + height - 2);
3511 _cairo_draw_line (cr, &color3,
3512 x + 1, y + height - 2, x + width - 2, y + height - 2);
3513 _cairo_draw_line (cr, &color3,
3514 x + width - 2, y, x + width - 2, y + height - 2);
3515 _cairo_draw_line (cr, &color4,
3516 x, y + height - 1, x + width - 1, y + height - 1);
3517 _cairo_draw_line (cr, &color4,
3518 x + width - 1, y, x + width - 1, y + height - 1);
3521 _cairo_draw_line (cr, &color1,
3522 x, y, x + gap_x - 1, y);
3523 _cairo_draw_line (cr, &color2,
3524 x + 1, y + 1, x + gap_x - 1, y + 1);
3525 _cairo_draw_line (cr, &color2,
3526 x + gap_x, y, x + gap_x, y);
3528 if ((width - (gap_x + gap_width)) > 0)
3530 _cairo_draw_line (cr, &color1,
3531 x + gap_x + gap_width, y, x + width - 2, y);
3532 _cairo_draw_line (cr, &color2,
3533 x + gap_x + gap_width, y + 1, x + width - 2, y + 1);
3534 _cairo_draw_line (cr, &color2,
3535 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
3538 case GTK_POS_BOTTOM:
3539 _cairo_draw_line (cr, &color1,
3540 x, y, x + width - 1, y);
3541 _cairo_draw_line (cr, &color1,
3542 x, y, x, y + height - 1);
3543 _cairo_draw_line (cr, &color2,
3544 x + 1, y + 1, x + width - 2, y + 1);
3545 _cairo_draw_line (cr, &color2,
3546 x + 1, y + 1, x + 1, y + height - 1);
3548 _cairo_draw_line (cr, &color3,
3549 x + width - 2, y + 1, x + width - 2, y + height - 1);
3550 _cairo_draw_line (cr, &color4,
3551 x + width - 1, y, x + width - 1, y + height - 1);
3554 _cairo_draw_line (cr, &color4,
3555 x, y + height - 1, x + gap_x - 1, y + height - 1);
3556 _cairo_draw_line (cr, &color3,
3557 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
3558 _cairo_draw_line (cr, &color3,
3559 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
3561 if ((width - (gap_x + gap_width)) > 0)
3563 _cairo_draw_line (cr, &color4,
3564 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
3565 _cairo_draw_line (cr, &color3,
3566 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
3567 _cairo_draw_line (cr, &color3,
3568 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
3572 _cairo_draw_line (cr, &color1,
3573 x, y, x + width - 1, y);
3574 _cairo_draw_line (cr, &color2,
3575 x, y + 1, x + width - 2, y + 1);
3577 _cairo_draw_line (cr, &color3,
3578 x, y + height - 2, x + width - 2, y + height - 2);
3579 _cairo_draw_line (cr, &color3,
3580 x + width - 2, y + 1, x + width - 2, y + height - 2);
3581 _cairo_draw_line (cr, &color4,
3582 x, y + height - 1, x + width - 1, y + height - 1);
3583 _cairo_draw_line (cr, &color4,
3584 x + width - 1, y, x + width - 1, y + height - 1);
3587 _cairo_draw_line (cr, &color1,
3588 x, y, x, y + gap_x - 1);
3589 _cairo_draw_line (cr, &color2,
3590 x + 1, y + 1, x + 1, y + gap_x - 1);
3591 _cairo_draw_line (cr, &color2,
3592 x, y + gap_x, x, y + gap_x);
3594 if ((height - (gap_x + gap_width)) > 0)
3596 _cairo_draw_line (cr, &color1,
3597 x, y + gap_x + gap_width, x, y + height - 2);
3598 _cairo_draw_line (cr, &color2,
3599 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
3600 _cairo_draw_line (cr, &color2,
3601 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
3605 _cairo_draw_line (cr, &color1,
3606 x, y, x + width - 1, y);
3607 _cairo_draw_line (cr, &color1,
3608 x, y, x, y + height - 1);
3609 _cairo_draw_line (cr, &color2,
3610 x + 1, y + 1, x + width - 1, y + 1);
3611 _cairo_draw_line (cr, &color2,
3612 x + 1, y + 1, x + 1, y + height - 2);
3614 _cairo_draw_line (cr, &color3,
3615 x + 1, y + height - 2, x + width - 1, y + height - 2);
3616 _cairo_draw_line (cr, &color4,
3617 x, y + height - 1, x + width - 1, y + height - 1);
3620 _cairo_draw_line (cr, &color4,
3621 x + width - 1, y, x + width - 1, y + gap_x - 1);
3622 _cairo_draw_line (cr, &color3,
3623 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
3624 _cairo_draw_line (cr, &color3,
3625 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
3627 if ((height - (gap_x + gap_width)) > 0)
3629 _cairo_draw_line (cr, &color4,
3630 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
3631 _cairo_draw_line (cr, &color3,
3632 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
3633 _cairo_draw_line (cr, &color3,
3634 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
3645 gtk_default_draw_extension (GtkStyle *style,
3647 GtkStateType state_type,
3648 GtkShadowType shadow_type,
3651 const gchar *detail,
3656 GtkPositionType gap_side)
3664 sanitize_size (window, &width, &height);
3669 gtk_style_apply_default_background (style, window,
3670 widget && gtk_widget_get_has_window (widget),
3677 case GTK_POS_BOTTOM:
3678 gtk_style_apply_default_background (style, window,
3679 widget && gtk_widget_get_has_window (widget),
3687 gtk_style_apply_default_background (style, window,
3688 widget && gtk_widget_get_has_window (widget),
3696 gtk_style_apply_default_background (style, window,
3697 widget && gtk_widget_get_has_window (widget),
3707 cr = gdk_cairo_create (window);
3710 gdk_cairo_rectangle (cr, area);
3714 switch (shadow_type)
3716 case GTK_SHADOW_NONE:
3719 color1 = style->dark[state_type];
3720 color2 = style->black;
3721 color3 = style->bg[state_type];
3722 color4 = style->light[state_type];
3724 case GTK_SHADOW_ETCHED_IN:
3725 color1 = style->dark[state_type];
3726 color2 = style->light[state_type];
3727 color3 = style->dark[state_type];
3728 color4 = style->light[state_type];
3730 case GTK_SHADOW_OUT:
3731 color1 = style->light[state_type];
3732 color2 = style->bg[state_type];
3733 color3 = style->dark[state_type];
3734 color4 = style->black;
3736 case GTK_SHADOW_ETCHED_OUT:
3737 color1 = style->light[state_type];
3738 color2 = style->dark[state_type];
3739 color3 = style->light[state_type];
3740 color4 = style->dark[state_type];
3744 cairo_set_line_width (cr, 1.0);
3746 switch (shadow_type)
3748 case GTK_SHADOW_NONE:
3750 case GTK_SHADOW_OUT:
3751 case GTK_SHADOW_ETCHED_IN:
3752 case GTK_SHADOW_ETCHED_OUT:
3756 _cairo_draw_line (cr, &color1,
3757 x, y, x, y + height - 2);
3758 _cairo_draw_line (cr, &color2,
3759 x + 1, y, x + 1, y + height - 2);
3761 _cairo_draw_line (cr, &color3,
3762 x + 2, y + height - 2, x + width - 2, y + height - 2);
3763 _cairo_draw_line (cr, &color3,
3764 x + width - 2, y, x + width - 2, y + height - 2);
3765 _cairo_draw_line (cr, &color4,
3766 x + 1, y + height - 1, x + width - 2, y + height - 1);
3767 _cairo_draw_line (cr, &color4,
3768 x + width - 1, y, x + width - 1, y + height - 2);
3770 case GTK_POS_BOTTOM:
3771 _cairo_draw_line (cr, &color1,
3772 x + 1, y, x + width - 2, y);
3773 _cairo_draw_line (cr, &color1,
3774 x, y + 1, x, y + height - 1);
3775 _cairo_draw_line (cr, &color2,
3776 x + 1, y + 1, x + width - 2, y + 1);
3777 _cairo_draw_line (cr, &color2,
3778 x + 1, y + 1, x + 1, y + height - 1);
3780 _cairo_draw_line (cr, &color3,
3781 x + width - 2, y + 2, x + width - 2, y + height - 1);
3782 _cairo_draw_line (cr, &color4,
3783 x + width - 1, y + 1, x + width - 1, y + height - 1);
3786 _cairo_draw_line (cr, &color1,
3787 x, y, x + width - 2, y);
3788 _cairo_draw_line (cr, &color2,
3789 x + 1, y + 1, x + width - 2, y + 1);
3791 _cairo_draw_line (cr, &color3,
3792 x, y + height - 2, x + width - 2, y + height - 2);
3793 _cairo_draw_line (cr, &color3,
3794 x + width - 2, y + 2, x + width - 2, y + height - 2);
3795 _cairo_draw_line (cr, &color4,
3796 x, y + height - 1, x + width - 2, y + height - 1);
3797 _cairo_draw_line (cr, &color4,
3798 x + width - 1, y + 1, x + width - 1, y + height - 2);
3801 _cairo_draw_line (cr, &color1,
3802 x + 1, y, x + width - 1, y);
3803 _cairo_draw_line (cr, &color1,
3804 x, y + 1, x, y + height - 2);
3805 _cairo_draw_line (cr, &color2,
3806 x + 1, y + 1, x + width - 1, y + 1);
3807 _cairo_draw_line (cr, &color2,
3808 x + 1, y + 1, x + 1, y + height - 2);
3810 _cairo_draw_line (cr, &color3,
3811 x + 2, y + height - 2, x + width - 1, y + height - 2);
3812 _cairo_draw_line (cr, &color4,
3813 x + 1, y + height - 1, x + width - 1, y + height - 1);
3822 gtk_default_draw_focus (GtkStyle *style,
3824 GtkStateType state_type,
3827 const gchar *detail,
3834 gboolean free_dash_list = FALSE;
3835 gint line_width = 1;
3836 gint8 *dash_list = (gint8 *) "\1\1";
3840 gtk_widget_style_get (widget,
3841 "focus-line-width", &line_width,
3842 "focus-line-pattern", (gchar *)&dash_list,
3845 free_dash_list = TRUE;
3848 if (detail && !strcmp (detail, "add-mode"))
3853 dash_list = (gint8 *) "\4\4";
3854 free_dash_list = FALSE;
3857 sanitize_size (window, &width, &height);
3859 cr = gdk_cairo_create (window);
3861 if (detail && !strcmp (detail, "colorwheel_light"))
3862 cairo_set_source_rgb (cr, 0., 0., 0.);
3863 else if (detail && !strcmp (detail, "colorwheel_dark"))
3864 cairo_set_source_rgb (cr, 1., 1., 1.);
3866 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3868 cairo_set_line_width (cr, line_width);
3872 gint n_dashes = strlen ((const gchar *) dash_list);
3873 gdouble *dashes = g_new (gdouble, n_dashes);
3874 gdouble total_length = 0;
3875 gdouble dash_offset;
3878 for (i = 0; i < n_dashes; i++)
3880 dashes[i] = dash_list[i];
3881 total_length += dash_list[i];
3884 /* The dash offset here aligns the pattern to integer pixels
3885 * by starting the dash at the right side of the left border
3886 * Negative dash offsets in cairo don't work
3887 * (https://bugs.freedesktop.org/show_bug.cgi?id=2729)
3889 dash_offset = - line_width / 2.;
3890 while (dash_offset < 0)
3891 dash_offset += total_length;
3893 cairo_set_dash (cr, dashes, n_dashes, dash_offset);
3899 gdk_cairo_rectangle (cr, area);
3903 cairo_rectangle (cr,
3904 x + line_width / 2.,
3905 y + line_width / 2.,
3907 height - line_width);
3916 gtk_default_draw_slider (GtkStyle *style,
3918 GtkStateType state_type,
3919 GtkShadowType shadow_type,
3922 const gchar *detail,
3927 GtkOrientation orientation)
3929 sanitize_size (window, &width, &height);
3931 gtk_paint_box (style, window, state_type, shadow_type,
3932 area, widget, detail, x, y, width, height);
3935 (strcmp ("hscale", detail) == 0 ||
3936 strcmp ("vscale", detail) == 0))
3938 if (orientation == GTK_ORIENTATION_HORIZONTAL)
3939 gtk_paint_vline (style, window, state_type, area, widget, detail,
3940 y + style->ythickness,
3941 y + height - style->ythickness - 1, x + width / 2);
3943 gtk_paint_hline (style, window, state_type, area, widget, detail,
3944 x + style->xthickness,
3945 x + width - style->xthickness - 1, y + height / 2);
3950 draw_dot (cairo_t *cr,
3957 size = CLAMP (size, 2, 3);
3961 _cairo_draw_point (cr, light, x, y);
3962 _cairo_draw_point (cr, light, x+1, y+1);
3966 _cairo_draw_point (cr, light, x, y);
3967 _cairo_draw_point (cr, light, x+1, y);
3968 _cairo_draw_point (cr, light, x, y+1);
3969 _cairo_draw_point (cr, dark, x+1, y+2);
3970 _cairo_draw_point (cr, dark, x+2, y+1);
3971 _cairo_draw_point (cr, dark, x+2, y+2);
3976 gtk_default_draw_handle (GtkStyle *style,
3978 GtkStateType state_type,
3979 GtkShadowType shadow_type,
3982 const gchar *detail,
3987 GtkOrientation orientation)
3990 gint xthick, ythick;
3991 GdkColor light, dark;
3994 sanitize_size (window, &width, &height);
3996 gtk_paint_box (style, window, state_type, shadow_type, area, widget,
3997 detail, x, y, width, height);
3999 cr = gdk_cairo_create (window);
4002 gdk_cairo_rectangle (cr, area);
4006 if (detail && !strcmp (detail, "paned"))
4008 /* we want to ignore the shadow border in paned widgets */
4012 if (state_type == GTK_STATE_SELECTED && widget && !gtk_widget_has_focus (widget))
4013 _gtk_style_shade (&style->base[GTK_STATE_ACTIVE], &light,
4016 light = style->light[state_type];
4018 dark = style->black;
4022 xthick = style->xthickness;
4023 ythick = style->ythickness;
4025 light = style->light[state_type];
4026 dark = style->dark[state_type];
4029 cairo_rectangle(cr, x + xthick, y + ythick,
4030 width - (xthick * 2), height - (ythick * 2));
4033 if (detail && !strcmp (detail, "paned"))
4035 if (orientation == GTK_ORIENTATION_HORIZONTAL)
4036 for (xx = x + width/2 - 15; xx <= x + width/2 + 15; xx += 5)
4037 draw_dot (cr, &light, &dark, xx, y + height/2 - 1, 3);
4039 for (yy = y + height/2 - 15; yy <= y + height/2 + 15; yy += 5)
4040 draw_dot (cr, &light, &dark, x + width/2 - 1, yy, 3);
4044 for (yy = y + ythick; yy < (y + height - ythick); yy += 3)
4045 for (xx = x + xthick; xx < (x + width - xthick); xx += 6)
4047 draw_dot (cr, &light, &dark, xx, yy, 2);
4048 draw_dot (cr, &light, &dark, xx + 3, yy + 1, 2);
4056 gtk_default_draw_expander (GtkStyle *style,
4058 GtkStateType state_type,
4061 const gchar *detail,
4064 GtkExpanderStyle expander_style)
4066 #define DEFAULT_EXPANDER_SIZE 12
4070 double vertical_overshoot;
4073 double interp; /* interpolation factor for center position */
4074 double x_double_horz, y_double_horz;
4075 double x_double_vert, y_double_vert;
4076 double x_double, y_double;
4079 cairo_t *cr = gdk_cairo_create (window);
4083 gdk_cairo_rectangle (cr, area);
4088 gtk_widget_class_find_style_property (GTK_WIDGET_GET_CLASS (widget),
4091 gtk_widget_style_get (widget,
4092 "expander-size", &expander_size,
4096 expander_size = DEFAULT_EXPANDER_SIZE;
4098 line_width = MAX (1, expander_size/9);
4100 switch (expander_style)
4102 case GTK_EXPANDER_COLLAPSED:
4103 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 180 : 0;
4106 case GTK_EXPANDER_SEMI_COLLAPSED:
4107 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 150 : 30;
4110 case GTK_EXPANDER_SEMI_EXPANDED:
4111 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 120 : 60;
4114 case GTK_EXPANDER_EXPANDED:
4119 g_assert_not_reached ();
4122 /* Compute distance that the stroke extends beyonds the end
4123 * of the triangle we draw.
4125 vertical_overshoot = line_width / 2.0 * (1. / tan (G_PI / 8));
4127 /* For odd line widths, we end the vertical line of the triangle
4128 * at a half pixel, so we round differently.
4130 if (line_width % 2 == 1)
4131 vertical_overshoot = ceil (0.5 + vertical_overshoot) - 0.5;
4133 vertical_overshoot = ceil (vertical_overshoot);
4135 /* Adjust the size of the triangle we draw so that the entire stroke fits
4137 diameter = MAX (3, expander_size - 2 * vertical_overshoot);
4139 /* If the line width is odd, we want the diameter to be even,
4140 * and vice versa, so force the sum to be odd. This relationship
4141 * makes the point of the triangle look right.
4143 diameter -= (1 - (diameter + line_width) % 2);
4145 radius = diameter / 2.;
4147 /* Adjust the center so that the stroke is properly aligned with
4148 * the pixel grid. The center adjustment is different for the
4149 * horizontal and vertical orientations. For intermediate positions
4150 * we interpolate between the two.
4152 x_double_vert = floor (x - (radius + line_width) / 2.) + (radius + line_width) / 2.;
4153 y_double_vert = y - 0.5;
4155 x_double_horz = x - 0.5;
4156 y_double_horz = floor (y - (radius + line_width) / 2.) + (radius + line_width) / 2.;
4158 x_double = x_double_vert * (1 - interp) + x_double_horz * interp;
4159 y_double = y_double_vert * (1 - interp) + y_double_horz * interp;
4161 cairo_translate (cr, x_double, y_double);
4162 cairo_rotate (cr, degrees * G_PI / 180);
4164 cairo_move_to (cr, - radius / 2., - radius);
4165 cairo_line_to (cr, radius / 2., 0);
4166 cairo_line_to (cr, - radius / 2., radius);
4167 cairo_close_path (cr);
4169 cairo_set_line_width (cr, line_width);
4171 if (state_type == GTK_STATE_PRELIGHT)
4172 gdk_cairo_set_source_color (cr,
4173 &style->fg[GTK_STATE_PRELIGHT]);
4174 else if (state_type == GTK_STATE_ACTIVE)
4175 gdk_cairo_set_source_color (cr,
4176 &style->light[GTK_STATE_ACTIVE]);
4178 gdk_cairo_set_source_color (cr,
4179 &style->base[GTK_STATE_NORMAL]);
4181 cairo_fill_preserve (cr);
4183 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
4190 gtk_default_draw_layout (GtkStyle *style,
4192 GtkStateType state_type,
4196 const gchar *detail,
4199 PangoLayout *layout)
4204 cr = gdk_cairo_create (window);
4208 gdk_cairo_rectangle (cr, area);
4212 if (state_type == GTK_STATE_INSENSITIVE)
4214 gdk_cairo_set_source_color (cr, &style->white);
4215 cairo_move_to (cr, x + 1, y + 1);
4216 pango_cairo_layout_path (cr, layout);
4220 gc = use_text ? &style->text[state_type] : &style->fg[state_type];
4222 cairo_move_to (cr, x, y);
4223 gdk_cairo_set_source_color (cr, gc);
4225 pango_cairo_show_layout (cr, layout);
4231 gtk_default_draw_resize_grip (GtkStyle *style,
4233 GtkStateType state_type,
4236 const gchar *detail,
4246 cr = gdk_cairo_create (window);
4247 cairo_rectangle (cr, x, y, width, height);
4251 gdk_cairo_rectangle (cr, area);
4255 cairo_set_line_width (cr, 1.0);
4260 case GDK_WINDOW_EDGE_NORTH_WEST:
4261 /* make it square */
4264 else if (height < width)
4268 case GDK_WINDOW_EDGE_NORTH:
4272 case GDK_WINDOW_EDGE_NORTH_EAST:
4273 /* make it square, aligning to top right */
4276 else if (height < width)
4278 x += (width - height);
4283 case GDK_WINDOW_EDGE_WEST:
4287 case GDK_WINDOW_EDGE_EAST:
4288 /* aligning to right */
4291 x += (width - height);
4295 case GDK_WINDOW_EDGE_SOUTH_WEST:
4296 /* make it square, aligning to bottom left */
4299 y += (height - width);
4302 else if (height < width)
4306 case GDK_WINDOW_EDGE_SOUTH:
4307 /* align to bottom */
4310 y += (height - width);
4314 case GDK_WINDOW_EDGE_SOUTH_EAST:
4315 /* make it square, aligning to bottom right */
4318 y += (height - width);
4321 else if (height < width)
4323 x += (width - height);
4329 g_assert_not_reached ();
4334 case GDK_WINDOW_EDGE_WEST:
4335 case GDK_WINDOW_EDGE_EAST:
4341 while (xi < x + width)
4343 _cairo_draw_line (cr,
4344 &style->light[state_type],
4349 _cairo_draw_line (cr,
4350 &style->dark[state_type],
4358 case GDK_WINDOW_EDGE_NORTH:
4359 case GDK_WINDOW_EDGE_SOUTH:
4365 while (yi < y + height)
4367 _cairo_draw_line (cr,
4368 &style->light[state_type],
4373 _cairo_draw_line (cr,
4374 &style->dark[state_type],
4382 case GDK_WINDOW_EDGE_NORTH_WEST:
4391 _cairo_draw_line (cr,
4392 &style->dark[state_type],
4399 _cairo_draw_line (cr,
4400 &style->dark[state_type],
4407 _cairo_draw_line (cr,
4408 &style->light[state_type],
4418 case GDK_WINDOW_EDGE_NORTH_EAST:
4425 while (xi < (x + width - 3))
4427 _cairo_draw_line (cr,
4428 &style->light[state_type],
4435 _cairo_draw_line (cr,
4436 &style->dark[state_type],
4443 _cairo_draw_line (cr,
4444 &style->dark[state_type],
4453 case GDK_WINDOW_EDGE_SOUTH_WEST:
4462 _cairo_draw_line (cr,
4463 &style->dark[state_type],
4470 _cairo_draw_line (cr,
4471 &style->dark[state_type],
4478 _cairo_draw_line (cr,
4479 &style->light[state_type],
4489 case GDK_WINDOW_EDGE_SOUTH_EAST:
4496 while (xi < (x + width - 3))
4498 _cairo_draw_line (cr,
4499 &style->light[state_type],
4506 _cairo_draw_line (cr,
4507 &style->dark[state_type],
4514 _cairo_draw_line (cr,
4515 &style->dark[state_type],
4525 g_assert_not_reached ();
4533 gtk_default_draw_spinner (GtkStyle *style,
4535 GtkStateType state_type,
4538 const gchar *detail,
4554 gtk_style_get (style, GTK_TYPE_SPINNER,
4555 "num-steps", &num_steps,
4557 real_step = step % num_steps;
4559 /* get cairo context */
4560 cr = gdk_cairo_create (window);
4562 /* set a clip region for the expose event */
4563 cairo_rectangle (cr, x, y, width, height);
4566 cairo_translate (cr, x, y);
4568 /* draw clip region */
4569 cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
4571 color = &style->fg[state_type];
4574 radius = MIN (width / 2, height / 2);
4575 half = num_steps / 2;
4577 for (i = 0; i < num_steps; i++)
4579 gint inset = 0.7 * radius;
4581 /* transparency is a function of time and intial value */
4582 gdouble t = (gdouble) ((i + num_steps - real_step)
4583 % num_steps) / num_steps;
4587 cairo_set_source_rgba (cr,
4588 color->red / 65535.,
4589 color->green / 65535.,
4590 color->blue / 65535.,
4593 cairo_set_line_width (cr, 2.0);
4595 dx + (radius - inset) * cos (i * G_PI / half),
4596 dy + (radius - inset) * sin (i * G_PI / half));
4598 dx + radius * cos (i * G_PI / half),
4599 dy + radius * sin (i * G_PI / half));
4610 _gtk_style_shade (const GdkColor *a,
4618 red = (gdouble) a->red / 65535.0;
4619 green = (gdouble) a->green / 65535.0;
4620 blue = (gdouble) a->blue / 65535.0;
4622 rgb_to_hls (&red, &green, &blue);
4627 else if (green < 0.0)
4633 else if (blue < 0.0)
4636 hls_to_rgb (&red, &green, &blue);
4638 b->red = red * 65535.0;
4639 b->green = green * 65535.0;
4640 b->blue = blue * 65535.0;
4644 rgb_to_hls (gdouble *r,
4685 l = (max + min) / 2;
4692 s = (max - min) / (max + min);
4694 s = (max - min) / (2 - max - min);
4698 h = (green - blue) / delta;
4699 else if (green == max)
4700 h = 2 + (blue - red) / delta;
4701 else if (blue == max)
4702 h = 4 + (red - green) / delta;
4715 hls_to_rgb (gdouble *h,
4728 if (lightness <= 0.5)
4729 m2 = lightness * (1 + saturation);
4731 m2 = lightness + saturation - lightness * saturation;
4732 m1 = 2 * lightness - m2;
4734 if (saturation == 0)
4749 r = m1 + (m2 - m1) * hue / 60;
4753 r = m1 + (m2 - m1) * (240 - hue) / 60;
4764 g = m1 + (m2 - m1) * hue / 60;
4768 g = m1 + (m2 - m1) * (240 - hue) / 60;
4779 b = m1 + (m2 - m1) * hue / 60;
4783 b = m1 + (m2 - m1) * (240 - hue) / 60;
4796 * @style: a #GtkStyle
4797 * @window: a #GdkWindow
4798 * @state_type: a state
4799 * @area: (allow-none): rectangle to which the output is clipped, or %NULL if the
4800 * output should not be clipped
4801 * @widget: (allow-none): the widget
4802 * @detail: (allow-none): a style detail
4803 * @x1: the starting x coordinate
4804 * @x2: the ending x coordinate
4805 * @y: the y coordinate
4807 * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @window
4808 * using the given style and state.
4811 gtk_paint_hline (GtkStyle *style,
4813 GtkStateType state_type,
4814 const GdkRectangle *area,
4816 const gchar *detail,
4821 g_return_if_fail (GTK_IS_STYLE (style));
4822 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
4823 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
4825 GTK_STYLE_GET_CLASS (style)->draw_hline (style, window, state_type,
4826 (GdkRectangle *) area, widget, detail,
4832 * @style: a #GtkStyle
4833 * @window: a #GdkWindow
4834 * @state_type: a state
4835 * @area: (allow-none): rectangle to which the output is clipped, or %NULL if the
4836 * output should not be clipped
4837 * @widget: (allow-none): the widget
4838 * @detail: (allow-none): a style detail
4839 * @y1_: the starting y coordinate
4840 * @y2_: the ending y coordinate
4841 * @x: the x coordinate
4843 * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @window
4844 * using the given style and state.
4847 gtk_paint_vline (GtkStyle *style,
4849 GtkStateType state_type,
4850 const GdkRectangle *area,
4852 const gchar *detail,
4857 g_return_if_fail (GTK_IS_STYLE (style));
4858 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
4859 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
4861 GTK_STYLE_GET_CLASS (style)->draw_vline (style, window, state_type,
4862 (GdkRectangle *) area, widget, detail,
4868 * @style: a #GtkStyle
4869 * @window: a #GdkWindow
4870 * @state_type: a state
4871 * @shadow_type: type of shadow to draw
4872 * @area: (allow-none): clip rectangle or %NULL if the
4873 * output should not be clipped
4874 * @widget: (allow-none): the widget
4875 * @detail: (allow-none): a style detail
4876 * @x: x origin of the rectangle
4877 * @y: y origin of the rectangle
4878 * @width: width of the rectangle
4879 * @height: width of the rectangle
4881 * Draws a shadow around the given rectangle in @window
4882 * using the given style and state and shadow type.
4885 gtk_paint_shadow (GtkStyle *style,
4887 GtkStateType state_type,
4888 GtkShadowType shadow_type,
4889 const GdkRectangle *area,
4891 const gchar *detail,
4897 g_return_if_fail (GTK_IS_STYLE (style));
4898 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
4899 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
4901 GTK_STYLE_GET_CLASS (style)->draw_shadow (style, window, state_type, shadow_type,
4902 (GdkRectangle *) area, widget, detail,
4903 x, y, width, height);
4908 * @style: a #GtkStyle
4909 * @window: a #GdkWindow
4910 * @state_type: a state
4911 * @shadow_type: the type of shadow to draw
4912 * @area: (allow-none): clip rectangle, or %NULL if the
4913 * output should not be clipped
4914 * @widget: (allow-none): the widget
4915 * @detail: (allow-none): a style detail
4916 * @arrow_type: the type of arrow to draw
4917 * @fill: %TRUE if the arrow tip should be filled
4918 * @x: x origin of the rectangle to draw the arrow in
4919 * @y: y origin of the rectangle to draw the arrow in
4920 * @width: width of the rectangle to draw the arrow in
4921 * @height: height of the rectangle to draw the arrow in
4923 * Draws an arrow in the given rectangle on @window using the given
4924 * parameters. @arrow_type determines the direction of the arrow.
4927 gtk_paint_arrow (GtkStyle *style,
4929 GtkStateType state_type,
4930 GtkShadowType shadow_type,
4931 const GdkRectangle *area,
4933 const gchar *detail,
4934 GtkArrowType arrow_type,
4941 g_return_if_fail (GTK_IS_STYLE (style));
4942 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
4943 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
4945 GTK_STYLE_GET_CLASS (style)->draw_arrow (style, window, state_type, shadow_type,
4946 (GdkRectangle *) area, widget, detail,
4947 arrow_type, fill, x, y, width, height);
4951 * gtk_paint_diamond:
4952 * @style: a #GtkStyle
4953 * @window: a #GdkWindow
4954 * @state_type: a state
4955 * @shadow_type: the type of shadow to draw
4956 * @area: (allow-none): clip rectangle, or %NULL if the
4957 * output should not be clipped
4958 * @widget: (allow-none): the widget
4959 * @detail: (allow-none): a style detail
4960 * @x: x origin of the rectangle to draw the diamond in
4961 * @y: y origin of the rectangle to draw the diamond in
4962 * @width: width of the rectangle to draw the diamond in
4963 * @height: height of the rectangle to draw the diamond in
4965 * Draws a diamond in the given rectangle on @window using the given
4969 gtk_paint_diamond (GtkStyle *style,
4971 GtkStateType state_type,
4972 GtkShadowType shadow_type,
4973 const GdkRectangle *area,
4975 const gchar *detail,
4981 g_return_if_fail (GTK_IS_STYLE (style));
4982 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
4983 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
4985 GTK_STYLE_GET_CLASS (style)->draw_diamond (style, window, state_type, shadow_type,
4986 (GdkRectangle *) area, widget, detail,
4987 x, y, width, height);
4992 * @style: a #GtkStyle
4993 * @window: a #GdkWindow
4994 * @state_type: a state
4995 * @shadow_type: the type of shadow to draw
4996 * @area: (allow-none): clip rectangle, or %NULL if the
4997 * output should not be clipped
4998 * @widget: (allow-none): the widget
4999 * @detail: (allow-none): a style detail
5000 * @x: x origin of the box
5001 * @y: y origin of the box
5002 * @width: the width of the box
5003 * @height: the height of the box
5005 * Draws a box on @window with the given parameters.
5008 gtk_paint_box (GtkStyle *style,
5010 GtkStateType state_type,
5011 GtkShadowType shadow_type,
5012 const GdkRectangle *area,
5014 const gchar *detail,
5020 g_return_if_fail (GTK_IS_STYLE (style));
5021 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
5022 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5024 GTK_STYLE_GET_CLASS (style)->draw_box (style, window, state_type, shadow_type,
5025 (GdkRectangle *) area, widget, detail,
5026 x, y, width, height);
5030 * gtk_paint_flat_box:
5031 * @style: a #GtkStyle
5032 * @window: a #GdkWindow
5033 * @state_type: a state
5034 * @shadow_type: the type of shadow to draw
5035 * @area: (allow-none): clip rectangle, or %NULL if the
5036 * output should not be clipped
5037 * @widget: (allow-none): the widget
5038 * @detail: (allow-none): a style detail
5039 * @x: x origin of the box
5040 * @y: y origin of the box
5041 * @width: the width of the box
5042 * @height: the height of the box
5044 * Draws a flat box on @window with the given parameters.
5047 gtk_paint_flat_box (GtkStyle *style,
5049 GtkStateType state_type,
5050 GtkShadowType shadow_type,
5051 const GdkRectangle *area,
5053 const gchar *detail,
5059 g_return_if_fail (GTK_IS_STYLE (style));
5060 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
5061 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5063 GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, window, state_type, shadow_type,
5064 (GdkRectangle *) area, widget, detail,
5065 x, y, width, height);
5070 * @style: a #GtkStyle
5071 * @window: a #GdkWindow
5072 * @state_type: a state
5073 * @shadow_type: the type of shadow to draw
5074 * @area: (allow-none): clip rectangle, or %NULL if the
5075 * output should not be clipped
5076 * @widget: (allow-none): the widget
5077 * @detail: (allow-none): a style detail
5078 * @x: x origin of the rectangle to draw the check in
5079 * @y: y origin of the rectangle to draw the check in
5080 * @width: the width of the rectangle to draw the check in
5081 * @height: the height of the rectangle to draw the check in
5083 * Draws a check button indicator in the given rectangle on @window with
5084 * the given parameters.
5087 gtk_paint_check (GtkStyle *style,
5089 GtkStateType state_type,
5090 GtkShadowType shadow_type,
5091 const GdkRectangle *area,
5093 const gchar *detail,
5099 g_return_if_fail (GTK_IS_STYLE (style));
5100 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
5101 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5103 GTK_STYLE_GET_CLASS (style)->draw_check (style, window, state_type, shadow_type,
5104 (GdkRectangle *) area, widget, detail,
5105 x, y, width, height);
5110 * @style: a #GtkStyle
5111 * @window: a #GdkWindow
5112 * @state_type: a state
5113 * @shadow_type: the type of shadow to draw
5114 * @area: (allow-none): clip rectangle, or %NULL if the
5115 * output should not be clipped
5116 * @widget: (allow-none): the widget
5117 * @detail: (allow-none): a style detail
5118 * @x: x origin of the rectangle to draw the option in
5119 * @y: y origin of the rectangle to draw the option in
5120 * @width: the width of the rectangle to draw the option in
5121 * @height: the height of the rectangle to draw the option in
5123 * Draws a radio button indicator in the given rectangle on @window with
5124 * the given parameters.
5127 gtk_paint_option (GtkStyle *style,
5129 GtkStateType state_type,
5130 GtkShadowType shadow_type,
5131 const GdkRectangle *area,
5133 const gchar *detail,
5139 g_return_if_fail (GTK_IS_STYLE (style));
5140 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
5141 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5143 GTK_STYLE_GET_CLASS (style)->draw_option (style, window, state_type, shadow_type,
5144 (GdkRectangle *) area, widget, detail,
5145 x, y, width, height);
5150 * @style: a #GtkStyle
5151 * @window: a #GdkWindow
5152 * @state_type: a state
5153 * @shadow_type: the type of shadow to draw
5154 * @area: (allow-none): clip rectangle, or %NULL if the
5155 * output should not be clipped
5156 * @widget: (allow-none): the widget
5157 * @detail: (allow-none): a style detail
5158 * @x: x origin of the rectangle to draw the tab in
5159 * @y: y origin of the rectangle to draw the tab in
5160 * @width: the width of the rectangle to draw the tab in
5161 * @height: the height of the rectangle to draw the tab in
5163 * Draws an option menu tab (i.e. the up and down pointing arrows)
5164 * in the given rectangle on @window using the given parameters.
5167 gtk_paint_tab (GtkStyle *style,
5169 GtkStateType state_type,
5170 GtkShadowType shadow_type,
5171 const GdkRectangle *area,
5173 const gchar *detail,
5179 g_return_if_fail (GTK_IS_STYLE (style));
5180 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
5181 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5183 GTK_STYLE_GET_CLASS (style)->draw_tab (style, window, state_type, shadow_type,
5184 (GdkRectangle *) area, widget, detail,
5185 x, y, width, height);
5189 * gtk_paint_shadow_gap:
5190 * @style: a #GtkStyle
5191 * @window: a #GdkWindow
5192 * @state_type: a state
5193 * @shadow_type: type of shadow to draw
5194 * @area: (allow-none): clip rectangle, or %NULL if the
5195 * output should not be clipped
5196 * @widget: (allow-none): the widget
5197 * @detail: (allow-none): a style detail
5198 * @x: x origin of the rectangle
5199 * @y: y origin of the rectangle
5200 * @width: width of the rectangle
5201 * @height: width of the rectangle
5202 * @gap_side: side in which to leave the gap
5203 * @gap_x: starting position of the gap
5204 * @gap_width: width of the gap
5206 * Draws a shadow around the given rectangle in @window
5207 * using the given style and state and shadow type, leaving a
5211 gtk_paint_shadow_gap (GtkStyle *style,
5213 GtkStateType state_type,
5214 GtkShadowType shadow_type,
5215 const GdkRectangle *area,
5217 const gchar *detail,
5222 GtkPositionType gap_side,
5226 g_return_if_fail (GTK_IS_STYLE (style));
5227 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
5228 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5230 GTK_STYLE_GET_CLASS (style)->draw_shadow_gap (style, window, state_type, shadow_type,
5231 (GdkRectangle *) area, widget, detail,
5232 x, y, width, height, gap_side, gap_x, gap_width);
5237 * gtk_paint_box_gap:
5238 * @style: a #GtkStyle
5239 * @window: a #GdkWindow
5240 * @state_type: a state
5241 * @shadow_type: type of shadow to draw
5242 * @area: (allow-none): clip rectangle, or %NULL if the
5243 * output should not be clipped
5244 * @widget: (allow-none): the widget
5245 * @detail: (allow-none): a style detail
5246 * @x: x origin of the rectangle
5247 * @y: y origin of the rectangle
5248 * @width: width of the rectangle
5249 * @height: width of the rectangle
5250 * @gap_side: side in which to leave the gap
5251 * @gap_x: starting position of the gap
5252 * @gap_width: width of the gap
5254 * Draws a box in @window using the given style and state and shadow type,
5255 * leaving a gap in one side.
5258 gtk_paint_box_gap (GtkStyle *style,
5260 GtkStateType state_type,
5261 GtkShadowType shadow_type,
5262 const GdkRectangle *area,
5264 const gchar *detail,
5269 GtkPositionType gap_side,
5273 g_return_if_fail (GTK_IS_STYLE (style));
5274 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
5275 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5277 GTK_STYLE_GET_CLASS (style)->draw_box_gap (style, window, state_type, shadow_type,
5278 (GdkRectangle *) area, widget, detail,
5279 x, y, width, height, gap_side, gap_x, gap_width);
5283 * gtk_paint_extension:
5284 * @style: a #GtkStyle
5285 * @window: a #GdkWindow
5286 * @state_type: a state
5287 * @shadow_type: type of shadow to draw
5288 * @area: (allow-none): clip rectangle, or %NULL if the
5289 * output should not be clipped
5290 * @widget: (allow-none): the widget
5291 * @detail: (allow-none): a style detail
5292 * @x: x origin of the extension
5293 * @y: y origin of the extension
5294 * @width: width of the extension
5295 * @height: width of the extension
5296 * @gap_side: the side on to which the extension is attached
5298 * Draws an extension, i.e. a notebook tab.
5301 gtk_paint_extension (GtkStyle *style,
5303 GtkStateType state_type,
5304 GtkShadowType shadow_type,
5305 const GdkRectangle *area,
5307 const gchar *detail,
5312 GtkPositionType gap_side)
5314 g_return_if_fail (GTK_IS_STYLE (style));
5315 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
5316 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5318 GTK_STYLE_GET_CLASS (style)->draw_extension (style, window, state_type, shadow_type,
5319 (GdkRectangle *) area, widget, detail,
5320 x, y, width, height, gap_side);
5325 * @style: a #GtkStyle
5326 * @window: a #GdkWindow
5327 * @state_type: a state
5328 * @area: (allow-none): clip rectangle, or %NULL if the
5329 * output should not be clipped
5330 * @widget: (allow-none): the widget
5331 * @detail: (allow-none): a style detail
5332 * @x: the x origin of the rectangle around which to draw a focus indicator
5333 * @y: the y origin of the rectangle around which to draw a focus indicator
5334 * @width: the width of the rectangle around which to draw a focus indicator
5335 * @height: the height of the rectangle around which to draw a focus indicator
5337 * Draws a focus indicator around the given rectangle on @window using the
5341 gtk_paint_focus (GtkStyle *style,
5343 GtkStateType state_type,
5344 const GdkRectangle *area,
5346 const gchar *detail,
5352 g_return_if_fail (GTK_IS_STYLE (style));
5353 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
5354 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5356 GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, state_type,
5357 (GdkRectangle *) area, widget, detail,
5358 x, y, width, height);
5363 * @style: a #GtkStyle
5364 * @window: a #GdkWindow
5365 * @state_type: a state
5366 * @shadow_type: a shadow
5367 * @area: (allow-none): clip rectangle, or %NULL if the
5368 * output should not be clipped
5369 * @widget: (allow-none): the widget
5370 * @detail: (allow-none): a style detail
5371 * @x: the x origin of the rectangle in which to draw a slider
5372 * @y: the y origin of the rectangle in which to draw a slider
5373 * @width: the width of the rectangle in which to draw a slider
5374 * @height: the height of the rectangle in which to draw a slider
5375 * @orientation: the orientation to be used
5377 * Draws a slider in the given rectangle on @window using the
5378 * given style and orientation.
5381 gtk_paint_slider (GtkStyle *style,
5383 GtkStateType state_type,
5384 GtkShadowType shadow_type,
5385 const GdkRectangle *area,
5387 const gchar *detail,
5392 GtkOrientation orientation)
5394 g_return_if_fail (GTK_IS_STYLE (style));
5395 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
5396 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5398 GTK_STYLE_GET_CLASS (style)->draw_slider (style, window, state_type, shadow_type,
5399 (GdkRectangle *) area, widget, detail,
5400 x, y, width, height, orientation);
5405 * @style: a #GtkStyle
5406 * @window: a #GdkWindow
5407 * @state_type: a state
5408 * @shadow_type: type of shadow to draw
5409 * @area: (allow-none): clip rectangle, or %NULL if the
5410 * output should not be clipped
5411 * @widget: (allow-none): the widget
5412 * @detail: (allow-none): a style detail
5413 * @x: x origin of the handle
5414 * @y: y origin of the handle
5415 * @width: with of the handle
5416 * @height: height of the handle
5417 * @orientation: the orientation of the handle
5419 * Draws a handle as used in #GtkHandleBox and #GtkPaned.
5422 gtk_paint_handle (GtkStyle *style,
5424 GtkStateType state_type,
5425 GtkShadowType shadow_type,
5426 const GdkRectangle *area,
5428 const gchar *detail,
5433 GtkOrientation orientation)
5435 g_return_if_fail (GTK_IS_STYLE (style));
5436 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
5437 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5439 GTK_STYLE_GET_CLASS (style)->draw_handle (style, window, state_type, shadow_type,
5440 (GdkRectangle *) area, widget, detail,
5441 x, y, width, height, orientation);
5445 * gtk_paint_expander:
5446 * @style: a #GtkStyle
5447 * @window: a #GdkWindow
5448 * @state_type: a state
5449 * @area: (allow-none): clip rectangle, or %NULL if the
5450 * output should not be clipped
5451 * @widget: (allow-none): the widget
5452 * @detail: (allow-none): a style detail
5453 * @x: the x position to draw the expander at
5454 * @y: the y position to draw the expander at
5455 * @expander_style: the style to draw the expander in; determines
5456 * whether the expander is collapsed, expanded, or in an
5457 * intermediate state.
5459 * Draws an expander as used in #GtkTreeView. @x and @y specify the
5460 * center the expander. The size of the expander is determined by the
5461 * "expander-size" style property of @widget. (If widget is not
5462 * specified or doesn't have an "expander-size" property, an
5463 * unspecified default size will be used, since the caller doesn't
5464 * have sufficient information to position the expander, this is
5465 * likely not useful.) The expander is expander_size pixels tall
5466 * in the collapsed position and expander_size pixels wide in the
5467 * expanded position.
5470 gtk_paint_expander (GtkStyle *style,
5472 GtkStateType state_type,
5473 const GdkRectangle *area,
5475 const gchar *detail,
5478 GtkExpanderStyle expander_style)
5480 g_return_if_fail (GTK_IS_STYLE (style));
5481 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
5482 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5484 GTK_STYLE_GET_CLASS (style)->draw_expander (style, window, state_type,
5485 (GdkRectangle *) area, widget, detail,
5486 x, y, expander_style);
5491 * @style: a #GtkStyle
5492 * @window: a #GdkWindow
5493 * @state_type: a state
5494 * @use_text: whether to use the text or foreground
5495 * graphics context of @style
5496 * @area: (allow-none): clip rectangle, or %NULL if the
5497 * output should not be clipped
5498 * @widget: (allow-none): the widget
5499 * @detail: (allow-none): a style detail
5502 * @layout: the layout to draw
5504 * Draws a layout on @window using the given parameters.
5507 gtk_paint_layout (GtkStyle *style,
5509 GtkStateType state_type,
5511 const GdkRectangle *area,
5513 const gchar *detail,
5516 PangoLayout *layout)
5518 g_return_if_fail (GTK_IS_STYLE (style));
5519 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
5520 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5522 GTK_STYLE_GET_CLASS (style)->draw_layout (style, window, state_type, use_text,
5523 (GdkRectangle *) area, widget, detail,
5528 * gtk_paint_resize_grip:
5529 * @style: a #GtkStyle
5530 * @window: a #GdkWindow
5531 * @state_type: a state
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 * @edge: the edge in which to draw the resize grip
5537 * @x: the x origin of the rectangle in which to draw the resize grip
5538 * @y: the y origin of the rectangle in which to draw the resize grip
5539 * @width: the width of the rectangle in which to draw the resize grip
5540 * @height: the height of the rectangle in which to draw the resize grip
5542 * Draws a resize grip in the given rectangle on @window using the given
5546 gtk_paint_resize_grip (GtkStyle *style,
5548 GtkStateType state_type,
5549 const GdkRectangle *area,
5551 const gchar *detail,
5559 g_return_if_fail (GTK_IS_STYLE (style));
5560 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
5561 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5563 GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, window, state_type,
5564 (GdkRectangle *) area, widget, detail,
5565 edge, x, y, width, height);
5569 * gtk_paint_spinner:
5570 * @style: a #GtkStyle
5571 * @window: a #GdkWindow
5572 * @state_type: a state
5573 * @area: (allow-none): clip rectangle, or %NULL if the
5574 * output should not be clipped
5575 * @widget: (allow-none): the widget (may be %NULL)
5576 * @detail: (allow-none): a style detail (may be %NULL)
5577 * @step: the nth step, a value between 0 and #GtkSpinner:num-steps
5578 * @x: the x origin of the rectangle in which to draw the spinner
5579 * @y: the y origin of the rectangle in which to draw the spinner
5580 * @width: the width of the rectangle in which to draw the spinner
5581 * @height: the height of the rectangle in which to draw the spinner
5583 * Draws a spinner on @window using the given parameters.
5588 gtk_paint_spinner (GtkStyle *style,
5590 GtkStateType state_type,
5591 const GdkRectangle *area,
5593 const gchar *detail,
5600 g_return_if_fail (GTK_IS_STYLE (style));
5601 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_spinner != NULL);
5602 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5604 GTK_STYLE_GET_CLASS (style)->draw_spinner (style, window, state_type,
5605 (GdkRectangle *)area, widget, detail,
5606 step, x, y, width, height);
5612 * Allocates a new #GtkBorder structure and initializes its elements to zero.
5614 * Returns: a new empty #GtkBorder. The newly allocated #GtkBorder should be
5615 * freed with gtk_border_free()
5620 gtk_border_new (void)
5622 return g_slice_new0 (GtkBorder);
5627 * @border_: a #GtkBorder.
5628 * @returns: a copy of @border_.
5630 * Copies a #GtkBorder structure.
5633 gtk_border_copy (const GtkBorder *border)
5635 g_return_val_if_fail (border != NULL, NULL);
5637 return g_slice_dup (GtkBorder, border);
5642 * @border_: a #GtkBorder.
5644 * Frees a #GtkBorder structure.
5647 gtk_border_free (GtkBorder *border)
5649 g_slice_free (GtkBorder, border);
5653 gtk_border_get_type (void)
5655 static GType our_type = 0;
5658 our_type = g_boxed_type_register_static (I_("GtkBorder"),
5659 (GBoxedCopyFunc) gtk_border_copy,
5660 (GBoxedFreeFunc) gtk_border_free);
5665 typedef struct _CursorInfo CursorInfo;
5675 style_unrealize_cursors (GtkStyle *style)
5679 cursor_info = g_object_get_data (G_OBJECT (style), "gtk-style-cursor-info");
5682 g_free (cursor_info);
5683 g_object_set_data (G_OBJECT (style), I_("gtk-style-cursor-info"), NULL);
5687 static const GdkColor *
5688 get_insertion_cursor_color (GtkWidget *widget,
5689 gboolean is_primary)
5691 CursorInfo *cursor_info;
5692 GdkColor *cursor_color;
5694 cursor_info = g_object_get_data (G_OBJECT (widget->style), "gtk-style-cursor-info");
5697 cursor_info = g_new0 (CursorInfo, 1);
5698 g_object_set_data (G_OBJECT (widget->style), I_("gtk-style-cursor-info"), cursor_info);
5699 cursor_info->for_type = G_TYPE_INVALID;
5702 /* We have to keep track of the type because gtk_widget_style_get()
5703 * can return different results when called on the same property and
5704 * same style but for different widgets. :-(. That is,
5705 * GtkEntry::cursor-color = "red" in a style will modify the cursor
5706 * color for entries but not for text view.
5708 if (cursor_info->for_type != G_OBJECT_TYPE (widget))
5710 cursor_info->for_type = G_OBJECT_TYPE (widget);
5712 /* Cursors in text widgets are drawn only in NORMAL state,
5713 * so we can use text[GTK_STATE_NORMAL] as text color here */
5714 gtk_widget_style_get (widget, "cursor-color", &cursor_color, NULL);
5717 cursor_info->primary = *cursor_color;
5718 gdk_color_free (cursor_color);
5722 cursor_info->primary = widget->style->text[GTK_STATE_NORMAL];
5725 gtk_widget_style_get (widget, "secondary-cursor-color", &cursor_color, NULL);
5728 cursor_info->secondary = *cursor_color;
5729 gdk_color_free (cursor_color);
5733 /* text_aa is the average of text and base colors,
5734 * in usual black-on-white case it's grey. */
5735 cursor_info->secondary = widget->style->text_aa[GTK_STATE_NORMAL];
5740 return &cursor_info->primary;
5742 return &cursor_info->secondary;
5746 _gtk_widget_get_cursor_color (GtkWidget *widget,
5749 GdkColor *style_color;
5751 g_return_if_fail (GTK_IS_WIDGET (widget));
5752 g_return_if_fail (color != NULL);
5754 gtk_widget_style_get (widget, "cursor-color", &style_color, NULL);
5758 *color = *style_color;
5759 gdk_color_free (style_color);
5762 *color = widget->style->text[GTK_STATE_NORMAL];
5766 draw_insertion_cursor (GtkWidget *widget,
5768 const GdkRectangle *location,
5769 GtkTextDirection direction,
5770 gboolean draw_arrow)
5775 gfloat cursor_aspect_ratio;
5778 /* When changing the shape or size of the cursor here,
5779 * propagate the changes to gtktextview.c:text_window_invalidate_cursors().
5782 gtk_widget_style_get (widget, "cursor-aspect-ratio", &cursor_aspect_ratio, NULL);
5784 stem_width = location->height * cursor_aspect_ratio + 1;
5785 arrow_width = stem_width + 1;
5787 /* put (stem_width % 2) on the proper side of the cursor */
5788 if (direction == GTK_TEXT_DIR_LTR)
5789 offset = stem_width / 2;
5791 offset = stem_width - stem_width / 2;
5793 cairo_rectangle (cr,
5794 location->x - offset, location->y,
5795 stem_width, location->height);
5800 if (direction == GTK_TEXT_DIR_RTL)
5802 x = location->x - offset - 1;
5803 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
5805 cairo_move_to (cr, x, y + 1);
5806 cairo_line_to (cr, x - arrow_width, y + arrow_width);
5807 cairo_line_to (cr, x, y + 2 * arrow_width);
5810 else if (direction == GTK_TEXT_DIR_LTR)
5812 x = location->x + stem_width - offset;
5813 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
5815 cairo_move_to (cr, x, y + 1);
5816 cairo_line_to (cr, x + arrow_width, y + arrow_width);
5817 cairo_line_to (cr, x, y + 2 * arrow_width);
5824 * gtk_draw_insertion_cursor:
5825 * @widget: a #GtkWidget
5826 * @drawable: a #GdkDrawable
5827 * @area: (allow-none): rectangle to which the output is clipped, or %NULL if the
5828 * output should not be clipped
5829 * @location: location where to draw the cursor (@location->width is ignored)
5830 * @is_primary: if the cursor should be the primary cursor color.
5831 * @direction: whether the cursor is left-to-right or
5832 * right-to-left. Should never be #GTK_TEXT_DIR_NONE
5833 * @draw_arrow: %TRUE to draw a directional arrow on the
5834 * cursor. Should be %FALSE unless the cursor is split.
5836 * Draws a text caret on @drawable at @location. This is not a style function
5837 * but merely a convenience function for drawing the standard cursor shape.
5842 gtk_draw_insertion_cursor (GtkWidget *widget,
5843 GdkDrawable *drawable,
5844 const GdkRectangle *area,
5845 const GdkRectangle *location,
5846 gboolean is_primary,
5847 GtkTextDirection direction,
5848 gboolean draw_arrow)
5852 g_return_if_fail (GTK_IS_WIDGET (widget));
5853 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
5854 g_return_if_fail (location != NULL);
5855 g_return_if_fail (direction != GTK_TEXT_DIR_NONE);
5857 cr = gdk_cairo_create (drawable);
5860 gdk_cairo_rectangle (cr, area);
5864 gdk_cairo_set_source_color (cr, get_insertion_cursor_color (widget, is_primary));
5865 draw_insertion_cursor (widget, cr, location, direction, draw_arrow);