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>
33 #include "gtkmarshalers.h"
34 #undef GTK_DISABLE_DEPRECATED
35 #include "gtkoptionmenu.h"
37 #include "gtkspinbutton.h"
39 #include "gtkwidget.h"
40 #include "gtkthemes.h"
41 #include "gtkiconfactory.h"
42 #include "gtksettings.h" /* _gtk_settings_parse_convert() */
46 #define LIGHTNESS_MULT 1.3
47 #define DARKNESS_MULT 0.7
49 /* --- typedefs & structures --- */
56 #define GTK_STYLE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_STYLE, GtkStylePrivate))
58 typedef struct _GtkStylePrivate GtkStylePrivate;
60 struct _GtkStylePrivate {
64 /* --- prototypes --- */
65 static void gtk_style_finalize (GObject *object);
66 static void gtk_style_realize (GtkStyle *style,
67 GdkColormap *colormap);
68 static void gtk_style_real_realize (GtkStyle *style);
69 static void gtk_style_real_unrealize (GtkStyle *style);
70 static void gtk_style_real_copy (GtkStyle *style,
72 static void gtk_style_real_set_background (GtkStyle *style,
74 GtkStateType state_type);
75 static GtkStyle *gtk_style_real_clone (GtkStyle *style);
76 static void gtk_style_real_init_from_rc (GtkStyle *style,
77 GtkRcStyle *rc_style);
78 static GdkPixbuf *gtk_default_render_icon (GtkStyle *style,
79 const GtkIconSource *source,
80 GtkTextDirection direction,
85 static void gtk_default_draw_hline (GtkStyle *style,
87 GtkStateType state_type,
94 static void gtk_default_draw_vline (GtkStyle *style,
96 GtkStateType state_type,
103 static void gtk_default_draw_shadow (GtkStyle *style,
105 GtkStateType state_type,
106 GtkShadowType shadow_type,
114 static void gtk_default_draw_polygon (GtkStyle *style,
116 GtkStateType state_type,
117 GtkShadowType shadow_type,
124 static void gtk_default_draw_arrow (GtkStyle *style,
126 GtkStateType state_type,
127 GtkShadowType shadow_type,
131 GtkArrowType arrow_type,
137 static void gtk_default_draw_diamond (GtkStyle *style,
139 GtkStateType state_type,
140 GtkShadowType shadow_type,
148 static void gtk_default_draw_string (GtkStyle *style,
150 GtkStateType state_type,
156 const gchar *string);
157 static void gtk_default_draw_box (GtkStyle *style,
159 GtkStateType state_type,
160 GtkShadowType shadow_type,
168 static void gtk_default_draw_flat_box (GtkStyle *style,
170 GtkStateType state_type,
171 GtkShadowType shadow_type,
179 static void gtk_default_draw_check (GtkStyle *style,
181 GtkStateType state_type,
182 GtkShadowType shadow_type,
190 static void gtk_default_draw_option (GtkStyle *style,
192 GtkStateType state_type,
193 GtkShadowType shadow_type,
201 static void gtk_default_draw_tab (GtkStyle *style,
203 GtkStateType state_type,
204 GtkShadowType shadow_type,
212 static void gtk_default_draw_shadow_gap (GtkStyle *style,
214 GtkStateType state_type,
215 GtkShadowType shadow_type,
223 GtkPositionType gap_side,
226 static void gtk_default_draw_box_gap (GtkStyle *style,
228 GtkStateType state_type,
229 GtkShadowType shadow_type,
237 GtkPositionType gap_side,
240 static void gtk_default_draw_extension (GtkStyle *style,
242 GtkStateType state_type,
243 GtkShadowType shadow_type,
251 GtkPositionType gap_side);
252 static void gtk_default_draw_focus (GtkStyle *style,
254 GtkStateType state_type,
262 static void gtk_default_draw_slider (GtkStyle *style,
264 GtkStateType state_type,
265 GtkShadowType shadow_type,
273 GtkOrientation orientation);
274 static void gtk_default_draw_handle (GtkStyle *style,
276 GtkStateType state_type,
277 GtkShadowType shadow_type,
285 GtkOrientation orientation);
286 static void gtk_default_draw_expander (GtkStyle *style,
288 GtkStateType state_type,
294 GtkExpanderStyle expander_style);
295 static void gtk_default_draw_layout (GtkStyle *style,
297 GtkStateType state_type,
304 PangoLayout *layout);
305 static void gtk_default_draw_resize_grip (GtkStyle *style,
307 GtkStateType state_type,
316 static void gtk_default_draw_spinner (GtkStyle *style,
318 GtkStateType state_type,
328 static void rgb_to_hls (gdouble *r,
331 static void hls_to_rgb (gdouble *h,
335 static void style_unrealize_cursor_gcs (GtkStyle *style);
337 static GdkFont *gtk_style_get_font_internal (GtkStyle *style);
340 * Data for default check and radio buttons
343 static const GtkRequisition default_option_indicator_size = { 7, 13 };
344 static const GtkBorder default_option_indicator_spacing = { 7, 5, 2, 2 };
346 #define GTK_GRAY 0xdcdc, 0xdada, 0xd5d5
347 #define GTK_DARK_GRAY 0xc4c4, 0xc2c2, 0xbdbd
348 #define GTK_LIGHT_GRAY 0xeeee, 0xebeb, 0xe7e7
349 #define GTK_WHITE 0xffff, 0xffff, 0xffff
350 #define GTK_BLUE 0x4b4b, 0x6969, 0x8383
351 #define GTK_VERY_DARK_GRAY 0x9c9c, 0x9a9a, 0x9494
352 #define GTK_BLACK 0x0000, 0x0000, 0x0000
353 #define GTK_WEAK_GRAY 0x7530, 0x7530, 0x7530
355 /* --- variables --- */
356 static const GdkColor gtk_default_normal_fg = { 0, GTK_BLACK };
357 static const GdkColor gtk_default_active_fg = { 0, GTK_BLACK };
358 static const GdkColor gtk_default_prelight_fg = { 0, GTK_BLACK };
359 static const GdkColor gtk_default_selected_fg = { 0, GTK_WHITE };
360 static const GdkColor gtk_default_insensitive_fg = { 0, GTK_WEAK_GRAY };
362 static const GdkColor gtk_default_normal_bg = { 0, GTK_GRAY };
363 static const GdkColor gtk_default_active_bg = { 0, GTK_DARK_GRAY };
364 static const GdkColor gtk_default_prelight_bg = { 0, GTK_LIGHT_GRAY };
365 static const GdkColor gtk_default_selected_bg = { 0, GTK_BLUE };
366 static const GdkColor gtk_default_insensitive_bg = { 0, GTK_GRAY };
367 static const GdkColor gtk_default_selected_base = { 0, GTK_BLUE };
368 static const GdkColor gtk_default_active_base = { 0, GTK_VERY_DARK_GRAY };
370 /* --- signals --- */
371 static guint realize_signal = 0;
372 static guint unrealize_signal = 0;
374 G_DEFINE_TYPE (GtkStyle, gtk_style, G_TYPE_OBJECT)
376 /* --- functions --- */
379 * _gtk_style_init_for_settings:
380 * @style: a #GtkStyle
381 * @settings: a #GtkSettings
383 * Initializes the font description in @style according to the default
384 * font name of @settings. This is called for gtk_style_new() with
385 * the settings for the default screen (if any); if we are creating
386 * a style for a particular screen, we then call it again in a
387 * location where we know the correct settings.
388 * The reason for this is that gtk_rc_style_create_style() doesn't
389 * take the screen for an argument.
392 _gtk_style_init_for_settings (GtkStyle *style,
393 GtkSettings *settings)
395 const gchar *font_name = _gtk_rc_context_get_default_font_name (settings);
397 if (style->font_desc)
398 pango_font_description_free (style->font_desc);
400 style->font_desc = pango_font_description_from_string (font_name);
402 if (!pango_font_description_get_family (style->font_desc))
404 g_warning ("Default font does not have a family set");
405 pango_font_description_set_family (style->font_desc, "Sans");
407 if (pango_font_description_get_size (style->font_desc) <= 0)
409 g_warning ("Default font does not have a positive size");
410 pango_font_description_set_size (style->font_desc, 10 * PANGO_SCALE);
415 gtk_style_init (GtkStyle *style)
419 GtkSettings *settings = gtk_settings_get_default ();
422 _gtk_style_init_for_settings (style, settings);
424 style->font_desc = pango_font_description_from_string ("Sans 10");
426 style->attach_count = 0;
427 style->colormap = NULL;
430 style->black.red = 0;
431 style->black.green = 0;
432 style->black.blue = 0;
434 style->white.red = 65535;
435 style->white.green = 65535;
436 style->white.blue = 65535;
438 style->black_gc = NULL;
439 style->white_gc = NULL;
441 style->fg[GTK_STATE_NORMAL] = gtk_default_normal_fg;
442 style->fg[GTK_STATE_ACTIVE] = gtk_default_active_fg;
443 style->fg[GTK_STATE_PRELIGHT] = gtk_default_prelight_fg;
444 style->fg[GTK_STATE_SELECTED] = gtk_default_selected_fg;
445 style->fg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
447 style->bg[GTK_STATE_NORMAL] = gtk_default_normal_bg;
448 style->bg[GTK_STATE_ACTIVE] = gtk_default_active_bg;
449 style->bg[GTK_STATE_PRELIGHT] = gtk_default_prelight_bg;
450 style->bg[GTK_STATE_SELECTED] = gtk_default_selected_bg;
451 style->bg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_bg;
453 for (i = 0; i < 4; i++)
455 style->text[i] = style->fg[i];
456 style->base[i] = style->white;
459 style->base[GTK_STATE_SELECTED] = gtk_default_selected_base;
460 style->text[GTK_STATE_SELECTED] = style->white;
461 style->base[GTK_STATE_ACTIVE] = gtk_default_active_base;
462 style->text[GTK_STATE_ACTIVE] = style->white;
463 style->base[GTK_STATE_INSENSITIVE] = gtk_default_prelight_bg;
464 style->text[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
466 for (i = 0; i < 5; i++)
467 style->bg_pixmap[i] = NULL;
469 style->rc_style = NULL;
471 for (i = 0; i < 5; i++)
473 style->fg_gc[i] = NULL;
474 style->bg_gc[i] = NULL;
475 style->light_gc[i] = NULL;
476 style->dark_gc[i] = NULL;
477 style->mid_gc[i] = NULL;
478 style->text_gc[i] = NULL;
479 style->base_gc[i] = NULL;
480 style->text_aa_gc[i] = NULL;
483 style->xthickness = 2;
484 style->ythickness = 2;
486 style->property_cache = NULL;
490 gtk_style_class_init (GtkStyleClass *klass)
492 GObjectClass *object_class = G_OBJECT_CLASS (klass);
494 object_class->finalize = gtk_style_finalize;
496 klass->clone = gtk_style_real_clone;
497 klass->copy = gtk_style_real_copy;
498 klass->init_from_rc = gtk_style_real_init_from_rc;
499 klass->realize = gtk_style_real_realize;
500 klass->unrealize = gtk_style_real_unrealize;
501 klass->set_background = gtk_style_real_set_background;
502 klass->render_icon = gtk_default_render_icon;
504 klass->draw_hline = gtk_default_draw_hline;
505 klass->draw_vline = gtk_default_draw_vline;
506 klass->draw_shadow = gtk_default_draw_shadow;
507 klass->draw_polygon = gtk_default_draw_polygon;
508 klass->draw_arrow = gtk_default_draw_arrow;
509 klass->draw_diamond = gtk_default_draw_diamond;
510 klass->draw_string = gtk_default_draw_string;
511 klass->draw_box = gtk_default_draw_box;
512 klass->draw_flat_box = gtk_default_draw_flat_box;
513 klass->draw_check = gtk_default_draw_check;
514 klass->draw_option = gtk_default_draw_option;
515 klass->draw_tab = gtk_default_draw_tab;
516 klass->draw_shadow_gap = gtk_default_draw_shadow_gap;
517 klass->draw_box_gap = gtk_default_draw_box_gap;
518 klass->draw_extension = gtk_default_draw_extension;
519 klass->draw_focus = gtk_default_draw_focus;
520 klass->draw_slider = gtk_default_draw_slider;
521 klass->draw_handle = gtk_default_draw_handle;
522 klass->draw_expander = gtk_default_draw_expander;
523 klass->draw_layout = gtk_default_draw_layout;
524 klass->draw_resize_grip = gtk_default_draw_resize_grip;
525 klass->draw_spinner = gtk_default_draw_spinner;
527 g_type_class_add_private (object_class, sizeof (GtkStylePrivate));
531 * @style: the object which received the signal
533 * Emitted when the style has been initialized for a particular
534 * colormap and depth. Connecting to this signal is probably seldom
535 * useful since most of the time applications and widgets only
536 * deal with styles that have been already realized.
540 realize_signal = g_signal_new (I_("realize"),
541 G_TYPE_FROM_CLASS (object_class),
543 G_STRUCT_OFFSET (GtkStyleClass, realize),
545 _gtk_marshal_VOID__VOID,
548 * GtkStyle::unrealize:
549 * @style: the object which received the signal
551 * Emitted when the aspects of the style specific to a particular colormap
552 * and depth are being cleaned up. A connection to this signal can be useful
553 * if a widget wants to cache objects like a #GdkGC as object data on #GtkStyle.
554 * This signal provides a convenient place to free such cached objects.
558 unrealize_signal = g_signal_new (I_("unrealize"),
559 G_TYPE_FROM_CLASS (object_class),
561 G_STRUCT_OFFSET (GtkStyleClass, unrealize),
563 _gtk_marshal_VOID__VOID,
568 clear_property_cache (GtkStyle *style)
570 if (style->property_cache)
574 for (i = 0; i < style->property_cache->len; i++)
576 PropertyValue *node = &g_array_index (style->property_cache, PropertyValue, i);
578 g_param_spec_unref (node->pspec);
579 g_value_unset (&node->value);
581 g_array_free (style->property_cache, TRUE);
582 style->property_cache = NULL;
587 gtk_style_finalize (GObject *object)
589 GtkStyle *style = GTK_STYLE (object);
590 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
592 g_return_if_fail (style->attach_count == 0);
594 clear_property_cache (style);
596 /* All the styles in the list have the same
597 * style->styles pointer. If we delete the
598 * *first* style from the list, we need to update
599 * the style->styles pointers from all the styles.
600 * Otherwise we simply remove the node from
605 if (style->styles->data != style)
606 style->styles = g_slist_remove (style->styles, style);
609 GSList *tmp_list = style->styles->next;
613 GTK_STYLE (tmp_list->data)->styles = style->styles->next;
614 tmp_list = tmp_list->next;
616 g_slist_free_1 (style->styles);
620 g_slist_foreach (style->icon_factories, (GFunc) g_object_unref, NULL);
621 g_slist_free (style->icon_factories);
623 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_unref, NULL);
624 g_slist_free (priv->color_hashes);
626 pango_font_description_free (style->font_desc);
628 if (style->private_font)
629 gdk_font_unref (style->private_font);
631 if (style->private_font_desc)
632 pango_font_description_free (style->private_font_desc);
635 g_object_unref (style->rc_style);
637 G_OBJECT_CLASS (gtk_style_parent_class)->finalize (object);
643 * @style: a #GtkStyle
645 * Creates a copy of the passed in #GtkStyle object.
647 * Returns: a copy of @style
650 gtk_style_copy (GtkStyle *style)
654 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
656 new_style = GTK_STYLE_GET_CLASS (style)->clone (style);
657 GTK_STYLE_GET_CLASS (style)->copy (new_style, style);
663 gtk_style_duplicate (GtkStyle *style)
667 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
669 new_style = gtk_style_copy (style);
671 /* All the styles in the list have the same
672 * style->styles pointer. When we insert a new
673 * style, we append it to the list to avoid having
674 * to update the existing ones.
676 style->styles = g_slist_append (style->styles, new_style);
677 new_style->styles = style->styles;
684 * @returns: a new #GtkStyle.
686 * Creates a new #GtkStyle.
693 style = g_object_new (GTK_TYPE_STYLE, NULL);
700 * @style: a #GtkStyle.
701 * @window: a #GdkWindow.
703 * Attaches a style to a window; this process allocates the
704 * colors and creates the GC's for the style - it specializes
705 * it to a particular visual and colormap. The process may
706 * involve the creation of a new style if the style has already
707 * been attached to a window with a different style and colormap.
709 * Since this function may return a new object, you have to use it
710 * in the following way:
711 * <literal>style = gtk_style_attach (style, window)</literal>
713 * Returns: Either @style, or a newly-created #GtkStyle.
714 * If the style is newly created, the style parameter
715 * will be unref'ed, and the new style will have
716 * a reference count belonging to the caller.
719 gtk_style_attach (GtkStyle *style,
723 GtkStyle *new_style = NULL;
724 GdkColormap *colormap;
726 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
727 g_return_val_if_fail (window != NULL, NULL);
729 colormap = gdk_drawable_get_colormap (window);
732 style->styles = g_slist_append (NULL, style);
734 styles = style->styles;
737 new_style = styles->data;
739 if (new_style->colormap == colormap)
743 styles = styles->next;
748 styles = style->styles;
752 new_style = styles->data;
754 if (new_style->attach_count == 0)
756 gtk_style_realize (new_style, colormap);
761 styles = styles->next;
767 new_style = gtk_style_duplicate (style);
768 if (gdk_colormap_get_screen (style->colormap) != gdk_colormap_get_screen (colormap) &&
769 new_style->private_font)
771 gdk_font_unref (new_style->private_font);
772 new_style->private_font = NULL;
774 gtk_style_realize (new_style, colormap);
777 /* A style gets a refcount from being attached */
778 if (new_style->attach_count == 0)
779 g_object_ref (new_style);
781 /* Another refcount belongs to the parent */
782 if (style != new_style)
784 g_object_unref (style);
785 g_object_ref (new_style);
788 new_style->attach_count++;
795 * @style: a #GtkStyle
797 * Detaches a style from a window. If the style is not attached
798 * to any windows anymore, it is unrealized. See gtk_style_attach().
802 gtk_style_detach (GtkStyle *style)
804 g_return_if_fail (GTK_IS_STYLE (style));
805 g_return_if_fail (style->attach_count > 0);
807 style->attach_count -= 1;
808 if (style->attach_count == 0)
810 g_signal_emit (style, unrealize_signal, 0);
812 g_object_unref (style->colormap);
813 style->colormap = NULL;
815 if (style->private_font_desc)
817 if (style->private_font)
819 gdk_font_unref (style->private_font);
820 style->private_font = NULL;
823 pango_font_description_free (style->private_font_desc);
824 style->private_font_desc = NULL;
827 g_object_unref (style);
833 * @style: a #GtkStyle.
836 * Increase the reference count of @style.
838 * Deprecated: 2.0: use g_object_ref() instead.
841 gtk_style_ref (GtkStyle *style)
843 return (GtkStyle *) g_object_ref (style);
848 * @style: a #GtkStyle.
850 * Decrease the reference count of @style.
852 * Deprecated: 2.0: use g_object_unref() instead.
855 gtk_style_unref (GtkStyle *style)
857 g_object_unref (style);
861 gtk_style_realize (GtkStyle *style,
862 GdkColormap *colormap)
864 style->colormap = g_object_ref (colormap);
865 style->depth = gdk_colormap_get_visual (colormap)->depth;
867 g_signal_emit (style, realize_signal, 0);
871 * gtk_style_lookup_icon_set:
872 * @style: a #GtkStyle
873 * @stock_id: an icon name
875 * Looks up @stock_id in the icon factories associated with @style
876 * and the default icon factory, returning an icon set if found,
879 * Return value: icon set of @stock_id
882 gtk_style_lookup_icon_set (GtkStyle *style,
883 const char *stock_id)
887 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
888 g_return_val_if_fail (stock_id != NULL, NULL);
890 iter = style->icon_factories;
893 GtkIconSet *icon_set = gtk_icon_factory_lookup (GTK_ICON_FACTORY (iter->data),
898 iter = g_slist_next (iter);
901 return gtk_icon_factory_lookup_default (stock_id);
905 * gtk_style_lookup_color:
906 * @style: a #GtkStyle
907 * @color_name: the name of the logical color to look up
908 * @color: the #GdkColor to fill in
910 * Looks up @color_name in the style's logical color mappings,
911 * filling in @color and returning %TRUE if found, otherwise
912 * returning %FALSE. Do not cache the found mapping, because
913 * it depends on the #GtkStyle and might change when a theme
916 * Return value: %TRUE if the mapping was found.
921 gtk_style_lookup_color (GtkStyle *style,
922 const char *color_name,
925 GtkStylePrivate *priv;
928 g_return_val_if_fail (GTK_IS_STYLE (style), FALSE);
929 g_return_val_if_fail (color_name != NULL, FALSE);
930 g_return_val_if_fail (color != NULL, FALSE);
932 priv = GTK_STYLE_GET_PRIVATE (style);
934 for (iter = priv->color_hashes; iter != NULL; iter = iter->next)
936 GHashTable *hash = iter->data;
937 GdkColor *mapping = g_hash_table_lookup (hash, color_name);
941 color->red = mapping->red;
942 color->green = mapping->green;
943 color->blue = mapping->blue;
953 * @style: a #GtkStyle
954 * @window: a #GdkWindow
955 * @state_type: a state
956 * @x1: the starting x coordinate
957 * @x2: the ending x coordinate
958 * @y: the y coordinate
960 * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @window
961 * using the given style and state.
963 * Deprecated: 2.0: Use gtk_paint_hline() instead.
966 gtk_draw_hline (GtkStyle *style,
968 GtkStateType state_type,
973 g_return_if_fail (GTK_IS_STYLE (style));
974 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
976 GTK_STYLE_GET_CLASS (style)->draw_hline (style, window, state_type, NULL, NULL, NULL, x1, x2, y);
982 * @style: a #GtkStyle
983 * @window: a #GdkWindow
984 * @state_type: a state
985 * @y1_: the starting y coordinate
986 * @y2_: the ending y coordinate
987 * @x: the x coordinate
989 * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @window
990 * using the given style and state.
992 * Deprecated: 2.0: Use gtk_paint_vline() instead.
995 gtk_draw_vline (GtkStyle *style,
997 GtkStateType state_type,
1002 g_return_if_fail (GTK_IS_STYLE (style));
1003 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
1005 GTK_STYLE_GET_CLASS (style)->draw_vline (style, window, state_type, NULL, NULL, NULL, y1_, y2_, x);
1010 * @style: a #GtkStyle
1011 * @window: a #GdkWindow
1012 * @state_type: a state
1013 * @shadow_type: type of shadow to draw
1014 * @x: x origin of the rectangle
1015 * @y: y origin of the rectangle
1016 * @width: width of the rectangle
1017 * @height: width of the rectangle
1019 * Draws a shadow around the given rectangle in @window
1020 * using the given style and state and shadow type.
1022 * Deprecated: 2.0: Use gtk_paint_shadow() instead.
1025 gtk_draw_shadow (GtkStyle *style,
1027 GtkStateType state_type,
1028 GtkShadowType shadow_type,
1034 g_return_if_fail (GTK_IS_STYLE (style));
1035 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
1037 GTK_STYLE_GET_CLASS (style)->draw_shadow (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1042 * @style: a #GtkStyle
1043 * @window: a #GdkWindow
1044 * @state_type: a state
1045 * @shadow_type: type of shadow to draw
1046 * @points: an array of #GdkPoint<!-- -->s
1047 * @npoints: length of @points
1048 * @fill: %TRUE if the polygon should be filled
1050 * Draws a polygon on @window with the given parameters.
1052 * Deprecated: 2.0: Use gtk_paint_polygon() instead.
1055 gtk_draw_polygon (GtkStyle *style,
1057 GtkStateType state_type,
1058 GtkShadowType shadow_type,
1063 g_return_if_fail (GTK_IS_STYLE (style));
1064 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_polygon != NULL);
1066 GTK_STYLE_GET_CLASS (style)->draw_polygon (style, window, state_type, shadow_type, NULL, NULL, NULL, points, npoints, fill);
1071 * @style: a #GtkStyle
1072 * @window: a #GdkWindow
1073 * @state_type: a state
1074 * @shadow_type: the type of shadow to draw
1075 * @arrow_type: the type of arrow to draw
1076 * @fill: %TRUE if the arrow tip should be filled
1077 * @x: x origin of the rectangle to draw the arrow in
1078 * @y: y origin of the rectangle to draw the arrow in
1079 * @width: width of the rectangle to draw the arrow in
1080 * @height: height of the rectangle to draw the arrow in
1082 * Draws an arrow in the given rectangle on @window using the given
1083 * parameters. @arrow_type determines the direction of the arrow.
1085 * Deprecated: 2.0: Use gtk_paint_arrow() instead.
1088 gtk_draw_arrow (GtkStyle *style,
1090 GtkStateType state_type,
1091 GtkShadowType shadow_type,
1092 GtkArrowType arrow_type,
1099 g_return_if_fail (GTK_IS_STYLE (style));
1100 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
1102 GTK_STYLE_GET_CLASS (style)->draw_arrow (style, window, state_type, shadow_type, NULL, NULL, NULL, arrow_type, fill, x, y, width, height);
1107 * @style: a #GtkStyle
1108 * @window: a #GdkWindow
1109 * @state_type: a state
1110 * @shadow_type: the type of shadow to draw
1111 * @x: x origin of the rectangle to draw the diamond in
1112 * @y: y origin of the rectangle to draw the diamond in
1113 * @width: width of the rectangle to draw the diamond in
1114 * @height: height of the rectangle to draw the diamond in
1116 * Draws a diamond in the given rectangle on @window using the given
1119 * Deprecated: 2.0: Use gtk_paint_diamond() instead.
1122 gtk_draw_diamond (GtkStyle *style,
1124 GtkStateType state_type,
1125 GtkShadowType shadow_type,
1131 g_return_if_fail (GTK_IS_STYLE (style));
1132 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
1134 GTK_STYLE_GET_CLASS (style)->draw_diamond (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1139 * @style: a #GtkStyle
1140 * @window: a #GdkWindow
1141 * @state_type: a state
1144 * @string: the string to draw
1146 * Draws a text string on @window with the given parameters.
1148 * Deprecated: 2.0: Use gtk_paint_layout() instead.
1151 gtk_draw_string (GtkStyle *style,
1153 GtkStateType state_type,
1156 const gchar *string)
1158 g_return_if_fail (GTK_IS_STYLE (style));
1159 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_string != NULL);
1161 GTK_STYLE_GET_CLASS (style)->draw_string (style, window, state_type, NULL, NULL, NULL, x, y, string);
1166 * @style: a #GtkStyle
1167 * @window: a #GdkWindow
1168 * @state_type: a state
1169 * @shadow_type: the type of shadow to draw
1170 * @x: x origin of the box
1171 * @y: y origin of the box
1172 * @width: the width of the box
1173 * @height: the height of the box
1175 * Draws a box on @window with the given parameters.
1177 * Deprecated: 2.0: Use gtk_paint_box() instead.
1180 gtk_draw_box (GtkStyle *style,
1182 GtkStateType state_type,
1183 GtkShadowType shadow_type,
1189 g_return_if_fail (GTK_IS_STYLE (style));
1190 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
1192 GTK_STYLE_GET_CLASS (style)->draw_box (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1196 * gtk_draw_flat_box:
1197 * @style: a #GtkStyle
1198 * @window: a #GdkWindow
1199 * @state_type: a state
1200 * @shadow_type: the type of shadow to draw
1201 * @x: x origin of the box
1202 * @y: y origin of the box
1203 * @width: the width of the box
1204 * @height: the height of the box
1206 * Draws a flat box on @window with the given parameters.
1208 * Deprecated: 2.0: Use gtk_paint_flat_box() instead.
1211 gtk_draw_flat_box (GtkStyle *style,
1213 GtkStateType state_type,
1214 GtkShadowType shadow_type,
1220 g_return_if_fail (GTK_IS_STYLE (style));
1221 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
1223 GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1228 * @style: a #GtkStyle
1229 * @window: a #GdkWindow
1230 * @state_type: a state
1231 * @shadow_type: the type of shadow to draw
1232 * @x: x origin of the rectangle to draw the check in
1233 * @y: y origin of the rectangle to draw the check in
1234 * @width: the width of the rectangle to draw the check in
1235 * @height: the height of the rectangle to draw the check in
1237 * Draws a check button indicator in the given rectangle on @window with
1238 * the given parameters.
1240 * Deprecated: 2.0: Use gtk_paint_check() instead.
1243 gtk_draw_check (GtkStyle *style,
1245 GtkStateType state_type,
1246 GtkShadowType shadow_type,
1252 g_return_if_fail (GTK_IS_STYLE (style));
1253 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
1255 GTK_STYLE_GET_CLASS (style)->draw_check (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1260 * @style: a #GtkStyle
1261 * @window: a #GdkWindow
1262 * @state_type: a state
1263 * @shadow_type: the type of shadow to draw
1264 * @x: x origin of the rectangle to draw the option in
1265 * @y: y origin of the rectangle to draw the option in
1266 * @width: the width of the rectangle to draw the option in
1267 * @height: the height of the rectangle to draw the option in
1269 * Draws a radio button indicator in the given rectangle on @window with
1270 * the given parameters.
1272 * Deprecated: 2.0: Use gtk_paint_option() instead.
1275 gtk_draw_option (GtkStyle *style,
1277 GtkStateType state_type,
1278 GtkShadowType shadow_type,
1284 g_return_if_fail (GTK_IS_STYLE (style));
1285 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
1287 GTK_STYLE_GET_CLASS (style)->draw_option (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1292 * @style: a #GtkStyle
1293 * @window: a #GdkWindow
1294 * @state_type: a state
1295 * @shadow_type: the type of shadow to draw
1296 * @x: x origin of the rectangle to draw the tab in
1297 * @y: y origin of the rectangle to draw the tab in
1298 * @width: the width of the rectangle to draw the tab in
1299 * @height: the height of the rectangle to draw the tab in
1301 * Draws an option menu tab (i.e. the up and down pointing arrows)
1302 * in the given rectangle on @window using the given parameters.
1304 * Deprecated: 2.0: Use gtk_paint_tab() instead.
1307 gtk_draw_tab (GtkStyle *style,
1309 GtkStateType state_type,
1310 GtkShadowType shadow_type,
1316 g_return_if_fail (GTK_IS_STYLE (style));
1317 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
1319 GTK_STYLE_GET_CLASS (style)->draw_tab (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1323 * gtk_draw_shadow_gap:
1324 * @style: a #GtkStyle
1325 * @window: a #GdkWindow
1326 * @state_type: a state
1327 * @shadow_type: type of shadow to draw
1328 * @x: x origin of the rectangle
1329 * @y: y origin of the rectangle
1330 * @width: width of the rectangle
1331 * @height: width of the rectangle
1332 * @gap_side: side in which to leave the gap
1333 * @gap_x: starting position of the gap
1334 * @gap_width: width of the gap
1336 * Draws a shadow around the given rectangle in @window
1337 * using the given style and state and shadow type, leaving a
1340 * Deprecated: 2.0: Use gtk_paint_shadow_gap() instead.
1343 gtk_draw_shadow_gap (GtkStyle *style,
1345 GtkStateType state_type,
1346 GtkShadowType shadow_type,
1351 GtkPositionType gap_side,
1355 g_return_if_fail (GTK_IS_STYLE (style));
1356 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
1358 GTK_STYLE_GET_CLASS (style)->draw_shadow_gap (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, gap_side, gap_x, gap_width);
1363 * @style: a #GtkStyle
1364 * @window: a #GdkWindow
1365 * @state_type: a state
1366 * @shadow_type: type of shadow to draw
1367 * @x: x origin of the rectangle
1368 * @y: y origin of the rectangle
1369 * @width: width of the rectangle
1370 * @height: width of the rectangle
1371 * @gap_side: side in which to leave the gap
1372 * @gap_x: starting position of the gap
1373 * @gap_width: width of the gap
1375 * Draws a box in @window using the given style and state and shadow type,
1376 * leaving a gap in one side.
1378 * Deprecated: 2.0: Use gtk_paint_box_gap() instead.
1381 gtk_draw_box_gap (GtkStyle *style,
1383 GtkStateType state_type,
1384 GtkShadowType shadow_type,
1389 GtkPositionType gap_side,
1393 g_return_if_fail (GTK_IS_STYLE (style));
1394 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
1396 GTK_STYLE_GET_CLASS (style)->draw_box_gap (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, gap_side, gap_x, gap_width);
1400 * gtk_draw_extension:
1401 * @style: a #GtkStyle
1402 * @window: a #GdkWindow
1403 * @state_type: a state
1404 * @shadow_type: type of shadow to draw
1405 * @x: x origin of the extension
1406 * @y: y origin of the extension
1407 * @width: width of the extension
1408 * @height: width of the extension
1409 * @gap_side: the side on to which the extension is attached
1411 * Draws an extension, i.e. a notebook tab.
1413 * Deprecated: 2.0: Use gtk_paint_extension() instead.
1416 gtk_draw_extension (GtkStyle *style,
1418 GtkStateType state_type,
1419 GtkShadowType shadow_type,
1424 GtkPositionType gap_side)
1426 g_return_if_fail (GTK_IS_STYLE (style));
1427 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
1429 GTK_STYLE_GET_CLASS (style)->draw_extension (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, gap_side);
1434 * @style: a #GtkStyle
1435 * @window: a #GdkWindow
1436 * @x: the x origin of the rectangle around which to draw a focus indicator
1437 * @y: the y origin of the rectangle around which to draw a focus indicator
1438 * @width: the width of the rectangle around which to draw a focus indicator
1439 * @height: the height of the rectangle around which to draw a focus indicator
1441 * Draws a focus indicator around the given rectangle on @window using the
1444 * Deprecated: 2.0: Use gtk_paint_focus() instead.
1447 gtk_draw_focus (GtkStyle *style,
1454 g_return_if_fail (GTK_IS_STYLE (style));
1455 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
1457 GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, GTK_STATE_NORMAL, NULL, NULL, NULL, x, y, width, height);
1462 * @style: a #GtkStyle
1463 @window: a #GdkWindow
1464 * @state_type: a state
1465 * @shadow_type: a shadow
1466 * @x: the x origin of the rectangle in which to draw a slider
1467 * @y: the y origin of the rectangle in which to draw a slider
1468 * @width: the width of the rectangle in which to draw a slider
1469 * @height: the height of the rectangle in which to draw a slider
1470 * @orientation: the orientation to be used
1472 * Draws a slider in the given rectangle on @window using the
1473 * given style and orientation.
1476 gtk_draw_slider (GtkStyle *style,
1478 GtkStateType state_type,
1479 GtkShadowType shadow_type,
1484 GtkOrientation orientation)
1486 g_return_if_fail (GTK_IS_STYLE (style));
1487 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
1489 GTK_STYLE_GET_CLASS (style)->draw_slider (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, orientation);
1494 * @style: a #GtkStyle
1495 * @window: a #GdkWindow
1496 * @state_type: a state
1497 * @shadow_type: type of shadow to draw
1498 * @x: x origin of the handle
1499 * @y: y origin of the handle
1500 * @width: with of the handle
1501 * @height: height of the handle
1502 * @orientation: the orientation of the handle
1504 * Draws a handle as used in #GtkHandleBox and #GtkPaned.
1506 * Deprecated: 2.0: Use gtk_paint_handle() instead.
1509 gtk_draw_handle (GtkStyle *style,
1511 GtkStateType state_type,
1512 GtkShadowType shadow_type,
1517 GtkOrientation orientation)
1519 g_return_if_fail (GTK_IS_STYLE (style));
1520 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
1522 GTK_STYLE_GET_CLASS (style)->draw_handle (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, orientation);
1526 * gtk_draw_expander:
1527 * @style: a #GtkStyle
1528 * @window: a #GdkWindow
1529 * @state_type: a state
1530 * @x: the x position to draw the expander at
1531 * @y: the y position to draw the expander at
1532 * @expander_style: the style to draw the expander in
1534 * Draws an expander as used in #GtkTreeView.
1536 * Deprecated: 2.0: Use gtk_paint_expander() instead.
1539 gtk_draw_expander (GtkStyle *style,
1541 GtkStateType state_type,
1544 GtkExpanderStyle expander_style)
1546 g_return_if_fail (GTK_IS_STYLE (style));
1547 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
1549 GTK_STYLE_GET_CLASS (style)->draw_expander (style, window, state_type,
1551 x, y, expander_style);
1556 * @style: a #GtkStyle
1557 * @window: a #GdkWindow
1558 * @state_type: a state
1559 * @use_text: whether to use the text or foreground
1560 * graphics context of @style
1563 * @layout: the layout to draw
1565 * Draws a layout on @window using the given parameters.
1568 gtk_draw_layout (GtkStyle *style,
1570 GtkStateType state_type,
1574 PangoLayout *layout)
1576 g_return_if_fail (GTK_IS_STYLE (style));
1577 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
1579 GTK_STYLE_GET_CLASS (style)->draw_layout (style, window, state_type, use_text,
1585 * gtk_draw_resize_grip:
1586 * @style: a #GtkStyle
1587 * @window: a #GdkWindow
1588 * @state_type: a state
1589 * @edge: the edge in which to draw the resize grip
1590 * @x: the x origin of the rectangle in which to draw the resize grip
1591 * @y: the y origin of the rectangle in which to draw the resize grip
1592 * @width: the width of the rectangle in which to draw the resize grip
1593 * @height: the height of the rectangle in which to draw the resize grip
1595 * Draws a resize grip in the given rectangle on @window using the given
1598 * Deprecated: 2.0: Use gtk_paint_resize_grip() instead.
1601 gtk_draw_resize_grip (GtkStyle *style,
1603 GtkStateType state_type,
1610 g_return_if_fail (GTK_IS_STYLE (style));
1611 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
1613 GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, window, state_type,
1616 x, y, width, height);
1621 * gtk_style_set_background:
1622 * @style: a #GtkStyle
1623 * @window: a #GdkWindow
1624 * @state_type: a state
1626 * Sets the background of @window to the background color or pixmap
1627 * specified by @style for the given state.
1630 gtk_style_set_background (GtkStyle *style,
1632 GtkStateType state_type)
1634 g_return_if_fail (GTK_IS_STYLE (style));
1635 g_return_if_fail (window != NULL);
1637 GTK_STYLE_GET_CLASS (style)->set_background (style, window, state_type);
1640 /* Default functions */
1642 gtk_style_real_clone (GtkStyle *style)
1644 return g_object_new (G_OBJECT_TYPE (style), NULL);
1648 gtk_style_real_copy (GtkStyle *style,
1651 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
1652 GtkStylePrivate *src_priv = GTK_STYLE_GET_PRIVATE (src);
1655 for (i = 0; i < 5; i++)
1657 style->fg[i] = src->fg[i];
1658 style->bg[i] = src->bg[i];
1659 style->text[i] = src->text[i];
1660 style->base[i] = src->base[i];
1662 if (style->bg_pixmap[i])
1663 g_object_unref (style->bg_pixmap[i]),
1664 style->bg_pixmap[i] = src->bg_pixmap[i];
1665 if (style->bg_pixmap[i])
1666 g_object_ref (style->bg_pixmap[i]);
1669 if (style->private_font)
1670 gdk_font_unref (style->private_font);
1671 style->private_font = src->private_font;
1672 if (style->private_font)
1673 gdk_font_ref (style->private_font);
1675 if (style->font_desc)
1676 pango_font_description_free (style->font_desc);
1678 style->font_desc = pango_font_description_copy (src->font_desc);
1680 style->font_desc = NULL;
1682 style->xthickness = src->xthickness;
1683 style->ythickness = src->ythickness;
1685 if (style->rc_style)
1686 g_object_unref (style->rc_style);
1687 style->rc_style = src->rc_style;
1689 g_object_ref (src->rc_style);
1691 g_slist_foreach (style->icon_factories, (GFunc) g_object_unref, NULL);
1692 g_slist_free (style->icon_factories);
1693 style->icon_factories = g_slist_copy (src->icon_factories);
1694 g_slist_foreach (style->icon_factories, (GFunc) g_object_ref, NULL);
1696 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_unref, NULL);
1697 g_slist_free (priv->color_hashes);
1698 priv->color_hashes = g_slist_copy (src_priv->color_hashes);
1699 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_ref, NULL);
1701 /* don't copy, just clear cache */
1702 clear_property_cache (style);
1706 gtk_style_real_init_from_rc (GtkStyle *style,
1707 GtkRcStyle *rc_style)
1709 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
1712 /* cache _should_ be still empty */
1713 clear_property_cache (style);
1715 if (rc_style->font_desc)
1716 pango_font_description_merge (style->font_desc, rc_style->font_desc, TRUE);
1718 for (i = 0; i < 5; i++)
1720 if (rc_style->color_flags[i] & GTK_RC_FG)
1721 style->fg[i] = rc_style->fg[i];
1722 if (rc_style->color_flags[i] & GTK_RC_BG)
1723 style->bg[i] = rc_style->bg[i];
1724 if (rc_style->color_flags[i] & GTK_RC_TEXT)
1725 style->text[i] = rc_style->text[i];
1726 if (rc_style->color_flags[i] & GTK_RC_BASE)
1727 style->base[i] = rc_style->base[i];
1730 if (rc_style->xthickness >= 0)
1731 style->xthickness = rc_style->xthickness;
1732 if (rc_style->ythickness >= 0)
1733 style->ythickness = rc_style->ythickness;
1735 style->icon_factories = g_slist_copy (rc_style->icon_factories);
1736 g_slist_foreach (style->icon_factories, (GFunc) g_object_ref, NULL);
1738 priv->color_hashes = g_slist_copy (_gtk_rc_style_get_color_hashes (rc_style));
1739 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_ref, NULL);
1743 style_property_values_cmp (gconstpointer bsearch_node1,
1744 gconstpointer bsearch_node2)
1746 const PropertyValue *val1 = bsearch_node1;
1747 const PropertyValue *val2 = bsearch_node2;
1749 if (val1->widget_type == val2->widget_type)
1750 return val1->pspec < val2->pspec ? -1 : val1->pspec == val2->pspec ? 0 : 1;
1752 return val1->widget_type < val2->widget_type ? -1 : 1;
1756 * gtk_style_get_style_property:
1757 * @style: a #GtkStyle
1758 * @widget_type: the #GType of a descendant of #GtkWidget
1759 * @property_name: the name of the style property to get
1760 * @value: a #GValue where the value of the property being
1761 * queried will be stored
1763 * Queries the value of a style property corresponding to a
1764 * widget class is in the given style.
1769 gtk_style_get_style_property (GtkStyle *style,
1771 const gchar *property_name,
1774 GtkWidgetClass *klass;
1776 GtkRcPropertyParser parser;
1777 const GValue *peek_value;
1779 klass = g_type_class_ref (widget_type);
1780 pspec = gtk_widget_class_find_style_property (klass, property_name);
1781 g_type_class_unref (klass);
1785 g_warning ("%s: widget class `%s' has no property named `%s'",
1787 g_type_name (widget_type),
1792 parser = g_param_spec_get_qdata (pspec,
1793 g_quark_from_static_string ("gtk-rc-property-parser"));
1795 peek_value = _gtk_style_peek_property_value (style, widget_type, pspec, parser);
1797 if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec))
1798 g_value_copy (peek_value, value);
1799 else if (g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
1800 g_value_transform (peek_value, value);
1802 g_warning ("can't retrieve style property `%s' of type `%s' as value of type `%s'",
1804 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1805 G_VALUE_TYPE_NAME (value));
1809 * gtk_style_get_valist:
1810 * @style: a #GtkStyle
1811 * @widget_type: the #GType of a descendant of #GtkWidget
1812 * @first_property_name: the name of the first style property to get
1813 * @var_args: a <type>va_list</type> of pairs of property names and
1814 * locations to return the property values, starting with the
1815 * location for @first_property_name.
1817 * Non-vararg variant of gtk_style_get().
1818 * Used primarily by language bindings.
1823 gtk_style_get_valist (GtkStyle *style,
1825 const gchar *first_property_name,
1828 const char *property_name;
1829 GtkWidgetClass *klass;
1831 g_return_if_fail (GTK_IS_STYLE (style));
1833 klass = g_type_class_ref (widget_type);
1835 property_name = first_property_name;
1836 while (property_name)
1839 GtkRcPropertyParser parser;
1840 const GValue *peek_value;
1843 pspec = gtk_widget_class_find_style_property (klass, property_name);
1847 g_warning ("%s: widget class `%s' has no property named `%s'",
1849 g_type_name (widget_type),
1854 parser = g_param_spec_get_qdata (pspec,
1855 g_quark_from_static_string ("gtk-rc-property-parser"));
1857 peek_value = _gtk_style_peek_property_value (style, widget_type, pspec, parser);
1858 G_VALUE_LCOPY (peek_value, var_args, 0, &error);
1861 g_warning ("%s: %s", G_STRLOC, error);
1866 property_name = va_arg (var_args, gchar*);
1869 g_type_class_unref (klass);
1874 * @style: a #GtkStyle
1875 * @widget_type: the #GType of a descendant of #GtkWidget
1876 * @first_property_name: the name of the first style property to get
1877 * @Varargs: pairs of property names and locations to
1878 * return the property values, starting with the location for
1879 * @first_property_name, terminated by %NULL.
1881 * Gets the values of a multiple style properties for @widget_type
1887 gtk_style_get (GtkStyle *style,
1889 const gchar *first_property_name,
1894 va_start (var_args, first_property_name);
1895 gtk_style_get_valist (style, widget_type, first_property_name, var_args);
1900 _gtk_style_peek_property_value (GtkStyle *style,
1903 GtkRcPropertyParser parser)
1905 PropertyValue *pcache, key = { 0, NULL, { 0, } };
1906 const GtkRcProperty *rcprop = NULL;
1909 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1910 g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL);
1911 g_return_val_if_fail (g_type_is_a (pspec->owner_type, GTK_TYPE_WIDGET), NULL);
1912 g_return_val_if_fail (g_type_is_a (widget_type, pspec->owner_type), NULL);
1914 key.widget_type = widget_type;
1917 /* need value cache array */
1918 if (!style->property_cache)
1919 style->property_cache = g_array_new (FALSE, FALSE, sizeof (PropertyValue));
1922 pcache = bsearch (&key,
1923 style->property_cache->data, style->property_cache->len,
1924 sizeof (PropertyValue), style_property_values_cmp);
1926 return &pcache->value;
1930 while (i < style->property_cache->len &&
1931 style_property_values_cmp (&key, &g_array_index (style->property_cache, PropertyValue, i)) >= 0)
1934 g_array_insert_val (style->property_cache, i, key);
1935 pcache = &g_array_index (style->property_cache, PropertyValue, i);
1937 /* cache miss, initialize value type, then set contents */
1938 g_param_spec_ref (pcache->pspec);
1939 g_value_init (&pcache->value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1941 /* value provided by rc style? */
1942 if (style->rc_style)
1944 GQuark prop_quark = g_quark_from_string (pspec->name);
1948 rcprop = _gtk_rc_style_lookup_rc_property (style->rc_style,
1949 g_type_qname (widget_type),
1953 widget_type = g_type_parent (widget_type);
1955 while (g_type_is_a (widget_type, pspec->owner_type));
1958 /* when supplied by rc style, we need to convert */
1959 if (rcprop && !_gtk_settings_parse_convert (parser, &rcprop->value,
1960 pspec, &pcache->value))
1962 gchar *contents = g_strdup_value_contents (&rcprop->value);
1964 g_message ("%s: failed to retrieve property `%s::%s' of type `%s' from rc file value \"%s\" of type `%s'",
1965 rcprop->origin ? rcprop->origin : "(for origin information, set GTK_DEBUG)",
1966 g_type_name (pspec->owner_type), pspec->name,
1967 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1969 G_VALUE_TYPE_NAME (&rcprop->value));
1971 rcprop = NULL; /* needs default */
1974 /* not supplied by rc style (or conversion failed), revert to default */
1976 g_param_value_set_default (pspec, &pcache->value);
1978 return &pcache->value;
1982 load_bg_image (GdkColormap *colormap,
1984 const gchar *filename)
1986 if (strcmp (filename, "<parent>") == 0)
1987 return (GdkPixmap*) GDK_PARENT_RELATIVE;
1990 return gdk_pixmap_colormap_create_from_xpm (NULL, colormap, NULL,
1997 gtk_style_real_realize (GtkStyle *style)
1999 GdkGCValues gc_values;
2000 GdkGCValuesMask gc_values_mask;
2004 for (i = 0; i < 5; i++)
2006 _gtk_style_shade (&style->bg[i], &style->light[i], LIGHTNESS_MULT);
2007 _gtk_style_shade (&style->bg[i], &style->dark[i], DARKNESS_MULT);
2009 style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
2010 style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
2011 style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
2013 style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
2014 style->text_aa[i].green = (style->text[i].green + style->base[i].green) / 2;
2015 style->text_aa[i].blue = (style->text[i].blue + style->base[i].blue) / 2;
2018 style->black.red = 0x0000;
2019 style->black.green = 0x0000;
2020 style->black.blue = 0x0000;
2021 gdk_colormap_alloc_color (style->colormap, &style->black, FALSE, TRUE);
2023 style->white.red = 0xffff;
2024 style->white.green = 0xffff;
2025 style->white.blue = 0xffff;
2026 gdk_colormap_alloc_color (style->colormap, &style->white, FALSE, TRUE);
2028 gc_values_mask = GDK_GC_FOREGROUND | GDK_GC_BACKGROUND;
2030 gc_values.foreground = style->black;
2031 gc_values.background = style->white;
2032 style->black_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
2034 gc_values.foreground = style->white;
2035 gc_values.background = style->black;
2036 style->white_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
2038 gc_values_mask = GDK_GC_FOREGROUND;
2040 for (i = 0; i < 5; i++)
2042 if (style->rc_style && style->rc_style->bg_pixmap_name[i])
2043 style->bg_pixmap[i] = load_bg_image (style->colormap,
2045 style->rc_style->bg_pixmap_name[i]);
2047 if (!gdk_colormap_alloc_color (style->colormap, &style->fg[i], FALSE, TRUE))
2048 g_warning ("unable to allocate color: ( %d %d %d )",
2049 style->fg[i].red, style->fg[i].green, style->fg[i].blue);
2050 if (!gdk_colormap_alloc_color (style->colormap, &style->bg[i], FALSE, TRUE))
2051 g_warning ("unable to allocate color: ( %d %d %d )",
2052 style->bg[i].red, style->bg[i].green, style->bg[i].blue);
2053 if (!gdk_colormap_alloc_color (style->colormap, &style->light[i], FALSE, TRUE))
2054 g_warning ("unable to allocate color: ( %d %d %d )",
2055 style->light[i].red, style->light[i].green, style->light[i].blue);
2056 if (!gdk_colormap_alloc_color (style->colormap, &style->dark[i], FALSE, TRUE))
2057 g_warning ("unable to allocate color: ( %d %d %d )",
2058 style->dark[i].red, style->dark[i].green, style->dark[i].blue);
2059 if (!gdk_colormap_alloc_color (style->colormap, &style->mid[i], FALSE, TRUE))
2060 g_warning ("unable to allocate color: ( %d %d %d )",
2061 style->mid[i].red, style->mid[i].green, style->mid[i].blue);
2062 if (!gdk_colormap_alloc_color (style->colormap, &style->text[i], FALSE, TRUE))
2063 g_warning ("unable to allocate color: ( %d %d %d )",
2064 style->text[i].red, style->text[i].green, style->text[i].blue);
2065 if (!gdk_colormap_alloc_color (style->colormap, &style->base[i], FALSE, TRUE))
2066 g_warning ("unable to allocate color: ( %d %d %d )",
2067 style->base[i].red, style->base[i].green, style->base[i].blue);
2068 if (!gdk_colormap_alloc_color (style->colormap, &style->text_aa[i], FALSE, TRUE))
2069 g_warning ("unable to allocate color: ( %d %d %d )",
2070 style->text_aa[i].red, style->text_aa[i].green, style->text_aa[i].blue);
2072 gc_values.foreground = style->fg[i];
2073 style->fg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
2075 gc_values.foreground = style->bg[i];
2076 style->bg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
2078 gc_values.foreground = style->light[i];
2079 style->light_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
2081 gc_values.foreground = style->dark[i];
2082 style->dark_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
2084 gc_values.foreground = style->mid[i];
2085 style->mid_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
2087 gc_values.foreground = style->text[i];
2088 style->text_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
2090 gc_values.foreground = style->base[i];
2091 style->base_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
2093 gc_values.foreground = style->text_aa[i];
2094 style->text_aa_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
2099 gtk_style_real_unrealize (GtkStyle *style)
2103 gtk_gc_release (style->black_gc);
2104 gtk_gc_release (style->white_gc);
2106 for (i = 0; i < 5; i++)
2108 gtk_gc_release (style->fg_gc[i]);
2109 gtk_gc_release (style->bg_gc[i]);
2110 gtk_gc_release (style->light_gc[i]);
2111 gtk_gc_release (style->dark_gc[i]);
2112 gtk_gc_release (style->mid_gc[i]);
2113 gtk_gc_release (style->text_gc[i]);
2114 gtk_gc_release (style->base_gc[i]);
2115 gtk_gc_release (style->text_aa_gc[i]);
2117 if (style->bg_pixmap[i] && style->bg_pixmap[i] != (GdkPixmap*) GDK_PARENT_RELATIVE)
2119 g_object_unref (style->bg_pixmap[i]);
2120 style->bg_pixmap[i] = NULL;
2125 gdk_colormap_free_colors (style->colormap, style->fg, 5);
2126 gdk_colormap_free_colors (style->colormap, style->bg, 5);
2127 gdk_colormap_free_colors (style->colormap, style->light, 5);
2128 gdk_colormap_free_colors (style->colormap, style->dark, 5);
2129 gdk_colormap_free_colors (style->colormap, style->mid, 5);
2130 gdk_colormap_free_colors (style->colormap, style->text, 5);
2131 gdk_colormap_free_colors (style->colormap, style->base, 5);
2132 gdk_colormap_free_colors (style->colormap, style->text_aa, 5);
2134 style_unrealize_cursor_gcs (style);
2138 gtk_style_real_set_background (GtkStyle *style,
2140 GtkStateType state_type)
2143 gint parent_relative;
2145 if (style->bg_pixmap[state_type])
2147 if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
2150 parent_relative = TRUE;
2154 pixmap = style->bg_pixmap[state_type];
2155 parent_relative = FALSE;
2158 gdk_window_set_back_pixmap (window, pixmap, parent_relative);
2161 gdk_window_set_background (window, &style->bg[state_type]);
2165 * gtk_style_render_icon:
2166 * @style: a #GtkStyle
2167 * @source: the #GtkIconSource specifying the icon to render
2168 * @direction: a text direction
2170 * @size: (type int) the size to render the icon at. A size of
2171 * (GtkIconSize)-1 means render at the size of the source and
2173 * @widget: (allow-none): the widget
2174 * @detail: (allow-none): a style detail
2175 * @returns: a newly-created #GdkPixbuf containing the rendered icon
2177 * Renders the icon specified by @source at the given @size
2178 * according to the given parameters and returns the result in a
2182 gtk_style_render_icon (GtkStyle *style,
2183 const GtkIconSource *source,
2184 GtkTextDirection direction,
2188 const gchar *detail)
2192 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
2193 g_return_val_if_fail (GTK_STYLE_GET_CLASS (style)->render_icon != NULL, NULL);
2195 pixbuf = GTK_STYLE_GET_CLASS (style)->render_icon (style, source, direction, state,
2196 size, widget, detail);
2198 g_return_val_if_fail (pixbuf != NULL, NULL);
2203 /* Default functions */
2206 * gtk_style_apply_default_background:
2211 * @area: (allow-none):
2218 gtk_style_apply_default_background (GtkStyle *style,
2221 GtkStateType state_type,
2222 const GdkRectangle *area,
2228 GdkRectangle new_rect, old_rect;
2234 old_rect.width = width;
2235 old_rect.height = height;
2237 if (!gdk_rectangle_intersect (area, &old_rect, &new_rect))
2244 new_rect.width = width;
2245 new_rect.height = height;
2248 if (!style->bg_pixmap[state_type] ||
2249 GDK_IS_PIXMAP (window) ||
2250 (!set_bg && style->bg_pixmap[state_type] != (GdkPixmap*) GDK_PARENT_RELATIVE))
2252 GdkGC *gc = style->bg_gc[state_type];
2254 if (style->bg_pixmap[state_type])
2256 gdk_gc_set_fill (gc, GDK_TILED);
2257 gdk_gc_set_tile (gc, style->bg_pixmap[state_type]);
2260 gdk_draw_rectangle (window, gc, TRUE,
2261 new_rect.x, new_rect.y, new_rect.width, new_rect.height);
2262 if (style->bg_pixmap[state_type])
2263 gdk_gc_set_fill (gc, GDK_SOLID);
2269 if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
2270 gdk_window_set_back_pixmap (window, NULL, TRUE);
2272 gdk_window_set_back_pixmap (window, style->bg_pixmap[state_type], FALSE);
2275 gdk_window_clear_area (window,
2276 new_rect.x, new_rect.y,
2277 new_rect.width, new_rect.height);
2282 scale_or_ref (GdkPixbuf *src,
2286 if (width == gdk_pixbuf_get_width (src) &&
2287 height == gdk_pixbuf_get_height (src))
2289 return g_object_ref (src);
2293 return gdk_pixbuf_scale_simple (src,
2295 GDK_INTERP_BILINEAR);
2300 gtk_default_render_icon (GtkStyle *style,
2301 const GtkIconSource *source,
2302 GtkTextDirection direction,
2306 const gchar *detail)
2312 GdkPixbuf *base_pixbuf;
2314 GtkSettings *settings;
2316 /* Oddly, style can be NULL in this function, because
2317 * GtkIconSet can be used without a style and if so
2318 * it uses this function.
2321 base_pixbuf = gtk_icon_source_get_pixbuf (source);
2323 g_return_val_if_fail (base_pixbuf != NULL, NULL);
2325 if (widget && gtk_widget_has_screen (widget))
2327 screen = gtk_widget_get_screen (widget);
2328 settings = gtk_settings_get_for_screen (screen);
2330 else if (style && style->colormap)
2332 screen = gdk_colormap_get_screen (style->colormap);
2333 settings = gtk_settings_get_for_screen (screen);
2337 settings = gtk_settings_get_default ();
2338 GTK_NOTE (MULTIHEAD,
2339 g_warning ("Using the default screen for gtk_default_render_icon()"));
2343 if (size != (GtkIconSize) -1 && !gtk_icon_size_lookup_for_settings (settings, size, &width, &height))
2345 g_warning (G_STRLOC ": invalid icon size '%d'", size);
2349 /* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
2352 if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source))
2353 scaled = scale_or_ref (base_pixbuf, width, height);
2355 scaled = g_object_ref (base_pixbuf);
2357 /* If the state was wildcarded, then generate a state. */
2358 if (gtk_icon_source_get_state_wildcarded (source))
2360 if (state == GTK_STATE_INSENSITIVE)
2362 stated = gdk_pixbuf_copy (scaled);
2364 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
2367 g_object_unref (scaled);
2369 else if (state == GTK_STATE_PRELIGHT)
2371 stated = gdk_pixbuf_copy (scaled);
2373 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
2376 g_object_unref (scaled);
2390 sanitize_size (GdkWindow *window,
2394 if ((*width == -1) && (*height == -1))
2395 gdk_drawable_get_size (window, width, height);
2396 else if (*width == -1)
2397 gdk_drawable_get_size (window, width, NULL);
2398 else if (*height == -1)
2399 gdk_drawable_get_size (window, NULL, height);
2403 gtk_default_draw_hline (GtkStyle *style,
2405 GtkStateType state_type,
2408 const gchar *detail,
2413 gint thickness_light;
2414 gint thickness_dark;
2417 thickness_light = style->ythickness / 2;
2418 thickness_dark = style->ythickness - thickness_light;
2422 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2423 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2426 if (detail && !strcmp (detail, "label"))
2428 if (state_type == GTK_STATE_INSENSITIVE)
2429 gdk_draw_line (window, style->white_gc, x1 + 1, y + 1, x2 + 1, y + 1);
2430 gdk_draw_line (window, style->fg_gc[state_type], x1, y, x2, y);
2434 for (i = 0; i < thickness_dark; i++)
2436 gdk_draw_line (window, style->dark_gc[state_type], x1, y + i, x2 - i - 1, y + i);
2437 gdk_draw_line (window, style->light_gc[state_type], x2 - i, y + i, x2, y + i);
2440 y += thickness_dark;
2441 for (i = 0; i < thickness_light; i++)
2443 gdk_draw_line (window, style->dark_gc[state_type], x1, y + i, x1 + thickness_light - i - 1, y + i);
2444 gdk_draw_line (window, style->light_gc[state_type], x1 + thickness_light - i, y + i, x2, y + i);
2450 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2451 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2457 gtk_default_draw_vline (GtkStyle *style,
2459 GtkStateType state_type,
2462 const gchar *detail,
2467 gint thickness_light;
2468 gint thickness_dark;
2471 thickness_light = style->xthickness / 2;
2472 thickness_dark = style->xthickness - thickness_light;
2476 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2477 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2479 for (i = 0; i < thickness_dark; i++)
2481 gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i, y2 - i - 1);
2482 gdk_draw_line (window, style->light_gc[state_type], x + i, y2 - i, x + i, y2);
2485 x += thickness_dark;
2486 for (i = 0; i < thickness_light; i++)
2488 gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i, y1 + thickness_light - i - 1);
2489 gdk_draw_line (window, style->light_gc[state_type], x + i, y1 + thickness_light - i, x + i, y2);
2493 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2494 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2499 draw_thin_shadow (GtkStyle *style,
2510 sanitize_size (window, &width, &height);
2512 gc1 = style->light_gc[state];
2513 gc2 = style->dark_gc[state];
2517 gdk_gc_set_clip_rectangle (gc1, area);
2518 gdk_gc_set_clip_rectangle (gc2, area);
2521 gdk_draw_line (window, gc1,
2522 x, y + height - 1, x + width - 1, y + height - 1);
2523 gdk_draw_line (window, gc1,
2524 x + width - 1, y, x + width - 1, y + height - 1);
2526 gdk_draw_line (window, gc2,
2527 x, y, x + width - 2, y);
2528 gdk_draw_line (window, gc2,
2529 x, y, x, y + height - 2);
2533 gdk_gc_set_clip_rectangle (gc1, NULL);
2534 gdk_gc_set_clip_rectangle (gc2, NULL);
2539 draw_spinbutton_shadow (GtkStyle *style,
2542 GtkTextDirection direction,
2549 sanitize_size (window, &width, &height);
2553 gdk_gc_set_clip_rectangle (style->black_gc, area);
2554 gdk_gc_set_clip_rectangle (style->bg_gc[state], area);
2555 gdk_gc_set_clip_rectangle (style->dark_gc[state], area);
2556 gdk_gc_set_clip_rectangle (style->light_gc[state], area);
2559 if (direction == GTK_TEXT_DIR_LTR)
2561 gdk_draw_line (window, style->dark_gc[state],
2562 x, y, x + width - 1, y);
2563 gdk_draw_line (window, style->black_gc,
2564 x, y + 1, x + width - 2, y + 1);
2565 gdk_draw_line (window, style->black_gc,
2566 x + width - 2, y + 2, x + width - 2, y + height - 3);
2567 gdk_draw_line (window, style->light_gc[state],
2568 x + width - 1, y + 1, x + width - 1, y + height - 2);
2569 gdk_draw_line (window, style->light_gc[state],
2570 x, y + height - 1, x + width - 1, y + height - 1);
2571 gdk_draw_line (window, style->bg_gc[state],
2572 x, y + height - 2, x + width - 2, y + height - 2);
2573 gdk_draw_line (window, style->black_gc,
2574 x, y + 2, x, y + height - 3);
2578 gdk_draw_line (window, style->dark_gc[state],
2579 x, y, x + width - 1, y);
2580 gdk_draw_line (window, style->dark_gc[state],
2581 x, y + 1, x, y + height - 1);
2582 gdk_draw_line (window, style->black_gc,
2583 x + 1, y + 1, x + width - 1, y + 1);
2584 gdk_draw_line (window, style->black_gc,
2585 x + 1, y + 2, x + 1, y + height - 2);
2586 gdk_draw_line (window, style->black_gc,
2587 x + width - 1, y + 2, x + width - 1, y + height - 3);
2588 gdk_draw_line (window, style->light_gc[state],
2589 x + 1, y + height - 1, x + width - 1, y + height - 1);
2590 gdk_draw_line (window, style->bg_gc[state],
2591 x + 2, y + height - 2, x + width - 1, y + height - 2);
2596 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
2597 gdk_gc_set_clip_rectangle (style->bg_gc[state], NULL);
2598 gdk_gc_set_clip_rectangle (style->dark_gc[state], NULL);
2599 gdk_gc_set_clip_rectangle (style->light_gc[state], NULL);
2604 draw_menu_shadow (GtkStyle *style,
2613 if (style->ythickness > 0)
2615 if (style->ythickness > 1)
2617 gdk_draw_line (window, style->dark_gc[state],
2618 x + 1, y + height - 2, x + width - 2, y + height - 2);
2619 gdk_draw_line (window, style->black_gc,
2620 x, y + height - 1, x + width - 1, y + height - 1);
2624 gdk_draw_line (window, style->dark_gc[state],
2625 x + 1, y + height - 1, x + width - 1, y + height - 1);
2629 if (style->xthickness > 0)
2631 if (style->xthickness > 1)
2633 gdk_draw_line (window, style->dark_gc[state],
2634 x + width - 2, y + 1, x + width - 2, y + height - 2);
2636 gdk_draw_line (window, style->black_gc,
2637 x + width - 1, y, x + width - 1, y + height - 1);
2641 gdk_draw_line (window, style->dark_gc[state],
2642 x + width - 1, y + 1, x + width - 1, y + height - 1);
2646 /* Light around top and left */
2648 if (style->ythickness > 0)
2649 gdk_draw_line (window, style->black_gc,
2650 x, y, x + width - 2, y);
2651 if (style->xthickness > 0)
2652 gdk_draw_line (window, style->black_gc,
2653 x, y, x, y + height - 2);
2655 if (style->ythickness > 1)
2656 gdk_draw_line (window, style->light_gc[state],
2657 x + 1, y + 1, x + width - 3, y + 1);
2658 if (style->xthickness > 1)
2659 gdk_draw_line (window, style->light_gc[state],
2660 x + 1, y + 1, x + 1, y + height - 3);
2663 static GtkTextDirection
2664 get_direction (GtkWidget *widget)
2666 GtkTextDirection dir;
2669 dir = gtk_widget_get_direction (widget);
2671 dir = GTK_TEXT_DIR_LTR;
2678 gtk_default_draw_shadow (GtkStyle *style,
2680 GtkStateType state_type,
2681 GtkShadowType shadow_type,
2684 const gchar *detail,
2692 gint thickness_light;
2693 gint thickness_dark;
2696 if (shadow_type == GTK_SHADOW_IN)
2698 if (detail && strcmp (detail, "buttondefault") == 0)
2700 sanitize_size (window, &width, &height);
2702 gdk_draw_rectangle (window, style->black_gc, FALSE,
2703 x, y, width - 1, height - 1);
2707 if (detail && strcmp (detail, "trough") == 0)
2709 draw_thin_shadow (style, window, state_type, area,
2710 x, y, width, height);
2713 if (GTK_IS_SPIN_BUTTON (widget) &&
2714 detail && strcmp (detail, "spinbutton") == 0)
2716 draw_spinbutton_shadow (style, window, state_type,
2717 get_direction (widget), area, x, y, width, height);
2723 if (shadow_type == GTK_SHADOW_OUT && detail && strcmp (detail, "menu") == 0)
2725 draw_menu_shadow (style, window, state_type, area, x, y, width, height);
2729 sanitize_size (window, &width, &height);
2731 switch (shadow_type)
2733 case GTK_SHADOW_NONE:
2736 case GTK_SHADOW_ETCHED_IN:
2737 gc1 = style->light_gc[state_type];
2738 gc2 = style->dark_gc[state_type];
2740 case GTK_SHADOW_OUT:
2741 case GTK_SHADOW_ETCHED_OUT:
2742 gc1 = style->dark_gc[state_type];
2743 gc2 = style->light_gc[state_type];
2749 gdk_gc_set_clip_rectangle (gc1, area);
2750 gdk_gc_set_clip_rectangle (gc2, area);
2751 if (shadow_type == GTK_SHADOW_IN ||
2752 shadow_type == GTK_SHADOW_OUT)
2754 gdk_gc_set_clip_rectangle (style->black_gc, area);
2755 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
2759 switch (shadow_type)
2761 case GTK_SHADOW_NONE:
2765 /* Light around right and bottom edge */
2767 if (style->ythickness > 0)
2768 gdk_draw_line (window, gc1,
2769 x, y + height - 1, x + width - 1, y + height - 1);
2770 if (style->xthickness > 0)
2771 gdk_draw_line (window, gc1,
2772 x + width - 1, y, x + width - 1, y + height - 1);
2774 if (style->ythickness > 1)
2775 gdk_draw_line (window, style->bg_gc[state_type],
2776 x + 1, y + height - 2, x + width - 2, y + height - 2);
2777 if (style->xthickness > 1)
2778 gdk_draw_line (window, style->bg_gc[state_type],
2779 x + width - 2, y + 1, x + width - 2, y + height - 2);
2781 /* Dark around left and top */
2783 if (style->ythickness > 1)
2784 gdk_draw_line (window, style->black_gc,
2785 x + 1, y + 1, x + width - 2, y + 1);
2786 if (style->xthickness > 1)
2787 gdk_draw_line (window, style->black_gc,
2788 x + 1, y + 1, x + 1, y + height - 2);
2790 if (style->ythickness > 0)
2791 gdk_draw_line (window, gc2,
2792 x, y, x + width - 1, y);
2793 if (style->xthickness > 0)
2794 gdk_draw_line (window, gc2,
2795 x, y, x, y + height - 1);
2798 case GTK_SHADOW_OUT:
2799 /* Dark around right and bottom edge */
2801 if (style->ythickness > 0)
2803 if (style->ythickness > 1)
2805 gdk_draw_line (window, gc1,
2806 x + 1, y + height - 2, x + width - 2, y + height - 2);
2807 gdk_draw_line (window, style->black_gc,
2808 x, y + height - 1, x + width - 1, y + height - 1);
2812 gdk_draw_line (window, gc1,
2813 x + 1, y + height - 1, x + width - 1, y + height - 1);
2817 if (style->xthickness > 0)
2819 if (style->xthickness > 1)
2821 gdk_draw_line (window, gc1,
2822 x + width - 2, y + 1, x + width - 2, y + height - 2);
2824 gdk_draw_line (window, style->black_gc,
2825 x + width - 1, y, x + width - 1, y + height - 1);
2829 gdk_draw_line (window, gc1,
2830 x + width - 1, y + 1, x + width - 1, y + height - 1);
2834 /* Light around top and left */
2836 if (style->ythickness > 0)
2837 gdk_draw_line (window, gc2,
2838 x, y, x + width - 2, y);
2839 if (style->xthickness > 0)
2840 gdk_draw_line (window, gc2,
2841 x, y, x, y + height - 2);
2843 if (style->ythickness > 1)
2844 gdk_draw_line (window, style->bg_gc[state_type],
2845 x + 1, y + 1, x + width - 3, y + 1);
2846 if (style->xthickness > 1)
2847 gdk_draw_line (window, style->bg_gc[state_type],
2848 x + 1, y + 1, x + 1, y + height - 3);
2851 case GTK_SHADOW_ETCHED_IN:
2852 case GTK_SHADOW_ETCHED_OUT:
2853 if (style->xthickness > 0)
2855 if (style->xthickness > 1)
2857 thickness_light = 1;
2860 for (i = 0; i < thickness_dark; i++)
2862 gdk_draw_line (window, gc1,
2866 y + height - i - 1);
2867 gdk_draw_line (window, gc2,
2871 y + height - i - 2);
2874 for (i = 0; i < thickness_light; i++)
2876 gdk_draw_line (window, gc1,
2877 x + thickness_dark + i,
2878 y + thickness_dark + i,
2879 x + thickness_dark + i,
2880 y + height - thickness_dark - i - 1);
2881 gdk_draw_line (window, gc2,
2882 x + width - thickness_light - i - 1,
2883 y + thickness_dark + i,
2884 x + width - thickness_light - i - 1,
2885 y + height - thickness_light - 1);
2890 gdk_draw_line (window,
2891 style->dark_gc[state_type],
2892 x, y, x, y + height);
2893 gdk_draw_line (window,
2894 style->dark_gc[state_type],
2895 x + width, y, x + width, y + height);
2899 if (style->ythickness > 0)
2901 if (style->ythickness > 1)
2903 thickness_light = 1;
2906 for (i = 0; i < thickness_dark; i++)
2908 gdk_draw_line (window, gc1,
2912 y + height - i - 1);
2914 gdk_draw_line (window, gc2,
2921 for (i = 0; i < thickness_light; i++)
2923 gdk_draw_line (window, gc1,
2924 x + thickness_dark + i,
2925 y + thickness_dark + i,
2926 x + width - thickness_dark - i - 2,
2927 y + thickness_dark + i);
2929 gdk_draw_line (window, gc2,
2930 x + thickness_dark + i,
2931 y + height - thickness_light - i - 1,
2932 x + width - thickness_light - 1,
2933 y + height - thickness_light - i - 1);
2938 gdk_draw_line (window,
2939 style->dark_gc[state_type],
2940 x, y, x + width, y);
2941 gdk_draw_line (window,
2942 style->dark_gc[state_type],
2943 x, y + height, x + width, y + height);
2950 if (shadow_type == GTK_SHADOW_IN &&
2951 GTK_IS_SPIN_BUTTON (widget) &&
2952 detail && strcmp (detail, "entry") == 0)
2954 if (get_direction (widget) == GTK_TEXT_DIR_LTR)
2956 gdk_draw_line (window,
2957 style->base_gc[state_type],
2958 x + width - 1, y + 2,
2959 x + width - 1, y + height - 3);
2960 gdk_draw_line (window,
2961 style->base_gc[state_type],
2962 x + width - 2, y + 2,
2963 x + width - 2, y + height - 3);
2964 gdk_draw_point (window,
2966 x + width - 1, y + 1);
2967 gdk_draw_point (window,
2968 style->bg_gc[state_type],
2969 x + width - 1, y + height - 2);
2973 gdk_draw_line (window,
2974 style->base_gc[state_type],
2977 gdk_draw_line (window,
2978 style->base_gc[state_type],
2980 x + 1, y + height - 3);
2981 gdk_draw_point (window,
2984 gdk_draw_line (window,
2985 style->bg_gc[state_type],
2987 x + 1, y + height - 2);
2988 gdk_draw_point (window,
2989 style->light_gc[state_type],
2997 gdk_gc_set_clip_rectangle (gc1, NULL);
2998 gdk_gc_set_clip_rectangle (gc2, NULL);
2999 if (shadow_type == GTK_SHADOW_IN ||
3000 shadow_type == GTK_SHADOW_OUT)
3002 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
3003 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
3009 gtk_default_draw_polygon (GtkStyle *style,
3011 GtkStateType state_type,
3012 GtkShadowType shadow_type,
3015 const gchar *detail,
3020 static const gdouble pi_over_4 = G_PI_4;
3021 static const gdouble pi_3_over_4 = G_PI_4 * 3;
3031 switch (shadow_type)
3034 gc1 = style->bg_gc[state_type];
3035 gc2 = style->dark_gc[state_type];
3036 gc3 = style->light_gc[state_type];
3037 gc4 = style->black_gc;
3039 case GTK_SHADOW_ETCHED_IN:
3040 gc1 = style->light_gc[state_type];
3041 gc2 = style->dark_gc[state_type];
3042 gc3 = style->dark_gc[state_type];
3043 gc4 = style->light_gc[state_type];
3045 case GTK_SHADOW_OUT:
3046 gc1 = style->dark_gc[state_type];
3047 gc2 = style->light_gc[state_type];
3048 gc3 = style->black_gc;
3049 gc4 = style->bg_gc[state_type];
3051 case GTK_SHADOW_ETCHED_OUT:
3052 gc1 = style->dark_gc[state_type];
3053 gc2 = style->light_gc[state_type];
3054 gc3 = style->light_gc[state_type];
3055 gc4 = style->dark_gc[state_type];
3063 gdk_gc_set_clip_rectangle (gc1, area);
3064 gdk_gc_set_clip_rectangle (gc2, area);
3065 gdk_gc_set_clip_rectangle (gc3, area);
3066 gdk_gc_set_clip_rectangle (gc4, area);
3070 gdk_draw_polygon (window, style->bg_gc[state_type], TRUE, points, npoints);
3074 for (i = 0; i < npoints; i++)
3076 if ((points[i].x == points[i+1].x) &&
3077 (points[i].y == points[i+1].y))
3083 angle = atan2 (points[i+1].y - points[i].y,
3084 points[i+1].x - points[i].x);
3087 if ((angle > -pi_3_over_4) && (angle < pi_over_4))
3089 if (angle > -pi_over_4)
3100 gdk_draw_line (window, gc1,
3101 points[i].x-xadjust, points[i].y-yadjust,
3102 points[i+1].x-xadjust, points[i+1].y-yadjust);
3103 gdk_draw_line (window, gc3,
3104 points[i].x, points[i].y,
3105 points[i+1].x, points[i+1].y);
3109 if ((angle < -pi_3_over_4) || (angle > pi_3_over_4))
3120 gdk_draw_line (window, gc4,
3121 points[i].x+xadjust, points[i].y+yadjust,
3122 points[i+1].x+xadjust, points[i+1].y+yadjust);
3123 gdk_draw_line (window, gc2,
3124 points[i].x, points[i].y,
3125 points[i+1].x, points[i+1].y);
3131 gdk_gc_set_clip_rectangle (gc1, NULL);
3132 gdk_gc_set_clip_rectangle (gc2, NULL);
3133 gdk_gc_set_clip_rectangle (gc3, NULL);
3134 gdk_gc_set_clip_rectangle (gc4, NULL);
3139 draw_arrow (GdkWindow *window,
3142 GtkArrowType arrow_type,
3148 cairo_t *cr = gdk_cairo_create (window);
3149 gdk_cairo_set_source_color (cr, color);
3153 gdk_cairo_rectangle (cr, area);
3157 if (arrow_type == GTK_ARROW_DOWN)
3159 cairo_move_to (cr, x, y);
3160 cairo_line_to (cr, x + width, y);
3161 cairo_line_to (cr, x + width / 2., y + height);
3163 else if (arrow_type == GTK_ARROW_UP)
3165 cairo_move_to (cr, x, y + height);
3166 cairo_line_to (cr, x + width / 2., y);
3167 cairo_line_to (cr, x + width, y + height);
3169 else if (arrow_type == GTK_ARROW_LEFT)
3171 cairo_move_to (cr, x + width, y);
3172 cairo_line_to (cr, x + width, y + height);
3173 cairo_line_to (cr, x, y + height / 2.);
3175 else if (arrow_type == GTK_ARROW_RIGHT)
3177 cairo_move_to (cr, x, y);
3178 cairo_line_to (cr, x + width, y + height / 2.);
3179 cairo_line_to (cr, x, y + height);
3182 cairo_close_path (cr);
3189 calculate_arrow_geometry (GtkArrowType arrow_type,
3201 case GTK_ARROW_DOWN:
3211 if (arrow_type == GTK_ARROW_DOWN)
3213 if (*height % 2 == 1 || h % 2 == 0)
3218 if (*height % 2 == 0 || h % 2 == 0)
3223 case GTK_ARROW_RIGHT:
3224 case GTK_ARROW_LEFT:
3234 if (arrow_type == GTK_ARROW_RIGHT)
3236 if (*width % 2 == 1 || w % 2 == 0)
3241 if (*width % 2 == 0 || w % 2 == 0)
3247 /* should not be reached */
3251 *x += (*width - w) / 2;
3252 *y += (*height - h) / 2;
3258 gtk_default_draw_arrow (GtkStyle *style,
3261 GtkShadowType shadow,
3264 const gchar *detail,
3265 GtkArrowType arrow_type,
3272 sanitize_size (window, &width, &height);
3274 calculate_arrow_geometry (arrow_type, &x, &y, &width, &height);
3276 if (detail && strcmp (detail, "menu_scroll_arrow_up") == 0)
3279 if (state == GTK_STATE_INSENSITIVE)
3280 draw_arrow (window, &style->white, area, arrow_type,
3281 x + 1, y + 1, width, height);
3282 draw_arrow (window, &style->fg[state], area, arrow_type,
3283 x, y, width, height);
3287 gtk_default_draw_diamond (GtkStyle *style,
3289 GtkStateType state_type,
3290 GtkShadowType shadow_type,
3293 const gchar *detail,
3301 GdkGC *outer_nw = NULL;
3302 GdkGC *outer_ne = NULL;
3303 GdkGC *outer_sw = NULL;
3304 GdkGC *outer_se = NULL;
3305 GdkGC *middle_nw = NULL;
3306 GdkGC *middle_ne = NULL;
3307 GdkGC *middle_sw = NULL;
3308 GdkGC *middle_se = NULL;
3309 GdkGC *inner_nw = NULL;
3310 GdkGC *inner_ne = NULL;
3311 GdkGC *inner_sw = NULL;
3312 GdkGC *inner_se = NULL;
3314 sanitize_size (window, &width, &height);
3316 half_width = width / 2;
3317 half_height = height / 2;
3321 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
3322 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
3323 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
3324 gdk_gc_set_clip_rectangle (style->black_gc, area);
3327 switch (shadow_type)
3330 inner_sw = inner_se = style->bg_gc[state_type];
3331 middle_sw = middle_se = style->light_gc[state_type];
3332 outer_sw = outer_se = style->light_gc[state_type];
3333 inner_nw = inner_ne = style->black_gc;
3334 middle_nw = middle_ne = style->dark_gc[state_type];
3335 outer_nw = outer_ne = style->dark_gc[state_type];
3338 case GTK_SHADOW_OUT:
3339 inner_sw = inner_se = style->dark_gc[state_type];
3340 middle_sw = middle_se = style->dark_gc[state_type];
3341 outer_sw = outer_se = style->black_gc;
3342 inner_nw = inner_ne = style->bg_gc[state_type];
3343 middle_nw = middle_ne = style->light_gc[state_type];
3344 outer_nw = outer_ne = style->light_gc[state_type];
3347 case GTK_SHADOW_ETCHED_IN:
3348 inner_sw = inner_se = style->bg_gc[state_type];
3349 middle_sw = middle_se = style->dark_gc[state_type];
3350 outer_sw = outer_se = style->light_gc[state_type];
3351 inner_nw = inner_ne = style->bg_gc[state_type];
3352 middle_nw = middle_ne = style->light_gc[state_type];
3353 outer_nw = outer_ne = style->dark_gc[state_type];
3356 case GTK_SHADOW_ETCHED_OUT:
3357 inner_sw = inner_se = style->bg_gc[state_type];
3358 middle_sw = middle_se = style->light_gc[state_type];
3359 outer_sw = outer_se = style->dark_gc[state_type];
3360 inner_nw = inner_ne = style->bg_gc[state_type];
3361 middle_nw = middle_ne = style->dark_gc[state_type];
3362 outer_nw = outer_ne = style->light_gc[state_type];
3372 gdk_draw_line (window, inner_sw,
3373 x + 2, y + half_height,
3374 x + half_width, y + height - 2);
3375 gdk_draw_line (window, inner_se,
3376 x + half_width, y + height - 2,
3377 x + width - 2, y + half_height);
3378 gdk_draw_line (window, middle_sw,
3379 x + 1, y + half_height,
3380 x + half_width, y + height - 1);
3381 gdk_draw_line (window, middle_se,
3382 x + half_width, y + height - 1,
3383 x + width - 1, y + half_height);
3384 gdk_draw_line (window, outer_sw,
3386 x + half_width, y + height);
3387 gdk_draw_line (window, outer_se,
3388 x + half_width, y + height,
3389 x + width, y + half_height);
3391 gdk_draw_line (window, inner_nw,
3392 x + 2, y + half_height,
3393 x + half_width, y + 2);
3394 gdk_draw_line (window, inner_ne,
3395 x + half_width, y + 2,
3396 x + width - 2, y + half_height);
3397 gdk_draw_line (window, middle_nw,
3398 x + 1, y + half_height,
3399 x + half_width, y + 1);
3400 gdk_draw_line (window, middle_ne,
3401 x + half_width, y + 1,
3402 x + width - 1, y + half_height);
3403 gdk_draw_line (window, outer_nw,
3406 gdk_draw_line (window, outer_ne,
3408 x + width, y + half_height);
3413 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
3414 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
3415 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
3416 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
3421 gtk_default_draw_string (GtkStyle *style,
3423 GtkStateType state_type,
3426 const gchar *detail,
3429 const gchar *string)
3433 gdk_gc_set_clip_rectangle (style->white_gc, area);
3434 gdk_gc_set_clip_rectangle (style->fg_gc[state_type], area);
3437 if (state_type == GTK_STATE_INSENSITIVE)
3438 gdk_draw_string (window,
3439 gtk_style_get_font_internal (style),
3440 style->white_gc, x + 1, y + 1, string);
3442 gdk_draw_string (window,
3443 gtk_style_get_font_internal (style),
3444 style->fg_gc[state_type], x, y, string);
3448 gdk_gc_set_clip_rectangle (style->white_gc, NULL);
3449 gdk_gc_set_clip_rectangle (style->fg_gc[state_type], NULL);
3454 option_menu_get_props (GtkWidget *widget,
3455 GtkRequisition *indicator_size,
3456 GtkBorder *indicator_spacing)
3458 GtkRequisition *tmp_size = NULL;
3459 GtkBorder *tmp_spacing = NULL;
3461 if (GTK_IS_OPTION_MENU (widget))
3462 gtk_widget_style_get (widget,
3463 "indicator-size", &tmp_size,
3464 "indicator-spacing", &tmp_spacing,
3469 *indicator_size = *tmp_size;
3470 gtk_requisition_free (tmp_size);
3473 *indicator_size = default_option_indicator_size;
3477 *indicator_spacing = *tmp_spacing;
3478 gtk_border_free (tmp_spacing);
3481 *indicator_spacing = default_option_indicator_spacing;
3485 gtk_default_draw_box (GtkStyle *style,
3487 GtkStateType state_type,
3488 GtkShadowType shadow_type,
3491 const gchar *detail,
3497 gboolean is_spinbutton_box = FALSE;
3499 sanitize_size (window, &width, &height);
3501 if (GTK_IS_SPIN_BUTTON (widget) && detail)
3503 if (strcmp (detail, "spinbutton_up") == 0)
3509 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
3514 is_spinbutton_box = TRUE;
3516 else if (strcmp (detail, "spinbutton_down") == 0)
3521 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
3526 is_spinbutton_box = TRUE;
3530 if (!style->bg_pixmap[state_type] ||
3531 GDK_IS_PIXMAP (window))
3533 GdkGC *gc = style->bg_gc[state_type];
3535 if (state_type == GTK_STATE_SELECTED && detail && strcmp (detail, "paned") == 0)
3537 if (widget && !gtk_widget_has_focus (widget))
3538 gc = style->base_gc[GTK_STATE_ACTIVE];
3542 gdk_gc_set_clip_rectangle (gc, area);
3544 gdk_draw_rectangle (window, gc, TRUE,
3545 x, y, width, height);
3547 gdk_gc_set_clip_rectangle (gc, NULL);
3550 gtk_style_apply_default_background (style, window,
3551 widget && gtk_widget_get_has_window (widget),
3552 state_type, area, x, y, width, height);
3554 if (is_spinbutton_box)
3559 lower_gc = style->dark_gc[state_type];
3560 if (shadow_type == GTK_SHADOW_OUT)
3561 upper_gc = style->light_gc[state_type];
3563 upper_gc = style->dark_gc[state_type];
3567 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
3568 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
3571 gdk_draw_line (window, upper_gc, x, y, x + width - 1, y);
3572 gdk_draw_line (window, lower_gc, x, y + height - 1, x + width - 1, y + height - 1);
3576 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
3577 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
3582 gtk_paint_shadow (style, window, state_type, shadow_type, area, widget, detail,
3583 x, y, width, height);
3585 if (detail && strcmp (detail, "optionmenu") == 0)
3587 GtkRequisition indicator_size;
3588 GtkBorder indicator_spacing;
3591 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
3593 sanitize_size (window, &width, &height);
3595 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
3596 vline_x = x + indicator_size.width + indicator_spacing.left + indicator_spacing.right;
3598 vline_x = x + width - (indicator_size.width + indicator_spacing.left + indicator_spacing.right) - style->xthickness;
3600 gtk_paint_vline (style, window, state_type, area, widget,
3602 y + style->ythickness + 1,
3603 y + height - style->ythickness - 3,
3609 get_darkened_gc (GdkWindow *window,
3610 const GdkColor *color,
3613 GdkColor src = *color;
3614 GdkColor shaded = *color;
3617 gc = gdk_gc_new (window);
3619 while (darken_count)
3621 _gtk_style_shade (&src, &shaded, 0.93);
3626 gdk_gc_set_rgb_fg_color (gc, &shaded);
3632 gtk_default_draw_flat_box (GtkStyle *style,
3634 GtkStateType state_type,
3635 GtkShadowType shadow_type,
3638 const gchar *detail,
3645 GdkGC *freeme = NULL;
3647 sanitize_size (window, &width, &height);
3651 if (state_type == GTK_STATE_SELECTED)
3653 if (!strcmp ("text", detail))
3654 gc1 = style->bg_gc[GTK_STATE_SELECTED];
3655 else if (!strcmp ("cell_even", detail) ||
3656 !strcmp ("cell_odd", detail) ||
3657 !strcmp ("cell_even_ruled", detail) ||
3658 !strcmp ("cell_even_ruled_sorted", detail))
3660 /* This has to be really broken; alex made me do it. -jrb */
3661 if (widget && gtk_widget_has_focus (widget))
3662 gc1 = style->base_gc[state_type];
3664 gc1 = style->base_gc[GTK_STATE_ACTIVE];
3666 else if (!strcmp ("cell_odd_ruled", detail) ||
3667 !strcmp ("cell_odd_ruled_sorted", detail))
3669 if (widget && gtk_widget_has_focus (widget))
3670 freeme = get_darkened_gc (window, &style->base[state_type], 1);
3672 freeme = get_darkened_gc (window, &style->base[GTK_STATE_ACTIVE], 1);
3677 gc1 = style->bg_gc[state_type];
3682 if (!strcmp ("viewportbin", detail))
3683 gc1 = style->bg_gc[GTK_STATE_NORMAL];
3684 else if (!strcmp ("entry_bg", detail))
3685 gc1 = style->base_gc[state_type];
3687 /* For trees: even rows are base color, odd rows are a shade of
3688 * the base color, the sort column is a shade of the original color
3692 else if (!strcmp ("cell_even", detail) ||
3693 !strcmp ("cell_odd", detail) ||
3694 !strcmp ("cell_even_ruled", detail))
3696 GdkColor *color = NULL;
3698 gtk_widget_style_get (widget,
3699 "even-row-color", &color,
3704 freeme = get_darkened_gc (window, color, 0);
3707 gdk_color_free (color);
3710 gc1 = style->base_gc[state_type];
3712 else if (!strcmp ("cell_odd_ruled", detail))
3714 GdkColor *color = NULL;
3716 gtk_widget_style_get (widget,
3717 "odd-row-color", &color,
3722 freeme = get_darkened_gc (window, color, 0);
3725 gdk_color_free (color);
3729 gtk_widget_style_get (widget,
3730 "even-row-color", &color,
3735 freeme = get_darkened_gc (window, color, 1);
3736 gdk_color_free (color);
3739 freeme = get_darkened_gc (window, &style->base[state_type], 1);
3743 else if (!strcmp ("cell_even_sorted", detail) ||
3744 !strcmp ("cell_odd_sorted", detail) ||
3745 !strcmp ("cell_even_ruled_sorted", detail))
3747 GdkColor *color = NULL;
3749 if (!strcmp ("cell_odd_sorted", detail))
3750 gtk_widget_style_get (widget,
3751 "odd-row-color", &color,
3754 gtk_widget_style_get (widget,
3755 "even-row-color", &color,
3760 freeme = get_darkened_gc (window, color, 1);
3763 gdk_color_free (color);
3767 freeme = get_darkened_gc (window, &style->base[state_type], 1);
3771 else if (!strcmp ("cell_odd_ruled_sorted", detail))
3773 GdkColor *color = NULL;
3775 gtk_widget_style_get (widget,
3776 "odd-row-color", &color,
3781 freeme = get_darkened_gc (window, color, 1);
3784 gdk_color_free (color);
3788 gtk_widget_style_get (widget,
3789 "even-row-color", &color,
3794 freeme = get_darkened_gc (window, color, 2);
3795 gdk_color_free (color);
3798 freeme = get_darkened_gc (window, &style->base[state_type], 2);
3803 gc1 = style->bg_gc[state_type];
3807 gc1 = style->bg_gc[state_type];
3809 if (!style->bg_pixmap[state_type] || gc1 != style->bg_gc[state_type] ||
3810 GDK_IS_PIXMAP (window))
3813 gdk_gc_set_clip_rectangle (gc1, area);
3815 gdk_draw_rectangle (window, gc1, TRUE,
3816 x, y, width, height);
3818 if (detail && !strcmp ("tooltip", detail))
3819 gdk_draw_rectangle (window, style->black_gc, FALSE,
3820 x, y, width - 1, height - 1);
3823 gdk_gc_set_clip_rectangle (gc1, NULL);
3826 gtk_style_apply_default_background (style, window,
3827 widget && gtk_widget_get_has_window (widget),
3828 state_type, area, x, y, width, height);
3832 g_object_unref (freeme);
3836 gtk_default_draw_check (GtkStyle *style,
3838 GtkStateType state_type,
3839 GtkShadowType shadow_type,
3842 const gchar *detail,
3848 cairo_t *cr = gdk_cairo_create (window);
3849 enum { BUTTON, MENU, CELL } type = BUTTON;
3856 if (strcmp (detail, "cellcheck") == 0)
3858 else if (strcmp (detail, "check") == 0)
3864 gdk_cairo_rectangle (cr, area);
3868 exterior_size = MIN (width, height);
3869 if (exterior_size % 2 == 0) /* Ensure odd */
3872 pad = style->xthickness + MAX (1, (exterior_size - 2 * style->xthickness) / 9);
3873 interior_size = MAX (1, exterior_size - 2 * pad);
3875 if (interior_size < 7)
3878 pad = MAX (0, (exterior_size - interior_size) / 2);
3881 x -= (1 + exterior_size - width) / 2;
3882 y -= (1 + exterior_size - height) / 2;
3889 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3891 gdk_cairo_set_source_color (cr, &style->text[state_type]);
3893 cairo_set_line_width (cr, 1.0);
3894 cairo_rectangle (cr, x + 0.5, y + 0.5, exterior_size - 1, exterior_size - 1);
3897 gdk_cairo_set_source_color (cr, &style->base[state_type]);
3898 cairo_rectangle (cr, x + 1, y + 1, exterior_size - 2, exterior_size - 2);
3910 gdk_cairo_set_source_color (cr, &style->text[state_type]);
3913 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3917 if (shadow_type == GTK_SHADOW_IN)
3919 cairo_translate (cr,
3922 cairo_scale (cr, interior_size / 7., interior_size / 7.);
3924 cairo_move_to (cr, 7.0, 0.0);
3925 cairo_line_to (cr, 7.5, 1.0);
3926 cairo_curve_to (cr, 5.3, 2.0,
3929 cairo_curve_to (cr, 3.0, 5.7,
3932 cairo_line_to (cr, 0.2, 3.5);
3933 cairo_curve_to (cr, 1.1, 3.5,
3936 cairo_curve_to (cr, 1.0, 3.9,
3939 cairo_curve_to (cr, 3.5, 3.1,
3945 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
3947 int line_thickness = MAX (1, (3 + interior_size * 2) / 7);
3949 cairo_rectangle (cr,
3951 y + pad + (1 + interior_size - line_thickness) / 2,
3961 gtk_default_draw_option (GtkStyle *style,
3963 GtkStateType state_type,
3964 GtkShadowType shadow_type,
3967 const gchar *detail,
3973 cairo_t *cr = gdk_cairo_create (window);
3974 enum { BUTTON, MENU, CELL } type = BUTTON;
3979 if (strcmp (detail, "radio") == 0)
3981 else if (strcmp (detail, "option") == 0)
3987 gdk_cairo_rectangle (cr, area);
3991 exterior_size = MIN (width, height);
3992 if (exterior_size % 2 == 0) /* Ensure odd */
3995 x -= (1 + exterior_size - width) / 2;
3996 y -= (1 + exterior_size - height) / 2;
4002 gdk_cairo_set_source_color (cr, &style->base[state_type]);
4005 x + exterior_size / 2.,
4006 y + exterior_size / 2.,
4007 (exterior_size - 1) / 2.,
4010 cairo_fill_preserve (cr);
4013 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
4015 gdk_cairo_set_source_color (cr, &style->text[state_type]);
4017 cairo_set_line_width (cr, 1.);
4028 gdk_cairo_set_source_color (cr, &style->text[state_type]);
4033 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
4037 if (shadow_type == GTK_SHADOW_IN)
4039 int pad = style->xthickness + MAX (1, 2 * (exterior_size - 2 * style->xthickness) / 9);
4040 int interior_size = MAX (1, exterior_size - 2 * pad);
4042 if (interior_size < 5)
4045 pad = MAX (0, (exterior_size - interior_size) / 2);
4049 x + pad + interior_size / 2.,
4050 y + pad + interior_size / 2.,
4055 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
4057 int pad = style->xthickness + MAX (1, (exterior_size - 2 * style->xthickness) / 9);
4058 int interior_size = MAX (1, exterior_size - 2 * pad);
4061 if (interior_size < 7)
4064 pad = MAX (0, (exterior_size - interior_size) / 2);
4067 line_thickness = MAX (1, (3 + interior_size * 2) / 7);
4069 cairo_rectangle (cr,
4071 y + pad + (interior_size - line_thickness) / 2.,
4081 gtk_default_draw_tab (GtkStyle *style,
4083 GtkStateType state_type,
4084 GtkShadowType shadow_type,
4087 const gchar *detail,
4093 #define ARROW_SPACE 4
4095 GtkRequisition indicator_size;
4096 GtkBorder indicator_spacing;
4099 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
4101 indicator_size.width += (indicator_size.width % 2) - 1;
4102 arrow_height = indicator_size.width / 2 + 1;
4104 x += (width - indicator_size.width) / 2;
4105 y += (height - (2 * arrow_height + ARROW_SPACE)) / 2;
4107 if (state_type == GTK_STATE_INSENSITIVE)
4109 draw_arrow (window, &style->white, area,
4110 GTK_ARROW_UP, x + 1, y + 1,
4111 indicator_size.width, arrow_height);
4113 draw_arrow (window, &style->white, area,
4114 GTK_ARROW_DOWN, x + 1, y + arrow_height + ARROW_SPACE + 1,
4115 indicator_size.width, arrow_height);
4118 draw_arrow (window, &style->fg[state_type], area,
4120 indicator_size.width, arrow_height);
4123 draw_arrow (window, &style->fg[state_type], area,
4124 GTK_ARROW_DOWN, x, y + arrow_height + ARROW_SPACE,
4125 indicator_size.width, arrow_height);
4129 gtk_default_draw_shadow_gap (GtkStyle *style,
4131 GtkStateType state_type,
4132 GtkShadowType shadow_type,
4135 const gchar *detail,
4140 GtkPositionType gap_side,
4149 sanitize_size (window, &width, &height);
4151 switch (shadow_type)
4153 case GTK_SHADOW_NONE:
4156 gc1 = style->dark_gc[state_type];
4157 gc2 = style->black_gc;
4158 gc3 = style->bg_gc[state_type];
4159 gc4 = style->light_gc[state_type];
4161 case GTK_SHADOW_ETCHED_IN:
4162 gc1 = style->dark_gc[state_type];
4163 gc2 = style->light_gc[state_type];
4164 gc3 = style->dark_gc[state_type];
4165 gc4 = style->light_gc[state_type];
4167 case GTK_SHADOW_OUT:
4168 gc1 = style->light_gc[state_type];
4169 gc2 = style->bg_gc[state_type];
4170 gc3 = style->dark_gc[state_type];
4171 gc4 = style->black_gc;
4173 case GTK_SHADOW_ETCHED_OUT:
4174 gc1 = style->light_gc[state_type];
4175 gc2 = style->dark_gc[state_type];
4176 gc3 = style->light_gc[state_type];
4177 gc4 = style->dark_gc[state_type];
4182 gdk_gc_set_clip_rectangle (gc1, area);
4183 gdk_gc_set_clip_rectangle (gc2, area);
4184 gdk_gc_set_clip_rectangle (gc3, area);
4185 gdk_gc_set_clip_rectangle (gc4, area);
4188 switch (shadow_type)
4190 case GTK_SHADOW_NONE:
4192 case GTK_SHADOW_OUT:
4193 case GTK_SHADOW_ETCHED_IN:
4194 case GTK_SHADOW_ETCHED_OUT:
4198 gdk_draw_line (window, gc1,
4199 x, y, x, y + height - 1);
4200 gdk_draw_line (window, gc2,
4201 x + 1, y, x + 1, y + height - 2);
4203 gdk_draw_line (window, gc3,
4204 x + 1, y + height - 2, x + width - 2, y + height - 2);
4205 gdk_draw_line (window, gc3,
4206 x + width - 2, y, x + width - 2, y + height - 2);
4207 gdk_draw_line (window, gc4,
4208 x, y + height - 1, x + width - 1, y + height - 1);
4209 gdk_draw_line (window, gc4,
4210 x + width - 1, y, x + width - 1, y + height - 1);
4213 gdk_draw_line (window, gc1,
4214 x, y, x + gap_x - 1, y);
4215 gdk_draw_line (window, gc2,
4216 x + 1, y + 1, x + gap_x - 1, y + 1);
4217 gdk_draw_line (window, gc2,
4218 x + gap_x, y, x + gap_x, y);
4220 if ((width - (gap_x + gap_width)) > 0)
4222 gdk_draw_line (window, gc1,
4223 x + gap_x + gap_width, y, x + width - 2, y);
4224 gdk_draw_line (window, gc2,
4225 x + gap_x + gap_width, y + 1, x + width - 3, y + 1);
4226 gdk_draw_line (window, gc2,
4227 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
4230 case GTK_POS_BOTTOM:
4231 gdk_draw_line (window, gc1,
4232 x, y, x + width - 1, y);
4233 gdk_draw_line (window, gc1,
4234 x, y, x, y + height - 1);
4235 gdk_draw_line (window, gc2,
4236 x + 1, y + 1, x + width - 2, y + 1);
4237 gdk_draw_line (window, gc2,
4238 x + 1, y + 1, x + 1, y + height - 1);
4240 gdk_draw_line (window, gc3,
4241 x + width - 2, y + 1, x + width - 2, y + height - 1);
4242 gdk_draw_line (window, gc4,
4243 x + width - 1, y, x + width - 1, y + height - 1);
4246 gdk_draw_line (window, gc4,
4247 x, y + height - 1, x + gap_x - 1, y + height - 1);
4248 gdk_draw_line (window, gc3,
4249 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
4250 gdk_draw_line (window, gc3,
4251 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
4253 if ((width - (gap_x + gap_width)) > 0)
4255 gdk_draw_line (window, gc4,
4256 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
4257 gdk_draw_line (window, gc3,
4258 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
4259 gdk_draw_line (window, gc3,
4260 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
4264 gdk_draw_line (window, gc1,
4265 x, y, x + width - 1, y);
4266 gdk_draw_line (window, gc2,
4267 x, y + 1, x + width - 2, y + 1);
4269 gdk_draw_line (window, gc3,
4270 x, y + height - 2, x + width - 2, y + height - 2);
4271 gdk_draw_line (window, gc3,
4272 x + width - 2, y + 1, x + width - 2, y + height - 2);
4273 gdk_draw_line (window, gc4,
4274 x, y + height - 1, x + width - 1, y + height - 1);
4275 gdk_draw_line (window, gc4,
4276 x + width - 1, y, x + width - 1, y + height - 1);
4279 gdk_draw_line (window, gc1,
4280 x, y, x, y + gap_x - 1);
4281 gdk_draw_line (window, gc2,
4282 x + 1, y + 1, x + 1, y + gap_x - 1);
4283 gdk_draw_line (window, gc2,
4284 x, y + gap_x, x, y + gap_x);
4286 if ((width - (gap_x + gap_width)) > 0)
4288 gdk_draw_line (window, gc1,
4289 x, y + gap_x + gap_width, x, y + height - 2);
4290 gdk_draw_line (window, gc2,
4291 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
4292 gdk_draw_line (window, gc2,
4293 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
4297 gdk_draw_line (window, gc1,
4298 x, y, x + width - 1, y);
4299 gdk_draw_line (window, gc1,
4300 x, y, x, y + height - 1);
4301 gdk_draw_line (window, gc2,
4302 x + 1, y + 1, x + width - 1, y + 1);
4303 gdk_draw_line (window, gc2,
4304 x + 1, y + 1, x + 1, y + height - 2);
4306 gdk_draw_line (window, gc3,
4307 x + 1, y + height - 2, x + width - 1, y + height - 2);
4308 gdk_draw_line (window, gc4,
4309 x, y + height - 1, x + width - 1, y + height - 1);
4312 gdk_draw_line (window, gc4,
4313 x + width - 1, y, x + width - 1, y + gap_x - 1);
4314 gdk_draw_line (window, gc3,
4315 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
4316 gdk_draw_line (window, gc3,
4317 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
4319 if ((width - (gap_x + gap_width)) > 0)
4321 gdk_draw_line (window, gc4,
4322 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
4323 gdk_draw_line (window, gc3,
4324 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
4325 gdk_draw_line (window, gc3,
4326 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
4334 gdk_gc_set_clip_rectangle (gc1, NULL);
4335 gdk_gc_set_clip_rectangle (gc2, NULL);
4336 gdk_gc_set_clip_rectangle (gc3, NULL);
4337 gdk_gc_set_clip_rectangle (gc4, NULL);
4342 gtk_default_draw_box_gap (GtkStyle *style,
4344 GtkStateType state_type,
4345 GtkShadowType shadow_type,
4348 const gchar *detail,
4353 GtkPositionType gap_side,
4362 gtk_style_apply_default_background (style, window,
4363 widget && gtk_widget_get_has_window (widget),
4364 state_type, area, x, y, width, height);
4366 sanitize_size (window, &width, &height);
4368 switch (shadow_type)
4370 case GTK_SHADOW_NONE:
4373 gc1 = style->dark_gc[state_type];
4374 gc2 = style->black_gc;
4375 gc3 = style->bg_gc[state_type];
4376 gc4 = style->light_gc[state_type];
4378 case GTK_SHADOW_ETCHED_IN:
4379 gc1 = style->dark_gc[state_type];
4380 gc2 = style->light_gc[state_type];
4381 gc3 = style->dark_gc[state_type];
4382 gc4 = style->light_gc[state_type];
4384 case GTK_SHADOW_OUT:
4385 gc1 = style->light_gc[state_type];
4386 gc2 = style->bg_gc[state_type];
4387 gc3 = style->dark_gc[state_type];
4388 gc4 = style->black_gc;
4390 case GTK_SHADOW_ETCHED_OUT:
4391 gc1 = style->light_gc[state_type];
4392 gc2 = style->dark_gc[state_type];
4393 gc3 = style->light_gc[state_type];
4394 gc4 = style->dark_gc[state_type];
4400 gdk_gc_set_clip_rectangle (gc1, area);
4401 gdk_gc_set_clip_rectangle (gc2, area);
4402 gdk_gc_set_clip_rectangle (gc3, area);
4403 gdk_gc_set_clip_rectangle (gc4, area);
4406 switch (shadow_type)
4408 case GTK_SHADOW_NONE:
4410 case GTK_SHADOW_OUT:
4411 case GTK_SHADOW_ETCHED_IN:
4412 case GTK_SHADOW_ETCHED_OUT:
4416 gdk_draw_line (window, gc1,
4417 x, y, x, y + height - 1);
4418 gdk_draw_line (window, gc2,
4419 x + 1, y, x + 1, y + height - 2);
4421 gdk_draw_line (window, gc3,
4422 x + 1, y + height - 2, x + width - 2, y + height - 2);
4423 gdk_draw_line (window, gc3,
4424 x + width - 2, y, x + width - 2, y + height - 2);
4425 gdk_draw_line (window, gc4,
4426 x, y + height - 1, x + width - 1, y + height - 1);
4427 gdk_draw_line (window, gc4,
4428 x + width - 1, y, x + width - 1, y + height - 1);
4431 gdk_draw_line (window, gc1,
4432 x, y, x + gap_x - 1, y);
4433 gdk_draw_line (window, gc2,
4434 x + 1, y + 1, x + gap_x - 1, y + 1);
4435 gdk_draw_line (window, gc2,
4436 x + gap_x, y, x + gap_x, y);
4438 if ((width - (gap_x + gap_width)) > 0)
4440 gdk_draw_line (window, gc1,
4441 x + gap_x + gap_width, y, x + width - 2, y);
4442 gdk_draw_line (window, gc2,
4443 x + gap_x + gap_width, y + 1, x + width - 2, y + 1);
4444 gdk_draw_line (window, gc2,
4445 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
4448 case GTK_POS_BOTTOM:
4449 gdk_draw_line (window, gc1,
4450 x, y, x + width - 1, y);
4451 gdk_draw_line (window, gc1,
4452 x, y, x, y + height - 1);
4453 gdk_draw_line (window, gc2,
4454 x + 1, y + 1, x + width - 2, y + 1);
4455 gdk_draw_line (window, gc2,
4456 x + 1, y + 1, x + 1, y + height - 1);
4458 gdk_draw_line (window, gc3,
4459 x + width - 2, y + 1, x + width - 2, y + height - 1);
4460 gdk_draw_line (window, gc4,
4461 x + width - 1, y, x + width - 1, y + height - 1);
4464 gdk_draw_line (window, gc4,
4465 x, y + height - 1, x + gap_x - 1, y + height - 1);
4466 gdk_draw_line (window, gc3,
4467 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
4468 gdk_draw_line (window, gc3,
4469 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
4471 if ((width - (gap_x + gap_width)) > 0)
4473 gdk_draw_line (window, gc4,
4474 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
4475 gdk_draw_line (window, gc3,
4476 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
4477 gdk_draw_line (window, gc3,
4478 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
4482 gdk_draw_line (window, gc1,
4483 x, y, x + width - 1, y);
4484 gdk_draw_line (window, gc2,
4485 x, y + 1, x + width - 2, y + 1);
4487 gdk_draw_line (window, gc3,
4488 x, y + height - 2, x + width - 2, y + height - 2);
4489 gdk_draw_line (window, gc3,
4490 x + width - 2, y + 1, x + width - 2, y + height - 2);
4491 gdk_draw_line (window, gc4,
4492 x, y + height - 1, x + width - 1, y + height - 1);
4493 gdk_draw_line (window, gc4,
4494 x + width - 1, y, x + width - 1, y + height - 1);
4497 gdk_draw_line (window, gc1,
4498 x, y, x, y + gap_x - 1);
4499 gdk_draw_line (window, gc2,
4500 x + 1, y + 1, x + 1, y + gap_x - 1);
4501 gdk_draw_line (window, gc2,
4502 x, y + gap_x, x, y + gap_x);
4504 if ((height - (gap_x + gap_width)) > 0)
4506 gdk_draw_line (window, gc1,
4507 x, y + gap_x + gap_width, x, y + height - 2);
4508 gdk_draw_line (window, gc2,
4509 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
4510 gdk_draw_line (window, gc2,
4511 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
4515 gdk_draw_line (window, gc1,
4516 x, y, x + width - 1, y);
4517 gdk_draw_line (window, gc1,
4518 x, y, x, y + height - 1);
4519 gdk_draw_line (window, gc2,
4520 x + 1, y + 1, x + width - 1, y + 1);
4521 gdk_draw_line (window, gc2,
4522 x + 1, y + 1, x + 1, y + height - 2);
4524 gdk_draw_line (window, gc3,
4525 x + 1, y + height - 2, x + width - 1, y + height - 2);
4526 gdk_draw_line (window, gc4,
4527 x, y + height - 1, x + width - 1, y + height - 1);
4530 gdk_draw_line (window, gc4,
4531 x + width - 1, y, x + width - 1, y + gap_x - 1);
4532 gdk_draw_line (window, gc3,
4533 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
4534 gdk_draw_line (window, gc3,
4535 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
4537 if ((height - (gap_x + gap_width)) > 0)
4539 gdk_draw_line (window, gc4,
4540 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
4541 gdk_draw_line (window, gc3,
4542 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
4543 gdk_draw_line (window, gc3,
4544 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
4552 gdk_gc_set_clip_rectangle (gc1, NULL);
4553 gdk_gc_set_clip_rectangle (gc2, NULL);
4554 gdk_gc_set_clip_rectangle (gc3, NULL);
4555 gdk_gc_set_clip_rectangle (gc4, NULL);
4560 gtk_default_draw_extension (GtkStyle *style,
4562 GtkStateType state_type,
4563 GtkShadowType shadow_type,
4566 const gchar *detail,
4571 GtkPositionType gap_side)
4578 gtk_style_apply_default_background (style, window,
4579 widget && gtk_widget_get_has_window (widget),
4580 GTK_STATE_NORMAL, area, x, y, width, height);
4582 sanitize_size (window, &width, &height);
4584 switch (shadow_type)
4586 case GTK_SHADOW_NONE:
4589 gc1 = style->dark_gc[state_type];
4590 gc2 = style->black_gc;
4591 gc3 = style->bg_gc[state_type];
4592 gc4 = style->light_gc[state_type];
4594 case GTK_SHADOW_ETCHED_IN:
4595 gc1 = style->dark_gc[state_type];
4596 gc2 = style->light_gc[state_type];
4597 gc3 = style->dark_gc[state_type];
4598 gc4 = style->light_gc[state_type];
4600 case GTK_SHADOW_OUT:
4601 gc1 = style->light_gc[state_type];
4602 gc2 = style->bg_gc[state_type];
4603 gc3 = style->dark_gc[state_type];
4604 gc4 = style->black_gc;
4606 case GTK_SHADOW_ETCHED_OUT:
4607 gc1 = style->light_gc[state_type];
4608 gc2 = style->dark_gc[state_type];
4609 gc3 = style->light_gc[state_type];
4610 gc4 = style->dark_gc[state_type];
4616 gdk_gc_set_clip_rectangle (gc1, area);
4617 gdk_gc_set_clip_rectangle (gc2, area);
4618 gdk_gc_set_clip_rectangle (gc3, area);
4619 gdk_gc_set_clip_rectangle (gc4, area);
4622 switch (shadow_type)
4624 case GTK_SHADOW_NONE:
4626 case GTK_SHADOW_OUT:
4627 case GTK_SHADOW_ETCHED_IN:
4628 case GTK_SHADOW_ETCHED_OUT:
4632 gtk_style_apply_default_background (style, window,
4633 widget && gtk_widget_get_has_window (widget),
4635 x + style->xthickness,
4637 width - (2 * style->xthickness),
4638 height - (style->ythickness));
4639 gdk_draw_line (window, gc1,
4640 x, y, x, y + height - 2);
4641 gdk_draw_line (window, gc2,
4642 x + 1, y, x + 1, y + height - 2);
4644 gdk_draw_line (window, gc3,
4645 x + 2, y + height - 2, x + width - 2, y + height - 2);
4646 gdk_draw_line (window, gc3,
4647 x + width - 2, y, x + width - 2, y + height - 2);
4648 gdk_draw_line (window, gc4,
4649 x + 1, y + height - 1, x + width - 2, y + height - 1);
4650 gdk_draw_line (window, gc4,
4651 x + width - 1, y, x + width - 1, y + height - 2);
4653 case GTK_POS_BOTTOM:
4654 gtk_style_apply_default_background (style, window,
4655 widget && gtk_widget_get_has_window (widget),
4657 x + style->xthickness,
4658 y + style->ythickness,
4659 width - (2 * style->xthickness),
4660 height - (style->ythickness));
4661 gdk_draw_line (window, gc1,
4662 x + 1, y, x + width - 2, y);
4663 gdk_draw_line (window, gc1,
4664 x, y + 1, x, y + height - 1);
4665 gdk_draw_line (window, gc2,
4666 x + 1, y + 1, x + width - 2, y + 1);
4667 gdk_draw_line (window, gc2,
4668 x + 1, y + 1, x + 1, y + height - 1);
4670 gdk_draw_line (window, gc3,
4671 x + width - 2, y + 2, x + width - 2, y + height - 1);
4672 gdk_draw_line (window, gc4,
4673 x + width - 1, y + 1, x + width - 1, y + height - 1);
4676 gtk_style_apply_default_background (style, window,
4677 widget && gtk_widget_get_has_window (widget),
4680 y + style->ythickness,
4681 width - (style->xthickness),
4682 height - (2 * style->ythickness));
4683 gdk_draw_line (window, gc1,
4684 x, y, x + width - 2, y);
4685 gdk_draw_line (window, gc2,
4686 x + 1, y + 1, x + width - 2, y + 1);
4688 gdk_draw_line (window, gc3,
4689 x, y + height - 2, x + width - 2, y + height - 2);
4690 gdk_draw_line (window, gc3,
4691 x + width - 2, y + 2, x + width - 2, y + height - 2);
4692 gdk_draw_line (window, gc4,
4693 x, y + height - 1, x + width - 2, y + height - 1);
4694 gdk_draw_line (window, gc4,
4695 x + width - 1, y + 1, x + width - 1, y + height - 2);
4698 gtk_style_apply_default_background (style, window,
4699 widget && gtk_widget_get_has_window (widget),
4701 x + style->xthickness,
4702 y + style->ythickness,
4703 width - (style->xthickness),
4704 height - (2 * style->ythickness));
4705 gdk_draw_line (window, gc1,
4706 x + 1, y, x + width - 1, y);
4707 gdk_draw_line (window, gc1,
4708 x, y + 1, x, y + height - 2);
4709 gdk_draw_line (window, gc2,
4710 x + 1, y + 1, x + width - 1, y + 1);
4711 gdk_draw_line (window, gc2,
4712 x + 1, y + 1, x + 1, y + height - 2);
4714 gdk_draw_line (window, gc3,
4715 x + 2, y + height - 2, x + width - 1, y + height - 2);
4716 gdk_draw_line (window, gc4,
4717 x + 1, y + height - 1, x + width - 1, y + height - 1);
4724 gdk_gc_set_clip_rectangle (gc1, NULL);
4725 gdk_gc_set_clip_rectangle (gc2, NULL);
4726 gdk_gc_set_clip_rectangle (gc3, NULL);
4727 gdk_gc_set_clip_rectangle (gc4, NULL);
4732 gtk_default_draw_focus (GtkStyle *style,
4734 GtkStateType state_type,
4737 const gchar *detail,
4744 gboolean free_dash_list = FALSE;
4745 gint line_width = 1;
4746 gint8 *dash_list = (gint8 *) "\1\1";
4750 gtk_widget_style_get (widget,
4751 "focus-line-width", &line_width,
4752 "focus-line-pattern", (gchar *)&dash_list,
4755 free_dash_list = TRUE;
4758 if (detail && !strcmp (detail, "add-mode"))
4763 dash_list = (gint8 *) "\4\4";
4764 free_dash_list = FALSE;
4767 sanitize_size (window, &width, &height);
4769 cr = gdk_cairo_create (window);
4771 if (detail && !strcmp (detail, "colorwheel_light"))
4772 cairo_set_source_rgb (cr, 0., 0., 0.);
4773 else if (detail && !strcmp (detail, "colorwheel_dark"))
4774 cairo_set_source_rgb (cr, 1., 1., 1.);
4776 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
4778 cairo_set_line_width (cr, line_width);
4782 gint n_dashes = strlen ((const gchar *) dash_list);
4783 gdouble *dashes = g_new (gdouble, n_dashes);
4784 gdouble total_length = 0;
4785 gdouble dash_offset;
4788 for (i = 0; i < n_dashes; i++)
4790 dashes[i] = dash_list[i];
4791 total_length += dash_list[i];
4794 /* The dash offset here aligns the pattern to integer pixels
4795 * by starting the dash at the right side of the left border
4796 * Negative dash offsets in cairo don't work
4797 * (https://bugs.freedesktop.org/show_bug.cgi?id=2729)
4799 dash_offset = - line_width / 2.;
4800 while (dash_offset < 0)
4801 dash_offset += total_length;
4803 cairo_set_dash (cr, dashes, n_dashes, dash_offset);
4809 gdk_cairo_rectangle (cr, area);
4813 cairo_rectangle (cr,
4814 x + line_width / 2.,
4815 y + line_width / 2.,
4817 height - line_width);
4826 gtk_default_draw_slider (GtkStyle *style,
4828 GtkStateType state_type,
4829 GtkShadowType shadow_type,
4832 const gchar *detail,
4837 GtkOrientation orientation)
4839 sanitize_size (window, &width, &height);
4841 gtk_paint_box (style, window, state_type, shadow_type,
4842 area, widget, detail, x, y, width, height);
4845 (strcmp ("hscale", detail) == 0 ||
4846 strcmp ("vscale", detail) == 0))
4848 if (orientation == GTK_ORIENTATION_HORIZONTAL)
4849 gtk_paint_vline (style, window, state_type, area, widget, detail,
4850 y + style->ythickness,
4851 y + height - style->ythickness - 1, x + width / 2);
4853 gtk_paint_hline (style, window, state_type, area, widget, detail,
4854 x + style->xthickness,
4855 x + width - style->xthickness - 1, y + height / 2);
4860 draw_dot (GdkWindow *window,
4867 size = CLAMP (size, 2, 3);
4871 gdk_draw_point (window, light_gc, x, y);
4872 gdk_draw_point (window, light_gc, x+1, y+1);
4876 gdk_draw_point (window, light_gc, x, y);
4877 gdk_draw_point (window, light_gc, x+1, y);
4878 gdk_draw_point (window, light_gc, x, y+1);
4879 gdk_draw_point (window, dark_gc, x+1, y+2);
4880 gdk_draw_point (window, dark_gc, x+2, y+1);
4881 gdk_draw_point (window, dark_gc, x+2, y+2);
4886 gtk_default_draw_handle (GtkStyle *style,
4888 GtkStateType state_type,
4889 GtkShadowType shadow_type,
4892 const gchar *detail,
4897 GtkOrientation orientation)
4900 gint xthick, ythick;
4901 GdkGC *light_gc, *dark_gc;
4902 GdkGC *free_me = NULL;
4907 sanitize_size (window, &width, &height);
4909 gtk_paint_box (style, window, state_type, shadow_type, area, widget,
4910 detail, x, y, width, height);
4913 if (detail && !strcmp (detail, "paned"))
4915 /* we want to ignore the shadow border in paned widgets */
4919 if (state_type == GTK_STATE_SELECTED && widget && !gtk_widget_has_focus (widget))
4921 GdkColor unfocused_light;
4923 _gtk_style_shade (&style->base[GTK_STATE_ACTIVE], &unfocused_light,
4926 light_gc = free_me = gdk_gc_new (window);
4927 gdk_gc_set_rgb_fg_color (light_gc, &unfocused_light);
4930 light_gc = style->light_gc[state_type];
4932 dark_gc = style->black_gc;
4936 xthick = style->xthickness;
4937 ythick = style->ythickness;
4939 light_gc = style->light_gc[state_type];
4940 dark_gc = style->dark_gc[state_type];
4943 rect.x = x + xthick;
4944 rect.y = y + ythick;
4945 rect.width = width - (xthick * 2);
4946 rect.height = height - (ythick * 2);
4949 intersect = gdk_rectangle_intersect (area, &rect, &dest);
4959 gdk_gc_set_clip_rectangle (light_gc, &dest);
4960 gdk_gc_set_clip_rectangle (dark_gc, &dest);
4962 if (detail && !strcmp (detail, "paned"))
4964 if (orientation == GTK_ORIENTATION_HORIZONTAL)
4965 for (xx = x + width/2 - 15; xx <= x + width/2 + 15; xx += 5)
4966 draw_dot (window, light_gc, dark_gc, xx, y + height/2 - 1, 3);
4968 for (yy = y + height/2 - 15; yy <= y + height/2 + 15; yy += 5)
4969 draw_dot (window, light_gc, dark_gc, x + width/2 - 1, yy, 3);
4973 for (yy = y + ythick; yy < (y + height - ythick); yy += 3)
4974 for (xx = x + xthick; xx < (x + width - xthick); xx += 6)
4976 draw_dot (window, light_gc, dark_gc, xx, yy, 2);
4977 draw_dot (window, light_gc, dark_gc, xx + 3, yy + 1, 2);
4981 gdk_gc_set_clip_rectangle (light_gc, NULL);
4982 gdk_gc_set_clip_rectangle (dark_gc, NULL);
4986 g_object_unref (free_me);
4990 gtk_default_draw_expander (GtkStyle *style,
4992 GtkStateType state_type,
4995 const gchar *detail,
4998 GtkExpanderStyle expander_style)
5000 #define DEFAULT_EXPANDER_SIZE 12
5004 double vertical_overshoot;
5007 double interp; /* interpolation factor for center position */
5008 double x_double_horz, y_double_horz;
5009 double x_double_vert, y_double_vert;
5010 double x_double, y_double;
5013 cairo_t *cr = gdk_cairo_create (window);
5017 gdk_cairo_rectangle (cr, area);
5022 gtk_widget_class_find_style_property (GTK_WIDGET_GET_CLASS (widget),
5025 gtk_widget_style_get (widget,
5026 "expander-size", &expander_size,
5030 expander_size = DEFAULT_EXPANDER_SIZE;
5032 line_width = MAX (1, expander_size/9);
5034 switch (expander_style)
5036 case GTK_EXPANDER_COLLAPSED:
5037 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 180 : 0;
5040 case GTK_EXPANDER_SEMI_COLLAPSED:
5041 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 150 : 30;
5044 case GTK_EXPANDER_SEMI_EXPANDED:
5045 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 120 : 60;
5048 case GTK_EXPANDER_EXPANDED:
5053 g_assert_not_reached ();
5056 /* Compute distance that the stroke extends beyonds the end
5057 * of the triangle we draw.
5059 vertical_overshoot = line_width / 2.0 * (1. / tan (G_PI / 8));
5061 /* For odd line widths, we end the vertical line of the triangle
5062 * at a half pixel, so we round differently.
5064 if (line_width % 2 == 1)
5065 vertical_overshoot = ceil (0.5 + vertical_overshoot) - 0.5;
5067 vertical_overshoot = ceil (vertical_overshoot);
5069 /* Adjust the size of the triangle we draw so that the entire stroke fits
5071 diameter = MAX (3, expander_size - 2 * vertical_overshoot);
5073 /* If the line width is odd, we want the diameter to be even,
5074 * and vice versa, so force the sum to be odd. This relationship
5075 * makes the point of the triangle look right.
5077 diameter -= (1 - (diameter + line_width) % 2);
5079 radius = diameter / 2.;
5081 /* Adjust the center so that the stroke is properly aligned with
5082 * the pixel grid. The center adjustment is different for the
5083 * horizontal and vertical orientations. For intermediate positions
5084 * we interpolate between the two.
5086 x_double_vert = floor (x - (radius + line_width) / 2.) + (radius + line_width) / 2.;
5087 y_double_vert = y - 0.5;
5089 x_double_horz = x - 0.5;
5090 y_double_horz = floor (y - (radius + line_width) / 2.) + (radius + line_width) / 2.;
5092 x_double = x_double_vert * (1 - interp) + x_double_horz * interp;
5093 y_double = y_double_vert * (1 - interp) + y_double_horz * interp;
5095 cairo_translate (cr, x_double, y_double);
5096 cairo_rotate (cr, degrees * G_PI / 180);
5098 cairo_move_to (cr, - radius / 2., - radius);
5099 cairo_line_to (cr, radius / 2., 0);
5100 cairo_line_to (cr, - radius / 2., radius);
5101 cairo_close_path (cr);
5103 cairo_set_line_width (cr, line_width);
5105 if (state_type == GTK_STATE_PRELIGHT)
5106 gdk_cairo_set_source_color (cr,
5107 &style->fg[GTK_STATE_PRELIGHT]);
5108 else if (state_type == GTK_STATE_ACTIVE)
5109 gdk_cairo_set_source_color (cr,
5110 &style->light[GTK_STATE_ACTIVE]);
5112 gdk_cairo_set_source_color (cr,
5113 &style->base[GTK_STATE_NORMAL]);
5115 cairo_fill_preserve (cr);
5117 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
5123 typedef struct _ByteRange ByteRange;
5132 range_new (guint start,
5135 ByteRange *br = g_new (ByteRange, 1);
5144 get_insensitive_layout (GdkDrawable *drawable,
5145 PangoLayout *layout)
5147 GSList *embossed_ranges = NULL;
5148 GSList *stippled_ranges = NULL;
5149 PangoLayoutIter *iter;
5150 GSList *tmp_list = NULL;
5151 PangoLayout *new_layout;
5152 PangoAttrList *attrs;
5153 GdkBitmap *stipple = NULL;
5155 iter = pango_layout_get_iter (layout);
5159 PangoLayoutRun *run;
5160 PangoAttribute *attr;
5161 gboolean need_stipple = FALSE;
5164 run = pango_layout_iter_get_run_readonly (iter);
5168 tmp_list = run->item->analysis.extra_attrs;
5170 while (tmp_list != NULL)
5172 attr = tmp_list->data;
5173 switch (attr->klass->type)
5175 case PANGO_ATTR_FOREGROUND:
5176 case PANGO_ATTR_BACKGROUND:
5177 need_stipple = TRUE;
5187 tmp_list = g_slist_next (tmp_list);
5190 br = range_new (run->item->offset, run->item->offset + run->item->length);
5193 stippled_ranges = g_slist_prepend (stippled_ranges, br);
5195 embossed_ranges = g_slist_prepend (embossed_ranges, br);
5198 while (pango_layout_iter_next_run (iter));
5200 pango_layout_iter_free (iter);
5202 new_layout = pango_layout_copy (layout);
5204 attrs = pango_layout_get_attributes (new_layout);
5208 /* Create attr list if there wasn't one */
5209 attrs = pango_attr_list_new ();
5210 pango_layout_set_attributes (new_layout, attrs);
5211 pango_attr_list_unref (attrs);
5214 tmp_list = embossed_ranges;
5215 while (tmp_list != NULL)
5217 PangoAttribute *attr;
5218 ByteRange *br = tmp_list->data;
5220 attr = gdk_pango_attr_embossed_new (TRUE);
5222 attr->start_index = br->start;
5223 attr->end_index = br->end;
5225 pango_attr_list_change (attrs, attr);
5229 tmp_list = g_slist_next (tmp_list);
5232 g_slist_free (embossed_ranges);
5234 tmp_list = stippled_ranges;
5235 while (tmp_list != NULL)
5237 PangoAttribute *attr;
5238 ByteRange *br = tmp_list->data;
5240 if (stipple == NULL)
5242 #define gray50_width 2
5243 #define gray50_height 2
5244 static const char gray50_bits[] = {
5248 stipple = gdk_bitmap_create_from_data (drawable,
5249 gray50_bits, gray50_width,
5253 attr = gdk_pango_attr_stipple_new (stipple);
5255 attr->start_index = br->start;
5256 attr->end_index = br->end;
5258 pango_attr_list_change (attrs, attr);
5262 tmp_list = g_slist_next (tmp_list);
5265 g_slist_free (stippled_ranges);
5268 g_object_unref (stipple);
5274 gtk_default_draw_layout (GtkStyle *style,
5276 GtkStateType state_type,
5280 const gchar *detail,
5283 PangoLayout *layout)
5287 gc = use_text ? style->text_gc[state_type] : style->fg_gc[state_type];
5290 gdk_gc_set_clip_rectangle (gc, area);
5292 if (state_type == GTK_STATE_INSENSITIVE)
5296 ins = get_insensitive_layout (window, layout);
5298 gdk_draw_layout (window, gc, x, y, ins);
5300 g_object_unref (ins);
5304 gdk_draw_layout (window, gc, x, y, layout);
5308 gdk_gc_set_clip_rectangle (gc, NULL);
5312 gtk_default_draw_resize_grip (GtkStyle *style,
5314 GtkStateType state_type,
5317 const gchar *detail,
5329 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
5330 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
5331 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
5337 case GDK_WINDOW_EDGE_NORTH_WEST:
5338 /* make it square */
5341 else if (height < width)
5345 case GDK_WINDOW_EDGE_NORTH:
5349 case GDK_WINDOW_EDGE_NORTH_EAST:
5350 /* make it square, aligning to top right */
5353 else if (height < width)
5355 x += (width - height);
5360 case GDK_WINDOW_EDGE_WEST:
5364 case GDK_WINDOW_EDGE_EAST:
5365 /* aligning to right */
5368 x += (width - height);
5372 case GDK_WINDOW_EDGE_SOUTH_WEST:
5373 /* make it square, aligning to bottom left */
5376 y += (height - width);
5379 else if (height < width)
5383 case GDK_WINDOW_EDGE_SOUTH:
5384 /* align to bottom */
5387 y += (height - width);
5391 case GDK_WINDOW_EDGE_SOUTH_EAST:
5392 /* make it square, aligning to bottom right */
5395 y += (height - width);
5398 else if (height < width)
5400 x += (width - height);
5406 g_assert_not_reached ();
5408 /* Clear background */
5410 for (i = 0; i < 4; i++)
5414 points[j].x = (i == 0 || i == 3) ? x : x + width;
5415 points[j].y = (i < 2) ? y : y + height;
5420 gdk_draw_polygon (window, style->bg_gc[state_type], TRUE,
5421 points, skip < 0 ? 4 : 3);
5425 case GDK_WINDOW_EDGE_WEST:
5426 case GDK_WINDOW_EDGE_EAST:
5432 while (xi < x + width)
5434 gdk_draw_line (window,
5435 style->light_gc[state_type],
5440 gdk_draw_line (window,
5441 style->dark_gc[state_type],
5449 case GDK_WINDOW_EDGE_NORTH:
5450 case GDK_WINDOW_EDGE_SOUTH:
5456 while (yi < y + height)
5458 gdk_draw_line (window,
5459 style->light_gc[state_type],
5464 gdk_draw_line (window,
5465 style->dark_gc[state_type],
5473 case GDK_WINDOW_EDGE_NORTH_WEST:
5482 gdk_draw_line (window,
5483 style->dark_gc[state_type],
5490 gdk_draw_line (window,
5491 style->dark_gc[state_type],
5498 gdk_draw_line (window,
5499 style->light_gc[state_type],
5509 case GDK_WINDOW_EDGE_NORTH_EAST:
5516 while (xi < (x + width - 3))
5518 gdk_draw_line (window,
5519 style->light_gc[state_type],
5526 gdk_draw_line (window,
5527 style->dark_gc[state_type],
5534 gdk_draw_line (window,
5535 style->dark_gc[state_type],
5544 case GDK_WINDOW_EDGE_SOUTH_WEST:
5553 gdk_draw_line (window,
5554 style->dark_gc[state_type],
5561 gdk_draw_line (window,
5562 style->dark_gc[state_type],
5569 gdk_draw_line (window,
5570 style->light_gc[state_type],
5580 case GDK_WINDOW_EDGE_SOUTH_EAST:
5587 while (xi < (x + width - 3))
5589 gdk_draw_line (window,
5590 style->light_gc[state_type],
5597 gdk_draw_line (window,
5598 style->dark_gc[state_type],
5605 gdk_draw_line (window,
5606 style->dark_gc[state_type],
5616 g_assert_not_reached ();
5622 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
5623 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
5624 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
5629 gtk_default_draw_spinner (GtkStyle *style,
5631 GtkStateType state_type,
5634 const gchar *detail,
5650 gtk_style_get (style, GTK_TYPE_SPINNER,
5651 "num-steps", &num_steps,
5653 real_step = step % num_steps;
5655 /* get cairo context */
5656 cr = gdk_cairo_create (window);
5658 /* set a clip region for the expose event */
5659 cairo_rectangle (cr, x, y, width, height);
5662 cairo_translate (cr, x, y);
5664 /* draw clip region */
5665 cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
5667 color = &style->fg[state_type];
5670 radius = MIN (width / 2, height / 2);
5671 half = num_steps / 2;
5673 for (i = 0; i < num_steps; i++)
5675 gint inset = 0.7 * radius;
5677 /* transparency is a function of time and intial value */
5678 gdouble t = (gdouble) ((i + num_steps - real_step)
5679 % num_steps) / num_steps;
5683 cairo_set_source_rgba (cr,
5684 color->red / 65535.,
5685 color->green / 65535.,
5686 color->blue / 65535.,
5689 cairo_set_line_width (cr, 2.0);
5691 dx + (radius - inset) * cos (i * G_PI / half),
5692 dy + (radius - inset) * sin (i * G_PI / half));
5694 dx + radius * cos (i * G_PI / half),
5695 dy + radius * sin (i * G_PI / half));
5706 _gtk_style_shade (const GdkColor *a,
5714 red = (gdouble) a->red / 65535.0;
5715 green = (gdouble) a->green / 65535.0;
5716 blue = (gdouble) a->blue / 65535.0;
5718 rgb_to_hls (&red, &green, &blue);
5723 else if (green < 0.0)
5729 else if (blue < 0.0)
5732 hls_to_rgb (&red, &green, &blue);
5734 b->red = red * 65535.0;
5735 b->green = green * 65535.0;
5736 b->blue = blue * 65535.0;
5740 rgb_to_hls (gdouble *r,
5781 l = (max + min) / 2;
5788 s = (max - min) / (max + min);
5790 s = (max - min) / (2 - max - min);
5794 h = (green - blue) / delta;
5795 else if (green == max)
5796 h = 2 + (blue - red) / delta;
5797 else if (blue == max)
5798 h = 4 + (red - green) / delta;
5811 hls_to_rgb (gdouble *h,
5824 if (lightness <= 0.5)
5825 m2 = lightness * (1 + saturation);
5827 m2 = lightness + saturation - lightness * saturation;
5828 m1 = 2 * lightness - m2;
5830 if (saturation == 0)
5845 r = m1 + (m2 - m1) * hue / 60;
5849 r = m1 + (m2 - m1) * (240 - hue) / 60;
5860 g = m1 + (m2 - m1) * hue / 60;
5864 g = m1 + (m2 - m1) * (240 - hue) / 60;
5875 b = m1 + (m2 - m1) * hue / 60;
5879 b = m1 + (m2 - m1) * (240 - hue) / 60;
5892 * @style: a #GtkStyle
5893 * @window: a #GdkWindow
5894 * @state_type: a state
5895 * @area: (allow-none): rectangle to which the output is clipped, or %NULL if the
5896 * output should not be clipped
5897 * @widget: (allow-none): the widget
5898 * @detail: (allow-none): a style detail
5899 * @x1: the starting x coordinate
5900 * @x2: the ending x coordinate
5901 * @y: the y coordinate
5903 * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @window
5904 * using the given style and state.
5907 gtk_paint_hline (GtkStyle *style,
5909 GtkStateType state_type,
5910 const GdkRectangle *area,
5912 const gchar *detail,
5917 g_return_if_fail (GTK_IS_STYLE (style));
5918 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
5919 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5921 GTK_STYLE_GET_CLASS (style)->draw_hline (style, window, state_type,
5922 (GdkRectangle *) area, widget, detail,
5928 * @style: a #GtkStyle
5929 * @window: a #GdkWindow
5930 * @state_type: a state
5931 * @area: (allow-none): rectangle to which the output is clipped, or %NULL if the
5932 * output should not be clipped
5933 * @widget: (allow-none): the widget
5934 * @detail: (allow-none): a style detail
5935 * @y1_: the starting y coordinate
5936 * @y2_: the ending y coordinate
5937 * @x: the x coordinate
5939 * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @window
5940 * using the given style and state.
5943 gtk_paint_vline (GtkStyle *style,
5945 GtkStateType state_type,
5946 const GdkRectangle *area,
5948 const gchar *detail,
5953 g_return_if_fail (GTK_IS_STYLE (style));
5954 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
5955 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5957 GTK_STYLE_GET_CLASS (style)->draw_vline (style, window, state_type,
5958 (GdkRectangle *) area, widget, detail,
5964 * @style: a #GtkStyle
5965 * @window: a #GdkWindow
5966 * @state_type: a state
5967 * @shadow_type: type of shadow to draw
5968 * @area: (allow-none): clip rectangle or %NULL if the
5969 * output should not be clipped
5970 * @widget: (allow-none): the widget
5971 * @detail: (allow-none): a style detail
5972 * @x: x origin of the rectangle
5973 * @y: y origin of the rectangle
5974 * @width: width of the rectangle
5975 * @height: width of the rectangle
5977 * Draws a shadow around the given rectangle in @window
5978 * using the given style and state and shadow type.
5981 gtk_paint_shadow (GtkStyle *style,
5983 GtkStateType state_type,
5984 GtkShadowType shadow_type,
5985 const GdkRectangle *area,
5987 const gchar *detail,
5993 g_return_if_fail (GTK_IS_STYLE (style));
5994 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
5995 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5997 GTK_STYLE_GET_CLASS (style)->draw_shadow (style, window, state_type, shadow_type,
5998 (GdkRectangle *) area, widget, detail,
5999 x, y, width, height);
6003 * gtk_paint_polygon:
6004 * @style: a #GtkStyle
6005 * @window: a #GdkWindow
6006 * @state_type: a state
6007 * @shadow_type: type of shadow to draw
6008 * @area: (allow-none): clip rectangle, or %NULL if the
6009 * output should not be clipped
6010 * @widget: (allow-none): the widget
6011 * @detail: (allow-none): a style detail
6012 * @points: an array of #GdkPoint<!-- -->s
6013 * @n_points: length of @points
6014 * @fill: %TRUE if the polygon should be filled
6016 * Draws a polygon on @window with the given parameters.
6019 gtk_paint_polygon (GtkStyle *style,
6021 GtkStateType state_type,
6022 GtkShadowType shadow_type,
6023 const GdkRectangle *area,
6025 const gchar *detail,
6026 const GdkPoint *points,
6030 g_return_if_fail (GTK_IS_STYLE (style));
6031 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_polygon != NULL);
6032 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6034 GTK_STYLE_GET_CLASS (style)->draw_polygon (style, window, state_type, shadow_type,
6035 (GdkRectangle *) area, widget, detail,
6036 (GdkPoint *) points, n_points, fill);
6041 * @style: a #GtkStyle
6042 * @window: a #GdkWindow
6043 * @state_type: a state
6044 * @shadow_type: the type of shadow to draw
6045 * @area: (allow-none): clip rectangle, or %NULL if the
6046 * output should not be clipped
6047 * @widget: (allow-none): the widget
6048 * @detail: (allow-none): a style detail
6049 * @arrow_type: the type of arrow to draw
6050 * @fill: %TRUE if the arrow tip should be filled
6051 * @x: x origin of the rectangle to draw the arrow in
6052 * @y: y origin of the rectangle to draw the arrow in
6053 * @width: width of the rectangle to draw the arrow in
6054 * @height: height of the rectangle to draw the arrow in
6056 * Draws an arrow in the given rectangle on @window using the given
6057 * parameters. @arrow_type determines the direction of the arrow.
6060 gtk_paint_arrow (GtkStyle *style,
6062 GtkStateType state_type,
6063 GtkShadowType shadow_type,
6064 const GdkRectangle *area,
6066 const gchar *detail,
6067 GtkArrowType arrow_type,
6074 g_return_if_fail (GTK_IS_STYLE (style));
6075 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
6076 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6078 GTK_STYLE_GET_CLASS (style)->draw_arrow (style, window, state_type, shadow_type,
6079 (GdkRectangle *) area, widget, detail,
6080 arrow_type, fill, x, y, width, height);
6084 * gtk_paint_diamond:
6085 * @style: a #GtkStyle
6086 * @window: a #GdkWindow
6087 * @state_type: a state
6088 * @shadow_type: the type of shadow to draw
6089 * @area: (allow-none): clip rectangle, or %NULL if the
6090 * output should not be clipped
6091 * @widget: (allow-none): the widget
6092 * @detail: (allow-none): a style detail
6093 * @x: x origin of the rectangle to draw the diamond in
6094 * @y: y origin of the rectangle to draw the diamond in
6095 * @width: width of the rectangle to draw the diamond in
6096 * @height: height of the rectangle to draw the diamond in
6098 * Draws a diamond in the given rectangle on @window using the given
6102 gtk_paint_diamond (GtkStyle *style,
6104 GtkStateType state_type,
6105 GtkShadowType shadow_type,
6106 const GdkRectangle *area,
6108 const gchar *detail,
6114 g_return_if_fail (GTK_IS_STYLE (style));
6115 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
6116 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6118 GTK_STYLE_GET_CLASS (style)->draw_diamond (style, window, state_type, shadow_type,
6119 (GdkRectangle *) area, widget, detail,
6120 x, y, width, height);
6125 * @style: a #GtkStyle
6126 * @window: a #GdkWindow
6127 * @state_type: a state
6128 * @area: (allow-none): clip rectangle, or %NULL if the
6129 * output should not be clipped
6130 * @widget: (allow-none): the widget
6131 * @detail: (allow-none): a style detail
6134 * @string: the string to draw
6136 * Draws a text string on @window with the given parameters.
6138 * Deprecated: 2.0: Use gtk_paint_layout() instead.
6141 gtk_paint_string (GtkStyle *style,
6143 GtkStateType state_type,
6144 const GdkRectangle *area,
6146 const gchar *detail,
6149 const gchar *string)
6151 g_return_if_fail (GTK_IS_STYLE (style));
6152 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_string != NULL);
6153 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6155 GTK_STYLE_GET_CLASS (style)->draw_string (style, window, state_type,
6156 (GdkRectangle *) area, widget, detail,
6162 * @style: a #GtkStyle
6163 * @window: a #GdkWindow
6164 * @state_type: a state
6165 * @shadow_type: the type of shadow to draw
6166 * @area: (allow-none): clip rectangle, or %NULL if the
6167 * output should not be clipped
6168 * @widget: (allow-none): the widget
6169 * @detail: (allow-none): a style detail
6170 * @x: x origin of the box
6171 * @y: y origin of the box
6172 * @width: the width of the box
6173 * @height: the height of the box
6175 * Draws a box on @window with the given parameters.
6178 gtk_paint_box (GtkStyle *style,
6180 GtkStateType state_type,
6181 GtkShadowType shadow_type,
6182 const GdkRectangle *area,
6184 const gchar *detail,
6190 g_return_if_fail (GTK_IS_STYLE (style));
6191 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
6192 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6194 GTK_STYLE_GET_CLASS (style)->draw_box (style, window, state_type, shadow_type,
6195 (GdkRectangle *) area, widget, detail,
6196 x, y, width, height);
6200 * gtk_paint_flat_box:
6201 * @style: a #GtkStyle
6202 * @window: a #GdkWindow
6203 * @state_type: a state
6204 * @shadow_type: the type of shadow to draw
6205 * @area: (allow-none): clip rectangle, or %NULL if the
6206 * output should not be clipped
6207 * @widget: (allow-none): the widget
6208 * @detail: (allow-none): a style detail
6209 * @x: x origin of the box
6210 * @y: y origin of the box
6211 * @width: the width of the box
6212 * @height: the height of the box
6214 * Draws a flat box on @window with the given parameters.
6217 gtk_paint_flat_box (GtkStyle *style,
6219 GtkStateType state_type,
6220 GtkShadowType shadow_type,
6221 const GdkRectangle *area,
6223 const gchar *detail,
6229 g_return_if_fail (GTK_IS_STYLE (style));
6230 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
6231 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6233 GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, window, state_type, shadow_type,
6234 (GdkRectangle *) area, widget, detail,
6235 x, y, width, height);
6240 * @style: a #GtkStyle
6241 * @window: a #GdkWindow
6242 * @state_type: a state
6243 * @shadow_type: the type of shadow to draw
6244 * @area: (allow-none): clip rectangle, or %NULL if the
6245 * output should not be clipped
6246 * @widget: (allow-none): the widget
6247 * @detail: (allow-none): a style detail
6248 * @x: x origin of the rectangle to draw the check in
6249 * @y: y origin of the rectangle to draw the check in
6250 * @width: the width of the rectangle to draw the check in
6251 * @height: the height of the rectangle to draw the check in
6253 * Draws a check button indicator in the given rectangle on @window with
6254 * the given parameters.
6257 gtk_paint_check (GtkStyle *style,
6259 GtkStateType state_type,
6260 GtkShadowType shadow_type,
6261 const GdkRectangle *area,
6263 const gchar *detail,
6269 g_return_if_fail (GTK_IS_STYLE (style));
6270 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
6271 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6273 GTK_STYLE_GET_CLASS (style)->draw_check (style, window, state_type, shadow_type,
6274 (GdkRectangle *) area, widget, detail,
6275 x, y, width, height);
6280 * @style: a #GtkStyle
6281 * @window: a #GdkWindow
6282 * @state_type: a state
6283 * @shadow_type: the type of shadow to draw
6284 * @area: (allow-none): clip rectangle, or %NULL if the
6285 * output should not be clipped
6286 * @widget: (allow-none): the widget
6287 * @detail: (allow-none): a style detail
6288 * @x: x origin of the rectangle to draw the option in
6289 * @y: y origin of the rectangle to draw the option in
6290 * @width: the width of the rectangle to draw the option in
6291 * @height: the height of the rectangle to draw the option in
6293 * Draws a radio button indicator in the given rectangle on @window with
6294 * the given parameters.
6297 gtk_paint_option (GtkStyle *style,
6299 GtkStateType state_type,
6300 GtkShadowType shadow_type,
6301 const GdkRectangle *area,
6303 const gchar *detail,
6309 g_return_if_fail (GTK_IS_STYLE (style));
6310 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
6311 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6313 GTK_STYLE_GET_CLASS (style)->draw_option (style, window, state_type, shadow_type,
6314 (GdkRectangle *) area, widget, detail,
6315 x, y, width, height);
6320 * @style: a #GtkStyle
6321 * @window: a #GdkWindow
6322 * @state_type: a state
6323 * @shadow_type: the type of shadow to draw
6324 * @area: (allow-none): clip rectangle, or %NULL if the
6325 * output should not be clipped
6326 * @widget: (allow-none): the widget
6327 * @detail: (allow-none): a style detail
6328 * @x: x origin of the rectangle to draw the tab in
6329 * @y: y origin of the rectangle to draw the tab in
6330 * @width: the width of the rectangle to draw the tab in
6331 * @height: the height of the rectangle to draw the tab in
6333 * Draws an option menu tab (i.e. the up and down pointing arrows)
6334 * in the given rectangle on @window using the given parameters.
6337 gtk_paint_tab (GtkStyle *style,
6339 GtkStateType state_type,
6340 GtkShadowType shadow_type,
6341 const GdkRectangle *area,
6343 const gchar *detail,
6349 g_return_if_fail (GTK_IS_STYLE (style));
6350 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
6351 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6353 GTK_STYLE_GET_CLASS (style)->draw_tab (style, window, state_type, shadow_type,
6354 (GdkRectangle *) area, widget, detail,
6355 x, y, width, height);
6359 * gtk_paint_shadow_gap:
6360 * @style: a #GtkStyle
6361 * @window: a #GdkWindow
6362 * @state_type: a state
6363 * @shadow_type: type of shadow to draw
6364 * @area: (allow-none): clip rectangle, or %NULL if the
6365 * output should not be clipped
6366 * @widget: (allow-none): the widget
6367 * @detail: (allow-none): a style detail
6368 * @x: x origin of the rectangle
6369 * @y: y origin of the rectangle
6370 * @width: width of the rectangle
6371 * @height: width of the rectangle
6372 * @gap_side: side in which to leave the gap
6373 * @gap_x: starting position of the gap
6374 * @gap_width: width of the gap
6376 * Draws a shadow around the given rectangle in @window
6377 * using the given style and state and shadow type, leaving a
6381 gtk_paint_shadow_gap (GtkStyle *style,
6383 GtkStateType state_type,
6384 GtkShadowType shadow_type,
6385 const GdkRectangle *area,
6387 const gchar *detail,
6392 GtkPositionType gap_side,
6396 g_return_if_fail (GTK_IS_STYLE (style));
6397 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
6398 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6400 GTK_STYLE_GET_CLASS (style)->draw_shadow_gap (style, window, state_type, shadow_type,
6401 (GdkRectangle *) area, widget, detail,
6402 x, y, width, height, gap_side, gap_x, gap_width);
6407 * gtk_paint_box_gap:
6408 * @style: a #GtkStyle
6409 * @window: a #GdkWindow
6410 * @state_type: a state
6411 * @shadow_type: type of shadow to draw
6412 * @area: (allow-none): clip rectangle, or %NULL if the
6413 * output should not be clipped
6414 * @widget: (allow-none): the widget
6415 * @detail: (allow-none): a style detail
6416 * @x: x origin of the rectangle
6417 * @y: y origin of the rectangle
6418 * @width: width of the rectangle
6419 * @height: width of the rectangle
6420 * @gap_side: side in which to leave the gap
6421 * @gap_x: starting position of the gap
6422 * @gap_width: width of the gap
6424 * Draws a box in @window using the given style and state and shadow type,
6425 * leaving a gap in one side.
6428 gtk_paint_box_gap (GtkStyle *style,
6430 GtkStateType state_type,
6431 GtkShadowType shadow_type,
6432 const GdkRectangle *area,
6434 const gchar *detail,
6439 GtkPositionType gap_side,
6443 g_return_if_fail (GTK_IS_STYLE (style));
6444 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
6445 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6447 GTK_STYLE_GET_CLASS (style)->draw_box_gap (style, window, state_type, shadow_type,
6448 (GdkRectangle *) area, widget, detail,
6449 x, y, width, height, gap_side, gap_x, gap_width);
6453 * gtk_paint_extension:
6454 * @style: a #GtkStyle
6455 * @window: a #GdkWindow
6456 * @state_type: a state
6457 * @shadow_type: type of shadow to draw
6458 * @area: (allow-none): clip rectangle, or %NULL if the
6459 * output should not be clipped
6460 * @widget: (allow-none): the widget
6461 * @detail: (allow-none): a style detail
6462 * @x: x origin of the extension
6463 * @y: y origin of the extension
6464 * @width: width of the extension
6465 * @height: width of the extension
6466 * @gap_side: the side on to which the extension is attached
6468 * Draws an extension, i.e. a notebook tab.
6471 gtk_paint_extension (GtkStyle *style,
6473 GtkStateType state_type,
6474 GtkShadowType shadow_type,
6475 const GdkRectangle *area,
6477 const gchar *detail,
6482 GtkPositionType gap_side)
6484 g_return_if_fail (GTK_IS_STYLE (style));
6485 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
6486 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6488 GTK_STYLE_GET_CLASS (style)->draw_extension (style, window, state_type, shadow_type,
6489 (GdkRectangle *) area, widget, detail,
6490 x, y, width, height, gap_side);
6495 * @style: a #GtkStyle
6496 * @window: a #GdkWindow
6497 * @state_type: a state
6498 * @area: (allow-none): clip rectangle, or %NULL if the
6499 * output should not be clipped
6500 * @widget: (allow-none): the widget
6501 * @detail: (allow-none): a style detail
6502 * @x: the x origin of the rectangle around which to draw a focus indicator
6503 * @y: the y origin of the rectangle around which to draw a focus indicator
6504 * @width: the width of the rectangle around which to draw a focus indicator
6505 * @height: the height of the rectangle around which to draw a focus indicator
6507 * Draws a focus indicator around the given rectangle on @window using the
6511 gtk_paint_focus (GtkStyle *style,
6513 GtkStateType state_type,
6514 const GdkRectangle *area,
6516 const gchar *detail,
6522 g_return_if_fail (GTK_IS_STYLE (style));
6523 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
6524 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6526 GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, state_type,
6527 (GdkRectangle *) area, widget, detail,
6528 x, y, width, height);
6533 * @style: a #GtkStyle
6534 * @window: a #GdkWindow
6535 * @state_type: a state
6536 * @shadow_type: a shadow
6537 * @area: (allow-none): clip rectangle, or %NULL if the
6538 * output should not be clipped
6539 * @widget: (allow-none): the widget
6540 * @detail: (allow-none): a style detail
6541 * @x: the x origin of the rectangle in which to draw a slider
6542 * @y: the y origin of the rectangle in which to draw a slider
6543 * @width: the width of the rectangle in which to draw a slider
6544 * @height: the height of the rectangle in which to draw a slider
6545 * @orientation: the orientation to be used
6547 * Draws a slider in the given rectangle on @window using the
6548 * given style and orientation.
6551 gtk_paint_slider (GtkStyle *style,
6553 GtkStateType state_type,
6554 GtkShadowType shadow_type,
6555 const GdkRectangle *area,
6557 const gchar *detail,
6562 GtkOrientation orientation)
6564 g_return_if_fail (GTK_IS_STYLE (style));
6565 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
6566 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6568 GTK_STYLE_GET_CLASS (style)->draw_slider (style, window, state_type, shadow_type,
6569 (GdkRectangle *) area, widget, detail,
6570 x, y, width, height, orientation);
6575 * @style: a #GtkStyle
6576 * @window: a #GdkWindow
6577 * @state_type: a state
6578 * @shadow_type: type of shadow to draw
6579 * @area: (allow-none): clip rectangle, or %NULL if the
6580 * output should not be clipped
6581 * @widget: (allow-none): the widget
6582 * @detail: (allow-none): a style detail
6583 * @x: x origin of the handle
6584 * @y: y origin of the handle
6585 * @width: with of the handle
6586 * @height: height of the handle
6587 * @orientation: the orientation of the handle
6589 * Draws a handle as used in #GtkHandleBox and #GtkPaned.
6592 gtk_paint_handle (GtkStyle *style,
6594 GtkStateType state_type,
6595 GtkShadowType shadow_type,
6596 const GdkRectangle *area,
6598 const gchar *detail,
6603 GtkOrientation orientation)
6605 g_return_if_fail (GTK_IS_STYLE (style));
6606 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
6607 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6609 GTK_STYLE_GET_CLASS (style)->draw_handle (style, window, state_type, shadow_type,
6610 (GdkRectangle *) area, widget, detail,
6611 x, y, width, height, orientation);
6615 * gtk_paint_expander:
6616 * @style: a #GtkStyle
6617 * @window: a #GdkWindow
6618 * @state_type: a state
6619 * @area: (allow-none): clip rectangle, or %NULL if the
6620 * output should not be clipped
6621 * @widget: (allow-none): the widget
6622 * @detail: (allow-none): a style detail
6623 * @x: the x position to draw the expander at
6624 * @y: the y position to draw the expander at
6625 * @expander_style: the style to draw the expander in; determines
6626 * whether the expander is collapsed, expanded, or in an
6627 * intermediate state.
6629 * Draws an expander as used in #GtkTreeView. @x and @y specify the
6630 * center the expander. The size of the expander is determined by the
6631 * "expander-size" style property of @widget. (If widget is not
6632 * specified or doesn't have an "expander-size" property, an
6633 * unspecified default size will be used, since the caller doesn't
6634 * have sufficient information to position the expander, this is
6635 * likely not useful.) The expander is expander_size pixels tall
6636 * in the collapsed position and expander_size pixels wide in the
6637 * expanded position.
6640 gtk_paint_expander (GtkStyle *style,
6642 GtkStateType state_type,
6643 const GdkRectangle *area,
6645 const gchar *detail,
6648 GtkExpanderStyle expander_style)
6650 g_return_if_fail (GTK_IS_STYLE (style));
6651 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
6652 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6654 GTK_STYLE_GET_CLASS (style)->draw_expander (style, window, state_type,
6655 (GdkRectangle *) area, widget, detail,
6656 x, y, expander_style);
6661 * @style: a #GtkStyle
6662 * @window: a #GdkWindow
6663 * @state_type: a state
6664 * @use_text: whether to use the text or foreground
6665 * graphics context of @style
6666 * @area: (allow-none): clip rectangle, or %NULL if the
6667 * output should not be clipped
6668 * @widget: (allow-none): the widget
6669 * @detail: (allow-none): a style detail
6672 * @layout: the layout to draw
6674 * Draws a layout on @window using the given parameters.
6677 gtk_paint_layout (GtkStyle *style,
6679 GtkStateType state_type,
6681 const GdkRectangle *area,
6683 const gchar *detail,
6686 PangoLayout *layout)
6688 g_return_if_fail (GTK_IS_STYLE (style));
6689 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
6690 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6692 GTK_STYLE_GET_CLASS (style)->draw_layout (style, window, state_type, use_text,
6693 (GdkRectangle *) area, widget, detail,
6698 * gtk_paint_resize_grip:
6699 * @style: a #GtkStyle
6700 * @window: a #GdkWindow
6701 * @state_type: a state
6702 * @area: (allow-none): clip rectangle, or %NULL if the
6703 * output should not be clipped
6704 * @widget: (allow-none): the widget
6705 * @detail: (allow-none): a style detail
6706 * @edge: the edge in which to draw the resize grip
6707 * @x: the x origin of the rectangle in which to draw the resize grip
6708 * @y: the y origin of the rectangle in which to draw the resize grip
6709 * @width: the width of the rectangle in which to draw the resize grip
6710 * @height: the height of the rectangle in which to draw the resize grip
6712 * Draws a resize grip in the given rectangle on @window using the given
6716 gtk_paint_resize_grip (GtkStyle *style,
6718 GtkStateType state_type,
6719 const GdkRectangle *area,
6721 const gchar *detail,
6729 g_return_if_fail (GTK_IS_STYLE (style));
6730 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
6731 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6733 GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, window, state_type,
6734 (GdkRectangle *) area, widget, detail,
6735 edge, x, y, width, height);
6739 * gtk_paint_spinner:
6740 * @style: a #GtkStyle
6741 * @window: a #GdkWindow
6742 * @state_type: a state
6743 * @area: (allow-none): clip rectangle, or %NULL if the
6744 * output should not be clipped
6745 * @widget: (allow-none): the widget (may be %NULL)
6746 * @detail: (allow-none): a style detail (may be %NULL)
6747 * @step: the nth step, a value between 0 and #GtkSpinner:num-steps
6748 * @x: the x origin of the rectangle in which to draw the spinner
6749 * @y: the y origin of the rectangle in which to draw the spinner
6750 * @width: the width of the rectangle in which to draw the spinner
6751 * @height: the height of the rectangle in which to draw the spinner
6753 * Draws a spinner on @window using the given parameters.
6758 gtk_paint_spinner (GtkStyle *style,
6760 GtkStateType state_type,
6761 const GdkRectangle *area,
6763 const gchar *detail,
6770 g_return_if_fail (GTK_IS_STYLE (style));
6771 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_spinner != NULL);
6772 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6774 GTK_STYLE_GET_CLASS (style)->draw_spinner (style, window, state_type,
6775 (GdkRectangle *)area, widget, detail,
6776 step, x, y, width, height);
6782 * Allocates a new #GtkBorder structure and initializes its elements to zero.
6784 * Returns: a new empty #GtkBorder. The newly allocated #GtkBorder should be
6785 * freed with gtk_border_free()
6790 gtk_border_new (void)
6792 return g_slice_new0 (GtkBorder);
6797 * @border_: a #GtkBorder.
6798 * @returns: a copy of @border_.
6800 * Copies a #GtkBorder structure.
6803 gtk_border_copy (const GtkBorder *border)
6805 g_return_val_if_fail (border != NULL, NULL);
6807 return g_slice_dup (GtkBorder, border);
6812 * @border_: a #GtkBorder.
6814 * Frees a #GtkBorder structure.
6817 gtk_border_free (GtkBorder *border)
6819 g_slice_free (GtkBorder, border);
6823 gtk_border_get_type (void)
6825 static GType our_type = 0;
6828 our_type = g_boxed_type_register_static (I_("GtkBorder"),
6829 (GBoxedCopyFunc) gtk_border_copy,
6830 (GBoxedFreeFunc) gtk_border_free);
6836 gtk_style_get_font_internal (GtkStyle *style)
6838 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
6840 if (style->private_font && style->private_font_desc)
6842 if (!style->font_desc ||
6843 !pango_font_description_equal (style->private_font_desc, style->font_desc))
6845 gdk_font_unref (style->private_font);
6846 style->private_font = NULL;
6848 if (style->private_font_desc)
6850 pango_font_description_free (style->private_font_desc);
6851 style->private_font_desc = NULL;
6856 if (!style->private_font)
6858 GdkDisplay *display;
6860 if (style->colormap)
6862 display = gdk_screen_get_display (gdk_colormap_get_screen (style->colormap));
6866 display = gdk_display_get_default ();
6867 GTK_NOTE (MULTIHEAD,
6868 g_warning ("gtk_style_get_font() should not be called on an unattached style"));
6871 if (style->font_desc)
6873 style->private_font = gdk_font_from_description_for_display (display, style->font_desc);
6874 style->private_font_desc = pango_font_description_copy (style->font_desc);
6877 if (!style->private_font)
6878 style->private_font = gdk_font_load_for_display (display, "fixed");
6880 if (!style->private_font)
6881 g_error ("Unable to load \"fixed\" font");
6884 return style->private_font;
6888 * gtk_style_get_font:
6889 * @style: a #GtkStyle
6891 * Gets the #GdkFont to use for the given style. This is
6892 * meant only as a replacement for direct access to @style->font
6893 * and should not be used in new code. New code should
6894 * use @style->font_desc instead.
6896 * Return value: the #GdkFont for the style. This font is owned
6897 * by the style; if you want to keep around a copy, you must
6898 * call gdk_font_ref().
6901 gtk_style_get_font (GtkStyle *style)
6903 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
6905 return gtk_style_get_font_internal (style);
6909 * gtk_style_set_font:
6910 * @style: a #GtkStyle.
6911 * @font: (allow-none): a #GdkFont, or %NULL to use the #GdkFont corresponding
6912 * to style->font_desc.
6914 * Sets the #GdkFont to use for a given style. This is
6915 * meant only as a replacement for direct access to style->font
6916 * and should not be used in new code. New code should
6917 * use style->font_desc instead.
6920 gtk_style_set_font (GtkStyle *style,
6925 g_return_if_fail (GTK_IS_STYLE (style));
6927 old_font = style->private_font;
6929 style->private_font = font;
6931 gdk_font_ref (font);
6934 gdk_font_unref (old_font);
6936 if (style->private_font_desc)
6938 pango_font_description_free (style->private_font_desc);
6939 style->private_font_desc = NULL;
6943 typedef struct _CursorInfo CursorInfo;
6949 GdkGC *secondary_gc;
6953 style_unrealize_cursor_gcs (GtkStyle *style)
6957 cursor_info = g_object_get_data (G_OBJECT (style), "gtk-style-cursor-info");
6960 if (cursor_info->primary_gc)
6961 gtk_gc_release (cursor_info->primary_gc);
6963 if (cursor_info->secondary_gc)
6964 gtk_gc_release (cursor_info->secondary_gc);
6966 g_free (cursor_info);
6967 g_object_set_data (G_OBJECT (style), I_("gtk-style-cursor-info"), NULL);
6972 make_cursor_gc (GtkWidget *widget,
6973 const gchar *property_name,
6974 const GdkColor *fallback)
6976 GdkGCValues gc_values;
6977 GdkGCValuesMask gc_values_mask;
6978 GdkColor *cursor_color;
6980 gtk_widget_style_get (widget, property_name, &cursor_color, NULL);
6982 gc_values_mask = GDK_GC_FOREGROUND;
6985 gc_values.foreground = *cursor_color;
6986 gdk_color_free (cursor_color);
6989 gc_values.foreground = *fallback;
6991 gdk_rgb_find_color (widget->style->colormap, &gc_values.foreground);
6992 return gtk_gc_get (widget->style->depth, widget->style->colormap, &gc_values, gc_values_mask);
6996 get_insertion_cursor_gc (GtkWidget *widget,
6997 gboolean is_primary)
6999 CursorInfo *cursor_info;
7001 cursor_info = g_object_get_data (G_OBJECT (widget->style), "gtk-style-cursor-info");
7004 cursor_info = g_new (CursorInfo, 1);
7005 g_object_set_data (G_OBJECT (widget->style), I_("gtk-style-cursor-info"), cursor_info);
7006 cursor_info->primary_gc = NULL;
7007 cursor_info->secondary_gc = NULL;
7008 cursor_info->for_type = G_TYPE_INVALID;
7011 /* We have to keep track of the type because gtk_widget_style_get()
7012 * can return different results when called on the same property and
7013 * same style but for different widgets. :-(. That is,
7014 * GtkEntry::cursor-color = "red" in a style will modify the cursor
7015 * color for entries but not for text view.
7017 if (cursor_info->for_type != G_OBJECT_TYPE (widget))
7019 cursor_info->for_type = G_OBJECT_TYPE (widget);
7020 if (cursor_info->primary_gc)
7022 gtk_gc_release (cursor_info->primary_gc);
7023 cursor_info->primary_gc = NULL;
7025 if (cursor_info->secondary_gc)
7027 gtk_gc_release (cursor_info->secondary_gc);
7028 cursor_info->secondary_gc = NULL;
7032 /* Cursors in text widgets are drawn only in NORMAL state,
7033 * so we can use text[GTK_STATE_NORMAL] as text color here */
7036 if (!cursor_info->primary_gc)
7037 cursor_info->primary_gc = make_cursor_gc (widget,
7039 &widget->style->text[GTK_STATE_NORMAL]);
7041 return cursor_info->primary_gc;
7045 if (!cursor_info->secondary_gc)
7046 cursor_info->secondary_gc = make_cursor_gc (widget,
7047 "secondary-cursor-color",
7048 /* text_aa is the average of text and base colors,
7049 * in usual black-on-white case it's grey. */
7050 &widget->style->text_aa[GTK_STATE_NORMAL]);
7052 return cursor_info->secondary_gc;
7057 _gtk_widget_get_cursor_gc (GtkWidget *widget)
7059 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
7060 g_return_val_if_fail (gtk_widget_get_realized (widget), NULL);
7061 return get_insertion_cursor_gc (widget, TRUE);
7065 _gtk_widget_get_cursor_color (GtkWidget *widget,
7068 GdkColor *style_color;
7070 g_return_if_fail (GTK_IS_WIDGET (widget));
7071 g_return_if_fail (color != NULL);
7073 gtk_widget_style_get (widget, "cursor-color", &style_color, NULL);
7077 *color = *style_color;
7078 gdk_color_free (style_color);
7081 *color = widget->style->text[GTK_STATE_NORMAL];
7085 draw_insertion_cursor (GtkWidget *widget,
7086 GdkDrawable *drawable,
7088 const GdkRectangle *location,
7089 GtkTextDirection direction,
7090 gboolean draw_arrow)
7096 gfloat cursor_aspect_ratio;
7099 /* When changing the shape or size of the cursor here,
7100 * propagate the changes to gtktextview.c:text_window_invalidate_cursors().
7103 gtk_widget_style_get (widget, "cursor-aspect-ratio", &cursor_aspect_ratio, NULL);
7105 stem_width = location->height * cursor_aspect_ratio + 1;
7106 arrow_width = stem_width + 1;
7108 /* put (stem_width % 2) on the proper side of the cursor */
7109 if (direction == GTK_TEXT_DIR_LTR)
7110 offset = stem_width / 2;
7112 offset = stem_width - stem_width / 2;
7114 for (i = 0; i < stem_width; i++)
7115 gdk_draw_line (drawable, gc,
7116 location->x + i - offset, location->y,
7117 location->x + i - offset, location->y + location->height - 1);
7121 if (direction == GTK_TEXT_DIR_RTL)
7123 x = location->x - offset - 1;
7124 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
7126 for (i = 0; i < arrow_width; i++)
7128 gdk_draw_line (drawable, gc,
7130 x, y + 2 * arrow_width - i - 1);
7134 else if (direction == GTK_TEXT_DIR_LTR)
7136 x = location->x + stem_width - offset;
7137 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
7139 for (i = 0; i < arrow_width; i++)
7141 gdk_draw_line (drawable, gc,
7143 x, y + 2 * arrow_width - i - 1);
7151 * gtk_draw_insertion_cursor:
7152 * @widget: a #GtkWidget
7153 * @drawable: a #GdkDrawable
7154 * @area: (allow-none): rectangle to which the output is clipped, or %NULL if the
7155 * output should not be clipped
7156 * @location: location where to draw the cursor (@location->width is ignored)
7157 * @is_primary: if the cursor should be the primary cursor color.
7158 * @direction: whether the cursor is left-to-right or
7159 * right-to-left. Should never be #GTK_TEXT_DIR_NONE
7160 * @draw_arrow: %TRUE to draw a directional arrow on the
7161 * cursor. Should be %FALSE unless the cursor is split.
7163 * Draws a text caret on @drawable at @location. This is not a style function
7164 * but merely a convenience function for drawing the standard cursor shape.
7169 gtk_draw_insertion_cursor (GtkWidget *widget,
7170 GdkDrawable *drawable,
7171 const GdkRectangle *area,
7172 const GdkRectangle *location,
7173 gboolean is_primary,
7174 GtkTextDirection direction,
7175 gboolean draw_arrow)
7179 g_return_if_fail (GTK_IS_WIDGET (widget));
7180 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
7181 g_return_if_fail (location != NULL);
7182 g_return_if_fail (direction != GTK_TEXT_DIR_NONE);
7184 gc = get_insertion_cursor_gc (widget, is_primary);
7186 gdk_gc_set_clip_rectangle (gc, area);
7188 draw_insertion_cursor (widget, drawable, gc,
7189 location, direction, draw_arrow);
7192 gdk_gc_set_clip_rectangle (gc, NULL);
7195 #define __GTK_STYLE_C__
7196 #include "gtkaliasdef.c"