1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
31 #include <gobject/gvaluecollector.h>
32 #include "gtkmarshalers.h"
35 #include "gtkspinbutton.h"
37 #include "gtkwidget.h"
38 #include "gtkthemes.h"
39 #include "gtkiconfactory.h"
40 #include "gtksettings.h" /* _gtk_settings_parse_convert() */
42 #include "gtkspinner.h"
47 * @Short_description: An object that hold style information for widgets
50 * A #GtkStyle object encapsulates the information that provides the look and
51 * feel for a widget. Each #GtkWidget has an associated #GTkStyle object that
52 * is used when rendering that widget. Also, a #GtkStyle holds information for
53 * the five possible widget states though not every widget supports all five
54 * states; see #GtkStateType.
56 * Usually the #GtkStyle for a widget is the same as the default style that is
57 * set by GTK+ and modified the theme engine.
59 * Usually applications should not need to use or modify the #GtkStyle of their
64 #define LIGHTNESS_MULT 1.3
65 #define DARKNESS_MULT 0.7
67 /* --- typedefs & structures --- */
74 #define GTK_STYLE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_STYLE, GtkStylePrivate))
76 typedef struct _GtkStylePrivate GtkStylePrivate;
78 struct _GtkStylePrivate {
82 /* --- prototypes --- */
83 static void gtk_style_finalize (GObject *object);
84 static void gtk_style_realize (GtkStyle *style,
86 static void gtk_style_real_realize (GtkStyle *style);
87 static void gtk_style_real_unrealize (GtkStyle *style);
88 static void gtk_style_real_copy (GtkStyle *style,
90 static void gtk_style_real_set_background (GtkStyle *style,
92 GtkStateType state_type);
93 static GtkStyle *gtk_style_real_clone (GtkStyle *style);
94 static void gtk_style_real_init_from_rc (GtkStyle *style,
95 GtkRcStyle *rc_style);
96 static GdkPixbuf *gtk_default_render_icon (GtkStyle *style,
97 const GtkIconSource *source,
98 GtkTextDirection direction,
102 const gchar *detail);
103 static void gtk_default_draw_hline (GtkStyle *style,
105 GtkStateType state_type,
111 static void gtk_default_draw_vline (GtkStyle *style,
113 GtkStateType state_type,
119 static void gtk_default_draw_shadow (GtkStyle *style,
121 GtkStateType state_type,
122 GtkShadowType shadow_type,
129 static void gtk_default_draw_arrow (GtkStyle *style,
131 GtkStateType state_type,
132 GtkShadowType shadow_type,
135 GtkArrowType arrow_type,
141 static void gtk_default_draw_diamond (GtkStyle *style,
143 GtkStateType state_type,
144 GtkShadowType shadow_type,
151 static void gtk_default_draw_box (GtkStyle *style,
153 GtkStateType state_type,
154 GtkShadowType shadow_type,
161 static void gtk_default_draw_flat_box (GtkStyle *style,
163 GtkStateType state_type,
164 GtkShadowType shadow_type,
171 static void gtk_default_draw_check (GtkStyle *style,
173 GtkStateType state_type,
174 GtkShadowType shadow_type,
181 static void gtk_default_draw_option (GtkStyle *style,
183 GtkStateType state_type,
184 GtkShadowType shadow_type,
191 static void gtk_default_draw_tab (GtkStyle *style,
193 GtkStateType state_type,
194 GtkShadowType shadow_type,
201 static void gtk_default_draw_shadow_gap (GtkStyle *style,
203 GtkStateType state_type,
204 GtkShadowType shadow_type,
211 GtkPositionType gap_side,
214 static void gtk_default_draw_box_gap (GtkStyle *style,
216 GtkStateType state_type,
217 GtkShadowType shadow_type,
224 GtkPositionType gap_side,
227 static void gtk_default_draw_extension (GtkStyle *style,
229 GtkStateType state_type,
230 GtkShadowType shadow_type,
237 GtkPositionType gap_side);
238 static void gtk_default_draw_focus (GtkStyle *style,
240 GtkStateType state_type,
247 static void gtk_default_draw_slider (GtkStyle *style,
249 GtkStateType state_type,
250 GtkShadowType shadow_type,
257 GtkOrientation orientation);
258 static void gtk_default_draw_handle (GtkStyle *style,
260 GtkStateType state_type,
261 GtkShadowType shadow_type,
268 GtkOrientation orientation);
269 static void gtk_default_draw_expander (GtkStyle *style,
271 GtkStateType state_type,
276 GtkExpanderStyle expander_style);
277 static void gtk_default_draw_layout (GtkStyle *style,
279 GtkStateType state_type,
285 PangoLayout *layout);
286 static void gtk_default_draw_resize_grip (GtkStyle *style,
288 GtkStateType state_type,
296 static void gtk_default_draw_spinner (GtkStyle *style,
298 GtkStateType state_type,
307 static void rgb_to_hls (gdouble *r,
310 static void hls_to_rgb (gdouble *h,
314 static void style_unrealize_cursors (GtkStyle *style);
317 * Data for default check and radio buttons
320 static const GtkRequisition default_option_indicator_size = { 7, 13 };
321 static const GtkBorder default_option_indicator_spacing = { 7, 5, 2, 2 };
323 #define GTK_GRAY 0xdcdc, 0xdada, 0xd5d5
324 #define GTK_DARK_GRAY 0xc4c4, 0xc2c2, 0xbdbd
325 #define GTK_LIGHT_GRAY 0xeeee, 0xebeb, 0xe7e7
326 #define GTK_WHITE 0xffff, 0xffff, 0xffff
327 #define GTK_BLUE 0x4b4b, 0x6969, 0x8383
328 #define GTK_VERY_DARK_GRAY 0x9c9c, 0x9a9a, 0x9494
329 #define GTK_BLACK 0x0000, 0x0000, 0x0000
330 #define GTK_WEAK_GRAY 0x7530, 0x7530, 0x7530
332 /* --- variables --- */
333 static const GdkColor gtk_default_normal_fg = { 0, GTK_BLACK };
334 static const GdkColor gtk_default_active_fg = { 0, GTK_BLACK };
335 static const GdkColor gtk_default_prelight_fg = { 0, GTK_BLACK };
336 static const GdkColor gtk_default_selected_fg = { 0, GTK_WHITE };
337 static const GdkColor gtk_default_insensitive_fg = { 0, GTK_WEAK_GRAY };
339 static const GdkColor gtk_default_normal_bg = { 0, GTK_GRAY };
340 static const GdkColor gtk_default_active_bg = { 0, GTK_DARK_GRAY };
341 static const GdkColor gtk_default_prelight_bg = { 0, GTK_LIGHT_GRAY };
342 static const GdkColor gtk_default_selected_bg = { 0, GTK_BLUE };
343 static const GdkColor gtk_default_insensitive_bg = { 0, GTK_GRAY };
344 static const GdkColor gtk_default_selected_base = { 0, GTK_BLUE };
345 static const GdkColor gtk_default_active_base = { 0, GTK_VERY_DARK_GRAY };
347 /* --- signals --- */
348 static guint realize_signal = 0;
349 static guint unrealize_signal = 0;
351 G_DEFINE_TYPE (GtkStyle, gtk_style, G_TYPE_OBJECT)
353 /* --- functions --- */
356 * _gtk_style_init_for_settings:
357 * @style: a #GtkStyle
358 * @settings: a #GtkSettings
360 * Initializes the font description in @style according to the default
361 * font name of @settings. This is called for gtk_style_new() with
362 * the settings for the default screen (if any); if we are creating
363 * a style for a particular screen, we then call it again in a
364 * location where we know the correct settings.
365 * The reason for this is that gtk_rc_style_create_style() doesn't
366 * take the screen for an argument.
369 _gtk_style_init_for_settings (GtkStyle *style,
370 GtkSettings *settings)
372 const gchar *font_name = _gtk_rc_context_get_default_font_name (settings);
374 if (style->font_desc)
375 pango_font_description_free (style->font_desc);
377 style->font_desc = pango_font_description_from_string (font_name);
379 if (!pango_font_description_get_family (style->font_desc))
381 g_warning ("Default font does not have a family set");
382 pango_font_description_set_family (style->font_desc, "Sans");
384 if (pango_font_description_get_size (style->font_desc) <= 0)
386 g_warning ("Default font does not have a positive size");
387 pango_font_description_set_size (style->font_desc, 10 * PANGO_SCALE);
392 gtk_style_init (GtkStyle *style)
396 GtkSettings *settings = gtk_settings_get_default ();
399 _gtk_style_init_for_settings (style, settings);
401 style->font_desc = pango_font_description_from_string ("Sans 10");
403 style->attach_count = 0;
405 style->black.red = 0;
406 style->black.green = 0;
407 style->black.blue = 0;
409 style->white.red = 65535;
410 style->white.green = 65535;
411 style->white.blue = 65535;
413 style->fg[GTK_STATE_NORMAL] = gtk_default_normal_fg;
414 style->fg[GTK_STATE_ACTIVE] = gtk_default_active_fg;
415 style->fg[GTK_STATE_PRELIGHT] = gtk_default_prelight_fg;
416 style->fg[GTK_STATE_SELECTED] = gtk_default_selected_fg;
417 style->fg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
419 style->bg[GTK_STATE_NORMAL] = gtk_default_normal_bg;
420 style->bg[GTK_STATE_ACTIVE] = gtk_default_active_bg;
421 style->bg[GTK_STATE_PRELIGHT] = gtk_default_prelight_bg;
422 style->bg[GTK_STATE_SELECTED] = gtk_default_selected_bg;
423 style->bg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_bg;
425 for (i = 0; i < 4; i++)
427 style->text[i] = style->fg[i];
428 style->base[i] = style->white;
431 style->base[GTK_STATE_SELECTED] = gtk_default_selected_base;
432 style->text[GTK_STATE_SELECTED] = style->white;
433 style->base[GTK_STATE_ACTIVE] = gtk_default_active_base;
434 style->text[GTK_STATE_ACTIVE] = style->white;
435 style->base[GTK_STATE_INSENSITIVE] = gtk_default_prelight_bg;
436 style->text[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
438 style->rc_style = NULL;
440 style->xthickness = 2;
441 style->ythickness = 2;
443 style->property_cache = NULL;
447 gtk_style_class_init (GtkStyleClass *klass)
449 GObjectClass *object_class = G_OBJECT_CLASS (klass);
451 object_class->finalize = gtk_style_finalize;
453 klass->clone = gtk_style_real_clone;
454 klass->copy = gtk_style_real_copy;
455 klass->init_from_rc = gtk_style_real_init_from_rc;
456 klass->realize = gtk_style_real_realize;
457 klass->unrealize = gtk_style_real_unrealize;
458 klass->set_background = gtk_style_real_set_background;
459 klass->render_icon = gtk_default_render_icon;
461 klass->draw_hline = gtk_default_draw_hline;
462 klass->draw_vline = gtk_default_draw_vline;
463 klass->draw_shadow = gtk_default_draw_shadow;
464 klass->draw_arrow = gtk_default_draw_arrow;
465 klass->draw_diamond = gtk_default_draw_diamond;
466 klass->draw_box = gtk_default_draw_box;
467 klass->draw_flat_box = gtk_default_draw_flat_box;
468 klass->draw_check = gtk_default_draw_check;
469 klass->draw_option = gtk_default_draw_option;
470 klass->draw_tab = gtk_default_draw_tab;
471 klass->draw_shadow_gap = gtk_default_draw_shadow_gap;
472 klass->draw_box_gap = gtk_default_draw_box_gap;
473 klass->draw_extension = gtk_default_draw_extension;
474 klass->draw_focus = gtk_default_draw_focus;
475 klass->draw_slider = gtk_default_draw_slider;
476 klass->draw_handle = gtk_default_draw_handle;
477 klass->draw_expander = gtk_default_draw_expander;
478 klass->draw_layout = gtk_default_draw_layout;
479 klass->draw_resize_grip = gtk_default_draw_resize_grip;
480 klass->draw_spinner = gtk_default_draw_spinner;
482 g_type_class_add_private (object_class, sizeof (GtkStylePrivate));
486 * @style: the object which received the signal
488 * Emitted when the style has been initialized for a particular
489 * visual. Connecting to this signal is probably seldom
490 * useful since most of the time applications and widgets only
491 * deal with styles that have been already realized.
495 realize_signal = g_signal_new (I_("realize"),
496 G_TYPE_FROM_CLASS (object_class),
498 G_STRUCT_OFFSET (GtkStyleClass, realize),
500 _gtk_marshal_VOID__VOID,
503 * GtkStyle::unrealize:
504 * @style: the object which received the signal
506 * Emitted when the aspects of the style specific to a particular visual
507 * is being cleaned up. A connection to this signal can be useful
508 * if a widget wants to cache objects as object data on #GtkStyle.
509 * This signal provides a convenient place to free such cached objects.
513 unrealize_signal = g_signal_new (I_("unrealize"),
514 G_TYPE_FROM_CLASS (object_class),
516 G_STRUCT_OFFSET (GtkStyleClass, unrealize),
518 _gtk_marshal_VOID__VOID,
523 clear_property_cache (GtkStyle *style)
525 if (style->property_cache)
529 for (i = 0; i < style->property_cache->len; i++)
531 PropertyValue *node = &g_array_index (style->property_cache, PropertyValue, i);
533 g_param_spec_unref (node->pspec);
534 g_value_unset (&node->value);
536 g_array_free (style->property_cache, TRUE);
537 style->property_cache = NULL;
542 gtk_style_finalize (GObject *object)
544 GtkStyle *style = GTK_STYLE (object);
545 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
547 g_return_if_fail (style->attach_count == 0);
549 clear_property_cache (style);
551 /* All the styles in the list have the same
552 * style->styles pointer. If we delete the
553 * *first* style from the list, we need to update
554 * the style->styles pointers from all the styles.
555 * Otherwise we simply remove the node from
560 if (style->styles->data != style)
561 style->styles = g_slist_remove (style->styles, style);
564 GSList *tmp_list = style->styles->next;
568 GTK_STYLE (tmp_list->data)->styles = style->styles->next;
569 tmp_list = tmp_list->next;
571 g_slist_free_1 (style->styles);
575 g_slist_foreach (style->icon_factories, (GFunc) g_object_unref, NULL);
576 g_slist_free (style->icon_factories);
578 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_unref, NULL);
579 g_slist_free (priv->color_hashes);
581 pango_font_description_free (style->font_desc);
583 if (style->private_font_desc)
584 pango_font_description_free (style->private_font_desc);
587 g_object_unref (style->rc_style);
589 G_OBJECT_CLASS (gtk_style_parent_class)->finalize (object);
595 * @style: a #GtkStyle
597 * Creates a copy of the passed in #GtkStyle object.
599 * Returns: (transfer full): a copy of @style
602 gtk_style_copy (GtkStyle *style)
606 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
608 new_style = GTK_STYLE_GET_CLASS (style)->clone (style);
609 GTK_STYLE_GET_CLASS (style)->copy (new_style, style);
615 gtk_style_duplicate (GtkStyle *style)
619 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
621 new_style = gtk_style_copy (style);
623 /* All the styles in the list have the same
624 * style->styles pointer. When we insert a new
625 * style, we append it to the list to avoid having
626 * to update the existing ones.
628 style->styles = g_slist_append (style->styles, new_style);
629 new_style->styles = style->styles;
636 * @returns: a new #GtkStyle.
638 * Creates a new #GtkStyle.
645 style = g_object_new (GTK_TYPE_STYLE, NULL);
652 * @style: a #GtkStyle.
653 * @window: a #GdkWindow.
655 * Attaches a style to a window; this process allocates the
656 * colors and creates the GC's for the style - it specializes
657 * it to a particular visual. The process may involve the creation
658 * of a new style if the style has already been attached to a
659 * window with a different style and visual.
661 * Since this function may return a new object, you have to use it
662 * in the following way:
663 * <literal>style = gtk_style_attach (style, window)</literal>
665 * Returns: Either @style, or a newly-created #GtkStyle.
666 * If the style is newly created, the style parameter
667 * will be unref'ed, and the new style will have
668 * a reference count belonging to the caller.
671 gtk_style_attach (GtkStyle *style,
675 GtkStyle *new_style = NULL;
678 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
679 g_return_val_if_fail (window != NULL, NULL);
681 visual = gdk_window_get_visual (window);
684 style->styles = g_slist_append (NULL, style);
686 styles = style->styles;
689 new_style = styles->data;
691 if (new_style->visual == visual)
695 styles = styles->next;
700 styles = style->styles;
704 new_style = styles->data;
706 if (new_style->attach_count == 0)
708 gtk_style_realize (new_style, visual);
713 styles = styles->next;
719 new_style = gtk_style_duplicate (style);
720 gtk_style_realize (new_style, visual);
723 /* A style gets a refcount from being attached */
724 if (new_style->attach_count == 0)
725 g_object_ref (new_style);
727 /* Another refcount belongs to the parent */
728 if (style != new_style)
730 g_object_unref (style);
731 g_object_ref (new_style);
734 new_style->attach_count++;
741 * @style: a #GtkStyle
743 * Detaches a style from a window. If the style is not attached
744 * to any windows anymore, it is unrealized. See gtk_style_attach().
748 gtk_style_detach (GtkStyle *style)
750 g_return_if_fail (GTK_IS_STYLE (style));
751 g_return_if_fail (style->attach_count > 0);
753 style->attach_count -= 1;
754 if (style->attach_count == 0)
756 g_signal_emit (style, unrealize_signal, 0);
758 g_object_unref (style->visual);
759 style->visual = NULL;
761 if (style->private_font_desc)
763 pango_font_description_free (style->private_font_desc);
764 style->private_font_desc = NULL;
767 g_object_unref (style);
772 gtk_style_realize (GtkStyle *style,
775 style->visual = g_object_ref (visual);
777 g_signal_emit (style, realize_signal, 0);
781 * gtk_style_lookup_icon_set:
782 * @style: a #GtkStyle
783 * @stock_id: an icon name
785 * Looks up @stock_id in the icon factories associated with @style
786 * and the default icon factory, returning an icon set if found,
789 * Return value: icon set of @stock_id
792 gtk_style_lookup_icon_set (GtkStyle *style,
793 const char *stock_id)
797 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
798 g_return_val_if_fail (stock_id != NULL, NULL);
800 iter = style->icon_factories;
803 GtkIconSet *icon_set = gtk_icon_factory_lookup (GTK_ICON_FACTORY (iter->data),
808 iter = g_slist_next (iter);
811 return gtk_icon_factory_lookup_default (stock_id);
815 * gtk_style_lookup_color:
816 * @style: a #GtkStyle
817 * @color_name: the name of the logical color to look up
818 * @color: the #GdkColor to fill in
820 * Looks up @color_name in the style's logical color mappings,
821 * filling in @color and returning %TRUE if found, otherwise
822 * returning %FALSE. Do not cache the found mapping, because
823 * it depends on the #GtkStyle and might change when a theme
826 * Return value: %TRUE if the mapping was found.
831 gtk_style_lookup_color (GtkStyle *style,
832 const char *color_name,
835 GtkStylePrivate *priv;
838 g_return_val_if_fail (GTK_IS_STYLE (style), FALSE);
839 g_return_val_if_fail (color_name != NULL, FALSE);
840 g_return_val_if_fail (color != NULL, FALSE);
842 priv = GTK_STYLE_GET_PRIVATE (style);
844 for (iter = priv->color_hashes; iter != NULL; iter = iter->next)
846 GHashTable *hash = iter->data;
847 GdkColor *mapping = g_hash_table_lookup (hash, color_name);
851 color->red = mapping->red;
852 color->green = mapping->green;
853 color->blue = mapping->blue;
862 * gtk_style_set_background:
863 * @style: a #GtkStyle
864 * @window: a #GdkWindow
865 * @state_type: a state
867 * Sets the background of @window to the background color or pixmap
868 * specified by @style for the given state.
871 gtk_style_set_background (GtkStyle *style,
873 GtkStateType state_type)
875 g_return_if_fail (GTK_IS_STYLE (style));
876 g_return_if_fail (window != NULL);
878 GTK_STYLE_GET_CLASS (style)->set_background (style, window, state_type);
881 /* Default functions */
883 gtk_style_real_clone (GtkStyle *style)
885 return g_object_new (G_OBJECT_TYPE (style), NULL);
889 gtk_style_real_copy (GtkStyle *style,
892 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
893 GtkStylePrivate *src_priv = GTK_STYLE_GET_PRIVATE (src);
896 for (i = 0; i < 5; i++)
898 style->fg[i] = src->fg[i];
899 style->bg[i] = src->bg[i];
900 style->text[i] = src->text[i];
901 style->base[i] = src->base[i];
903 if (style->background[i])
904 cairo_pattern_destroy (style->background[i]),
905 style->background[i] = src->background[i];
906 if (style->background[i])
907 cairo_pattern_reference (style->background[i]);
910 if (style->font_desc)
911 pango_font_description_free (style->font_desc);
913 style->font_desc = pango_font_description_copy (src->font_desc);
915 style->font_desc = NULL;
917 style->xthickness = src->xthickness;
918 style->ythickness = src->ythickness;
921 g_object_unref (style->rc_style);
922 style->rc_style = src->rc_style;
924 g_object_ref (src->rc_style);
926 g_slist_foreach (style->icon_factories, (GFunc) g_object_unref, NULL);
927 g_slist_free (style->icon_factories);
928 style->icon_factories = g_slist_copy (src->icon_factories);
929 g_slist_foreach (style->icon_factories, (GFunc) g_object_ref, NULL);
931 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_unref, NULL);
932 g_slist_free (priv->color_hashes);
933 priv->color_hashes = g_slist_copy (src_priv->color_hashes);
934 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_ref, NULL);
936 /* don't copy, just clear cache */
937 clear_property_cache (style);
941 gtk_style_real_init_from_rc (GtkStyle *style,
942 GtkRcStyle *rc_style)
944 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
947 /* cache _should_ be still empty */
948 clear_property_cache (style);
950 if (rc_style->font_desc)
951 pango_font_description_merge (style->font_desc, rc_style->font_desc, TRUE);
953 for (i = 0; i < 5; i++)
955 if (rc_style->color_flags[i] & GTK_RC_FG)
956 style->fg[i] = rc_style->fg[i];
957 if (rc_style->color_flags[i] & GTK_RC_BG)
958 style->bg[i] = rc_style->bg[i];
959 if (rc_style->color_flags[i] & GTK_RC_TEXT)
960 style->text[i] = rc_style->text[i];
961 if (rc_style->color_flags[i] & GTK_RC_BASE)
962 style->base[i] = rc_style->base[i];
965 if (rc_style->xthickness >= 0)
966 style->xthickness = rc_style->xthickness;
967 if (rc_style->ythickness >= 0)
968 style->ythickness = rc_style->ythickness;
970 style->icon_factories = g_slist_copy (rc_style->icon_factories);
971 g_slist_foreach (style->icon_factories, (GFunc) g_object_ref, NULL);
973 priv->color_hashes = g_slist_copy (_gtk_rc_style_get_color_hashes (rc_style));
974 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_ref, NULL);
978 style_property_values_cmp (gconstpointer bsearch_node1,
979 gconstpointer bsearch_node2)
981 const PropertyValue *val1 = bsearch_node1;
982 const PropertyValue *val2 = bsearch_node2;
984 if (val1->widget_type == val2->widget_type)
985 return val1->pspec < val2->pspec ? -1 : val1->pspec == val2->pspec ? 0 : 1;
987 return val1->widget_type < val2->widget_type ? -1 : 1;
991 * gtk_style_get_style_property:
992 * @style: a #GtkStyle
993 * @widget_type: the #GType of a descendant of #GtkWidget
994 * @property_name: the name of the style property to get
995 * @value: a #GValue where the value of the property being
996 * queried will be stored
998 * Queries the value of a style property corresponding to a
999 * widget class is in the given style.
1004 gtk_style_get_style_property (GtkStyle *style,
1006 const gchar *property_name,
1009 GtkWidgetClass *klass;
1011 GtkRcPropertyParser parser;
1012 const GValue *peek_value;
1014 klass = g_type_class_ref (widget_type);
1015 pspec = gtk_widget_class_find_style_property (klass, property_name);
1016 g_type_class_unref (klass);
1020 g_warning ("%s: widget class `%s' has no property named `%s'",
1022 g_type_name (widget_type),
1027 parser = g_param_spec_get_qdata (pspec,
1028 g_quark_from_static_string ("gtk-rc-property-parser"));
1030 peek_value = _gtk_style_peek_property_value (style, widget_type, pspec, parser);
1032 if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec))
1033 g_value_copy (peek_value, value);
1034 else if (g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
1035 g_value_transform (peek_value, value);
1037 g_warning ("can't retrieve style property `%s' of type `%s' as value of type `%s'",
1039 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1040 G_VALUE_TYPE_NAME (value));
1044 * gtk_style_get_valist:
1045 * @style: a #GtkStyle
1046 * @widget_type: the #GType of a descendant of #GtkWidget
1047 * @first_property_name: the name of the first style property to get
1048 * @var_args: a <type>va_list</type> of pairs of property names and
1049 * locations to return the property values, starting with the
1050 * location for @first_property_name.
1052 * Non-vararg variant of gtk_style_get().
1053 * Used primarily by language bindings.
1058 gtk_style_get_valist (GtkStyle *style,
1060 const gchar *first_property_name,
1063 const char *property_name;
1064 GtkWidgetClass *klass;
1066 g_return_if_fail (GTK_IS_STYLE (style));
1068 klass = g_type_class_ref (widget_type);
1070 property_name = first_property_name;
1071 while (property_name)
1074 GtkRcPropertyParser parser;
1075 const GValue *peek_value;
1078 pspec = gtk_widget_class_find_style_property (klass, property_name);
1082 g_warning ("%s: widget class `%s' has no property named `%s'",
1084 g_type_name (widget_type),
1089 parser = g_param_spec_get_qdata (pspec,
1090 g_quark_from_static_string ("gtk-rc-property-parser"));
1092 peek_value = _gtk_style_peek_property_value (style, widget_type, pspec, parser);
1093 G_VALUE_LCOPY (peek_value, var_args, 0, &error);
1096 g_warning ("%s: %s", G_STRLOC, error);
1101 property_name = va_arg (var_args, gchar*);
1104 g_type_class_unref (klass);
1109 * @style: a #GtkStyle
1110 * @widget_type: the #GType of a descendant of #GtkWidget
1111 * @first_property_name: the name of the first style property to get
1112 * @Varargs: pairs of property names and locations to
1113 * return the property values, starting with the location for
1114 * @first_property_name, terminated by %NULL.
1116 * Gets the values of a multiple style properties for @widget_type
1122 gtk_style_get (GtkStyle *style,
1124 const gchar *first_property_name,
1129 va_start (var_args, first_property_name);
1130 gtk_style_get_valist (style, widget_type, first_property_name, var_args);
1135 _gtk_style_peek_property_value (GtkStyle *style,
1138 GtkRcPropertyParser parser)
1140 PropertyValue *pcache, key = { 0, NULL, { 0, } };
1141 const GtkRcProperty *rcprop = NULL;
1144 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1145 g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL);
1146 g_return_val_if_fail (g_type_is_a (pspec->owner_type, GTK_TYPE_WIDGET), NULL);
1147 g_return_val_if_fail (g_type_is_a (widget_type, pspec->owner_type), NULL);
1149 key.widget_type = widget_type;
1152 /* need value cache array */
1153 if (!style->property_cache)
1154 style->property_cache = g_array_new (FALSE, FALSE, sizeof (PropertyValue));
1157 pcache = bsearch (&key,
1158 style->property_cache->data, style->property_cache->len,
1159 sizeof (PropertyValue), style_property_values_cmp);
1161 return &pcache->value;
1165 while (i < style->property_cache->len &&
1166 style_property_values_cmp (&key, &g_array_index (style->property_cache, PropertyValue, i)) >= 0)
1169 g_array_insert_val (style->property_cache, i, key);
1170 pcache = &g_array_index (style->property_cache, PropertyValue, i);
1172 /* cache miss, initialize value type, then set contents */
1173 g_param_spec_ref (pcache->pspec);
1174 g_value_init (&pcache->value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1176 /* value provided by rc style? */
1177 if (style->rc_style)
1179 GQuark prop_quark = g_quark_from_string (pspec->name);
1183 rcprop = _gtk_rc_style_lookup_rc_property (style->rc_style,
1184 g_type_qname (widget_type),
1188 widget_type = g_type_parent (widget_type);
1190 while (g_type_is_a (widget_type, pspec->owner_type));
1193 /* when supplied by rc style, we need to convert */
1194 if (rcprop && !_gtk_settings_parse_convert (parser, &rcprop->value,
1195 pspec, &pcache->value))
1197 gchar *contents = g_strdup_value_contents (&rcprop->value);
1199 g_message ("%s: failed to retrieve property `%s::%s' of type `%s' from rc file value \"%s\" of type `%s'",
1200 rcprop->origin ? rcprop->origin : "(for origin information, set GTK_DEBUG)",
1201 g_type_name (pspec->owner_type), pspec->name,
1202 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1204 G_VALUE_TYPE_NAME (&rcprop->value));
1206 rcprop = NULL; /* needs default */
1209 /* not supplied by rc style (or conversion failed), revert to default */
1211 g_param_value_set_default (pspec, &pcache->value);
1213 return &pcache->value;
1216 static cairo_pattern_t *
1217 load_background (GdkVisual *visual,
1219 const gchar *filename)
1221 if (filename == NULL)
1223 return cairo_pattern_create_rgb (bg_color->red / 65535.0,
1224 bg_color->green / 65535.0,
1225 bg_color->blue / 65535.0);
1227 if (strcmp (filename, "<parent>") == 0)
1232 cairo_surface_t *surface;
1233 cairo_pattern_t *pattern;
1235 GdkScreen *screen = gdk_visual_get_screen (visual);
1237 pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
1241 surface = gdk_window_create_similar_surface (gdk_screen_get_root_window (screen),
1242 CAIRO_CONTENT_COLOR,
1243 gdk_pixbuf_get_width (pixbuf),
1244 gdk_pixbuf_get_height (pixbuf));
1246 cr = cairo_create (surface);
1248 gdk_cairo_set_source_color (cr, bg_color);
1251 gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
1255 g_object_unref (pixbuf);
1257 pattern = cairo_pattern_create_for_surface (surface);
1259 cairo_surface_destroy (surface);
1266 gtk_style_real_realize (GtkStyle *style)
1270 for (i = 0; i < 5; i++)
1272 _gtk_style_shade (&style->bg[i], &style->light[i], LIGHTNESS_MULT);
1273 _gtk_style_shade (&style->bg[i], &style->dark[i], DARKNESS_MULT);
1275 style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
1276 style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
1277 style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
1279 style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
1280 style->text_aa[i].green = (style->text[i].green + style->base[i].green) / 2;
1281 style->text_aa[i].blue = (style->text[i].blue + style->base[i].blue) / 2;
1284 style->black.red = 0x0000;
1285 style->black.green = 0x0000;
1286 style->black.blue = 0x0000;
1288 style->white.red = 0xffff;
1289 style->white.green = 0xffff;
1290 style->white.blue = 0xffff;
1292 for (i = 0; i < 5; i++)
1294 const char *image_name;
1296 if (style->rc_style)
1297 image_name = style->rc_style->bg_pixmap_name[i];
1301 style->background[i] = load_background (style->visual,
1308 gtk_style_real_unrealize (GtkStyle *style)
1312 for (i = 0; i < 5; i++)
1314 if (style->background[i])
1316 cairo_pattern_destroy (style->background[i]);
1317 style->background[i] = NULL;
1322 style_unrealize_cursors (style);
1326 gtk_style_real_set_background (GtkStyle *style,
1328 GtkStateType state_type)
1330 gdk_window_set_background_pattern (window, style->background[state_type]);
1334 * gtk_style_render_icon:
1335 * @style: a #GtkStyle
1336 * @source: the #GtkIconSource specifying the icon to render
1337 * @direction: a text direction
1339 * @size: (type int): the size to render the icon at. A size of
1340 * (GtkIconSize)-1 means render at the size of the source and
1342 * @widget: (allow-none): the widget
1343 * @detail: (allow-none): a style detail
1345 * Renders the icon specified by @source at the given @size
1346 * according to the given parameters and returns the result in a
1349 * Return value: (transfer full): a newly-created #GdkPixbuf
1350 * containing the rendered icon
1353 gtk_style_render_icon (GtkStyle *style,
1354 const GtkIconSource *source,
1355 GtkTextDirection direction,
1359 const gchar *detail)
1363 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1364 g_return_val_if_fail (GTK_STYLE_GET_CLASS (style)->render_icon != NULL, NULL);
1366 pixbuf = GTK_STYLE_GET_CLASS (style)->render_icon (style, source, direction, state,
1367 size, widget, detail);
1369 g_return_val_if_fail (pixbuf != NULL, NULL);
1374 /* Default functions */
1377 * gtk_style_apply_default_background:
1383 * @area: (allow-none):
1390 gtk_style_apply_default_background (GtkStyle *style,
1393 GtkStateType state_type,
1401 if (style->background[state_type] == NULL)
1403 GdkWindow *parent = gdk_window_get_parent (window);
1404 int x_offset, y_offset;
1408 gdk_window_get_position (window, &x_offset, &y_offset);
1409 cairo_translate (cr, -x_offset, -y_offset);
1410 gtk_style_apply_default_background (style, cr,
1412 x + x_offset, y + y_offset,
1417 gdk_cairo_set_source_color (cr, &style->bg[state_type]);
1420 cairo_set_source (cr, style->background[state_type]);
1422 cairo_rectangle (cr, x, y, width, height);
1430 scale_or_ref (GdkPixbuf *src,
1434 if (width == gdk_pixbuf_get_width (src) &&
1435 height == gdk_pixbuf_get_height (src))
1437 return g_object_ref (src);
1441 return gdk_pixbuf_scale_simple (src,
1443 GDK_INTERP_BILINEAR);
1448 lookup_icon_size (GtkStyle *style,
1455 GtkSettings *settings;
1457 if (widget && gtk_widget_has_screen (widget))
1459 screen = gtk_widget_get_screen (widget);
1460 settings = gtk_settings_get_for_screen (screen);
1462 else if (style && style->visual)
1464 screen = gdk_visual_get_screen (style->visual);
1465 settings = gtk_settings_get_for_screen (screen);
1469 settings = gtk_settings_get_default ();
1470 GTK_NOTE (MULTIHEAD,
1471 g_warning ("Using the default screen for gtk_default_render_icon()"));
1474 return gtk_icon_size_lookup_for_settings (settings, size, width, height);
1478 gtk_default_render_icon (GtkStyle *style,
1479 const GtkIconSource *source,
1480 GtkTextDirection direction,
1484 const gchar *detail)
1490 GdkPixbuf *base_pixbuf;
1492 /* Oddly, style can be NULL in this function, because
1493 * GtkIconSet can be used without a style and if so
1494 * it uses this function.
1497 base_pixbuf = gtk_icon_source_get_pixbuf (source);
1499 g_return_val_if_fail (base_pixbuf != NULL, NULL);
1501 if (size != (GtkIconSize) -1 && !lookup_icon_size(style, widget, size, &width, &height))
1503 g_warning (G_STRLOC ": invalid icon size '%d'", size);
1507 /* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
1510 if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source))
1511 scaled = scale_or_ref (base_pixbuf, width, height);
1513 scaled = g_object_ref (base_pixbuf);
1515 /* If the state was wildcarded, then generate a state. */
1516 if (gtk_icon_source_get_state_wildcarded (source))
1518 if (state == GTK_STATE_INSENSITIVE)
1520 stated = gdk_pixbuf_copy (scaled);
1522 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
1525 g_object_unref (scaled);
1527 else if (state == GTK_STATE_PRELIGHT)
1529 stated = gdk_pixbuf_copy (scaled);
1531 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
1534 g_object_unref (scaled);
1548 _cairo_draw_line (cairo_t *cr,
1557 gdk_cairo_set_source_color (cr, color);
1558 cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
1560 cairo_move_to (cr, x1 + 0.5, y1 + 0.5);
1561 cairo_line_to (cr, x2 + 0.5, y2 + 0.5);
1568 _cairo_draw_rectangle (cairo_t *cr,
1576 gdk_cairo_set_source_color (cr, color);
1580 cairo_rectangle (cr, x, y, width, height);
1585 cairo_rectangle (cr, x + 0.5, y + 0.5, width, height);
1591 _cairo_draw_point (cairo_t *cr,
1596 gdk_cairo_set_source_color (cr, color);
1597 cairo_rectangle (cr, x, y, 1, 1);
1602 gtk_default_draw_hline (GtkStyle *style,
1604 GtkStateType state_type,
1606 const gchar *detail,
1611 gint thickness_light;
1612 gint thickness_dark;
1615 thickness_light = style->ythickness / 2;
1616 thickness_dark = style->ythickness - thickness_light;
1618 cairo_set_line_width (cr, 1.0);
1620 if (detail && !strcmp (detail, "label"))
1622 if (state_type == GTK_STATE_INSENSITIVE)
1623 _cairo_draw_line (cr, &style->white, x1 + 1, y + 1, x2 + 1, y + 1);
1624 _cairo_draw_line (cr, &style->fg[state_type], x1, y, x2, y);
1628 for (i = 0; i < thickness_dark; i++)
1630 _cairo_draw_line (cr, &style->dark[state_type], x1, y + i, x2 - i - 1, y + i);
1631 _cairo_draw_line (cr, &style->light[state_type], x2 - i, y + i, x2, y + i);
1634 y += thickness_dark;
1635 for (i = 0; i < thickness_light; i++)
1637 _cairo_draw_line (cr, &style->dark[state_type], x1, y + i, x1 + thickness_light - i - 1, y + i);
1638 _cairo_draw_line (cr, &style->light[state_type], x1 + thickness_light - i, y + i, x2, y + i);
1645 gtk_default_draw_vline (GtkStyle *style,
1647 GtkStateType state_type,
1649 const gchar *detail,
1654 gint thickness_light;
1655 gint thickness_dark;
1658 thickness_light = style->xthickness / 2;
1659 thickness_dark = style->xthickness - thickness_light;
1661 cairo_set_line_width (cr, 1.0);
1663 for (i = 0; i < thickness_dark; i++)
1665 _cairo_draw_line (cr, &style->dark[state_type],
1666 x + i, y1, x + i, y2 - i - 1);
1667 _cairo_draw_line (cr, &style->light[state_type],
1668 x + i, y2 - i, x + i, y2);
1671 x += thickness_dark;
1672 for (i = 0; i < thickness_light; i++)
1674 _cairo_draw_line (cr, &style->dark[state_type],
1675 x + i, y1, x + i, y1 + thickness_light - i - 1);
1676 _cairo_draw_line (cr, &style->light[state_type],
1677 x + i, y1 + thickness_light - i, x + i, y2);
1682 draw_thin_shadow (GtkStyle *style,
1690 GdkColor *gc1, *gc2;
1692 gc1 = &style->light[state];
1693 gc2 = &style->dark[state];
1695 _cairo_draw_line (cr, gc1,
1696 x, y + height - 1, x + width - 1, y + height - 1);
1697 _cairo_draw_line (cr, gc1,
1698 x + width - 1, y, x + width - 1, y + height - 1);
1700 _cairo_draw_line (cr, gc2,
1701 x, y, x + width - 2, y);
1702 _cairo_draw_line (cr, gc2,
1703 x, y, x, y + height - 2);
1707 draw_spinbutton_shadow (GtkStyle *style,
1710 GtkTextDirection direction,
1717 if (direction == GTK_TEXT_DIR_LTR)
1719 _cairo_draw_line (cr, &style->dark[state],
1720 x, y, x + width - 1, y);
1721 _cairo_draw_line (cr, &style->black,
1722 x, y + 1, x + width - 2, y + 1);
1723 _cairo_draw_line (cr, &style->black,
1724 x + width - 2, y + 2, x + width - 2, y + height - 3);
1725 _cairo_draw_line (cr, &style->light[state],
1726 x + width - 1, y + 1, x + width - 1, y + height - 2);
1727 _cairo_draw_line (cr, &style->light[state],
1728 x, y + height - 1, x + width - 1, y + height - 1);
1729 _cairo_draw_line (cr, &style->bg[state],
1730 x, y + height - 2, x + width - 2, y + height - 2);
1731 _cairo_draw_line (cr, &style->black,
1732 x, y + 2, x, y + height - 3);
1736 _cairo_draw_line (cr, &style->dark[state],
1737 x, y, x + width - 1, y);
1738 _cairo_draw_line (cr, &style->dark[state],
1739 x, y + 1, x, y + height - 1);
1740 _cairo_draw_line (cr, &style->black,
1741 x + 1, y + 1, x + width - 1, y + 1);
1742 _cairo_draw_line (cr, &style->black,
1743 x + 1, y + 2, x + 1, y + height - 2);
1744 _cairo_draw_line (cr, &style->black,
1745 x + width - 1, y + 2, x + width - 1, y + height - 3);
1746 _cairo_draw_line (cr, &style->light[state],
1747 x + 1, y + height - 1, x + width - 1, y + height - 1);
1748 _cairo_draw_line (cr, &style->bg[state],
1749 x + 2, y + height - 2, x + width - 1, y + height - 2);
1754 draw_menu_shadow (GtkStyle *style,
1762 if (style->ythickness > 0)
1764 if (style->ythickness > 1)
1766 _cairo_draw_line (cr, &style->dark[state],
1767 x + 1, y + height - 2,
1768 x + width - 2, y + height - 2);
1769 _cairo_draw_line (cr, &style->black,
1770 x, y + height - 1, x + width - 1, y + height - 1);
1774 _cairo_draw_line (cr, &style->dark[state],
1775 x + 1, y + height - 1, x + width - 1, y + height - 1);
1779 if (style->xthickness > 0)
1781 if (style->xthickness > 1)
1783 _cairo_draw_line (cr, &style->dark[state],
1784 x + width - 2, y + 1,
1785 x + width - 2, y + height - 2);
1787 _cairo_draw_line (cr, &style->black,
1788 x + width - 1, y, x + width - 1, y + height - 1);
1792 _cairo_draw_line (cr, &style->dark[state],
1793 x + width - 1, y + 1, x + width - 1, y + height - 1);
1797 /* Light around top and left */
1799 if (style->ythickness > 0)
1800 _cairo_draw_line (cr, &style->black,
1801 x, y, x + width - 2, y);
1802 if (style->xthickness > 0)
1803 _cairo_draw_line (cr, &style->black,
1804 x, y, x, y + height - 2);
1806 if (style->ythickness > 1)
1807 _cairo_draw_line (cr, &style->light[state],
1808 x + 1, y + 1, x + width - 3, y + 1);
1809 if (style->xthickness > 1)
1810 _cairo_draw_line (cr, &style->light[state],
1811 x + 1, y + 1, x + 1, y + height - 3);
1814 static GtkTextDirection
1815 get_direction (GtkWidget *widget)
1817 GtkTextDirection dir;
1820 dir = gtk_widget_get_direction (widget);
1822 dir = GTK_TEXT_DIR_LTR;
1829 gtk_default_draw_shadow (GtkStyle *style,
1831 GtkStateType state_type,
1832 GtkShadowType shadow_type,
1834 const gchar *detail,
1840 GdkColor *gc1 = NULL;
1841 GdkColor *gc2 = NULL;
1842 gint thickness_light;
1843 gint thickness_dark;
1846 cairo_set_line_width (cr, 1.0);
1848 if (shadow_type == GTK_SHADOW_IN)
1850 if (detail && strcmp (detail, "buttondefault") == 0)
1852 _cairo_draw_rectangle (cr, &style->black, FALSE,
1853 x, y, width - 1, height - 1);
1857 if (detail && strcmp (detail, "trough") == 0)
1859 draw_thin_shadow (style, cr, state_type,
1860 x, y, width, height);
1864 if (GTK_IS_SPIN_BUTTON (widget) &&
1865 detail && strcmp (detail, "spinbutton") == 0)
1867 draw_spinbutton_shadow (style, cr, state_type,
1868 get_direction (widget), x, y, width, height);
1874 if (shadow_type == GTK_SHADOW_OUT && detail && strcmp (detail, "menu") == 0)
1876 draw_menu_shadow (style, cr, state_type, x, y, width, height);
1880 switch (shadow_type)
1882 case GTK_SHADOW_NONE:
1885 case GTK_SHADOW_ETCHED_IN:
1886 gc1 = &style->light[state_type];
1887 gc2 = &style->dark[state_type];
1889 case GTK_SHADOW_OUT:
1890 case GTK_SHADOW_ETCHED_OUT:
1891 gc1 = &style->dark[state_type];
1892 gc2 = &style->light[state_type];
1896 switch (shadow_type)
1898 case GTK_SHADOW_NONE:
1902 /* Light around right and bottom edge */
1904 if (style->ythickness > 0)
1905 _cairo_draw_line (cr, gc1,
1906 x, y + height - 1, x + width - 1, y + height - 1);
1907 if (style->xthickness > 0)
1908 _cairo_draw_line (cr, gc1,
1909 x + width - 1, y, x + width - 1, y + height - 1);
1911 if (style->ythickness > 1)
1912 _cairo_draw_line (cr, &style->bg[state_type],
1913 x + 1, y + height - 2, x + width - 2, y + height - 2);
1914 if (style->xthickness > 1)
1915 _cairo_draw_line (cr, &style->bg[state_type],
1916 x + width - 2, y + 1, x + width - 2, y + height - 2);
1918 /* Dark around left and top */
1920 if (style->ythickness > 1)
1921 _cairo_draw_line (cr, &style->black,
1922 x + 1, y + 1, x + width - 2, y + 1);
1923 if (style->xthickness > 1)
1924 _cairo_draw_line (cr, &style->black,
1925 x + 1, y + 1, x + 1, y + height - 2);
1927 if (style->ythickness > 0)
1928 _cairo_draw_line (cr, gc2,
1929 x, y, x + width - 1, y);
1930 if (style->xthickness > 0)
1931 _cairo_draw_line (cr, gc2,
1932 x, y, x, y + height - 1);
1935 case GTK_SHADOW_OUT:
1936 /* Dark around right and bottom edge */
1938 if (style->ythickness > 0)
1940 if (style->ythickness > 1)
1942 _cairo_draw_line (cr, gc1,
1943 x + 1, y + height - 2, x + width - 2, y + height - 2);
1944 _cairo_draw_line (cr, &style->black,
1945 x, y + height - 1, x + width - 1, y + height - 1);
1949 _cairo_draw_line (cr, gc1,
1950 x + 1, y + height - 1, x + width - 1, y + height - 1);
1954 if (style->xthickness > 0)
1956 if (style->xthickness > 1)
1958 _cairo_draw_line (cr, gc1,
1959 x + width - 2, y + 1, x + width - 2, y + height - 2);
1961 _cairo_draw_line (cr, &style->black,
1962 x + width - 1, y, x + width - 1, y + height - 1);
1966 _cairo_draw_line (cr, gc1,
1967 x + width - 1, y + 1, x + width - 1, y + height - 1);
1971 /* Light around top and left */
1973 if (style->ythickness > 0)
1974 _cairo_draw_line (cr, gc2,
1975 x, y, x + width - 2, y);
1976 if (style->xthickness > 0)
1977 _cairo_draw_line (cr, gc2,
1978 x, y, x, y + height - 2);
1980 if (style->ythickness > 1)
1981 _cairo_draw_line (cr, &style->bg[state_type],
1982 x + 1, y + 1, x + width - 3, y + 1);
1983 if (style->xthickness > 1)
1984 _cairo_draw_line (cr, &style->bg[state_type],
1985 x + 1, y + 1, x + 1, y + height - 3);
1988 case GTK_SHADOW_ETCHED_IN:
1989 case GTK_SHADOW_ETCHED_OUT:
1990 if (style->xthickness > 0)
1992 if (style->xthickness > 1)
1994 thickness_light = 1;
1997 for (i = 0; i < thickness_dark; i++)
1999 _cairo_draw_line (cr, gc1,
2003 y + height - i - 1);
2004 _cairo_draw_line (cr, gc2,
2008 y + height - i - 2);
2011 for (i = 0; i < thickness_light; i++)
2013 _cairo_draw_line (cr, gc1,
2014 x + thickness_dark + i,
2015 y + thickness_dark + i,
2016 x + thickness_dark + i,
2017 y + height - thickness_dark - i - 1);
2018 _cairo_draw_line (cr, gc2,
2019 x + width - thickness_light - i - 1,
2020 y + thickness_dark + i,
2021 x + width - thickness_light - i - 1,
2022 y + height - thickness_light - 1);
2027 _cairo_draw_line (cr,
2028 &style->dark[state_type],
2029 x, y, x, y + height);
2030 _cairo_draw_line (cr,
2031 &style->dark[state_type],
2032 x + width, y, x + width, y + height);
2036 if (style->ythickness > 0)
2038 if (style->ythickness > 1)
2040 thickness_light = 1;
2043 for (i = 0; i < thickness_dark; i++)
2045 _cairo_draw_line (cr, gc1,
2049 y + height - i - 1);
2051 _cairo_draw_line (cr, gc2,
2058 for (i = 0; i < thickness_light; i++)
2060 _cairo_draw_line (cr, gc1,
2061 x + thickness_dark + i,
2062 y + thickness_dark + i,
2063 x + width - thickness_dark - i - 2,
2064 y + thickness_dark + i);
2066 _cairo_draw_line (cr, gc2,
2067 x + thickness_dark + i,
2068 y + height - thickness_light - i - 1,
2069 x + width - thickness_light - 1,
2070 y + height - thickness_light - i - 1);
2075 _cairo_draw_line (cr,
2076 &style->dark[state_type],
2077 x, y, x + width, y);
2078 _cairo_draw_line (cr,
2079 &style->dark[state_type],
2080 x, y + height, x + width, y + height);
2087 if (shadow_type == GTK_SHADOW_IN &&
2088 GTK_IS_SPIN_BUTTON (widget) &&
2089 detail && strcmp (detail, "entry") == 0)
2091 if (get_direction (widget) == GTK_TEXT_DIR_LTR)
2093 _cairo_draw_line (cr,
2094 &style->base[state_type],
2095 x + width - 1, y + 2,
2096 x + width - 1, y + height - 3);
2097 _cairo_draw_line (cr,
2098 &style->base[state_type],
2099 x + width - 2, y + 2,
2100 x + width - 2, y + height - 3);
2102 _cairo_draw_point (cr,
2104 x + width - 1, y + 1);
2105 _cairo_draw_point (cr,
2106 &style->bg[state_type],
2107 x + width - 1, y + height - 2);
2111 _cairo_draw_line (cr,
2112 &style->base[state_type],
2115 _cairo_draw_line (cr,
2116 &style->base[state_type],
2118 x + 1, y + height - 3);
2120 _cairo_draw_point (cr,
2124 _cairo_draw_line (cr,
2125 &style->bg[state_type],
2127 x + 1, y + height - 2);
2128 _cairo_draw_point (cr,
2129 &style->light[state_type],
2136 draw_arrow (cairo_t *cr,
2138 GtkArrowType arrow_type,
2144 gdk_cairo_set_source_color (cr, color);
2147 if (arrow_type == GTK_ARROW_DOWN)
2149 cairo_move_to (cr, x, y);
2150 cairo_line_to (cr, x + width, y);
2151 cairo_line_to (cr, x + width / 2., y + height);
2153 else if (arrow_type == GTK_ARROW_UP)
2155 cairo_move_to (cr, x, y + height);
2156 cairo_line_to (cr, x + width / 2., y);
2157 cairo_line_to (cr, x + width, y + height);
2159 else if (arrow_type == GTK_ARROW_LEFT)
2161 cairo_move_to (cr, x + width, y);
2162 cairo_line_to (cr, x + width, y + height);
2163 cairo_line_to (cr, x, y + height / 2.);
2165 else if (arrow_type == GTK_ARROW_RIGHT)
2167 cairo_move_to (cr, x, y);
2168 cairo_line_to (cr, x + width, y + height / 2.);
2169 cairo_line_to (cr, x, y + height);
2172 cairo_close_path (cr);
2179 calculate_arrow_geometry (GtkArrowType arrow_type,
2191 case GTK_ARROW_DOWN:
2201 if (arrow_type == GTK_ARROW_DOWN)
2203 if (*height % 2 == 1 || h % 2 == 0)
2208 if (*height % 2 == 0 || h % 2 == 0)
2213 case GTK_ARROW_RIGHT:
2214 case GTK_ARROW_LEFT:
2224 if (arrow_type == GTK_ARROW_RIGHT)
2226 if (*width % 2 == 1 || w % 2 == 0)
2231 if (*width % 2 == 0 || w % 2 == 0)
2237 /* should not be reached */
2241 *x += (*width - w) / 2;
2242 *y += (*height - h) / 2;
2248 gtk_default_draw_arrow (GtkStyle *style,
2251 GtkShadowType shadow,
2253 const gchar *detail,
2254 GtkArrowType arrow_type,
2261 calculate_arrow_geometry (arrow_type, &x, &y, &width, &height);
2263 if (detail && strcmp (detail, "menu_scroll_arrow_up") == 0)
2266 if (state == GTK_STATE_INSENSITIVE)
2267 draw_arrow (cr, &style->white, arrow_type,
2268 x + 1, y + 1, width, height);
2269 draw_arrow (cr, &style->fg[state], arrow_type,
2270 x, y, width, height);
2274 gtk_default_draw_diamond (GtkStyle *style,
2276 GtkStateType state_type,
2277 GtkShadowType shadow_type,
2279 const gchar *detail,
2287 GdkColor *outer_nw = NULL;
2288 GdkColor *outer_ne = NULL;
2289 GdkColor *outer_sw = NULL;
2290 GdkColor *outer_se = NULL;
2291 GdkColor *middle_nw = NULL;
2292 GdkColor *middle_ne = NULL;
2293 GdkColor *middle_sw = NULL;
2294 GdkColor *middle_se = NULL;
2295 GdkColor *inner_nw = NULL;
2296 GdkColor *inner_ne = NULL;
2297 GdkColor *inner_sw = NULL;
2298 GdkColor *inner_se = NULL;
2300 half_width = width / 2;
2301 half_height = height / 2;
2303 switch (shadow_type)
2306 inner_sw = inner_se = &style->bg[state_type];
2307 middle_sw = middle_se = &style->light[state_type];
2308 outer_sw = outer_se = &style->light[state_type];
2309 inner_nw = inner_ne = &style->black;
2310 middle_nw = middle_ne = &style->dark[state_type];
2311 outer_nw = outer_ne = &style->dark[state_type];
2314 case GTK_SHADOW_OUT:
2315 inner_sw = inner_se = &style->dark[state_type];
2316 middle_sw = middle_se = &style->dark[state_type];
2317 outer_sw = outer_se = &style->black;
2318 inner_nw = inner_ne = &style->bg[state_type];
2319 middle_nw = middle_ne = &style->light[state_type];
2320 outer_nw = outer_ne = &style->light[state_type];
2323 case GTK_SHADOW_ETCHED_IN:
2324 inner_sw = inner_se = &style->bg[state_type];
2325 middle_sw = middle_se = &style->dark[state_type];
2326 outer_sw = outer_se = &style->light[state_type];
2327 inner_nw = inner_ne = &style->bg[state_type];
2328 middle_nw = middle_ne = &style->light[state_type];
2329 outer_nw = outer_ne = &style->dark[state_type];
2332 case GTK_SHADOW_ETCHED_OUT:
2333 inner_sw = inner_se = &style->bg[state_type];
2334 middle_sw = middle_se = &style->light[state_type];
2335 outer_sw = outer_se = &style->dark[state_type];
2336 inner_nw = inner_ne = &style->bg[state_type];
2337 middle_nw = middle_ne = &style->dark[state_type];
2338 outer_nw = outer_ne = &style->light[state_type];
2348 _cairo_draw_line (cr, inner_sw,
2349 x + 2, y + half_height,
2350 x + half_width, y + height - 2);
2351 _cairo_draw_line (cr, inner_se,
2352 x + half_width, y + height - 2,
2353 x + width - 2, y + half_height);
2354 _cairo_draw_line (cr, middle_sw,
2355 x + 1, y + half_height,
2356 x + half_width, y + height - 1);
2357 _cairo_draw_line (cr, middle_se,
2358 x + half_width, y + height - 1,
2359 x + width - 1, y + half_height);
2360 _cairo_draw_line (cr, outer_sw,
2362 x + half_width, y + height);
2363 _cairo_draw_line (cr, outer_se,
2364 x + half_width, y + height,
2365 x + width, y + half_height);
2367 _cairo_draw_line (cr, inner_nw,
2368 x + 2, y + half_height,
2369 x + half_width, y + 2);
2370 _cairo_draw_line (cr, inner_ne,
2371 x + half_width, y + 2,
2372 x + width - 2, y + half_height);
2373 _cairo_draw_line (cr, middle_nw,
2374 x + 1, y + half_height,
2375 x + half_width, y + 1);
2376 _cairo_draw_line (cr, middle_ne,
2377 x + half_width, y + 1,
2378 x + width - 1, y + half_height);
2379 _cairo_draw_line (cr, outer_nw,
2382 _cairo_draw_line (cr, outer_ne,
2384 x + width, y + half_height);
2389 option_menu_get_props (GtkWidget *widget,
2390 GtkRequisition *indicator_size,
2391 GtkBorder *indicator_spacing)
2393 GtkRequisition *tmp_size = NULL;
2394 GtkBorder *tmp_spacing = NULL;
2398 *indicator_size = *tmp_size;
2399 gtk_requisition_free (tmp_size);
2402 *indicator_size = default_option_indicator_size;
2406 *indicator_spacing = *tmp_spacing;
2407 gtk_border_free (tmp_spacing);
2410 *indicator_spacing = default_option_indicator_spacing;
2414 background_is_solid (GtkStyle *style,
2417 if (style->background[type] == NULL)
2420 return cairo_pattern_get_type (style->background[type]) == CAIRO_PATTERN_TYPE_SOLID;
2424 gtk_default_draw_box (GtkStyle *style,
2426 GtkStateType state_type,
2427 GtkShadowType shadow_type,
2429 const gchar *detail,
2435 gboolean is_spinbutton_box = FALSE;
2437 if (GTK_IS_SPIN_BUTTON (widget) && detail)
2439 if (strcmp (detail, "spinbutton_up") == 0)
2445 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
2450 is_spinbutton_box = TRUE;
2452 else if (strcmp (detail, "spinbutton_down") == 0)
2457 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
2462 is_spinbutton_box = TRUE;
2466 if (background_is_solid (style, state_type))
2468 GdkColor *gc = &style->bg[state_type];
2470 if (state_type == GTK_STATE_SELECTED && detail && strcmp (detail, "paned") == 0)
2472 if (widget && !gtk_widget_has_focus (widget))
2473 gc = &style->base[GTK_STATE_ACTIVE];
2476 _cairo_draw_rectangle (cr, gc, TRUE,
2477 x, y, width, height);
2480 gtk_style_apply_default_background (style, cr, gtk_widget_get_window (widget),
2481 state_type, x, y, width, height);
2484 if (is_spinbutton_box)
2489 lower = &style->dark[state_type];
2490 if (shadow_type == GTK_SHADOW_OUT)
2491 upper = &style->light[state_type];
2493 upper = &style->dark[state_type];
2495 _cairo_draw_line (cr, upper, x, y, x + width - 1, y);
2496 _cairo_draw_line (cr, lower, x, y + height - 1, x + width - 1, y + height - 1);
2501 gtk_paint_shadow (style, cr, state_type, shadow_type, widget, detail,
2502 x, y, width, height);
2504 if (detail && strcmp (detail, "optionmenu") == 0)
2506 GtkRequisition indicator_size;
2507 GtkBorder indicator_spacing;
2510 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
2512 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
2513 vline_x = x + indicator_size.width + indicator_spacing.left + indicator_spacing.right;
2515 vline_x = x + width - (indicator_size.width + indicator_spacing.left + indicator_spacing.right) - style->xthickness;
2517 gtk_paint_vline (style, cr, state_type, widget,
2519 y + style->ythickness + 1,
2520 y + height - style->ythickness - 3,
2526 get_darkened (const GdkColor *color,
2529 GdkColor src = *color;
2530 GdkColor shaded = *color;
2532 while (darken_count)
2534 _gtk_style_shade (&src, &shaded, 0.93);
2539 return gdk_color_copy (&shaded);
2543 gtk_default_draw_flat_box (GtkStyle *style,
2545 GtkStateType state_type,
2546 GtkShadowType shadow_type,
2548 const gchar *detail,
2555 GdkColor *freeme = NULL;
2557 cairo_set_line_width (cr, 1.0);
2561 int trimmed_len = strlen (detail);
2563 if (g_str_has_prefix (detail, "cell_"))
2565 if (g_str_has_suffix (detail, "_start"))
2567 else if (g_str_has_suffix (detail, "_middle"))
2569 else if (g_str_has_suffix (detail, "_end"))
2573 if (state_type == GTK_STATE_SELECTED)
2575 if (!strcmp ("text", detail))
2576 gc1 = &style->bg[GTK_STATE_SELECTED];
2577 else if (!strncmp ("cell_even", detail, trimmed_len) ||
2578 !strncmp ("cell_odd", detail, trimmed_len) ||
2579 !strncmp ("cell_even_ruled", detail, trimmed_len) ||
2580 !strncmp ("cell_even_ruled_sorted", detail, trimmed_len))
2582 /* This has to be really broken; alex made me do it. -jrb */
2583 if (widget && gtk_widget_has_focus (widget))
2584 gc1 = &style->base[state_type];
2586 gc1 = &style->base[GTK_STATE_ACTIVE];
2588 else if (!strncmp ("cell_odd_ruled", detail, trimmed_len) ||
2589 !strncmp ("cell_odd_ruled_sorted", detail, trimmed_len))
2591 if (widget && gtk_widget_has_focus (widget))
2592 freeme = get_darkened (&style->base[state_type], 1);
2594 freeme = get_darkened (&style->base[GTK_STATE_ACTIVE], 1);
2599 gc1 = &style->bg[state_type];
2604 if (!strcmp ("viewportbin", detail))
2605 gc1 = &style->bg[GTK_STATE_NORMAL];
2606 else if (!strcmp ("entry_bg", detail))
2607 gc1 = &style->base[gtk_widget_get_state (widget)];
2609 /* For trees: even rows are base color, odd rows are a shade of
2610 * the base color, the sort column is a shade of the original color
2614 else if (!strncmp ("cell_even", detail, trimmed_len) ||
2615 !strncmp ("cell_odd", detail, trimmed_len) ||
2616 !strncmp ("cell_even_ruled", detail, trimmed_len))
2618 GdkColor *color = NULL;
2620 gtk_widget_style_get (widget,
2621 "even-row-color", &color,
2626 freeme = get_darkened (color, 0);
2629 gdk_color_free (color);
2632 gc1 = &style->base[state_type];
2634 else if (!strncmp ("cell_odd_ruled", detail, trimmed_len))
2636 GdkColor *color = NULL;
2638 gtk_widget_style_get (widget,
2639 "odd-row-color", &color,
2644 freeme = get_darkened (color, 0);
2647 gdk_color_free (color);
2651 gtk_widget_style_get (widget,
2652 "even-row-color", &color,
2657 freeme = get_darkened (color, 1);
2658 gdk_color_free (color);
2661 freeme = get_darkened (&style->base[state_type], 1);
2665 else if (!strncmp ("cell_even_sorted", detail, trimmed_len) ||
2666 !strncmp ("cell_odd_sorted", detail, trimmed_len) ||
2667 !strncmp ("cell_even_ruled_sorted", detail, trimmed_len))
2669 GdkColor *color = NULL;
2671 if (!strncmp ("cell_odd_sorted", detail, trimmed_len))
2672 gtk_widget_style_get (widget,
2673 "odd-row-color", &color,
2676 gtk_widget_style_get (widget,
2677 "even-row-color", &color,
2682 freeme = get_darkened (color, 1);
2685 gdk_color_free (color);
2689 freeme = get_darkened (&style->base[state_type], 1);
2693 else if (!strncmp ("cell_odd_ruled_sorted", detail, trimmed_len))
2695 GdkColor *color = NULL;
2697 gtk_widget_style_get (widget,
2698 "odd-row-color", &color,
2703 freeme = get_darkened (color, 1);
2706 gdk_color_free (color);
2710 gtk_widget_style_get (widget,
2711 "even-row-color", &color,
2716 freeme = get_darkened (color, 2);
2717 gdk_color_free (color);
2720 freeme = get_darkened (&style->base[state_type], 2);
2725 gc1 = &style->bg[state_type];
2729 gc1 = &style->bg[state_type];
2731 if (background_is_solid (style, state_type) || gc1 != &style->bg[state_type])
2733 _cairo_draw_rectangle (cr, gc1, TRUE,
2734 x, y, width, height);
2736 if (detail && !strcmp ("tooltip", detail))
2737 _cairo_draw_rectangle (cr, &style->black, FALSE,
2738 x, y, width - 1, height - 1);
2741 gtk_style_apply_default_background (style, cr, gtk_widget_get_window (widget),
2742 state_type, x, y, width, height);
2745 gdk_color_free (freeme);
2749 gtk_default_draw_check (GtkStyle *style,
2751 GtkStateType state_type,
2752 GtkShadowType shadow_type,
2754 const gchar *detail,
2760 enum { BUTTON, MENU, CELL } type = BUTTON;
2767 if (strcmp (detail, "cellcheck") == 0)
2769 else if (strcmp (detail, "check") == 0)
2773 exterior_size = MIN (width, height);
2774 if (exterior_size % 2 == 0) /* Ensure odd */
2777 pad = style->xthickness + MAX (1, (exterior_size - 2 * style->xthickness) / 9);
2778 interior_size = MAX (1, exterior_size - 2 * pad);
2780 if (interior_size < 7)
2783 pad = MAX (0, (exterior_size - interior_size) / 2);
2786 x -= (1 + exterior_size - width) / 2;
2787 y -= (1 + exterior_size - height) / 2;
2794 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
2796 gdk_cairo_set_source_color (cr, &style->text[state_type]);
2798 cairo_set_line_width (cr, 1.0);
2799 cairo_rectangle (cr, x + 0.5, y + 0.5, exterior_size - 1, exterior_size - 1);
2802 gdk_cairo_set_source_color (cr, &style->base[state_type]);
2803 cairo_rectangle (cr, x + 1, y + 1, exterior_size - 2, exterior_size - 2);
2815 gdk_cairo_set_source_color (cr, &style->text[state_type]);
2818 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
2822 if (shadow_type == GTK_SHADOW_IN)
2824 cairo_translate (cr,
2827 cairo_scale (cr, interior_size / 7., interior_size / 7.);
2829 cairo_move_to (cr, 7.0, 0.0);
2830 cairo_line_to (cr, 7.5, 1.0);
2831 cairo_curve_to (cr, 5.3, 2.0,
2834 cairo_curve_to (cr, 3.0, 5.7,
2837 cairo_line_to (cr, 0.2, 3.5);
2838 cairo_curve_to (cr, 1.1, 3.5,
2841 cairo_curve_to (cr, 1.0, 3.9,
2844 cairo_curve_to (cr, 3.5, 3.1,
2850 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
2852 int line_thickness = MAX (1, (3 + interior_size * 2) / 7);
2854 cairo_rectangle (cr,
2856 y + pad + (1 + interior_size - line_thickness) / 2,
2864 gtk_default_draw_option (GtkStyle *style,
2866 GtkStateType state_type,
2867 GtkShadowType shadow_type,
2869 const gchar *detail,
2875 enum { BUTTON, MENU, CELL } type = BUTTON;
2880 if (strcmp (detail, "radio") == 0)
2882 else if (strcmp (detail, "option") == 0)
2886 exterior_size = MIN (width, height);
2887 if (exterior_size % 2 == 0) /* Ensure odd */
2890 x -= (1 + exterior_size - width) / 2;
2891 y -= (1 + exterior_size - height) / 2;
2897 gdk_cairo_set_source_color (cr, &style->base[state_type]);
2900 x + exterior_size / 2.,
2901 y + exterior_size / 2.,
2902 (exterior_size - 1) / 2.,
2905 cairo_fill_preserve (cr);
2908 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
2910 gdk_cairo_set_source_color (cr, &style->text[state_type]);
2912 cairo_set_line_width (cr, 1.);
2923 gdk_cairo_set_source_color (cr, &style->text[state_type]);
2928 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
2932 if (shadow_type == GTK_SHADOW_IN)
2934 int pad = style->xthickness + MAX (1, 2 * (exterior_size - 2 * style->xthickness) / 9);
2935 int interior_size = MAX (1, exterior_size - 2 * pad);
2937 if (interior_size < 5)
2940 pad = MAX (0, (exterior_size - interior_size) / 2);
2944 x + pad + interior_size / 2.,
2945 y + pad + interior_size / 2.,
2950 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
2952 int pad = style->xthickness + MAX (1, (exterior_size - 2 * style->xthickness) / 9);
2953 int interior_size = MAX (1, exterior_size - 2 * pad);
2956 if (interior_size < 7)
2959 pad = MAX (0, (exterior_size - interior_size) / 2);
2962 line_thickness = MAX (1, (3 + interior_size * 2) / 7);
2964 cairo_rectangle (cr,
2966 y + pad + (interior_size - line_thickness) / 2.,
2974 gtk_default_draw_tab (GtkStyle *style,
2976 GtkStateType state_type,
2977 GtkShadowType shadow_type,
2979 const gchar *detail,
2985 #define ARROW_SPACE 4
2987 GtkRequisition indicator_size;
2988 GtkBorder indicator_spacing;
2991 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
2993 indicator_size.width += (indicator_size.width % 2) - 1;
2994 arrow_height = indicator_size.width / 2 + 1;
2996 x += (width - indicator_size.width) / 2;
2997 y += (height - (2 * arrow_height + ARROW_SPACE)) / 2;
2999 if (state_type == GTK_STATE_INSENSITIVE)
3001 draw_arrow (cr, &style->white,
3002 GTK_ARROW_UP, x + 1, y + 1,
3003 indicator_size.width, arrow_height);
3005 draw_arrow (cr, &style->white,
3006 GTK_ARROW_DOWN, x + 1, y + arrow_height + ARROW_SPACE + 1,
3007 indicator_size.width, arrow_height);
3010 draw_arrow (cr, &style->fg[state_type],
3012 indicator_size.width, arrow_height);
3015 draw_arrow (cr, &style->fg[state_type],
3016 GTK_ARROW_DOWN, x, y + arrow_height + ARROW_SPACE,
3017 indicator_size.width, arrow_height);
3021 gtk_default_draw_shadow_gap (GtkStyle *style,
3023 GtkStateType state_type,
3024 GtkShadowType shadow_type,
3026 const gchar *detail,
3031 GtkPositionType gap_side,
3035 GdkColor *color1 = NULL;
3036 GdkColor *color2 = NULL;
3037 GdkColor *color3 = NULL;
3038 GdkColor *color4 = NULL;
3040 switch (shadow_type)
3042 case GTK_SHADOW_NONE:
3046 color1 = &style->dark[state_type];
3047 color2 = &style->black;
3048 color3 = &style->bg[state_type];
3049 color4 = &style->light[state_type];
3051 case GTK_SHADOW_ETCHED_IN:
3052 color1 = &style->dark[state_type];
3053 color2 = &style->light[state_type];
3054 color3 = &style->dark[state_type];
3055 color4 = &style->light[state_type];
3057 case GTK_SHADOW_OUT:
3058 color1 = &style->light[state_type];
3059 color2 = &style->bg[state_type];
3060 color3 = &style->dark[state_type];
3061 color4 = &style->black;
3063 case GTK_SHADOW_ETCHED_OUT:
3064 color1 = &style->light[state_type];
3065 color2 = &style->dark[state_type];
3066 color3 = &style->light[state_type];
3067 color4 = &style->dark[state_type];
3071 switch (shadow_type)
3073 case GTK_SHADOW_NONE:
3075 case GTK_SHADOW_OUT:
3076 case GTK_SHADOW_ETCHED_IN:
3077 case GTK_SHADOW_ETCHED_OUT:
3081 _cairo_draw_line (cr, color1,
3082 x, y, x, y + height - 1);
3083 _cairo_draw_line (cr, color2,
3084 x + 1, y, x + 1, y + height - 2);
3086 _cairo_draw_line (cr, color3,
3087 x + 1, y + height - 2, x + width - 2, y + height - 2);
3088 _cairo_draw_line (cr, color3,
3089 x + width - 2, y, x + width - 2, y + height - 2);
3090 _cairo_draw_line (cr, color4,
3091 x, y + height - 1, x + width - 1, y + height - 1);
3092 _cairo_draw_line (cr, color4,
3093 x + width - 1, y, x + width - 1, y + height - 1);
3096 _cairo_draw_line (cr, color1,
3097 x, y, x + gap_x - 1, y);
3098 _cairo_draw_line (cr, color2,
3099 x + 1, y + 1, x + gap_x - 1, y + 1);
3100 _cairo_draw_line (cr, color2,
3101 x + gap_x, y, x + gap_x, y);
3103 if ((width - (gap_x + gap_width)) > 0)
3105 _cairo_draw_line (cr, color1,
3106 x + gap_x + gap_width, y, x + width - 2, y);
3107 _cairo_draw_line (cr, color2,
3108 x + gap_x + gap_width, y + 1, x + width - 3, y + 1);
3109 _cairo_draw_line (cr, color2,
3110 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
3113 case GTK_POS_BOTTOM:
3114 _cairo_draw_line (cr, color1,
3115 x, y, x + width - 1, y);
3116 _cairo_draw_line (cr, color1,
3117 x, y, x, y + height - 1);
3118 _cairo_draw_line (cr, color2,
3119 x + 1, y + 1, x + width - 2, y + 1);
3120 _cairo_draw_line (cr, color2,
3121 x + 1, y + 1, x + 1, y + height - 1);
3123 _cairo_draw_line (cr, color3,
3124 x + width - 2, y + 1, x + width - 2, y + height - 1);
3125 _cairo_draw_line (cr, color4,
3126 x + width - 1, y, x + width - 1, y + height - 1);
3129 _cairo_draw_line (cr, color4,
3130 x, y + height - 1, x + gap_x - 1, y + height - 1);
3131 _cairo_draw_line (cr, color3,
3132 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
3133 _cairo_draw_line (cr, color3,
3134 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
3136 if ((width - (gap_x + gap_width)) > 0)
3138 _cairo_draw_line (cr, color4,
3139 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
3140 _cairo_draw_line (cr, color3,
3141 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
3142 _cairo_draw_line (cr, color3,
3143 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
3147 _cairo_draw_line (cr, color1,
3148 x, y, x + width - 1, y);
3149 _cairo_draw_line (cr, color2,
3150 x, y + 1, x + width - 2, y + 1);
3152 _cairo_draw_line (cr, color3,
3153 x, y + height - 2, x + width - 2, y + height - 2);
3154 _cairo_draw_line (cr, color3,
3155 x + width - 2, y + 1, x + width - 2, y + height - 2);
3156 _cairo_draw_line (cr, color4,
3157 x, y + height - 1, x + width - 1, y + height - 1);
3158 _cairo_draw_line (cr, color4,
3159 x + width - 1, y, x + width - 1, y + height - 1);
3162 _cairo_draw_line (cr, color1,
3163 x, y, x, y + gap_x - 1);
3164 _cairo_draw_line (cr, color2,
3165 x + 1, y + 1, x + 1, y + gap_x - 1);
3166 _cairo_draw_line (cr, color2,
3167 x, y + gap_x, x, y + gap_x);
3169 if ((width - (gap_x + gap_width)) > 0)
3171 _cairo_draw_line (cr, color1,
3172 x, y + gap_x + gap_width, x, y + height - 2);
3173 _cairo_draw_line (cr, color2,
3174 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
3175 _cairo_draw_line (cr, color2,
3176 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
3180 _cairo_draw_line (cr, color1,
3181 x, y, x + width - 1, y);
3182 _cairo_draw_line (cr, color1,
3183 x, y, x, y + height - 1);
3184 _cairo_draw_line (cr, color2,
3185 x + 1, y + 1, x + width - 1, y + 1);
3186 _cairo_draw_line (cr, color2,
3187 x + 1, y + 1, x + 1, y + height - 2);
3189 _cairo_draw_line (cr, color3,
3190 x + 1, y + height - 2, x + width - 1, y + height - 2);
3191 _cairo_draw_line (cr, color4,
3192 x, y + height - 1, x + width - 1, y + height - 1);
3195 _cairo_draw_line (cr, color4,
3196 x + width - 1, y, x + width - 1, y + gap_x - 1);
3197 _cairo_draw_line (cr, color3,
3198 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
3199 _cairo_draw_line (cr, color3,
3200 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
3202 if ((width - (gap_x + gap_width)) > 0)
3204 _cairo_draw_line (cr, color4,
3205 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
3206 _cairo_draw_line (cr, color3,
3207 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
3208 _cairo_draw_line (cr, color3,
3209 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
3217 gtk_default_draw_box_gap (GtkStyle *style,
3219 GtkStateType state_type,
3220 GtkShadowType shadow_type,
3222 const gchar *detail,
3227 GtkPositionType gap_side,
3236 gtk_style_apply_default_background (style, cr, gtk_widget_get_window (widget),
3237 state_type, x, y, width, height);
3239 switch (shadow_type)
3241 case GTK_SHADOW_NONE:
3244 color1 = style->dark[state_type];
3245 color2 = style->black;
3246 color3 = style->bg[state_type];
3247 color4 = style->light[state_type];
3249 case GTK_SHADOW_ETCHED_IN:
3250 color1 = style->dark[state_type];
3251 color2 = style->light[state_type];
3252 color3 = style->dark[state_type];
3253 color4 = style->light[state_type];
3255 case GTK_SHADOW_OUT:
3256 color1 = style->light[state_type];
3257 color2 = style->bg[state_type];
3258 color3 = style->dark[state_type];
3259 color4 = style->black;
3261 case GTK_SHADOW_ETCHED_OUT:
3262 color1 = style->light[state_type];
3263 color2 = style->dark[state_type];
3264 color3 = style->light[state_type];
3265 color4 = style->dark[state_type];
3269 cairo_set_line_width (cr, 1.0);
3271 switch (shadow_type)
3273 case GTK_SHADOW_NONE:
3275 case GTK_SHADOW_OUT:
3276 case GTK_SHADOW_ETCHED_IN:
3277 case GTK_SHADOW_ETCHED_OUT:
3281 _cairo_draw_line (cr, &color1,
3282 x, y, x, y + height - 1);
3283 _cairo_draw_line (cr, &color2,
3284 x + 1, y, x + 1, y + height - 2);
3286 _cairo_draw_line (cr, &color3,
3287 x + 1, y + height - 2, x + width - 2, y + height - 2);
3288 _cairo_draw_line (cr, &color3,
3289 x + width - 2, y, x + width - 2, y + height - 2);
3290 _cairo_draw_line (cr, &color4,
3291 x, y + height - 1, x + width - 1, y + height - 1);
3292 _cairo_draw_line (cr, &color4,
3293 x + width - 1, y, x + width - 1, y + height - 1);
3296 _cairo_draw_line (cr, &color1,
3297 x, y, x + gap_x - 1, y);
3298 _cairo_draw_line (cr, &color2,
3299 x + 1, y + 1, x + gap_x - 1, y + 1);
3300 _cairo_draw_line (cr, &color2,
3301 x + gap_x, y, x + gap_x, y);
3303 if ((width - (gap_x + gap_width)) > 0)
3305 _cairo_draw_line (cr, &color1,
3306 x + gap_x + gap_width, y, x + width - 2, y);
3307 _cairo_draw_line (cr, &color2,
3308 x + gap_x + gap_width, y + 1, x + width - 2, y + 1);
3309 _cairo_draw_line (cr, &color2,
3310 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
3313 case GTK_POS_BOTTOM:
3314 _cairo_draw_line (cr, &color1,
3315 x, y, x + width - 1, y);
3316 _cairo_draw_line (cr, &color1,
3317 x, y, x, y + height - 1);
3318 _cairo_draw_line (cr, &color2,
3319 x + 1, y + 1, x + width - 2, y + 1);
3320 _cairo_draw_line (cr, &color2,
3321 x + 1, y + 1, x + 1, y + height - 1);
3323 _cairo_draw_line (cr, &color3,
3324 x + width - 2, y + 1, x + width - 2, y + height - 1);
3325 _cairo_draw_line (cr, &color4,
3326 x + width - 1, y, x + width - 1, y + height - 1);
3329 _cairo_draw_line (cr, &color4,
3330 x, y + height - 1, x + gap_x - 1, y + height - 1);
3331 _cairo_draw_line (cr, &color3,
3332 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
3333 _cairo_draw_line (cr, &color3,
3334 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
3336 if ((width - (gap_x + gap_width)) > 0)
3338 _cairo_draw_line (cr, &color4,
3339 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
3340 _cairo_draw_line (cr, &color3,
3341 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
3342 _cairo_draw_line (cr, &color3,
3343 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
3347 _cairo_draw_line (cr, &color1,
3348 x, y, x + width - 1, y);
3349 _cairo_draw_line (cr, &color2,
3350 x, y + 1, x + width - 2, y + 1);
3352 _cairo_draw_line (cr, &color3,
3353 x, y + height - 2, x + width - 2, y + height - 2);
3354 _cairo_draw_line (cr, &color3,
3355 x + width - 2, y + 1, x + width - 2, y + height - 2);
3356 _cairo_draw_line (cr, &color4,
3357 x, y + height - 1, x + width - 1, y + height - 1);
3358 _cairo_draw_line (cr, &color4,
3359 x + width - 1, y, x + width - 1, y + height - 1);
3362 _cairo_draw_line (cr, &color1,
3363 x, y, x, y + gap_x - 1);
3364 _cairo_draw_line (cr, &color2,
3365 x + 1, y + 1, x + 1, y + gap_x - 1);
3366 _cairo_draw_line (cr, &color2,
3367 x, y + gap_x, x, y + gap_x);
3369 if ((height - (gap_x + gap_width)) > 0)
3371 _cairo_draw_line (cr, &color1,
3372 x, y + gap_x + gap_width, x, y + height - 2);
3373 _cairo_draw_line (cr, &color2,
3374 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
3375 _cairo_draw_line (cr, &color2,
3376 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
3380 _cairo_draw_line (cr, &color1,
3381 x, y, x + width - 1, y);
3382 _cairo_draw_line (cr, &color1,
3383 x, y, x, y + height - 1);
3384 _cairo_draw_line (cr, &color2,
3385 x + 1, y + 1, x + width - 1, y + 1);
3386 _cairo_draw_line (cr, &color2,
3387 x + 1, y + 1, x + 1, y + height - 2);
3389 _cairo_draw_line (cr, &color3,
3390 x + 1, y + height - 2, x + width - 1, y + height - 2);
3391 _cairo_draw_line (cr, &color4,
3392 x, y + height - 1, x + width - 1, y + height - 1);
3395 _cairo_draw_line (cr, &color4,
3396 x + width - 1, y, x + width - 1, y + gap_x - 1);
3397 _cairo_draw_line (cr, &color3,
3398 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
3399 _cairo_draw_line (cr, &color3,
3400 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
3402 if ((height - (gap_x + gap_width)) > 0)
3404 _cairo_draw_line (cr, &color4,
3405 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
3406 _cairo_draw_line (cr, &color3,
3407 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
3408 _cairo_draw_line (cr, &color3,
3409 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
3417 gtk_default_draw_extension (GtkStyle *style,
3419 GtkStateType state_type,
3420 GtkShadowType shadow_type,
3422 const gchar *detail,
3427 GtkPositionType gap_side)
3429 GdkWindow *window = gtk_widget_get_window (widget);
3438 gtk_style_apply_default_background (style, cr, window,
3445 case GTK_POS_BOTTOM:
3446 gtk_style_apply_default_background (style, cr, window,
3454 gtk_style_apply_default_background (style, cr, window,
3462 gtk_style_apply_default_background (style, cr, window,
3471 switch (shadow_type)
3473 case GTK_SHADOW_NONE:
3476 color1 = style->dark[state_type];
3477 color2 = style->black;
3478 color3 = style->bg[state_type];
3479 color4 = style->light[state_type];
3481 case GTK_SHADOW_ETCHED_IN:
3482 color1 = style->dark[state_type];
3483 color2 = style->light[state_type];
3484 color3 = style->dark[state_type];
3485 color4 = style->light[state_type];
3487 case GTK_SHADOW_OUT:
3488 color1 = style->light[state_type];
3489 color2 = style->bg[state_type];
3490 color3 = style->dark[state_type];
3491 color4 = style->black;
3493 case GTK_SHADOW_ETCHED_OUT:
3494 color1 = style->light[state_type];
3495 color2 = style->dark[state_type];
3496 color3 = style->light[state_type];
3497 color4 = style->dark[state_type];
3501 cairo_set_line_width (cr, 1.0);
3503 switch (shadow_type)
3505 case GTK_SHADOW_NONE:
3507 case GTK_SHADOW_OUT:
3508 case GTK_SHADOW_ETCHED_IN:
3509 case GTK_SHADOW_ETCHED_OUT:
3513 _cairo_draw_line (cr, &color1,
3514 x, y, x, y + height - 2);
3515 _cairo_draw_line (cr, &color2,
3516 x + 1, y, x + 1, y + height - 2);
3518 _cairo_draw_line (cr, &color3,
3519 x + 2, y + height - 2, x + width - 2, y + height - 2);
3520 _cairo_draw_line (cr, &color3,
3521 x + width - 2, y, x + width - 2, y + height - 2);
3522 _cairo_draw_line (cr, &color4,
3523 x + 1, y + height - 1, x + width - 2, y + height - 1);
3524 _cairo_draw_line (cr, &color4,
3525 x + width - 1, y, x + width - 1, y + height - 2);
3527 case GTK_POS_BOTTOM:
3528 _cairo_draw_line (cr, &color1,
3529 x + 1, y, x + width - 2, y);
3530 _cairo_draw_line (cr, &color1,
3531 x, y + 1, x, y + height - 1);
3532 _cairo_draw_line (cr, &color2,
3533 x + 1, y + 1, x + width - 2, y + 1);
3534 _cairo_draw_line (cr, &color2,
3535 x + 1, y + 1, x + 1, y + height - 1);
3537 _cairo_draw_line (cr, &color3,
3538 x + width - 2, y + 2, x + width - 2, y + height - 1);
3539 _cairo_draw_line (cr, &color4,
3540 x + width - 1, y + 1, x + width - 1, y + height - 1);
3543 _cairo_draw_line (cr, &color1,
3544 x, y, x + width - 2, y);
3545 _cairo_draw_line (cr, &color2,
3546 x + 1, y + 1, x + width - 2, y + 1);
3548 _cairo_draw_line (cr, &color3,
3549 x, y + height - 2, x + width - 2, y + height - 2);
3550 _cairo_draw_line (cr, &color3,
3551 x + width - 2, y + 2, x + width - 2, y + height - 2);
3552 _cairo_draw_line (cr, &color4,
3553 x, y + height - 1, x + width - 2, y + height - 1);
3554 _cairo_draw_line (cr, &color4,
3555 x + width - 1, y + 1, x + width - 1, y + height - 2);
3558 _cairo_draw_line (cr, &color1,
3559 x + 1, y, x + width - 1, y);
3560 _cairo_draw_line (cr, &color1,
3561 x, y + 1, x, y + height - 2);
3562 _cairo_draw_line (cr, &color2,
3563 x + 1, y + 1, x + width - 1, y + 1);
3564 _cairo_draw_line (cr, &color2,
3565 x + 1, y + 1, x + 1, y + height - 2);
3567 _cairo_draw_line (cr, &color3,
3568 x + 2, y + height - 2, x + width - 1, y + height - 2);
3569 _cairo_draw_line (cr, &color4,
3570 x + 1, y + height - 1, x + width - 1, y + height - 1);
3577 gtk_default_draw_focus (GtkStyle *style,
3579 GtkStateType state_type,
3581 const gchar *detail,
3587 gboolean free_dash_list = FALSE;
3588 gint line_width = 1;
3589 gint8 *dash_list = (gint8 *) "\1\1";
3593 gtk_widget_style_get (widget,
3594 "focus-line-width", &line_width,
3595 "focus-line-pattern", (gchar *)&dash_list,
3598 free_dash_list = TRUE;
3601 if (detail && !strcmp (detail, "add-mode"))
3606 dash_list = (gint8 *) "\4\4";
3607 free_dash_list = FALSE;
3610 if (detail && !strcmp (detail, "colorwheel_light"))
3611 cairo_set_source_rgb (cr, 0., 0., 0.);
3612 else if (detail && !strcmp (detail, "colorwheel_dark"))
3613 cairo_set_source_rgb (cr, 1., 1., 1.);
3615 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3617 cairo_set_line_width (cr, line_width);
3621 gint n_dashes = strlen ((const gchar *) dash_list);
3622 gdouble *dashes = g_new (gdouble, n_dashes);
3623 gdouble total_length = 0;
3624 gdouble dash_offset;
3627 for (i = 0; i < n_dashes; i++)
3629 dashes[i] = dash_list[i];
3630 total_length += dash_list[i];
3633 /* The dash offset here aligns the pattern to integer pixels
3634 * by starting the dash at the right side of the left border
3635 * Negative dash offsets in cairo don't work
3636 * (https://bugs.freedesktop.org/show_bug.cgi?id=2729)
3638 dash_offset = - line_width / 2.;
3639 while (dash_offset < 0)
3640 dash_offset += total_length;
3642 cairo_set_dash (cr, dashes, n_dashes, dash_offset);
3646 cairo_rectangle (cr,
3647 x + line_width / 2.,
3648 y + line_width / 2.,
3650 height - line_width);
3658 gtk_default_draw_slider (GtkStyle *style,
3660 GtkStateType state_type,
3661 GtkShadowType shadow_type,
3663 const gchar *detail,
3668 GtkOrientation orientation)
3670 gtk_paint_box (style, cr, state_type, shadow_type,
3671 widget, detail, x, y, width, height);
3674 (strcmp ("hscale", detail) == 0 ||
3675 strcmp ("vscale", detail) == 0))
3677 if (orientation == GTK_ORIENTATION_HORIZONTAL)
3678 gtk_paint_vline (style, cr, state_type, widget, detail,
3679 y + style->ythickness,
3680 y + height - style->ythickness - 1, x + width / 2);
3682 gtk_paint_hline (style, cr, state_type, widget, detail,
3683 x + style->xthickness,
3684 x + width - style->xthickness - 1, y + height / 2);
3689 draw_dot (cairo_t *cr,
3696 size = CLAMP (size, 2, 3);
3700 _cairo_draw_point (cr, light, x, y);
3701 _cairo_draw_point (cr, light, x+1, y+1);
3705 _cairo_draw_point (cr, light, x, y);
3706 _cairo_draw_point (cr, light, x+1, y);
3707 _cairo_draw_point (cr, light, x, y+1);
3708 _cairo_draw_point (cr, dark, x+1, y+2);
3709 _cairo_draw_point (cr, dark, x+2, y+1);
3710 _cairo_draw_point (cr, dark, x+2, y+2);
3715 gtk_default_draw_handle (GtkStyle *style,
3717 GtkStateType state_type,
3718 GtkShadowType shadow_type,
3720 const gchar *detail,
3725 GtkOrientation orientation)
3728 gint xthick, ythick;
3729 GdkColor light, dark;
3731 gtk_paint_box (style, cr, state_type, shadow_type, widget,
3732 detail, x, y, width, height);
3734 if (detail && !strcmp (detail, "paned"))
3736 /* we want to ignore the shadow border in paned widgets */
3740 if (state_type == GTK_STATE_SELECTED && widget && !gtk_widget_has_focus (widget))
3741 _gtk_style_shade (&style->base[GTK_STATE_ACTIVE], &light,
3744 light = style->light[state_type];
3746 dark = style->black;
3750 xthick = style->xthickness;
3751 ythick = style->ythickness;
3753 light = style->light[state_type];
3754 dark = style->dark[state_type];
3757 cairo_rectangle(cr, x + xthick, y + ythick,
3758 width - (xthick * 2), height - (ythick * 2));
3761 if (detail && !strcmp (detail, "paned"))
3763 if (orientation == GTK_ORIENTATION_HORIZONTAL)
3764 for (xx = x + width/2 - 15; xx <= x + width/2 + 15; xx += 5)
3765 draw_dot (cr, &light, &dark, xx, y + height/2 - 1, 3);
3767 for (yy = y + height/2 - 15; yy <= y + height/2 + 15; yy += 5)
3768 draw_dot (cr, &light, &dark, x + width/2 - 1, yy, 3);
3772 for (yy = y + ythick; yy < (y + height - ythick); yy += 3)
3773 for (xx = x + xthick; xx < (x + width - xthick); xx += 6)
3775 draw_dot (cr, &light, &dark, xx, yy, 2);
3776 draw_dot (cr, &light, &dark, xx + 3, yy + 1, 2);
3782 gtk_default_draw_expander (GtkStyle *style,
3784 GtkStateType state_type,
3786 const gchar *detail,
3789 GtkExpanderStyle expander_style)
3791 #define DEFAULT_EXPANDER_SIZE 12
3795 double vertical_overshoot;
3798 double interp; /* interpolation factor for center position */
3799 double x_double_horz, y_double_horz;
3800 double x_double_vert, y_double_vert;
3801 double x_double, y_double;
3805 gtk_widget_class_find_style_property (GTK_WIDGET_GET_CLASS (widget),
3808 gtk_widget_style_get (widget,
3809 "expander-size", &expander_size,
3813 expander_size = DEFAULT_EXPANDER_SIZE;
3815 line_width = MAX (1, expander_size/9);
3817 switch (expander_style)
3819 case GTK_EXPANDER_COLLAPSED:
3820 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 180 : 0;
3823 case GTK_EXPANDER_SEMI_COLLAPSED:
3824 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 150 : 30;
3827 case GTK_EXPANDER_SEMI_EXPANDED:
3828 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 120 : 60;
3831 case GTK_EXPANDER_EXPANDED:
3836 g_assert_not_reached ();
3839 /* Compute distance that the stroke extends beyonds the end
3840 * of the triangle we draw.
3842 vertical_overshoot = line_width / 2.0 * (1. / tan (G_PI / 8));
3844 /* For odd line widths, we end the vertical line of the triangle
3845 * at a half pixel, so we round differently.
3847 if (line_width % 2 == 1)
3848 vertical_overshoot = ceil (0.5 + vertical_overshoot) - 0.5;
3850 vertical_overshoot = ceil (vertical_overshoot);
3852 /* Adjust the size of the triangle we draw so that the entire stroke fits
3854 diameter = MAX (3, expander_size - 2 * vertical_overshoot);
3856 /* If the line width is odd, we want the diameter to be even,
3857 * and vice versa, so force the sum to be odd. This relationship
3858 * makes the point of the triangle look right.
3860 diameter -= (1 - (diameter + line_width) % 2);
3862 radius = diameter / 2.;
3864 /* Adjust the center so that the stroke is properly aligned with
3865 * the pixel grid. The center adjustment is different for the
3866 * horizontal and vertical orientations. For intermediate positions
3867 * we interpolate between the two.
3869 x_double_vert = floor (x - (radius + line_width) / 2.) + (radius + line_width) / 2.;
3870 y_double_vert = y - 0.5;
3872 x_double_horz = x - 0.5;
3873 y_double_horz = floor (y - (radius + line_width) / 2.) + (radius + line_width) / 2.;
3875 x_double = x_double_vert * (1 - interp) + x_double_horz * interp;
3876 y_double = y_double_vert * (1 - interp) + y_double_horz * interp;
3878 cairo_translate (cr, x_double, y_double);
3879 cairo_rotate (cr, degrees * G_PI / 180);
3881 cairo_move_to (cr, - radius / 2., - radius);
3882 cairo_line_to (cr, radius / 2., 0);
3883 cairo_line_to (cr, - radius / 2., radius);
3884 cairo_close_path (cr);
3886 cairo_set_line_width (cr, line_width);
3888 if (state_type == GTK_STATE_PRELIGHT)
3889 gdk_cairo_set_source_color (cr,
3890 &style->fg[GTK_STATE_PRELIGHT]);
3891 else if (state_type == GTK_STATE_ACTIVE)
3892 gdk_cairo_set_source_color (cr,
3893 &style->light[GTK_STATE_ACTIVE]);
3895 gdk_cairo_set_source_color (cr,
3896 &style->base[GTK_STATE_NORMAL]);
3898 cairo_fill_preserve (cr);
3900 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3905 gtk_default_draw_layout (GtkStyle *style,
3907 GtkStateType state_type,
3910 const gchar *detail,
3913 PangoLayout *layout)
3916 const PangoMatrix *matrix;
3918 matrix = pango_context_get_matrix (pango_layout_get_context (layout));
3921 cairo_matrix_t cairo_matrix;
3922 PangoMatrix tmp_matrix;
3923 PangoRectangle rect;
3925 cairo_matrix_init (&cairo_matrix,
3926 matrix->xx, matrix->yx,
3927 matrix->xy, matrix->yy,
3928 matrix->x0, matrix->y0);
3930 pango_layout_get_extents (layout, NULL, &rect);
3931 pango_matrix_transform_rectangle (matrix, &rect);
3932 pango_extents_to_pixels (&rect, NULL);
3934 tmp_matrix = *matrix;
3935 cairo_matrix.x0 += x - rect.x;
3936 cairo_matrix.y0 += y - rect.y;
3938 cairo_set_matrix (cr, &cairo_matrix);
3941 cairo_translate (cr, x, y);
3943 cairo_new_path (cr);
3945 if (state_type == GTK_STATE_INSENSITIVE)
3947 gdk_cairo_set_source_color (cr, &style->white);
3948 cairo_move_to (cr, 1, 1);
3949 _gtk_pango_fill_layout (cr, layout);
3950 cairo_new_path (cr);
3953 gc = use_text ? &style->text[state_type] : &style->fg[state_type];
3955 gdk_cairo_set_source_color (cr, gc);
3957 pango_cairo_show_layout (cr, layout);
3961 gtk_default_draw_resize_grip (GtkStyle *style,
3963 GtkStateType state_type,
3965 const gchar *detail,
3974 cairo_rectangle (cr, x, y, width, height);
3977 cairo_set_line_width (cr, 1.0);
3982 case GDK_WINDOW_EDGE_NORTH_WEST:
3983 /* make it square */
3986 else if (height < width)
3990 case GDK_WINDOW_EDGE_NORTH:
3994 case GDK_WINDOW_EDGE_NORTH_EAST:
3995 /* make it square, aligning to top right */
3998 else if (height < width)
4000 x += (width - height);
4005 case GDK_WINDOW_EDGE_WEST:
4009 case GDK_WINDOW_EDGE_EAST:
4010 /* aligning to right */
4013 x += (width - height);
4017 case GDK_WINDOW_EDGE_SOUTH_WEST:
4018 /* make it square, aligning to bottom left */
4021 y += (height - width);
4024 else if (height < width)
4028 case GDK_WINDOW_EDGE_SOUTH:
4029 /* align to bottom */
4032 y += (height - width);
4036 case GDK_WINDOW_EDGE_SOUTH_EAST:
4037 /* make it square, aligning to bottom right */
4040 y += (height - width);
4043 else if (height < width)
4045 x += (width - height);
4051 g_assert_not_reached ();
4056 case GDK_WINDOW_EDGE_WEST:
4057 case GDK_WINDOW_EDGE_EAST:
4063 while (xi < x + width)
4065 _cairo_draw_line (cr,
4066 &style->light[state_type],
4071 _cairo_draw_line (cr,
4072 &style->dark[state_type],
4080 case GDK_WINDOW_EDGE_NORTH:
4081 case GDK_WINDOW_EDGE_SOUTH:
4087 while (yi < y + height)
4089 _cairo_draw_line (cr,
4090 &style->light[state_type],
4095 _cairo_draw_line (cr,
4096 &style->dark[state_type],
4104 case GDK_WINDOW_EDGE_NORTH_WEST:
4113 _cairo_draw_line (cr,
4114 &style->dark[state_type],
4121 _cairo_draw_line (cr,
4122 &style->dark[state_type],
4129 _cairo_draw_line (cr,
4130 &style->light[state_type],
4140 case GDK_WINDOW_EDGE_NORTH_EAST:
4147 while (xi < (x + width - 3))
4149 _cairo_draw_line (cr,
4150 &style->light[state_type],
4157 _cairo_draw_line (cr,
4158 &style->dark[state_type],
4165 _cairo_draw_line (cr,
4166 &style->dark[state_type],
4175 case GDK_WINDOW_EDGE_SOUTH_WEST:
4184 _cairo_draw_line (cr,
4185 &style->dark[state_type],
4192 _cairo_draw_line (cr,
4193 &style->dark[state_type],
4200 _cairo_draw_line (cr,
4201 &style->light[state_type],
4211 case GDK_WINDOW_EDGE_SOUTH_EAST:
4218 while (xi < (x + width - 3))
4220 _cairo_draw_line (cr,
4221 &style->light[state_type],
4228 _cairo_draw_line (cr,
4229 &style->dark[state_type],
4236 _cairo_draw_line (cr,
4237 &style->dark[state_type],
4247 g_assert_not_reached ();
4253 gtk_default_draw_spinner (GtkStyle *style,
4255 GtkStateType state_type,
4257 const gchar *detail,
4272 gtk_style_get (style, GTK_TYPE_SPINNER,
4273 "num-steps", &num_steps,
4275 real_step = step % num_steps;
4277 /* set a clip region for the expose event */
4278 cairo_rectangle (cr, x, y, width, height);
4281 cairo_translate (cr, x, y);
4283 /* draw clip region */
4284 cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
4286 color = &style->fg[state_type];
4289 radius = MIN (width / 2, height / 2);
4290 half = num_steps / 2;
4292 for (i = 0; i < num_steps; i++)
4294 gint inset = 0.7 * radius;
4296 /* transparency is a function of time and intial value */
4297 gdouble t = (gdouble) ((i + num_steps - real_step)
4298 % num_steps) / num_steps;
4302 cairo_set_source_rgba (cr,
4303 color->red / 65535.,
4304 color->green / 65535.,
4305 color->blue / 65535.,
4308 cairo_set_line_width (cr, 2.0);
4310 dx + (radius - inset) * cos (i * G_PI / half),
4311 dy + (radius - inset) * sin (i * G_PI / half));
4313 dx + radius * cos (i * G_PI / half),
4314 dy + radius * sin (i * G_PI / half));
4322 _gtk_style_shade (const GdkColor *a,
4330 red = (gdouble) a->red / 65535.0;
4331 green = (gdouble) a->green / 65535.0;
4332 blue = (gdouble) a->blue / 65535.0;
4334 rgb_to_hls (&red, &green, &blue);
4339 else if (green < 0.0)
4345 else if (blue < 0.0)
4348 hls_to_rgb (&red, &green, &blue);
4350 b->red = red * 65535.0;
4351 b->green = green * 65535.0;
4352 b->blue = blue * 65535.0;
4356 rgb_to_hls (gdouble *r,
4397 l = (max + min) / 2;
4404 s = (max - min) / (max + min);
4406 s = (max - min) / (2 - max - min);
4410 h = (green - blue) / delta;
4411 else if (green == max)
4412 h = 2 + (blue - red) / delta;
4413 else if (blue == max)
4414 h = 4 + (red - green) / delta;
4427 hls_to_rgb (gdouble *h,
4440 if (lightness <= 0.5)
4441 m2 = lightness * (1 + saturation);
4443 m2 = lightness + saturation - lightness * saturation;
4444 m1 = 2 * lightness - m2;
4446 if (saturation == 0)
4461 r = m1 + (m2 - m1) * hue / 60;
4465 r = m1 + (m2 - m1) * (240 - hue) / 60;
4476 g = m1 + (m2 - m1) * hue / 60;
4480 g = m1 + (m2 - m1) * (240 - hue) / 60;
4491 b = m1 + (m2 - m1) * hue / 60;
4495 b = m1 + (m2 - m1) * (240 - hue) / 60;
4508 * @style: a #GtkStyle
4510 * @state_type: a state
4511 * @widget: (allow-none): the widget
4512 * @detail: (allow-none): a style detail
4513 * @x1: the starting x coordinate
4514 * @x2: the ending x coordinate
4515 * @y: the y coordinate
4517 * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @cr
4518 * using the given style and state.
4521 gtk_paint_hline (GtkStyle *style,
4523 GtkStateType state_type,
4525 const gchar *detail,
4530 g_return_if_fail (GTK_IS_STYLE (style));
4531 g_return_if_fail (cr != NULL);
4532 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
4536 GTK_STYLE_GET_CLASS (style)->draw_hline (style, cr, state_type,
4545 * @style: a #GtkStyle
4547 * @state_type: a state
4548 * @widget: (allow-none): the widget
4549 * @detail: (allow-none): a style detail
4550 * @y1_: the starting y coordinate
4551 * @y2_: the ending y coordinate
4552 * @x: the x coordinate
4554 * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @cr
4555 * using the given style and state.
4558 gtk_paint_vline (GtkStyle *style,
4560 GtkStateType state_type,
4562 const gchar *detail,
4567 g_return_if_fail (GTK_IS_STYLE (style));
4568 g_return_if_fail (cr != NULL);
4569 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
4573 GTK_STYLE_GET_CLASS (style)->draw_vline (style, cr, state_type,
4582 * @style: a #GtkStyle
4584 * @state_type: a state
4585 * @shadow_type: type of shadow to draw
4586 * @widget: (allow-none): the widget
4587 * @detail: (allow-none): a style detail
4588 * @x: x origin of the rectangle
4589 * @y: y origin of the rectangle
4590 * @width: width of the rectangle
4591 * @height: width of the rectangle
4593 * Draws a shadow around the given rectangle in @cr
4594 * using the given style and state and shadow type.
4597 gtk_paint_shadow (GtkStyle *style,
4599 GtkStateType state_type,
4600 GtkShadowType shadow_type,
4602 const gchar *detail,
4608 g_return_if_fail (GTK_IS_STYLE (style));
4609 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
4610 g_return_if_fail (cr != NULL);
4611 g_return_if_fail (width >= 0);
4612 g_return_if_fail (height >= 0);
4616 GTK_STYLE_GET_CLASS (style)->draw_shadow (style, cr, state_type, shadow_type,
4618 x, y, width, height);
4625 * @style: a #GtkStyle
4627 * @state_type: a state
4628 * @shadow_type: the type of shadow to draw
4629 * @widget: (allow-none): the widget
4630 * @detail: (allow-none): a style detail
4631 * @arrow_type: the type of arrow to draw
4632 * @fill: %TRUE if the arrow tip should be filled
4633 * @x: x origin of the rectangle to draw the arrow in
4634 * @y: y origin of the rectangle to draw the arrow in
4635 * @width: width of the rectangle to draw the arrow in
4636 * @height: height of the rectangle to draw the arrow in
4638 * Draws an arrow in the given rectangle on @cr using the given
4639 * parameters. @arrow_type determines the direction of the arrow.
4642 gtk_paint_arrow (GtkStyle *style,
4644 GtkStateType state_type,
4645 GtkShadowType shadow_type,
4647 const gchar *detail,
4648 GtkArrowType arrow_type,
4655 g_return_if_fail (GTK_IS_STYLE (style));
4656 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
4657 g_return_if_fail (cr != NULL);
4658 g_return_if_fail (width >= 0);
4659 g_return_if_fail (height >= 0);
4663 GTK_STYLE_GET_CLASS (style)->draw_arrow (style, cr, state_type, shadow_type,
4665 arrow_type, fill, x, y, width, height);
4671 * gtk_paint_diamond:
4672 * @style: a #GtkStyle
4674 * @state_type: a state
4675 * @shadow_type: the type of shadow to draw
4676 * @widget: (allow-none): the widget
4677 * @detail: (allow-none): a style detail
4678 * @x: x origin of the rectangle to draw the diamond in
4679 * @y: y origin of the rectangle to draw the diamond in
4680 * @width: width of the rectangle to draw the diamond in
4681 * @height: height of the rectangle to draw the diamond in
4683 * Draws a diamond in the given rectangle on @window using the given
4687 gtk_paint_diamond (GtkStyle *style,
4689 GtkStateType state_type,
4690 GtkShadowType shadow_type,
4692 const gchar *detail,
4698 g_return_if_fail (GTK_IS_STYLE (style));
4699 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
4700 g_return_if_fail (cr != NULL);
4701 g_return_if_fail (width >= 0);
4702 g_return_if_fail (height >= 0);
4706 GTK_STYLE_GET_CLASS (style)->draw_diamond (style, cr, state_type, shadow_type,
4708 x, y, width, height);
4715 * @style: a #GtkStyle
4717 * @state_type: a state
4718 * @shadow_type: the type of shadow to draw
4719 * @widget: (allow-none): the widget
4720 * @detail: (allow-none): a style detail
4721 * @x: x origin of the box
4722 * @y: y origin of the box
4723 * @width: the width of the box
4724 * @height: the height of the box
4726 * Draws a box on @cr with the given parameters.
4729 gtk_paint_box (GtkStyle *style,
4731 GtkStateType state_type,
4732 GtkShadowType shadow_type,
4734 const gchar *detail,
4740 g_return_if_fail (GTK_IS_STYLE (style));
4741 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
4742 g_return_if_fail (cr != NULL);
4746 GTK_STYLE_GET_CLASS (style)->draw_box (style, cr, state_type, shadow_type,
4748 x, y, width, height);
4754 * gtk_paint_flat_box:
4755 * @style: a #GtkStyle
4757 * @state_type: a state
4758 * @shadow_type: the type of shadow to draw
4759 * @area: (allow-none): clip rectangle, or %NULL if the
4760 * output should not be clipped
4761 * @widget: (allow-none): the widget
4762 * @detail: (allow-none): a style detail
4763 * @x: x origin of the box
4764 * @y: y origin of the box
4765 * @width: the width of the box
4766 * @height: the height of the box
4768 * Draws a flat box on @cr with the given parameters.
4771 gtk_paint_flat_box (GtkStyle *style,
4773 GtkStateType state_type,
4774 GtkShadowType shadow_type,
4776 const gchar *detail,
4782 g_return_if_fail (GTK_IS_STYLE (style));
4783 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
4784 g_return_if_fail (cr != NULL);
4785 g_return_if_fail (width >= 0);
4786 g_return_if_fail (height >= 0);
4790 GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, cr, state_type, shadow_type,
4792 x, y, width, height);
4799 * @style: a #GtkStyle
4801 * @state_type: a state
4802 * @shadow_type: the type of shadow to draw
4803 * @widget: (allow-none): the widget
4804 * @detail: (allow-none): a style detail
4805 * @x: x origin of the rectangle to draw the check in
4806 * @y: y origin of the rectangle to draw the check in
4807 * @width: the width of the rectangle to draw the check in
4808 * @height: the height of the rectangle to draw the check in
4810 * Draws a check button indicator in the given rectangle on @cr with
4811 * the given parameters.
4814 gtk_paint_check (GtkStyle *style,
4816 GtkStateType state_type,
4817 GtkShadowType shadow_type,
4819 const gchar *detail,
4825 g_return_if_fail (GTK_IS_STYLE (style));
4826 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
4827 g_return_if_fail (cr != NULL);
4831 GTK_STYLE_GET_CLASS (style)->draw_check (style, cr, state_type, shadow_type,
4833 x, y, width, height);
4840 * @style: a #GtkStyle
4842 * @state_type: a state
4843 * @shadow_type: the type of shadow to draw
4844 * @widget: (allow-none): the widget
4845 * @detail: (allow-none): a style detail
4846 * @x: x origin of the rectangle to draw the option in
4847 * @y: y origin of the rectangle to draw the option in
4848 * @width: the width of the rectangle to draw the option in
4849 * @height: the height of the rectangle to draw the option in
4851 * Draws a radio button indicator in the given rectangle on @cr with
4852 * the given parameters.
4855 gtk_paint_option (GtkStyle *style,
4857 GtkStateType state_type,
4858 GtkShadowType shadow_type,
4860 const gchar *detail,
4866 g_return_if_fail (GTK_IS_STYLE (style));
4867 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
4868 g_return_if_fail (cr != NULL);
4872 GTK_STYLE_GET_CLASS (style)->draw_option (style, cr, state_type, shadow_type,
4874 x, y, width, height);
4881 * @style: a #GtkStyle
4883 * @state_type: a state
4884 * @shadow_type: the type of shadow to draw
4885 * @widget: (allow-none): the widget
4886 * @detail: (allow-none): a style detail
4887 * @x: x origin of the rectangle to draw the tab in
4888 * @y: y origin of the rectangle to draw the tab in
4889 * @width: the width of the rectangle to draw the tab in
4890 * @height: the height of the rectangle to draw the tab in
4892 * Draws an option menu tab (i.e. the up and down pointing arrows)
4893 * in the given rectangle on @cr using the given parameters.
4896 gtk_paint_tab (GtkStyle *style,
4898 GtkStateType state_type,
4899 GtkShadowType shadow_type,
4901 const gchar *detail,
4907 g_return_if_fail (GTK_IS_STYLE (style));
4908 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
4909 g_return_if_fail (cr != NULL);
4913 GTK_STYLE_GET_CLASS (style)->draw_tab (style, cr, state_type, shadow_type,
4915 x, y, width, height);
4921 * gtk_paint_shadow_gap:
4922 * @style: a #GtkStyle
4924 * @state_type: a state
4925 * @shadow_type: type of shadow to draw
4926 * @widget: (allow-none): the widget
4927 * @detail: (allow-none): a style detail
4928 * @x: x origin of the rectangle
4929 * @y: y origin of the rectangle
4930 * @width: width of the rectangle
4931 * @height: width of the rectangle
4932 * @gap_side: side in which to leave the gap
4933 * @gap_x: starting position of the gap
4934 * @gap_width: width of the gap
4936 * Draws a shadow around the given rectangle in @cr
4937 * using the given style and state and shadow type, leaving a
4941 gtk_paint_shadow_gap (GtkStyle *style,
4943 GtkStateType state_type,
4944 GtkShadowType shadow_type,
4946 const gchar *detail,
4951 GtkPositionType gap_side,
4955 g_return_if_fail (GTK_IS_STYLE (style));
4956 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
4957 g_return_if_fail (cr != NULL);
4958 g_return_if_fail (width >= 0);
4959 g_return_if_fail (height >= 0);
4963 GTK_STYLE_GET_CLASS (style)->draw_shadow_gap (style, cr, state_type, shadow_type,
4965 x, y, width, height, gap_side, gap_x, gap_width);
4971 * gtk_paint_box_gap:
4972 * @style: a #GtkStyle
4974 * @state_type: a state
4975 * @shadow_type: type of shadow to draw
4976 * @widget: (allow-none): the widget
4977 * @detail: (allow-none): a style detail
4978 * @x: x origin of the rectangle
4979 * @y: y origin of the rectangle
4980 * @width: width of the rectangle
4981 * @height: width of the rectangle
4982 * @gap_side: side in which to leave the gap
4983 * @gap_x: starting position of the gap
4984 * @gap_width: width of the gap
4986 * Draws a box in @cr using the given style and state and shadow type,
4987 * leaving a gap in one side.
4990 gtk_paint_box_gap (GtkStyle *style,
4992 GtkStateType state_type,
4993 GtkShadowType shadow_type,
4995 const gchar *detail,
5000 GtkPositionType gap_side,
5004 g_return_if_fail (GTK_IS_STYLE (style));
5005 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
5006 g_return_if_fail (cr != NULL);
5007 g_return_if_fail (width >= 0);
5008 g_return_if_fail (height >= 0);
5012 GTK_STYLE_GET_CLASS (style)->draw_box_gap (style, cr, state_type, shadow_type,
5014 x, y, width, height, gap_side, gap_x, gap_width);
5020 * gtk_paint_extension:
5021 * @style: a #GtkStyle
5023 * @state_type: a state
5024 * @shadow_type: type of shadow to draw
5025 * @widget: (allow-none): the widget
5026 * @detail: (allow-none): a style detail
5027 * @x: x origin of the extension
5028 * @y: y origin of the extension
5029 * @width: width of the extension
5030 * @height: width of the extension
5031 * @gap_side: the side on to which the extension is attached
5033 * Draws an extension, i.e. a notebook tab.
5036 gtk_paint_extension (GtkStyle *style,
5038 GtkStateType state_type,
5039 GtkShadowType shadow_type,
5041 const gchar *detail,
5046 GtkPositionType gap_side)
5048 g_return_if_fail (GTK_IS_STYLE (style));
5049 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
5050 g_return_if_fail (cr != NULL);
5051 g_return_if_fail (width >= 0);
5052 g_return_if_fail (height >= 0);
5056 GTK_STYLE_GET_CLASS (style)->draw_extension (style, cr, state_type, shadow_type,
5058 x, y, width, height, gap_side);
5065 * @style: a #GtkStyle
5067 * @state_type: a state
5068 * @widget: (allow-none): the widget
5069 * @detail: (allow-none): a style detail
5070 * @x: the x origin of the rectangle around which to draw a focus indicator
5071 * @y: the y origin of the rectangle around which to draw a focus indicator
5072 * @width: the width of the rectangle around which to draw a focus indicator
5073 * @height: the height of the rectangle around which to draw a focus indicator
5075 * Draws a focus indicator around the given rectangle on @cr using the
5079 gtk_paint_focus (GtkStyle *style,
5081 GtkStateType state_type,
5083 const gchar *detail,
5089 g_return_if_fail (GTK_IS_STYLE (style));
5090 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
5091 g_return_if_fail (cr != NULL);
5092 g_return_if_fail (width >= 0);
5093 g_return_if_fail (height >= 0);
5097 GTK_STYLE_GET_CLASS (style)->draw_focus (style, cr, state_type,
5099 x, y, width, height);
5106 * @style: a #GtkStyle
5108 * @state_type: a state
5109 * @shadow_type: a shadow
5110 * @widget: (allow-none): the widget
5111 * @detail: (allow-none): a style detail
5112 * @x: the x origin of the rectangle in which to draw a slider
5113 * @y: the y origin of the rectangle in which to draw a slider
5114 * @width: the width of the rectangle in which to draw a slider
5115 * @height: the height of the rectangle in which to draw a slider
5116 * @orientation: the orientation to be used
5118 * Draws a slider in the given rectangle on @cr using the
5119 * given style and orientation.
5122 gtk_paint_slider (GtkStyle *style,
5124 GtkStateType state_type,
5125 GtkShadowType shadow_type,
5127 const gchar *detail,
5132 GtkOrientation orientation)
5134 g_return_if_fail (GTK_IS_STYLE (style));
5135 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
5136 g_return_if_fail (cr != NULL);
5137 g_return_if_fail (width >= 0);
5138 g_return_if_fail (height >= 0);
5142 GTK_STYLE_GET_CLASS (style)->draw_slider (style, cr, state_type, shadow_type,
5144 x, y, width, height, orientation);
5151 * @style: a #GtkStyle
5153 * @state_type: a state
5154 * @shadow_type: type of shadow to draw
5155 * @widget: (allow-none): the widget
5156 * @detail: (allow-none): a style detail
5157 * @x: x origin of the handle
5158 * @y: y origin of the handle
5159 * @width: with of the handle
5160 * @height: height of the handle
5161 * @orientation: the orientation of the handle
5163 * Draws a handle as used in #GtkHandleBox and #GtkPaned.
5166 gtk_paint_handle (GtkStyle *style,
5168 GtkStateType state_type,
5169 GtkShadowType shadow_type,
5171 const gchar *detail,
5176 GtkOrientation orientation)
5178 g_return_if_fail (GTK_IS_STYLE (style));
5179 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
5180 g_return_if_fail (cr != NULL);
5181 g_return_if_fail (width >= 0);
5182 g_return_if_fail (height >= 0);
5186 GTK_STYLE_GET_CLASS (style)->draw_handle (style, cr, state_type, shadow_type,
5188 x, y, width, height, orientation);
5194 * gtk_paint_expander:
5195 * @style: a #GtkStyle
5197 * @state_type: a state
5198 * @widget: (allow-none): the widget
5199 * @detail: (allow-none): a style detail
5200 * @x: the x position to draw the expander at
5201 * @y: the y position to draw the expander at
5202 * @expander_style: the style to draw the expander in; determines
5203 * whether the expander is collapsed, expanded, or in an
5204 * intermediate state.
5206 * Draws an expander as used in #GtkTreeView. @x and @y specify the
5207 * center the expander. The size of the expander is determined by the
5208 * "expander-size" style property of @widget. (If widget is not
5209 * specified or doesn't have an "expander-size" property, an
5210 * unspecified default size will be used, since the caller doesn't
5211 * have sufficient information to position the expander, this is
5212 * likely not useful.) The expander is expander_size pixels tall
5213 * in the collapsed position and expander_size pixels wide in the
5214 * expanded position.
5217 gtk_paint_expander (GtkStyle *style,
5219 GtkStateType state_type,
5221 const gchar *detail,
5224 GtkExpanderStyle expander_style)
5226 g_return_if_fail (GTK_IS_STYLE (style));
5227 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
5228 g_return_if_fail (cr != NULL);
5232 GTK_STYLE_GET_CLASS (style)->draw_expander (style, cr, state_type,
5234 x, y, expander_style);
5241 * @style: a #GtkStyle
5243 * @state_type: a state
5244 * @use_text: whether to use the text or foreground
5245 * graphics context of @style
5246 * @widget: (allow-none): the widget
5247 * @detail: (allow-none): a style detail
5250 * @layout: the layout to draw
5252 * Draws a layout on @cr using the given parameters.
5255 gtk_paint_layout (GtkStyle *style,
5257 GtkStateType state_type,
5260 const gchar *detail,
5263 PangoLayout *layout)
5265 g_return_if_fail (GTK_IS_STYLE (style));
5266 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
5267 g_return_if_fail (cr != NULL);
5271 GTK_STYLE_GET_CLASS (style)->draw_layout (style, cr, state_type, use_text,
5279 * gtk_paint_resize_grip:
5280 * @style: a #GtkStyle
5282 * @state_type: a state
5283 * @widget: (allow-none): the widget
5284 * @detail: (allow-none): a style detail
5285 * @edge: the edge in which to draw the resize grip
5286 * @x: the x origin of the rectangle in which to draw the resize grip
5287 * @y: the y origin of the rectangle in which to draw the resize grip
5288 * @width: the width of the rectangle in which to draw the resize grip
5289 * @height: the height of the rectangle in which to draw the resize grip
5291 * Draws a resize grip in the given rectangle on @cr using the given
5295 gtk_paint_resize_grip (GtkStyle *style,
5297 GtkStateType state_type,
5299 const gchar *detail,
5306 g_return_if_fail (GTK_IS_STYLE (style));
5307 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
5308 g_return_if_fail (cr != NULL);
5312 GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, cr, state_type,
5314 edge, x, y, width, height);
5319 * gtk_paint_spinner:
5320 * @style: a #GtkStyle
5322 * @state_type: a state
5323 * @widget: (allow-none): the widget (may be %NULL)
5324 * @detail: (allow-none): a style detail (may be %NULL)
5325 * @step: the nth step, a value between 0 and #GtkSpinner:num-steps
5326 * @x: the x origin of the rectangle in which to draw the spinner
5327 * @y: the y origin of the rectangle in which to draw the spinner
5328 * @width: the width of the rectangle in which to draw the spinner
5329 * @height: the height of the rectangle in which to draw the spinner
5331 * Draws a spinner on @window using the given parameters.
5334 gtk_paint_spinner (GtkStyle *style,
5336 GtkStateType state_type,
5338 const gchar *detail,
5345 g_return_if_fail (GTK_IS_STYLE (style));
5346 g_return_if_fail (cr != NULL);
5347 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_spinner != NULL);
5351 GTK_STYLE_GET_CLASS (style)->draw_spinner (style, cr, state_type,
5353 step, x, y, width, height);
5361 * Allocates a new #GtkBorder structure and initializes its elements to zero.
5363 * Returns: a new empty #GtkBorder. The newly allocated #GtkBorder should be
5364 * freed with gtk_border_free()
5369 gtk_border_new (void)
5371 return g_slice_new0 (GtkBorder);
5376 * @border_: a #GtkBorder.
5377 * @returns: a copy of @border_.
5379 * Copies a #GtkBorder structure.
5382 gtk_border_copy (const GtkBorder *border)
5384 g_return_val_if_fail (border != NULL, NULL);
5386 return g_slice_dup (GtkBorder, border);
5391 * @border_: a #GtkBorder.
5393 * Frees a #GtkBorder structure.
5396 gtk_border_free (GtkBorder *border)
5398 g_slice_free (GtkBorder, border);
5401 G_DEFINE_BOXED_TYPE (GtkBorder, gtk_border,
5405 typedef struct _CursorInfo CursorInfo;
5415 style_unrealize_cursors (GtkStyle *style)
5419 cursor_info = g_object_get_data (G_OBJECT (style), "gtk-style-cursor-info");
5422 g_free (cursor_info);
5423 g_object_set_data (G_OBJECT (style), I_("gtk-style-cursor-info"), NULL);
5427 static const GdkColor *
5428 get_insertion_cursor_color (GtkWidget *widget,
5429 gboolean is_primary)
5431 CursorInfo *cursor_info;
5433 GdkColor *cursor_color;
5435 style = gtk_widget_get_style (widget);
5437 cursor_info = g_object_get_data (G_OBJECT (style), "gtk-style-cursor-info");
5440 cursor_info = g_new0 (CursorInfo, 1);
5441 g_object_set_data (G_OBJECT (style), I_("gtk-style-cursor-info"), cursor_info);
5442 cursor_info->for_type = G_TYPE_INVALID;
5445 /* We have to keep track of the type because gtk_widget_style_get()
5446 * can return different results when called on the same property and
5447 * same style but for different widgets. :-(. That is,
5448 * GtkEntry::cursor-color = "red" in a style will modify the cursor
5449 * color for entries but not for text view.
5451 if (cursor_info->for_type != G_OBJECT_TYPE (widget))
5453 cursor_info->for_type = G_OBJECT_TYPE (widget);
5455 /* Cursors in text widgets are drawn only in NORMAL state,
5456 * so we can use text[GTK_STATE_NORMAL] as text color here */
5457 gtk_widget_style_get (widget, "cursor-color", &cursor_color, NULL);
5460 cursor_info->primary = *cursor_color;
5461 gdk_color_free (cursor_color);
5465 cursor_info->primary = style->text[GTK_STATE_NORMAL];
5468 gtk_widget_style_get (widget, "secondary-cursor-color", &cursor_color, NULL);
5471 cursor_info->secondary = *cursor_color;
5472 gdk_color_free (cursor_color);
5476 /* text_aa is the average of text and base colors,
5477 * in usual black-on-white case it's grey. */
5478 cursor_info->secondary = style->text_aa[GTK_STATE_NORMAL];
5483 return &cursor_info->primary;
5485 return &cursor_info->secondary;
5489 _gtk_widget_get_cursor_color (GtkWidget *widget,
5492 GdkColor *style_color;
5494 g_return_if_fail (GTK_IS_WIDGET (widget));
5495 g_return_if_fail (color != NULL);
5497 gtk_widget_style_get (widget, "cursor-color", &style_color, NULL);
5501 *color = *style_color;
5502 gdk_color_free (style_color);
5505 *color = gtk_widget_get_style (widget)->text[GTK_STATE_NORMAL];
5509 * gtk_draw_insertion_cursor:
5510 * @widget: a #GtkWidget
5511 * @cr: cairo context to draw to
5512 * @location: location where to draw the cursor (@location->width is ignored)
5513 * @is_primary: if the cursor should be the primary cursor color.
5514 * @direction: whether the cursor is left-to-right or
5515 * right-to-left. Should never be #GTK_TEXT_DIR_NONE
5516 * @draw_arrow: %TRUE to draw a directional arrow on the
5517 * cursor. Should be %FALSE unless the cursor is split.
5519 * Draws a text caret on @cr at @location. This is not a style function
5520 * but merely a convenience function for drawing the standard cursor shape.
5525 gtk_draw_insertion_cursor (GtkWidget *widget,
5527 const GdkRectangle *location,
5528 gboolean is_primary,
5529 GtkTextDirection direction,
5530 gboolean draw_arrow)
5535 gfloat cursor_aspect_ratio;
5538 g_return_if_fail (GTK_IS_WIDGET (widget));
5539 g_return_if_fail (cr != NULL);
5540 g_return_if_fail (location != NULL);
5541 g_return_if_fail (direction != GTK_TEXT_DIR_NONE);
5543 gdk_cairo_set_source_color (cr, get_insertion_cursor_color (widget, is_primary));
5545 /* When changing the shape or size of the cursor here,
5546 * propagate the changes to gtktextview.c:text_window_invalidate_cursors().
5549 gtk_widget_style_get (widget, "cursor-aspect-ratio", &cursor_aspect_ratio, NULL);
5551 stem_width = location->height * cursor_aspect_ratio + 1;
5552 arrow_width = stem_width + 1;
5554 /* put (stem_width % 2) on the proper side of the cursor */
5555 if (direction == GTK_TEXT_DIR_LTR)
5556 offset = stem_width / 2;
5558 offset = stem_width - stem_width / 2;
5560 cairo_rectangle (cr,
5561 location->x - offset, location->y,
5562 stem_width, location->height);
5567 if (direction == GTK_TEXT_DIR_RTL)
5569 x = location->x - offset - 1;
5570 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
5572 cairo_move_to (cr, x, y + 1);
5573 cairo_line_to (cr, x - arrow_width, y + arrow_width);
5574 cairo_line_to (cr, x, y + 2 * arrow_width);
5577 else if (direction == GTK_TEXT_DIR_LTR)
5579 x = location->x + stem_width - offset;
5580 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
5582 cairo_move_to (cr, x, y + 1);
5583 cairo_line_to (cr, x + arrow_width, y + arrow_width);
5584 cairo_line_to (cr, x, y + 2 * arrow_width);