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,
317 static void rgb_to_hls (gdouble *r,
320 static void hls_to_rgb (gdouble *h,
324 static void style_unrealize_cursor_gcs (GtkStyle *style);
326 static GdkFont *gtk_style_get_font_internal (GtkStyle *style);
329 * Data for default check and radio buttons
332 static const GtkRequisition default_option_indicator_size = { 7, 13 };
333 static const GtkBorder default_option_indicator_spacing = { 7, 5, 2, 2 };
335 #define GTK_GRAY 0xdcdc, 0xdada, 0xd5d5
336 #define GTK_DARK_GRAY 0xc4c4, 0xc2c2, 0xbdbd
337 #define GTK_LIGHT_GRAY 0xeeee, 0xebeb, 0xe7e7
338 #define GTK_WHITE 0xffff, 0xffff, 0xffff
339 #define GTK_BLUE 0x4b4b, 0x6969, 0x8383
340 #define GTK_VERY_DARK_GRAY 0x9c9c, 0x9a9a, 0x9494
341 #define GTK_BLACK 0x0000, 0x0000, 0x0000
342 #define GTK_WEAK_GRAY 0x7530, 0x7530, 0x7530
344 /* --- variables --- */
345 static const GdkColor gtk_default_normal_fg = { 0, GTK_BLACK };
346 static const GdkColor gtk_default_active_fg = { 0, GTK_BLACK };
347 static const GdkColor gtk_default_prelight_fg = { 0, GTK_BLACK };
348 static const GdkColor gtk_default_selected_fg = { 0, GTK_WHITE };
349 static const GdkColor gtk_default_insensitive_fg = { 0, GTK_WEAK_GRAY };
351 static const GdkColor gtk_default_normal_bg = { 0, GTK_GRAY };
352 static const GdkColor gtk_default_active_bg = { 0, GTK_DARK_GRAY };
353 static const GdkColor gtk_default_prelight_bg = { 0, GTK_LIGHT_GRAY };
354 static const GdkColor gtk_default_selected_bg = { 0, GTK_BLUE };
355 static const GdkColor gtk_default_insensitive_bg = { 0, GTK_GRAY };
356 static const GdkColor gtk_default_selected_base = { 0, GTK_BLUE };
357 static const GdkColor gtk_default_active_base = { 0, GTK_VERY_DARK_GRAY };
359 /* --- signals --- */
360 static guint realize_signal = 0;
361 static guint unrealize_signal = 0;
363 G_DEFINE_TYPE (GtkStyle, gtk_style, G_TYPE_OBJECT)
365 /* --- functions --- */
368 * _gtk_style_init_for_settings:
369 * @style: a #GtkStyle
370 * @settings: a #GtkSettings
372 * Initializes the font description in @style according to the default
373 * font name of @settings. This is called for gtk_style_new() with
374 * the settings for the default screen (if any); if we are creating
375 * a style for a particular screen, we then call it again in a
376 * location where we know the correct settings.
377 * The reason for this is that gtk_rc_style_create_style() doesn't
378 * take the screen for an argument.
381 _gtk_style_init_for_settings (GtkStyle *style,
382 GtkSettings *settings)
384 const gchar *font_name = _gtk_rc_context_get_default_font_name (settings);
386 if (style->font_desc)
387 pango_font_description_free (style->font_desc);
389 style->font_desc = pango_font_description_from_string (font_name);
391 if (!pango_font_description_get_family (style->font_desc))
393 g_warning ("Default font does not have a family set");
394 pango_font_description_set_family (style->font_desc, "Sans");
396 if (pango_font_description_get_size (style->font_desc) <= 0)
398 g_warning ("Default font does not have a positive size");
399 pango_font_description_set_size (style->font_desc, 10 * PANGO_SCALE);
404 gtk_style_init (GtkStyle *style)
408 GtkSettings *settings = gtk_settings_get_default ();
411 _gtk_style_init_for_settings (style, settings);
413 style->font_desc = pango_font_description_from_string ("Sans 10");
415 style->attach_count = 0;
416 style->colormap = NULL;
419 style->black.red = 0;
420 style->black.green = 0;
421 style->black.blue = 0;
423 style->white.red = 65535;
424 style->white.green = 65535;
425 style->white.blue = 65535;
427 style->black_gc = NULL;
428 style->white_gc = NULL;
430 style->fg[GTK_STATE_NORMAL] = gtk_default_normal_fg;
431 style->fg[GTK_STATE_ACTIVE] = gtk_default_active_fg;
432 style->fg[GTK_STATE_PRELIGHT] = gtk_default_prelight_fg;
433 style->fg[GTK_STATE_SELECTED] = gtk_default_selected_fg;
434 style->fg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
436 style->bg[GTK_STATE_NORMAL] = gtk_default_normal_bg;
437 style->bg[GTK_STATE_ACTIVE] = gtk_default_active_bg;
438 style->bg[GTK_STATE_PRELIGHT] = gtk_default_prelight_bg;
439 style->bg[GTK_STATE_SELECTED] = gtk_default_selected_bg;
440 style->bg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_bg;
442 for (i = 0; i < 4; i++)
444 style->text[i] = style->fg[i];
445 style->base[i] = style->white;
448 style->base[GTK_STATE_SELECTED] = gtk_default_selected_base;
449 style->text[GTK_STATE_SELECTED] = style->white;
450 style->base[GTK_STATE_ACTIVE] = gtk_default_active_base;
451 style->text[GTK_STATE_ACTIVE] = style->white;
452 style->base[GTK_STATE_INSENSITIVE] = gtk_default_prelight_bg;
453 style->text[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
455 for (i = 0; i < 5; i++)
456 style->bg_pixmap[i] = NULL;
458 style->rc_style = NULL;
460 for (i = 0; i < 5; i++)
462 style->fg_gc[i] = NULL;
463 style->bg_gc[i] = NULL;
464 style->light_gc[i] = NULL;
465 style->dark_gc[i] = NULL;
466 style->mid_gc[i] = NULL;
467 style->text_gc[i] = NULL;
468 style->base_gc[i] = NULL;
469 style->text_aa_gc[i] = NULL;
472 style->xthickness = 2;
473 style->ythickness = 2;
475 style->property_cache = NULL;
479 gtk_style_class_init (GtkStyleClass *klass)
481 GObjectClass *object_class = G_OBJECT_CLASS (klass);
483 object_class->finalize = gtk_style_finalize;
485 klass->clone = gtk_style_real_clone;
486 klass->copy = gtk_style_real_copy;
487 klass->init_from_rc = gtk_style_real_init_from_rc;
488 klass->realize = gtk_style_real_realize;
489 klass->unrealize = gtk_style_real_unrealize;
490 klass->set_background = gtk_style_real_set_background;
491 klass->render_icon = gtk_default_render_icon;
493 klass->draw_hline = gtk_default_draw_hline;
494 klass->draw_vline = gtk_default_draw_vline;
495 klass->draw_shadow = gtk_default_draw_shadow;
496 klass->draw_polygon = gtk_default_draw_polygon;
497 klass->draw_arrow = gtk_default_draw_arrow;
498 klass->draw_diamond = gtk_default_draw_diamond;
499 klass->draw_string = gtk_default_draw_string;
500 klass->draw_box = gtk_default_draw_box;
501 klass->draw_flat_box = gtk_default_draw_flat_box;
502 klass->draw_check = gtk_default_draw_check;
503 klass->draw_option = gtk_default_draw_option;
504 klass->draw_tab = gtk_default_draw_tab;
505 klass->draw_shadow_gap = gtk_default_draw_shadow_gap;
506 klass->draw_box_gap = gtk_default_draw_box_gap;
507 klass->draw_extension = gtk_default_draw_extension;
508 klass->draw_focus = gtk_default_draw_focus;
509 klass->draw_slider = gtk_default_draw_slider;
510 klass->draw_handle = gtk_default_draw_handle;
511 klass->draw_expander = gtk_default_draw_expander;
512 klass->draw_layout = gtk_default_draw_layout;
513 klass->draw_resize_grip = gtk_default_draw_resize_grip;
515 g_type_class_add_private (object_class, sizeof (GtkStylePrivate));
519 * @style: the object which received the signal
521 * Emitted when the style has been initialized for a particular
522 * colormap and depth. Connecting to this signal is probably seldom
523 * useful since most of the time applications and widgets only
524 * deal with styles that have been already realized.
528 realize_signal = g_signal_new (I_("realize"),
529 G_TYPE_FROM_CLASS (object_class),
531 G_STRUCT_OFFSET (GtkStyleClass, realize),
533 _gtk_marshal_VOID__VOID,
536 * GtkStyle::unrealize:
537 * @style: the object which received the signal
539 * Emitted when the aspects of the style specific to a particular colormap
540 * and depth are being cleaned up. A connection to this signal can be useful
541 * if a widget wants to cache objects like a #GdkGC as object data on #GtkStyle.
542 * This signal provides a convenient place to free such cached objects.
546 unrealize_signal = g_signal_new (I_("unrealize"),
547 G_TYPE_FROM_CLASS (object_class),
549 G_STRUCT_OFFSET (GtkStyleClass, unrealize),
551 _gtk_marshal_VOID__VOID,
556 clear_property_cache (GtkStyle *style)
558 if (style->property_cache)
562 for (i = 0; i < style->property_cache->len; i++)
564 PropertyValue *node = &g_array_index (style->property_cache, PropertyValue, i);
566 g_param_spec_unref (node->pspec);
567 g_value_unset (&node->value);
569 g_array_free (style->property_cache, TRUE);
570 style->property_cache = NULL;
575 gtk_style_finalize (GObject *object)
577 GtkStyle *style = GTK_STYLE (object);
578 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
580 g_return_if_fail (style->attach_count == 0);
582 clear_property_cache (style);
584 /* All the styles in the list have the same
585 * style->styles pointer. If we delete the
586 * *first* style from the list, we need to update
587 * the style->styles pointers from all the styles.
588 * Otherwise we simply remove the node from
593 if (style->styles->data != style)
594 style->styles = g_slist_remove (style->styles, style);
597 GSList *tmp_list = style->styles->next;
601 GTK_STYLE (tmp_list->data)->styles = style->styles->next;
602 tmp_list = tmp_list->next;
604 g_slist_free_1 (style->styles);
608 g_slist_foreach (style->icon_factories, (GFunc) g_object_unref, NULL);
609 g_slist_free (style->icon_factories);
611 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_unref, NULL);
612 g_slist_free (priv->color_hashes);
614 pango_font_description_free (style->font_desc);
616 if (style->private_font)
617 gdk_font_unref (style->private_font);
619 if (style->private_font_desc)
620 pango_font_description_free (style->private_font_desc);
623 g_object_unref (style->rc_style);
625 G_OBJECT_CLASS (gtk_style_parent_class)->finalize (object);
631 * @style: a #GtkStyle
633 * Creates a copy of the passed in #GtkStyle object.
635 * Returns: a copy of @style
638 gtk_style_copy (GtkStyle *style)
642 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
644 new_style = GTK_STYLE_GET_CLASS (style)->clone (style);
645 GTK_STYLE_GET_CLASS (style)->copy (new_style, style);
651 gtk_style_duplicate (GtkStyle *style)
655 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
657 new_style = gtk_style_copy (style);
659 /* All the styles in the list have the same
660 * style->styles pointer. When we insert a new
661 * style, we append it to the list to avoid having
662 * to update the existing ones.
664 style->styles = g_slist_append (style->styles, new_style);
665 new_style->styles = style->styles;
672 * @returns: a new #GtkStyle.
674 * Creates a new #GtkStyle.
681 style = g_object_new (GTK_TYPE_STYLE, NULL);
688 * @style: a #GtkStyle.
689 * @window: a #GdkWindow.
691 * Attaches a style to a window; this process allocates the
692 * colors and creates the GC's for the style - it specializes
693 * it to a particular visual and colormap. The process may
694 * involve the creation of a new style if the style has already
695 * been attached to a window with a different style and colormap.
697 * Since this function may return a new object, you have to use it
698 * in the following way:
699 * <literal>style = gtk_style_attach (style, window)</literal>
701 * Returns: Either @style, or a newly-created #GtkStyle.
702 * If the style is newly created, the style parameter
703 * will be unref'ed, and the new style will have
704 * a reference count belonging to the caller.
707 gtk_style_attach (GtkStyle *style,
711 GtkStyle *new_style = NULL;
712 GdkColormap *colormap;
714 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
715 g_return_val_if_fail (window != NULL, NULL);
717 colormap = gdk_drawable_get_colormap (window);
720 style->styles = g_slist_append (NULL, style);
722 styles = style->styles;
725 new_style = styles->data;
727 if (new_style->colormap == colormap)
731 styles = styles->next;
736 styles = style->styles;
740 new_style = styles->data;
742 if (new_style->attach_count == 0)
744 gtk_style_realize (new_style, colormap);
749 styles = styles->next;
755 new_style = gtk_style_duplicate (style);
756 if (gdk_colormap_get_screen (style->colormap) != gdk_colormap_get_screen (colormap) &&
757 new_style->private_font)
759 gdk_font_unref (new_style->private_font);
760 new_style->private_font = NULL;
762 gtk_style_realize (new_style, colormap);
765 /* A style gets a refcount from being attached */
766 if (new_style->attach_count == 0)
767 g_object_ref (new_style);
769 /* Another refcount belongs to the parent */
770 if (style != new_style)
772 g_object_unref (style);
773 g_object_ref (new_style);
776 new_style->attach_count++;
783 * @style: a #GtkStyle
785 * Detaches a style from a window. If the style is not attached
786 * to any windows anymore, it is unrealized. See gtk_style_attach().
790 gtk_style_detach (GtkStyle *style)
792 g_return_if_fail (GTK_IS_STYLE (style));
793 g_return_if_fail (style->attach_count > 0);
795 style->attach_count -= 1;
796 if (style->attach_count == 0)
798 g_signal_emit (style, unrealize_signal, 0);
800 g_object_unref (style->colormap);
801 style->colormap = NULL;
803 if (style->private_font_desc)
805 if (style->private_font)
807 gdk_font_unref (style->private_font);
808 style->private_font = NULL;
811 pango_font_description_free (style->private_font_desc);
812 style->private_font_desc = NULL;
815 g_object_unref (style);
821 * @style: a #GtkStyle.
824 * Increase the reference count of @style.
826 * Deprecated: 2.0: use g_object_ref() instead.
829 gtk_style_ref (GtkStyle *style)
831 return (GtkStyle *) g_object_ref (style);
836 * @style: a #GtkStyle.
838 * Decrease the reference count of @style.
840 * Deprecated: 2.0: use g_object_unref() instead.
843 gtk_style_unref (GtkStyle *style)
845 g_object_unref (style);
849 gtk_style_realize (GtkStyle *style,
850 GdkColormap *colormap)
852 style->colormap = g_object_ref (colormap);
853 style->depth = gdk_colormap_get_visual (colormap)->depth;
855 g_signal_emit (style, realize_signal, 0);
859 * gtk_style_lookup_icon_set:
860 * @style: a #GtkStyle
861 * @stock_id: an icon name
863 * Looks up @stock_id in the icon factories associated with @style
864 * and the default icon factory, returning an icon set if found,
867 * Return value: icon set of @stock_id
870 gtk_style_lookup_icon_set (GtkStyle *style,
871 const char *stock_id)
875 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
876 g_return_val_if_fail (stock_id != NULL, NULL);
878 iter = style->icon_factories;
881 GtkIconSet *icon_set = gtk_icon_factory_lookup (GTK_ICON_FACTORY (iter->data),
886 iter = g_slist_next (iter);
889 return gtk_icon_factory_lookup_default (stock_id);
893 * gtk_style_lookup_color:
894 * @style: a #GtkStyle
895 * @color_name: the name of the logical color to look up
896 * @color: the #GdkColor to fill in
898 * Looks up @color_name in the style's logical color mappings,
899 * filling in @color and returning %TRUE if found, otherwise
900 * returning %FALSE. Do not cache the found mapping, because
901 * it depends on the #GtkStyle and might change when a theme
904 * Return value: %TRUE if the mapping was found.
909 gtk_style_lookup_color (GtkStyle *style,
910 const char *color_name,
913 GtkStylePrivate *priv;
916 g_return_val_if_fail (GTK_IS_STYLE (style), FALSE);
917 g_return_val_if_fail (color_name != NULL, FALSE);
918 g_return_val_if_fail (color != NULL, FALSE);
920 priv = GTK_STYLE_GET_PRIVATE (style);
922 for (iter = priv->color_hashes; iter != NULL; iter = iter->next)
924 GHashTable *hash = iter->data;
925 GdkColor *mapping = g_hash_table_lookup (hash, color_name);
929 color->red = mapping->red;
930 color->green = mapping->green;
931 color->blue = mapping->blue;
941 * @style: a #GtkStyle
942 * @window: a #GdkWindow
943 * @state_type: a state
944 * @x1: the starting x coordinate
945 * @x2: the ending x coordinate
946 * @y: the y coordinate
948 * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @window
949 * using the given style and state.
951 * Deprecated: 2.0: Use gtk_paint_hline() instead.
954 gtk_draw_hline (GtkStyle *style,
956 GtkStateType state_type,
961 g_return_if_fail (GTK_IS_STYLE (style));
962 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
964 GTK_STYLE_GET_CLASS (style)->draw_hline (style, window, state_type, NULL, NULL, NULL, x1, x2, y);
970 * @style: a #GtkStyle
971 * @window: a #GdkWindow
972 * @state_type: a state
973 * @y1_: the starting y coordinate
974 * @y2_: the ending y coordinate
975 * @x: the x coordinate
977 * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @window
978 * using the given style and state.
980 * Deprecated: 2.0: Use gtk_paint_vline() instead.
983 gtk_draw_vline (GtkStyle *style,
985 GtkStateType state_type,
990 g_return_if_fail (GTK_IS_STYLE (style));
991 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
993 GTK_STYLE_GET_CLASS (style)->draw_vline (style, window, state_type, NULL, NULL, NULL, y1_, y2_, x);
998 * @style: a #GtkStyle
999 * @window: a #GdkWindow
1000 * @state_type: a state
1001 * @shadow_type: type of shadow to draw
1002 * @x: x origin of the rectangle
1003 * @y: y origin of the rectangle
1004 * @width: width of the rectangle
1005 * @height: width of the rectangle
1007 * Draws a shadow around the given rectangle in @window
1008 * using the given style and state and shadow type.
1010 * Deprecated: 2.0: Use gtk_paint_shadow() instead.
1013 gtk_draw_shadow (GtkStyle *style,
1015 GtkStateType state_type,
1016 GtkShadowType shadow_type,
1022 g_return_if_fail (GTK_IS_STYLE (style));
1023 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
1025 GTK_STYLE_GET_CLASS (style)->draw_shadow (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1030 * @style: a #GtkStyle
1031 * @window: a #GdkWindow
1032 * @state_type: a state
1033 * @shadow_type: type of shadow to draw
1034 * @points: an array of #GdkPoint<!-- -->s
1035 * @npoints: length of @points
1036 * @fill: %TRUE if the polygon should be filled
1038 * Draws a polygon on @window with the given parameters.
1040 * Deprecated: 2.0: Use gtk_paint_polygon() instead.
1043 gtk_draw_polygon (GtkStyle *style,
1045 GtkStateType state_type,
1046 GtkShadowType shadow_type,
1051 g_return_if_fail (GTK_IS_STYLE (style));
1052 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_polygon != NULL);
1054 GTK_STYLE_GET_CLASS (style)->draw_polygon (style, window, state_type, shadow_type, NULL, NULL, NULL, points, npoints, fill);
1059 * @style: a #GtkStyle
1060 * @window: a #GdkWindow
1061 * @state_type: a state
1062 * @shadow_type: the type of shadow to draw
1063 * @arrow_type: the type of arrow to draw
1064 * @fill: %TRUE if the arrow tip should be filled
1065 * @x: x origin of the rectangle to draw the arrow in
1066 * @y: y origin of the rectangle to draw the arrow in
1067 * @width: width of the rectangle to draw the arrow in
1068 * @height: height of the rectangle to draw the arrow in
1070 * Draws an arrow in the given rectangle on @window using the given
1071 * parameters. @arrow_type determines the direction of the arrow.
1073 * Deprecated: 2.0: Use gtk_paint_arrow() instead.
1076 gtk_draw_arrow (GtkStyle *style,
1078 GtkStateType state_type,
1079 GtkShadowType shadow_type,
1080 GtkArrowType arrow_type,
1087 g_return_if_fail (GTK_IS_STYLE (style));
1088 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
1090 GTK_STYLE_GET_CLASS (style)->draw_arrow (style, window, state_type, shadow_type, NULL, NULL, NULL, arrow_type, fill, x, y, width, height);
1095 * @style: a #GtkStyle
1096 * @window: a #GdkWindow
1097 * @state_type: a state
1098 * @shadow_type: the type of shadow to draw
1099 * @x: x origin of the rectangle to draw the diamond in
1100 * @y: y origin of the rectangle to draw the diamond in
1101 * @width: width of the rectangle to draw the diamond in
1102 * @height: height of the rectangle to draw the diamond in
1104 * Draws a diamond in the given rectangle on @window using the given
1107 * Deprecated: 2.0: Use gtk_paint_diamond() instead.
1110 gtk_draw_diamond (GtkStyle *style,
1112 GtkStateType state_type,
1113 GtkShadowType shadow_type,
1119 g_return_if_fail (GTK_IS_STYLE (style));
1120 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
1122 GTK_STYLE_GET_CLASS (style)->draw_diamond (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1127 * @style: a #GtkStyle
1128 * @window: a #GdkWindow
1129 * @state_type: a state
1132 * @string: the string to draw
1134 * Draws a text string on @window with the given parameters.
1136 * Deprecated: 2.0: Use gtk_paint_layout() instead.
1139 gtk_draw_string (GtkStyle *style,
1141 GtkStateType state_type,
1144 const gchar *string)
1146 g_return_if_fail (GTK_IS_STYLE (style));
1147 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_string != NULL);
1149 GTK_STYLE_GET_CLASS (style)->draw_string (style, window, state_type, NULL, NULL, NULL, x, y, string);
1154 * @style: a #GtkStyle
1155 * @window: a #GdkWindow
1156 * @state_type: a state
1157 * @shadow_type: the type of shadow to draw
1158 * @x: x origin of the box
1159 * @y: y origin of the box
1160 * @width: the width of the box
1161 * @height: the height of the box
1163 * Draws a box on @window with the given parameters.
1165 * Deprecated: 2.0: Use gtk_paint_box() instead.
1168 gtk_draw_box (GtkStyle *style,
1170 GtkStateType state_type,
1171 GtkShadowType shadow_type,
1177 g_return_if_fail (GTK_IS_STYLE (style));
1178 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
1180 GTK_STYLE_GET_CLASS (style)->draw_box (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1184 * gtk_draw_flat_box:
1185 * @style: a #GtkStyle
1186 * @window: a #GdkWindow
1187 * @state_type: a state
1188 * @shadow_type: the type of shadow to draw
1189 * @x: x origin of the box
1190 * @y: y origin of the box
1191 * @width: the width of the box
1192 * @height: the height of the box
1194 * Draws a flat box on @window with the given parameters.
1196 * Deprecated: 2.0: Use gtk_paint_flat_box() instead.
1199 gtk_draw_flat_box (GtkStyle *style,
1201 GtkStateType state_type,
1202 GtkShadowType shadow_type,
1208 g_return_if_fail (GTK_IS_STYLE (style));
1209 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
1211 GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1216 * @style: a #GtkStyle
1217 * @window: a #GdkWindow
1218 * @state_type: a state
1219 * @shadow_type: the type of shadow to draw
1220 * @x: x origin of the rectangle to draw the check in
1221 * @y: y origin of the rectangle to draw the check in
1222 * @width: the width of the rectangle to draw the check in
1223 * @height: the height of the rectangle to draw the check in
1225 * Draws a check button indicator in the given rectangle on @window with
1226 * the given parameters.
1228 * Deprecated: 2.0: Use gtk_paint_check() instead.
1231 gtk_draw_check (GtkStyle *style,
1233 GtkStateType state_type,
1234 GtkShadowType shadow_type,
1240 g_return_if_fail (GTK_IS_STYLE (style));
1241 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
1243 GTK_STYLE_GET_CLASS (style)->draw_check (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1248 * @style: a #GtkStyle
1249 * @window: a #GdkWindow
1250 * @state_type: a state
1251 * @shadow_type: the type of shadow to draw
1252 * @x: x origin of the rectangle to draw the option in
1253 * @y: y origin of the rectangle to draw the option in
1254 * @width: the width of the rectangle to draw the option in
1255 * @height: the height of the rectangle to draw the option in
1257 * Draws a radio button indicator in the given rectangle on @window with
1258 * the given parameters.
1260 * Deprecated: 2.0: Use gtk_paint_option() instead.
1263 gtk_draw_option (GtkStyle *style,
1265 GtkStateType state_type,
1266 GtkShadowType shadow_type,
1272 g_return_if_fail (GTK_IS_STYLE (style));
1273 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
1275 GTK_STYLE_GET_CLASS (style)->draw_option (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1280 * @style: a #GtkStyle
1281 * @window: a #GdkWindow
1282 * @state_type: a state
1283 * @shadow_type: the type of shadow to draw
1284 * @x: x origin of the rectangle to draw the tab in
1285 * @y: y origin of the rectangle to draw the tab in
1286 * @width: the width of the rectangle to draw the tab in
1287 * @height: the height of the rectangle to draw the tab in
1289 * Draws an option menu tab (i.e. the up and down pointing arrows)
1290 * in the given rectangle on @window using the given parameters.
1292 * Deprecated: 2.0: Use gtk_paint_tab() instead.
1295 gtk_draw_tab (GtkStyle *style,
1297 GtkStateType state_type,
1298 GtkShadowType shadow_type,
1304 g_return_if_fail (GTK_IS_STYLE (style));
1305 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
1307 GTK_STYLE_GET_CLASS (style)->draw_tab (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1311 * gtk_draw_shadow_gap:
1312 * @style: a #GtkStyle
1313 * @window: a #GdkWindow
1314 * @state_type: a state
1315 * @shadow_type: type of shadow to draw
1316 * @x: x origin of the rectangle
1317 * @y: y origin of the rectangle
1318 * @width: width of the rectangle
1319 * @height: width of the rectangle
1320 * @gap_side: side in which to leave the gap
1321 * @gap_x: starting position of the gap
1322 * @gap_width: width of the gap
1324 * Draws a shadow around the given rectangle in @window
1325 * using the given style and state and shadow type, leaving a
1328 * Deprecated: 2.0: Use gtk_paint_shadow_gap() instead.
1331 gtk_draw_shadow_gap (GtkStyle *style,
1333 GtkStateType state_type,
1334 GtkShadowType shadow_type,
1339 GtkPositionType gap_side,
1343 g_return_if_fail (GTK_IS_STYLE (style));
1344 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
1346 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);
1351 * @style: a #GtkStyle
1352 * @window: a #GdkWindow
1353 * @state_type: a state
1354 * @shadow_type: type of shadow to draw
1355 * @x: x origin of the rectangle
1356 * @y: y origin of the rectangle
1357 * @width: width of the rectangle
1358 * @height: width of the rectangle
1359 * @gap_side: side in which to leave the gap
1360 * @gap_x: starting position of the gap
1361 * @gap_width: width of the gap
1363 * Draws a box in @window using the given style and state and shadow type,
1364 * leaving a gap in one side.
1366 * Deprecated: 2.0: Use gtk_paint_box_gap() instead.
1369 gtk_draw_box_gap (GtkStyle *style,
1371 GtkStateType state_type,
1372 GtkShadowType shadow_type,
1377 GtkPositionType gap_side,
1381 g_return_if_fail (GTK_IS_STYLE (style));
1382 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
1384 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);
1388 * gtk_draw_extension:
1389 * @style: a #GtkStyle
1390 * @window: a #GdkWindow
1391 * @state_type: a state
1392 * @shadow_type: type of shadow to draw
1393 * @x: x origin of the extension
1394 * @y: y origin of the extension
1395 * @width: width of the extension
1396 * @height: width of the extension
1397 * @gap_side: the side on to which the extension is attached
1399 * Draws an extension, i.e. a notebook tab.
1401 * Deprecated: 2.0: Use gtk_paint_extension() instead.
1404 gtk_draw_extension (GtkStyle *style,
1406 GtkStateType state_type,
1407 GtkShadowType shadow_type,
1412 GtkPositionType gap_side)
1414 g_return_if_fail (GTK_IS_STYLE (style));
1415 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
1417 GTK_STYLE_GET_CLASS (style)->draw_extension (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, gap_side);
1422 * @style: a #GtkStyle
1423 * @window: a #GdkWindow
1424 * @x: the x origin of the rectangle around which to draw a focus indicator
1425 * @y: the y origin of the rectangle around which to draw a focus indicator
1426 * @width: the width of the rectangle around which to draw a focus indicator
1427 * @height: the height of the rectangle around which to draw a focus indicator
1429 * Draws a focus indicator around the given rectangle on @window using the
1432 * Deprecated: 2.0: Use gtk_paint_focus() instead.
1435 gtk_draw_focus (GtkStyle *style,
1442 g_return_if_fail (GTK_IS_STYLE (style));
1443 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
1445 GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, GTK_STATE_NORMAL, NULL, NULL, NULL, x, y, width, height);
1450 * @style: a #GtkStyle
1451 @window: a #GdkWindow
1452 * @state_type: a state
1453 * @shadow_type: a shadow
1454 * @x: the x origin of the rectangle in which to draw a slider
1455 * @y: the y origin of the rectangle in which to draw a slider
1456 * @width: the width of the rectangle in which to draw a slider
1457 * @height: the height of the rectangle in which to draw a slider
1458 * @orientation: the orientation to be used
1460 * Draws a slider in the given rectangle on @window using the
1461 * given style and orientation.
1464 gtk_draw_slider (GtkStyle *style,
1466 GtkStateType state_type,
1467 GtkShadowType shadow_type,
1472 GtkOrientation orientation)
1474 g_return_if_fail (GTK_IS_STYLE (style));
1475 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
1477 GTK_STYLE_GET_CLASS (style)->draw_slider (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, orientation);
1482 * @style: a #GtkStyle
1483 * @window: a #GdkWindow
1484 * @state_type: a state
1485 * @shadow_type: type of shadow to draw
1486 * @x: x origin of the handle
1487 * @y: y origin of the handle
1488 * @width: with of the handle
1489 * @height: height of the handle
1490 * @orientation: the orientation of the handle
1492 * Draws a handle as used in #GtkHandleBox and #GtkPaned.
1494 * Deprecated: 2.0: Use gtk_paint_handle() instead.
1497 gtk_draw_handle (GtkStyle *style,
1499 GtkStateType state_type,
1500 GtkShadowType shadow_type,
1505 GtkOrientation orientation)
1507 g_return_if_fail (GTK_IS_STYLE (style));
1508 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
1510 GTK_STYLE_GET_CLASS (style)->draw_handle (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, orientation);
1514 * gtk_draw_expander:
1515 * @style: a #GtkStyle
1516 * @window: a #GdkWindow
1517 * @state_type: a state
1518 * @x: the x position to draw the expander at
1519 * @y: the y position to draw the expander at
1520 * @expander_style: the style to draw the expander in
1522 * Draws an expander as used in #GtkTreeView.
1524 * Deprecated: 2.0: Use gtk_paint_expander() instead.
1527 gtk_draw_expander (GtkStyle *style,
1529 GtkStateType state_type,
1532 GtkExpanderStyle expander_style)
1534 g_return_if_fail (GTK_IS_STYLE (style));
1535 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
1537 GTK_STYLE_GET_CLASS (style)->draw_expander (style, window, state_type,
1539 x, y, expander_style);
1544 * @style: a #GtkStyle
1545 * @window: a #GdkWindow
1546 * @state_type: a state
1547 * @use_text: whether to use the text or foreground
1548 * graphics context of @style
1551 * @layout: the layout to draw
1553 * Draws a layout on @window using the given parameters.
1556 gtk_draw_layout (GtkStyle *style,
1558 GtkStateType state_type,
1562 PangoLayout *layout)
1564 g_return_if_fail (GTK_IS_STYLE (style));
1565 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
1567 GTK_STYLE_GET_CLASS (style)->draw_layout (style, window, state_type, use_text,
1573 * gtk_draw_resize_grip:
1574 * @style: a #GtkStyle
1575 * @window: a #GdkWindow
1576 * @state_type: a state
1577 * @edge: the edge in which to draw the resize grip
1578 * @x: the x origin of the rectangle in which to draw the resize grip
1579 * @y: the y origin of the rectangle in which to draw the resize grip
1580 * @width: the width of the rectangle in which to draw the resize grip
1581 * @height: the height of the rectangle in which to draw the resize grip
1583 * Draws a resize grip in the given rectangle on @window using the given
1586 * Deprecated: 2.0: Use gtk_paint_resize_grip() instead.
1589 gtk_draw_resize_grip (GtkStyle *style,
1591 GtkStateType state_type,
1598 g_return_if_fail (GTK_IS_STYLE (style));
1599 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
1601 GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, window, state_type,
1604 x, y, width, height);
1609 * gtk_style_set_background:
1610 * @style: a #GtkStyle
1611 * @window: a #GdkWindow
1612 * @state_type: a state
1614 * Sets the background of @window to the background color or pixmap
1615 * specified by @style for the given state.
1618 gtk_style_set_background (GtkStyle *style,
1620 GtkStateType state_type)
1622 g_return_if_fail (GTK_IS_STYLE (style));
1623 g_return_if_fail (window != NULL);
1625 GTK_STYLE_GET_CLASS (style)->set_background (style, window, state_type);
1628 /* Default functions */
1630 gtk_style_real_clone (GtkStyle *style)
1632 return g_object_new (G_OBJECT_TYPE (style), NULL);
1636 gtk_style_real_copy (GtkStyle *style,
1639 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
1640 GtkStylePrivate *src_priv = GTK_STYLE_GET_PRIVATE (src);
1643 for (i = 0; i < 5; i++)
1645 style->fg[i] = src->fg[i];
1646 style->bg[i] = src->bg[i];
1647 style->text[i] = src->text[i];
1648 style->base[i] = src->base[i];
1650 if (style->bg_pixmap[i])
1651 g_object_unref (style->bg_pixmap[i]),
1652 style->bg_pixmap[i] = src->bg_pixmap[i];
1653 if (style->bg_pixmap[i])
1654 g_object_ref (style->bg_pixmap[i]);
1657 if (style->private_font)
1658 gdk_font_unref (style->private_font);
1659 style->private_font = src->private_font;
1660 if (style->private_font)
1661 gdk_font_ref (style->private_font);
1663 if (style->font_desc)
1664 pango_font_description_free (style->font_desc);
1666 style->font_desc = pango_font_description_copy (src->font_desc);
1668 style->font_desc = NULL;
1670 style->xthickness = src->xthickness;
1671 style->ythickness = src->ythickness;
1673 if (style->rc_style)
1674 g_object_unref (style->rc_style);
1675 style->rc_style = src->rc_style;
1677 g_object_ref (src->rc_style);
1679 g_slist_foreach (style->icon_factories, (GFunc) g_object_unref, NULL);
1680 g_slist_free (style->icon_factories);
1681 style->icon_factories = g_slist_copy (src->icon_factories);
1682 g_slist_foreach (style->icon_factories, (GFunc) g_object_ref, NULL);
1684 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_unref, NULL);
1685 g_slist_free (priv->color_hashes);
1686 priv->color_hashes = g_slist_copy (src_priv->color_hashes);
1687 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_ref, NULL);
1689 /* don't copy, just clear cache */
1690 clear_property_cache (style);
1694 gtk_style_real_init_from_rc (GtkStyle *style,
1695 GtkRcStyle *rc_style)
1697 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
1700 /* cache _should_ be still empty */
1701 clear_property_cache (style);
1703 if (rc_style->font_desc)
1704 pango_font_description_merge (style->font_desc, rc_style->font_desc, TRUE);
1706 for (i = 0; i < 5; i++)
1708 if (rc_style->color_flags[i] & GTK_RC_FG)
1709 style->fg[i] = rc_style->fg[i];
1710 if (rc_style->color_flags[i] & GTK_RC_BG)
1711 style->bg[i] = rc_style->bg[i];
1712 if (rc_style->color_flags[i] & GTK_RC_TEXT)
1713 style->text[i] = rc_style->text[i];
1714 if (rc_style->color_flags[i] & GTK_RC_BASE)
1715 style->base[i] = rc_style->base[i];
1718 if (rc_style->xthickness >= 0)
1719 style->xthickness = rc_style->xthickness;
1720 if (rc_style->ythickness >= 0)
1721 style->ythickness = rc_style->ythickness;
1723 style->icon_factories = g_slist_copy (rc_style->icon_factories);
1724 g_slist_foreach (style->icon_factories, (GFunc) g_object_ref, NULL);
1726 priv->color_hashes = g_slist_copy (_gtk_rc_style_get_color_hashes (rc_style));
1727 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_ref, NULL);
1731 style_property_values_cmp (gconstpointer bsearch_node1,
1732 gconstpointer bsearch_node2)
1734 const PropertyValue *val1 = bsearch_node1;
1735 const PropertyValue *val2 = bsearch_node2;
1737 if (val1->widget_type == val2->widget_type)
1738 return val1->pspec < val2->pspec ? -1 : val1->pspec == val2->pspec ? 0 : 1;
1740 return val1->widget_type < val2->widget_type ? -1 : 1;
1744 * gtk_style_get_property:
1745 * @style: a #GtkStyle
1746 * @widget_type: the #GType of a descendant of #GtkWidget
1747 * @property_name: the name of the style property to get
1748 * @value: a #GValue where the value of the property being
1749 * queried will be stored
1751 * Queries the value of a style property corresponding to a
1752 * widget class is in the given style.
1757 gtk_style_get_property (GtkStyle *style,
1759 const gchar *property_name,
1762 GtkWidgetClass *klass;
1764 GtkRcPropertyParser parser;
1765 const GValue *peek_value;
1767 klass = g_type_class_peek (widget_type);
1768 pspec = gtk_widget_class_find_style_property (klass, property_name);
1772 g_warning ("%s: widget class `%s' has no property named `%s'",
1774 g_type_name (widget_type),
1779 parser = g_param_spec_get_qdata (pspec,
1780 g_quark_from_static_string ("gtk-rc-property-parser"));
1782 peek_value = _gtk_style_peek_property_value (style, widget_type, pspec, parser);
1784 if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec))
1785 g_value_copy (peek_value, value);
1786 else if (g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
1787 g_value_transform (peek_value, value);
1789 g_warning ("can't retrieve style property `%s' of type `%s' as value of type `%s'",
1791 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1792 G_VALUE_TYPE_NAME (value));
1796 * gtk_style_get_valist:
1797 * @style: a #GtkStyle
1798 * @widget_type: the #GType of a descendant of #GtkWidget
1799 * @first_property_name: the name of the first style property to get
1800 * @var_args: a <type>va_list</type> of pairs of property names and
1801 * locations to return the property values, starting with the
1802 * location for @first_property_name.
1804 * Non-vararg variant of gtk_style_get().
1805 * Used primarily by language bindings.
1810 gtk_style_get_valist (GtkStyle *style,
1812 const gchar *first_property_name,
1815 const char *property_name;
1816 GtkWidgetClass *klass;
1818 g_return_if_fail (GTK_IS_STYLE (style));
1820 klass = g_type_class_ref (widget_type);
1822 property_name = first_property_name;
1823 while (property_name)
1826 GtkRcPropertyParser parser;
1827 const GValue *peek_value;
1830 pspec = gtk_widget_class_find_style_property (klass, property_name);
1834 g_warning ("%s: widget class `%s' has no property named `%s'",
1836 g_type_name (widget_type),
1841 parser = g_param_spec_get_qdata (pspec,
1842 g_quark_from_static_string ("gtk-rc-property-parser"));
1844 peek_value = _gtk_style_peek_property_value (style, widget_type, pspec, parser);
1845 G_VALUE_LCOPY (peek_value, var_args, 0, &error);
1848 g_warning ("%s: %s", G_STRLOC, error);
1853 property_name = va_arg (var_args, gchar*);
1856 g_type_class_unref (klass);
1861 * @style: a #GtkStyle
1862 * @widget_type: the #GType of a descendant of #GtkWidget
1863 * @first_property_name: the name of the first style property to get
1864 * @Varargs: pairs of property names and locations to
1865 * return the property values, starting with the location for
1866 * @first_property_name, terminated by %NULL.
1868 * Gets the values of a multiple style properties for @widget_type
1872 gtk_style_get (GtkStyle *style,
1874 const gchar *first_property_name,
1879 va_start (var_args, first_property_name);
1880 gtk_style_get_valist (style, widget_type, first_property_name, var_args);
1885 _gtk_style_peek_property_value (GtkStyle *style,
1888 GtkRcPropertyParser parser)
1890 PropertyValue *pcache, key = { 0, NULL, { 0, } };
1891 const GtkRcProperty *rcprop = NULL;
1894 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1895 g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL);
1896 g_return_val_if_fail (g_type_is_a (pspec->owner_type, GTK_TYPE_WIDGET), NULL);
1897 g_return_val_if_fail (g_type_is_a (widget_type, pspec->owner_type), NULL);
1899 key.widget_type = widget_type;
1902 /* need value cache array */
1903 if (!style->property_cache)
1904 style->property_cache = g_array_new (FALSE, FALSE, sizeof (PropertyValue));
1907 pcache = bsearch (&key,
1908 style->property_cache->data, style->property_cache->len,
1909 sizeof (PropertyValue), style_property_values_cmp);
1911 return &pcache->value;
1915 while (i < style->property_cache->len &&
1916 style_property_values_cmp (&key, &g_array_index (style->property_cache, PropertyValue, i)) >= 0)
1919 g_array_insert_val (style->property_cache, i, key);
1920 pcache = &g_array_index (style->property_cache, PropertyValue, i);
1922 /* cache miss, initialize value type, then set contents */
1923 g_param_spec_ref (pcache->pspec);
1924 g_value_init (&pcache->value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1926 /* value provided by rc style? */
1927 if (style->rc_style)
1929 GQuark prop_quark = g_quark_from_string (pspec->name);
1933 rcprop = _gtk_rc_style_lookup_rc_property (style->rc_style,
1934 g_type_qname (widget_type),
1938 widget_type = g_type_parent (widget_type);
1940 while (g_type_is_a (widget_type, pspec->owner_type));
1943 /* when supplied by rc style, we need to convert */
1944 if (rcprop && !_gtk_settings_parse_convert (parser, &rcprop->value,
1945 pspec, &pcache->value))
1947 gchar *contents = g_strdup_value_contents (&rcprop->value);
1949 g_message ("%s: failed to retrieve property `%s::%s' of type `%s' from rc file value \"%s\" of type `%s'",
1950 rcprop->origin ? rcprop->origin : "(for origin information, set GTK_DEBUG)",
1951 g_type_name (pspec->owner_type), pspec->name,
1952 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1954 G_VALUE_TYPE_NAME (&rcprop->value));
1956 rcprop = NULL; /* needs default */
1959 /* not supplied by rc style (or conversion failed), revert to default */
1961 g_param_value_set_default (pspec, &pcache->value);
1963 return &pcache->value;
1967 load_bg_image (GdkColormap *colormap,
1969 const gchar *filename)
1971 if (strcmp (filename, "<parent>") == 0)
1972 return (GdkPixmap*) GDK_PARENT_RELATIVE;
1975 return gdk_pixmap_colormap_create_from_xpm (NULL, colormap, NULL,
1982 gtk_style_real_realize (GtkStyle *style)
1984 GdkGCValues gc_values;
1985 GdkGCValuesMask gc_values_mask;
1989 for (i = 0; i < 5; i++)
1991 _gtk_style_shade (&style->bg[i], &style->light[i], LIGHTNESS_MULT);
1992 _gtk_style_shade (&style->bg[i], &style->dark[i], DARKNESS_MULT);
1994 style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
1995 style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
1996 style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
1998 style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
1999 style->text_aa[i].green = (style->text[i].green + style->base[i].green) / 2;
2000 style->text_aa[i].blue = (style->text[i].blue + style->base[i].blue) / 2;
2003 style->black.red = 0x0000;
2004 style->black.green = 0x0000;
2005 style->black.blue = 0x0000;
2006 gdk_colormap_alloc_color (style->colormap, &style->black, FALSE, TRUE);
2008 style->white.red = 0xffff;
2009 style->white.green = 0xffff;
2010 style->white.blue = 0xffff;
2011 gdk_colormap_alloc_color (style->colormap, &style->white, FALSE, TRUE);
2013 gc_values_mask = GDK_GC_FOREGROUND | GDK_GC_BACKGROUND;
2015 gc_values.foreground = style->black;
2016 gc_values.background = style->white;
2017 style->black_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
2019 gc_values.foreground = style->white;
2020 gc_values.background = style->black;
2021 style->white_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
2023 gc_values_mask = GDK_GC_FOREGROUND;
2025 for (i = 0; i < 5; i++)
2027 if (style->rc_style && style->rc_style->bg_pixmap_name[i])
2028 style->bg_pixmap[i] = load_bg_image (style->colormap,
2030 style->rc_style->bg_pixmap_name[i]);
2032 if (!gdk_colormap_alloc_color (style->colormap, &style->fg[i], FALSE, TRUE))
2033 g_warning ("unable to allocate color: ( %d %d %d )",
2034 style->fg[i].red, style->fg[i].green, style->fg[i].blue);
2035 if (!gdk_colormap_alloc_color (style->colormap, &style->bg[i], FALSE, TRUE))
2036 g_warning ("unable to allocate color: ( %d %d %d )",
2037 style->bg[i].red, style->bg[i].green, style->bg[i].blue);
2038 if (!gdk_colormap_alloc_color (style->colormap, &style->light[i], FALSE, TRUE))
2039 g_warning ("unable to allocate color: ( %d %d %d )",
2040 style->light[i].red, style->light[i].green, style->light[i].blue);
2041 if (!gdk_colormap_alloc_color (style->colormap, &style->dark[i], FALSE, TRUE))
2042 g_warning ("unable to allocate color: ( %d %d %d )",
2043 style->dark[i].red, style->dark[i].green, style->dark[i].blue);
2044 if (!gdk_colormap_alloc_color (style->colormap, &style->mid[i], FALSE, TRUE))
2045 g_warning ("unable to allocate color: ( %d %d %d )",
2046 style->mid[i].red, style->mid[i].green, style->mid[i].blue);
2047 if (!gdk_colormap_alloc_color (style->colormap, &style->text[i], FALSE, TRUE))
2048 g_warning ("unable to allocate color: ( %d %d %d )",
2049 style->text[i].red, style->text[i].green, style->text[i].blue);
2050 if (!gdk_colormap_alloc_color (style->colormap, &style->base[i], FALSE, TRUE))
2051 g_warning ("unable to allocate color: ( %d %d %d )",
2052 style->base[i].red, style->base[i].green, style->base[i].blue);
2053 if (!gdk_colormap_alloc_color (style->colormap, &style->text_aa[i], FALSE, TRUE))
2054 g_warning ("unable to allocate color: ( %d %d %d )",
2055 style->text_aa[i].red, style->text_aa[i].green, style->text_aa[i].blue);
2057 gc_values.foreground = style->fg[i];
2058 style->fg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
2060 gc_values.foreground = style->bg[i];
2061 style->bg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
2063 gc_values.foreground = style->light[i];
2064 style->light_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
2066 gc_values.foreground = style->dark[i];
2067 style->dark_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
2069 gc_values.foreground = style->mid[i];
2070 style->mid_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
2072 gc_values.foreground = style->text[i];
2073 style->text_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
2075 gc_values.foreground = style->base[i];
2076 style->base_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
2078 gc_values.foreground = style->text_aa[i];
2079 style->text_aa_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
2084 gtk_style_real_unrealize (GtkStyle *style)
2088 gtk_gc_release (style->black_gc);
2089 gtk_gc_release (style->white_gc);
2091 for (i = 0; i < 5; i++)
2093 gtk_gc_release (style->fg_gc[i]);
2094 gtk_gc_release (style->bg_gc[i]);
2095 gtk_gc_release (style->light_gc[i]);
2096 gtk_gc_release (style->dark_gc[i]);
2097 gtk_gc_release (style->mid_gc[i]);
2098 gtk_gc_release (style->text_gc[i]);
2099 gtk_gc_release (style->base_gc[i]);
2100 gtk_gc_release (style->text_aa_gc[i]);
2102 if (style->bg_pixmap[i] && style->bg_pixmap[i] != (GdkPixmap*) GDK_PARENT_RELATIVE)
2104 g_object_unref (style->bg_pixmap[i]);
2105 style->bg_pixmap[i] = NULL;
2110 gdk_colormap_free_colors (style->colormap, style->fg, 5);
2111 gdk_colormap_free_colors (style->colormap, style->bg, 5);
2112 gdk_colormap_free_colors (style->colormap, style->light, 5);
2113 gdk_colormap_free_colors (style->colormap, style->dark, 5);
2114 gdk_colormap_free_colors (style->colormap, style->mid, 5);
2115 gdk_colormap_free_colors (style->colormap, style->text, 5);
2116 gdk_colormap_free_colors (style->colormap, style->base, 5);
2117 gdk_colormap_free_colors (style->colormap, style->text_aa, 5);
2119 style_unrealize_cursor_gcs (style);
2123 gtk_style_real_set_background (GtkStyle *style,
2125 GtkStateType state_type)
2128 gint parent_relative;
2130 if (style->bg_pixmap[state_type])
2132 if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
2135 parent_relative = TRUE;
2139 pixmap = style->bg_pixmap[state_type];
2140 parent_relative = FALSE;
2143 gdk_window_set_back_pixmap (window, pixmap, parent_relative);
2146 gdk_window_set_background (window, &style->bg[state_type]);
2150 * gtk_style_render_icon:
2151 * @style: a #GtkStyle
2152 * @source: the #GtkIconSource specifying the icon to render
2153 * @direction: a text direction
2155 * @size: the size to render the icon at. A size of (GtkIconSize)-1
2156 * means render at the size of the source and don't scale.
2157 * @widget: the widget
2158 * @detail: a style detail
2159 * @returns: a newly-created #GdkPixbuf containing the rendered icon
2161 * Renders the icon specified by @source at the given @size
2162 * according to the given parameters and returns the result in a
2166 gtk_style_render_icon (GtkStyle *style,
2167 const GtkIconSource *source,
2168 GtkTextDirection direction,
2172 const gchar *detail)
2176 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
2177 g_return_val_if_fail (GTK_STYLE_GET_CLASS (style)->render_icon != NULL, NULL);
2179 pixbuf = GTK_STYLE_GET_CLASS (style)->render_icon (style, source, direction, state,
2180 size, widget, detail);
2182 g_return_val_if_fail (pixbuf != NULL, NULL);
2187 /* Default functions */
2189 gtk_style_apply_default_background (GtkStyle *style,
2192 GtkStateType state_type,
2193 const GdkRectangle *area,
2199 GdkRectangle new_rect, old_rect;
2205 old_rect.width = width;
2206 old_rect.height = height;
2208 if (!gdk_rectangle_intersect (area, &old_rect, &new_rect))
2215 new_rect.width = width;
2216 new_rect.height = height;
2219 if (!style->bg_pixmap[state_type] ||
2220 GDK_IS_PIXMAP (window) ||
2221 (!set_bg && style->bg_pixmap[state_type] != (GdkPixmap*) GDK_PARENT_RELATIVE))
2223 GdkGC *gc = style->bg_gc[state_type];
2225 if (style->bg_pixmap[state_type])
2227 gdk_gc_set_fill (gc, GDK_TILED);
2228 gdk_gc_set_tile (gc, style->bg_pixmap[state_type]);
2231 gdk_draw_rectangle (window, gc, TRUE,
2232 new_rect.x, new_rect.y, new_rect.width, new_rect.height);
2233 if (style->bg_pixmap[state_type])
2234 gdk_gc_set_fill (gc, GDK_SOLID);
2240 if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
2241 gdk_window_set_back_pixmap (window, NULL, TRUE);
2243 gdk_window_set_back_pixmap (window, style->bg_pixmap[state_type], FALSE);
2246 gdk_window_clear_area (window,
2247 new_rect.x, new_rect.y,
2248 new_rect.width, new_rect.height);
2253 scale_or_ref (GdkPixbuf *src,
2257 if (width == gdk_pixbuf_get_width (src) &&
2258 height == gdk_pixbuf_get_height (src))
2260 return g_object_ref (src);
2264 return gdk_pixbuf_scale_simple (src,
2266 GDK_INTERP_BILINEAR);
2271 gtk_default_render_icon (GtkStyle *style,
2272 const GtkIconSource *source,
2273 GtkTextDirection direction,
2277 const gchar *detail)
2283 GdkPixbuf *base_pixbuf;
2285 GtkSettings *settings;
2287 /* Oddly, style can be NULL in this function, because
2288 * GtkIconSet can be used without a style and if so
2289 * it uses this function.
2292 base_pixbuf = gtk_icon_source_get_pixbuf (source);
2294 g_return_val_if_fail (base_pixbuf != NULL, NULL);
2296 if (widget && gtk_widget_has_screen (widget))
2298 screen = gtk_widget_get_screen (widget);
2299 settings = gtk_settings_get_for_screen (screen);
2301 else if (style && style->colormap)
2303 screen = gdk_colormap_get_screen (style->colormap);
2304 settings = gtk_settings_get_for_screen (screen);
2308 settings = gtk_settings_get_default ();
2309 GTK_NOTE (MULTIHEAD,
2310 g_warning ("Using the default screen for gtk_default_render_icon()"));
2314 if (size != (GtkIconSize) -1 && !gtk_icon_size_lookup_for_settings (settings, size, &width, &height))
2316 g_warning (G_STRLOC ": invalid icon size '%d'", size);
2320 /* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
2323 if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source))
2324 scaled = scale_or_ref (base_pixbuf, width, height);
2326 scaled = g_object_ref (base_pixbuf);
2328 /* If the state was wildcarded, then generate a state. */
2329 if (gtk_icon_source_get_state_wildcarded (source))
2331 if (state == GTK_STATE_INSENSITIVE)
2333 stated = gdk_pixbuf_copy (scaled);
2335 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
2338 g_object_unref (scaled);
2340 else if (state == GTK_STATE_PRELIGHT)
2342 stated = gdk_pixbuf_copy (scaled);
2344 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
2347 g_object_unref (scaled);
2361 sanitize_size (GdkWindow *window,
2365 if ((*width == -1) && (*height == -1))
2366 gdk_drawable_get_size (window, width, height);
2367 else if (*width == -1)
2368 gdk_drawable_get_size (window, width, NULL);
2369 else if (*height == -1)
2370 gdk_drawable_get_size (window, NULL, height);
2374 gtk_default_draw_hline (GtkStyle *style,
2376 GtkStateType state_type,
2379 const gchar *detail,
2384 gint thickness_light;
2385 gint thickness_dark;
2388 thickness_light = style->ythickness / 2;
2389 thickness_dark = style->ythickness - thickness_light;
2393 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2394 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2397 if (detail && !strcmp (detail, "label"))
2399 if (state_type == GTK_STATE_INSENSITIVE)
2400 gdk_draw_line (window, style->white_gc, x1 + 1, y + 1, x2 + 1, y + 1);
2401 gdk_draw_line (window, style->fg_gc[state_type], x1, y, x2, y);
2405 for (i = 0; i < thickness_dark; i++)
2407 gdk_draw_line (window, style->dark_gc[state_type], x1, y + i, x2 - i - 1, y + i);
2408 gdk_draw_line (window, style->light_gc[state_type], x2 - i, y + i, x2, y + i);
2411 y += thickness_dark;
2412 for (i = 0; i < thickness_light; i++)
2414 gdk_draw_line (window, style->dark_gc[state_type], x1, y + i, x1 + thickness_light - i - 1, y + i);
2415 gdk_draw_line (window, style->light_gc[state_type], x1 + thickness_light - i, y + i, x2, y + i);
2421 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2422 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2428 gtk_default_draw_vline (GtkStyle *style,
2430 GtkStateType state_type,
2433 const gchar *detail,
2438 gint thickness_light;
2439 gint thickness_dark;
2442 thickness_light = style->xthickness / 2;
2443 thickness_dark = style->xthickness - thickness_light;
2447 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2448 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2450 for (i = 0; i < thickness_dark; i++)
2452 gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i, y2 - i - 1);
2453 gdk_draw_line (window, style->light_gc[state_type], x + i, y2 - i, x + i, y2);
2456 x += thickness_dark;
2457 for (i = 0; i < thickness_light; i++)
2459 gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i, y1 + thickness_light - i - 1);
2460 gdk_draw_line (window, style->light_gc[state_type], x + i, y1 + thickness_light - i, x + i, y2);
2464 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2465 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2470 draw_thin_shadow (GtkStyle *style,
2481 sanitize_size (window, &width, &height);
2483 gc1 = style->light_gc[state];
2484 gc2 = style->dark_gc[state];
2488 gdk_gc_set_clip_rectangle (gc1, area);
2489 gdk_gc_set_clip_rectangle (gc2, area);
2492 gdk_draw_line (window, gc1,
2493 x, y + height - 1, x + width - 1, y + height - 1);
2494 gdk_draw_line (window, gc1,
2495 x + width - 1, y, x + width - 1, y + height - 1);
2497 gdk_draw_line (window, gc2,
2498 x, y, x + width - 2, y);
2499 gdk_draw_line (window, gc2,
2500 x, y, x, y + height - 2);
2504 gdk_gc_set_clip_rectangle (gc1, NULL);
2505 gdk_gc_set_clip_rectangle (gc2, NULL);
2510 draw_spinbutton_shadow (GtkStyle *style,
2513 GtkTextDirection direction,
2520 sanitize_size (window, &width, &height);
2524 gdk_gc_set_clip_rectangle (style->black_gc, area);
2525 gdk_gc_set_clip_rectangle (style->bg_gc[state], area);
2526 gdk_gc_set_clip_rectangle (style->dark_gc[state], area);
2527 gdk_gc_set_clip_rectangle (style->light_gc[state], area);
2530 if (direction == GTK_TEXT_DIR_LTR)
2532 gdk_draw_line (window, style->dark_gc[state],
2533 x, y, x + width - 1, y);
2534 gdk_draw_line (window, style->black_gc,
2535 x, y + 1, x + width - 2, y + 1);
2536 gdk_draw_line (window, style->black_gc,
2537 x + width - 2, y + 2, x + width - 2, y + height - 3);
2538 gdk_draw_line (window, style->light_gc[state],
2539 x + width - 1, y + 1, x + width - 1, y + height - 2);
2540 gdk_draw_line (window, style->light_gc[state],
2541 x, y + height - 1, x + width - 1, y + height - 1);
2542 gdk_draw_line (window, style->bg_gc[state],
2543 x, y + height - 2, x + width - 2, y + height - 2);
2544 gdk_draw_line (window, style->black_gc,
2545 x, y + 2, x, y + height - 3);
2549 gdk_draw_line (window, style->dark_gc[state],
2550 x, y, x + width - 1, y);
2551 gdk_draw_line (window, style->dark_gc[state],
2552 x, y + 1, x, y + height - 1);
2553 gdk_draw_line (window, style->black_gc,
2554 x + 1, y + 1, x + width - 1, y + 1);
2555 gdk_draw_line (window, style->black_gc,
2556 x + 1, y + 2, x + 1, y + height - 2);
2557 gdk_draw_line (window, style->black_gc,
2558 x + width - 1, y + 2, x + width - 1, y + height - 3);
2559 gdk_draw_line (window, style->light_gc[state],
2560 x + 1, y + height - 1, x + width - 1, y + height - 1);
2561 gdk_draw_line (window, style->bg_gc[state],
2562 x + 2, y + height - 2, x + width - 1, y + height - 2);
2567 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
2568 gdk_gc_set_clip_rectangle (style->bg_gc[state], NULL);
2569 gdk_gc_set_clip_rectangle (style->dark_gc[state], NULL);
2570 gdk_gc_set_clip_rectangle (style->light_gc[state], NULL);
2575 draw_menu_shadow (GtkStyle *style,
2584 if (style->ythickness > 0)
2586 if (style->ythickness > 1)
2588 gdk_draw_line (window, style->dark_gc[state],
2589 x + 1, y + height - 2, x + width - 2, y + height - 2);
2590 gdk_draw_line (window, style->black_gc,
2591 x, y + height - 1, x + width - 1, y + height - 1);
2595 gdk_draw_line (window, style->dark_gc[state],
2596 x + 1, y + height - 1, x + width - 1, y + height - 1);
2600 if (style->xthickness > 0)
2602 if (style->xthickness > 1)
2604 gdk_draw_line (window, style->dark_gc[state],
2605 x + width - 2, y + 1, x + width - 2, y + height - 2);
2607 gdk_draw_line (window, style->black_gc,
2608 x + width - 1, y, x + width - 1, y + height - 1);
2612 gdk_draw_line (window, style->dark_gc[state],
2613 x + width - 1, y + 1, x + width - 1, y + height - 1);
2617 /* Light around top and left */
2619 if (style->ythickness > 0)
2620 gdk_draw_line (window, style->black_gc,
2621 x, y, x + width - 2, y);
2622 if (style->xthickness > 0)
2623 gdk_draw_line (window, style->black_gc,
2624 x, y, x, y + height - 2);
2626 if (style->ythickness > 1)
2627 gdk_draw_line (window, style->light_gc[state],
2628 x + 1, y + 1, x + width - 3, y + 1);
2629 if (style->xthickness > 1)
2630 gdk_draw_line (window, style->light_gc[state],
2631 x + 1, y + 1, x + 1, y + height - 3);
2634 static GtkTextDirection
2635 get_direction (GtkWidget *widget)
2637 GtkTextDirection dir;
2640 dir = gtk_widget_get_direction (widget);
2642 dir = GTK_TEXT_DIR_LTR;
2649 gtk_default_draw_shadow (GtkStyle *style,
2651 GtkStateType state_type,
2652 GtkShadowType shadow_type,
2655 const gchar *detail,
2663 gint thickness_light;
2664 gint thickness_dark;
2667 if (shadow_type == GTK_SHADOW_IN)
2669 if (detail && strcmp (detail, "buttondefault") == 0)
2671 sanitize_size (window, &width, &height);
2673 gdk_draw_rectangle (window, style->black_gc, FALSE,
2674 x, y, width - 1, height - 1);
2678 if (detail && strcmp (detail, "trough") == 0)
2680 draw_thin_shadow (style, window, state_type, area,
2681 x, y, width, height);
2684 if (GTK_IS_SPIN_BUTTON (widget) &&
2685 detail && strcmp (detail, "spinbutton") == 0)
2687 draw_spinbutton_shadow (style, window, state_type,
2688 get_direction (widget), area, x, y, width, height);
2694 if (shadow_type == GTK_SHADOW_OUT && detail && strcmp (detail, "menu") == 0)
2696 draw_menu_shadow (style, window, state_type, area, x, y, width, height);
2700 sanitize_size (window, &width, &height);
2702 switch (shadow_type)
2704 case GTK_SHADOW_NONE:
2707 case GTK_SHADOW_ETCHED_IN:
2708 gc1 = style->light_gc[state_type];
2709 gc2 = style->dark_gc[state_type];
2711 case GTK_SHADOW_OUT:
2712 case GTK_SHADOW_ETCHED_OUT:
2713 gc1 = style->dark_gc[state_type];
2714 gc2 = style->light_gc[state_type];
2720 gdk_gc_set_clip_rectangle (gc1, area);
2721 gdk_gc_set_clip_rectangle (gc2, area);
2722 if (shadow_type == GTK_SHADOW_IN ||
2723 shadow_type == GTK_SHADOW_OUT)
2725 gdk_gc_set_clip_rectangle (style->black_gc, area);
2726 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
2730 switch (shadow_type)
2732 case GTK_SHADOW_NONE:
2736 /* Light around right and bottom edge */
2738 if (style->ythickness > 0)
2739 gdk_draw_line (window, gc1,
2740 x, y + height - 1, x + width - 1, y + height - 1);
2741 if (style->xthickness > 0)
2742 gdk_draw_line (window, gc1,
2743 x + width - 1, y, x + width - 1, y + height - 1);
2745 if (style->ythickness > 1)
2746 gdk_draw_line (window, style->bg_gc[state_type],
2747 x + 1, y + height - 2, x + width - 2, y + height - 2);
2748 if (style->xthickness > 1)
2749 gdk_draw_line (window, style->bg_gc[state_type],
2750 x + width - 2, y + 1, x + width - 2, y + height - 2);
2752 /* Dark around left and top */
2754 if (style->ythickness > 1)
2755 gdk_draw_line (window, style->black_gc,
2756 x + 1, y + 1, x + width - 2, y + 1);
2757 if (style->xthickness > 1)
2758 gdk_draw_line (window, style->black_gc,
2759 x + 1, y + 1, x + 1, y + height - 2);
2761 if (style->ythickness > 0)
2762 gdk_draw_line (window, gc2,
2763 x, y, x + width - 1, y);
2764 if (style->xthickness > 0)
2765 gdk_draw_line (window, gc2,
2766 x, y, x, y + height - 1);
2769 case GTK_SHADOW_OUT:
2770 /* Dark around right and bottom edge */
2772 if (style->ythickness > 0)
2774 if (style->ythickness > 1)
2776 gdk_draw_line (window, gc1,
2777 x + 1, y + height - 2, x + width - 2, y + height - 2);
2778 gdk_draw_line (window, style->black_gc,
2779 x, y + height - 1, x + width - 1, y + height - 1);
2783 gdk_draw_line (window, gc1,
2784 x + 1, y + height - 1, x + width - 1, y + height - 1);
2788 if (style->xthickness > 0)
2790 if (style->xthickness > 1)
2792 gdk_draw_line (window, gc1,
2793 x + width - 2, y + 1, x + width - 2, y + height - 2);
2795 gdk_draw_line (window, style->black_gc,
2796 x + width - 1, y, x + width - 1, y + height - 1);
2800 gdk_draw_line (window, gc1,
2801 x + width - 1, y + 1, x + width - 1, y + height - 1);
2805 /* Light around top and left */
2807 if (style->ythickness > 0)
2808 gdk_draw_line (window, gc2,
2809 x, y, x + width - 2, y);
2810 if (style->xthickness > 0)
2811 gdk_draw_line (window, gc2,
2812 x, y, x, y + height - 2);
2814 if (style->ythickness > 1)
2815 gdk_draw_line (window, style->bg_gc[state_type],
2816 x + 1, y + 1, x + width - 3, y + 1);
2817 if (style->xthickness > 1)
2818 gdk_draw_line (window, style->bg_gc[state_type],
2819 x + 1, y + 1, x + 1, y + height - 3);
2822 case GTK_SHADOW_ETCHED_IN:
2823 case GTK_SHADOW_ETCHED_OUT:
2824 if (style->xthickness > 0)
2826 if (style->xthickness > 1)
2828 thickness_light = 1;
2831 for (i = 0; i < thickness_dark; i++)
2833 gdk_draw_line (window, gc1,
2837 y + height - i - 1);
2838 gdk_draw_line (window, gc2,
2842 y + height - i - 2);
2845 for (i = 0; i < thickness_light; i++)
2847 gdk_draw_line (window, gc1,
2848 x + thickness_dark + i,
2849 y + thickness_dark + i,
2850 x + thickness_dark + i,
2851 y + height - thickness_dark - i - 1);
2852 gdk_draw_line (window, gc2,
2853 x + width - thickness_light - i - 1,
2854 y + thickness_dark + i,
2855 x + width - thickness_light - i - 1,
2856 y + height - thickness_light - 1);
2861 gdk_draw_line (window,
2862 style->dark_gc[state_type],
2863 x, y, x, y + height);
2864 gdk_draw_line (window,
2865 style->dark_gc[state_type],
2866 x + width, y, x + width, y + height);
2870 if (style->ythickness > 0)
2872 if (style->ythickness > 1)
2874 thickness_light = 1;
2877 for (i = 0; i < thickness_dark; i++)
2879 gdk_draw_line (window, gc1,
2883 y + height - i - 1);
2885 gdk_draw_line (window, gc2,
2892 for (i = 0; i < thickness_light; i++)
2894 gdk_draw_line (window, gc1,
2895 x + thickness_dark + i,
2896 y + thickness_dark + i,
2897 x + width - thickness_dark - i - 2,
2898 y + thickness_dark + i);
2900 gdk_draw_line (window, gc2,
2901 x + thickness_dark + i,
2902 y + height - thickness_light - i - 1,
2903 x + width - thickness_light - 1,
2904 y + height - thickness_light - i - 1);
2909 gdk_draw_line (window,
2910 style->dark_gc[state_type],
2911 x, y, x + width, y);
2912 gdk_draw_line (window,
2913 style->dark_gc[state_type],
2914 x, y + height, x + width, y + height);
2921 if (shadow_type == GTK_SHADOW_IN &&
2922 GTK_IS_SPIN_BUTTON (widget) &&
2923 detail && strcmp (detail, "entry") == 0)
2925 if (get_direction (widget) == GTK_TEXT_DIR_LTR)
2927 gdk_draw_line (window,
2928 style->base_gc[state_type],
2929 x + width - 1, y + 2,
2930 x + width - 1, y + height - 3);
2931 gdk_draw_line (window,
2932 style->base_gc[state_type],
2933 x + width - 2, y + 2,
2934 x + width - 2, y + height - 3);
2935 gdk_draw_point (window,
2937 x + width - 1, y + 1);
2938 gdk_draw_point (window,
2939 style->bg_gc[state_type],
2940 x + width - 1, y + height - 2);
2944 gdk_draw_line (window,
2945 style->base_gc[state_type],
2948 gdk_draw_line (window,
2949 style->base_gc[state_type],
2951 x + 1, y + height - 3);
2952 gdk_draw_point (window,
2955 gdk_draw_line (window,
2956 style->bg_gc[state_type],
2958 x + 1, y + height - 2);
2959 gdk_draw_point (window,
2960 style->light_gc[state_type],
2968 gdk_gc_set_clip_rectangle (gc1, NULL);
2969 gdk_gc_set_clip_rectangle (gc2, NULL);
2970 if (shadow_type == GTK_SHADOW_IN ||
2971 shadow_type == GTK_SHADOW_OUT)
2973 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
2974 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
2980 gtk_default_draw_polygon (GtkStyle *style,
2982 GtkStateType state_type,
2983 GtkShadowType shadow_type,
2986 const gchar *detail,
2991 static const gdouble pi_over_4 = G_PI_4;
2992 static const gdouble pi_3_over_4 = G_PI_4 * 3;
3002 switch (shadow_type)
3005 gc1 = style->bg_gc[state_type];
3006 gc2 = style->dark_gc[state_type];
3007 gc3 = style->light_gc[state_type];
3008 gc4 = style->black_gc;
3010 case GTK_SHADOW_ETCHED_IN:
3011 gc1 = style->light_gc[state_type];
3012 gc2 = style->dark_gc[state_type];
3013 gc3 = style->dark_gc[state_type];
3014 gc4 = style->light_gc[state_type];
3016 case GTK_SHADOW_OUT:
3017 gc1 = style->dark_gc[state_type];
3018 gc2 = style->light_gc[state_type];
3019 gc3 = style->black_gc;
3020 gc4 = style->bg_gc[state_type];
3022 case GTK_SHADOW_ETCHED_OUT:
3023 gc1 = style->dark_gc[state_type];
3024 gc2 = style->light_gc[state_type];
3025 gc3 = style->light_gc[state_type];
3026 gc4 = style->dark_gc[state_type];
3034 gdk_gc_set_clip_rectangle (gc1, area);
3035 gdk_gc_set_clip_rectangle (gc2, area);
3036 gdk_gc_set_clip_rectangle (gc3, area);
3037 gdk_gc_set_clip_rectangle (gc4, area);
3041 gdk_draw_polygon (window, style->bg_gc[state_type], TRUE, points, npoints);
3045 for (i = 0; i < npoints; i++)
3047 if ((points[i].x == points[i+1].x) &&
3048 (points[i].y == points[i+1].y))
3054 angle = atan2 (points[i+1].y - points[i].y,
3055 points[i+1].x - points[i].x);
3058 if ((angle > -pi_3_over_4) && (angle < pi_over_4))
3060 if (angle > -pi_over_4)
3071 gdk_draw_line (window, gc1,
3072 points[i].x-xadjust, points[i].y-yadjust,
3073 points[i+1].x-xadjust, points[i+1].y-yadjust);
3074 gdk_draw_line (window, gc3,
3075 points[i].x, points[i].y,
3076 points[i+1].x, points[i+1].y);
3080 if ((angle < -pi_3_over_4) || (angle > pi_3_over_4))
3091 gdk_draw_line (window, gc4,
3092 points[i].x+xadjust, points[i].y+yadjust,
3093 points[i+1].x+xadjust, points[i+1].y+yadjust);
3094 gdk_draw_line (window, gc2,
3095 points[i].x, points[i].y,
3096 points[i+1].x, points[i+1].y);
3102 gdk_gc_set_clip_rectangle (gc1, NULL);
3103 gdk_gc_set_clip_rectangle (gc2, NULL);
3104 gdk_gc_set_clip_rectangle (gc3, NULL);
3105 gdk_gc_set_clip_rectangle (gc4, NULL);
3110 draw_arrow (GdkWindow *window,
3113 GtkArrowType arrow_type,
3119 cairo_t *cr = gdk_cairo_create (window);
3120 gdk_cairo_set_source_color (cr, color);
3124 gdk_cairo_rectangle (cr, area);
3128 if (arrow_type == GTK_ARROW_DOWN)
3130 cairo_move_to (cr, x, y);
3131 cairo_line_to (cr, x + width, y);
3132 cairo_line_to (cr, x + width / 2., y + height);
3134 else if (arrow_type == GTK_ARROW_UP)
3136 cairo_move_to (cr, x, y + height);
3137 cairo_line_to (cr, x + width / 2., y);
3138 cairo_line_to (cr, x + width, y + height);
3140 else if (arrow_type == GTK_ARROW_LEFT)
3142 cairo_move_to (cr, x + width, y);
3143 cairo_line_to (cr, x + width, y + height);
3144 cairo_line_to (cr, x, y + height / 2.);
3146 else if (arrow_type == GTK_ARROW_RIGHT)
3148 cairo_move_to (cr, x, y);
3149 cairo_line_to (cr, x + width, y + height / 2.);
3150 cairo_line_to (cr, x, y + height);
3153 cairo_close_path (cr);
3160 calculate_arrow_geometry (GtkArrowType arrow_type,
3172 case GTK_ARROW_DOWN:
3182 if (arrow_type == GTK_ARROW_DOWN)
3184 if (*height % 2 == 1 || h % 2 == 0)
3189 if (*height % 2 == 0 || h % 2 == 0)
3194 case GTK_ARROW_RIGHT:
3195 case GTK_ARROW_LEFT:
3205 if (arrow_type == GTK_ARROW_RIGHT)
3207 if (*width % 2 == 1 || w % 2 == 0)
3212 if (*width % 2 == 0 || w % 2 == 0)
3218 /* should not be reached */
3222 *x += (*width - w) / 2;
3223 *y += (*height - h) / 2;
3229 gtk_default_draw_arrow (GtkStyle *style,
3232 GtkShadowType shadow,
3235 const gchar *detail,
3236 GtkArrowType arrow_type,
3243 sanitize_size (window, &width, &height);
3245 calculate_arrow_geometry (arrow_type, &x, &y, &width, &height);
3247 if (detail && strcmp (detail, "menu_scroll_arrow_up") == 0)
3250 if (state == GTK_STATE_INSENSITIVE)
3251 draw_arrow (window, &style->white, area, arrow_type,
3252 x + 1, y + 1, width, height);
3253 draw_arrow (window, &style->fg[state], area, arrow_type,
3254 x, y, width, height);
3258 gtk_default_draw_diamond (GtkStyle *style,
3260 GtkStateType state_type,
3261 GtkShadowType shadow_type,
3264 const gchar *detail,
3272 GdkGC *outer_nw = NULL;
3273 GdkGC *outer_ne = NULL;
3274 GdkGC *outer_sw = NULL;
3275 GdkGC *outer_se = NULL;
3276 GdkGC *middle_nw = NULL;
3277 GdkGC *middle_ne = NULL;
3278 GdkGC *middle_sw = NULL;
3279 GdkGC *middle_se = NULL;
3280 GdkGC *inner_nw = NULL;
3281 GdkGC *inner_ne = NULL;
3282 GdkGC *inner_sw = NULL;
3283 GdkGC *inner_se = NULL;
3285 sanitize_size (window, &width, &height);
3287 half_width = width / 2;
3288 half_height = height / 2;
3292 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
3293 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
3294 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
3295 gdk_gc_set_clip_rectangle (style->black_gc, area);
3298 switch (shadow_type)
3301 inner_sw = inner_se = style->bg_gc[state_type];
3302 middle_sw = middle_se = style->light_gc[state_type];
3303 outer_sw = outer_se = style->light_gc[state_type];
3304 inner_nw = inner_ne = style->black_gc;
3305 middle_nw = middle_ne = style->dark_gc[state_type];
3306 outer_nw = outer_ne = style->dark_gc[state_type];
3309 case GTK_SHADOW_OUT:
3310 inner_sw = inner_se = style->dark_gc[state_type];
3311 middle_sw = middle_se = style->dark_gc[state_type];
3312 outer_sw = outer_se = style->black_gc;
3313 inner_nw = inner_ne = style->bg_gc[state_type];
3314 middle_nw = middle_ne = style->light_gc[state_type];
3315 outer_nw = outer_ne = style->light_gc[state_type];
3318 case GTK_SHADOW_ETCHED_IN:
3319 inner_sw = inner_se = style->bg_gc[state_type];
3320 middle_sw = middle_se = style->dark_gc[state_type];
3321 outer_sw = outer_se = style->light_gc[state_type];
3322 inner_nw = inner_ne = style->bg_gc[state_type];
3323 middle_nw = middle_ne = style->light_gc[state_type];
3324 outer_nw = outer_ne = style->dark_gc[state_type];
3327 case GTK_SHADOW_ETCHED_OUT:
3328 inner_sw = inner_se = style->bg_gc[state_type];
3329 middle_sw = middle_se = style->light_gc[state_type];
3330 outer_sw = outer_se = style->dark_gc[state_type];
3331 inner_nw = inner_ne = style->bg_gc[state_type];
3332 middle_nw = middle_ne = style->dark_gc[state_type];
3333 outer_nw = outer_ne = style->light_gc[state_type];
3343 gdk_draw_line (window, inner_sw,
3344 x + 2, y + half_height,
3345 x + half_width, y + height - 2);
3346 gdk_draw_line (window, inner_se,
3347 x + half_width, y + height - 2,
3348 x + width - 2, y + half_height);
3349 gdk_draw_line (window, middle_sw,
3350 x + 1, y + half_height,
3351 x + half_width, y + height - 1);
3352 gdk_draw_line (window, middle_se,
3353 x + half_width, y + height - 1,
3354 x + width - 1, y + half_height);
3355 gdk_draw_line (window, outer_sw,
3357 x + half_width, y + height);
3358 gdk_draw_line (window, outer_se,
3359 x + half_width, y + height,
3360 x + width, y + half_height);
3362 gdk_draw_line (window, inner_nw,
3363 x + 2, y + half_height,
3364 x + half_width, y + 2);
3365 gdk_draw_line (window, inner_ne,
3366 x + half_width, y + 2,
3367 x + width - 2, y + half_height);
3368 gdk_draw_line (window, middle_nw,
3369 x + 1, y + half_height,
3370 x + half_width, y + 1);
3371 gdk_draw_line (window, middle_ne,
3372 x + half_width, y + 1,
3373 x + width - 1, y + half_height);
3374 gdk_draw_line (window, outer_nw,
3377 gdk_draw_line (window, outer_ne,
3379 x + width, y + half_height);
3384 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
3385 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
3386 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
3387 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
3392 gtk_default_draw_string (GtkStyle *style,
3394 GtkStateType state_type,
3397 const gchar *detail,
3400 const gchar *string)
3404 gdk_gc_set_clip_rectangle (style->white_gc, area);
3405 gdk_gc_set_clip_rectangle (style->fg_gc[state_type], area);
3408 if (state_type == GTK_STATE_INSENSITIVE)
3409 gdk_draw_string (window,
3410 gtk_style_get_font_internal (style),
3411 style->white_gc, x + 1, y + 1, string);
3413 gdk_draw_string (window,
3414 gtk_style_get_font_internal (style),
3415 style->fg_gc[state_type], x, y, string);
3419 gdk_gc_set_clip_rectangle (style->white_gc, NULL);
3420 gdk_gc_set_clip_rectangle (style->fg_gc[state_type], NULL);
3425 option_menu_get_props (GtkWidget *widget,
3426 GtkRequisition *indicator_size,
3427 GtkBorder *indicator_spacing)
3429 GtkRequisition *tmp_size = NULL;
3430 GtkBorder *tmp_spacing = NULL;
3432 if (GTK_IS_OPTION_MENU (widget))
3433 gtk_widget_style_get (widget,
3434 "indicator-size", &tmp_size,
3435 "indicator-spacing", &tmp_spacing,
3440 *indicator_size = *tmp_size;
3441 gtk_requisition_free (tmp_size);
3444 *indicator_size = default_option_indicator_size;
3448 *indicator_spacing = *tmp_spacing;
3449 gtk_border_free (tmp_spacing);
3452 *indicator_spacing = default_option_indicator_spacing;
3456 gtk_default_draw_box (GtkStyle *style,
3458 GtkStateType state_type,
3459 GtkShadowType shadow_type,
3462 const gchar *detail,
3468 gboolean is_spinbutton_box = FALSE;
3470 sanitize_size (window, &width, &height);
3472 if (GTK_IS_SPIN_BUTTON (widget) && detail)
3474 if (strcmp (detail, "spinbutton_up") == 0)
3480 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
3485 is_spinbutton_box = TRUE;
3487 else if (strcmp (detail, "spinbutton_down") == 0)
3492 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
3497 is_spinbutton_box = TRUE;
3501 if (!style->bg_pixmap[state_type] ||
3502 GDK_IS_PIXMAP (window))
3504 GdkGC *gc = style->bg_gc[state_type];
3506 if (state_type == GTK_STATE_SELECTED && detail && strcmp (detail, "paned") == 0)
3508 if (widget && !GTK_WIDGET_HAS_FOCUS (widget))
3509 gc = style->base_gc[GTK_STATE_ACTIVE];
3513 gdk_gc_set_clip_rectangle (gc, area);
3515 gdk_draw_rectangle (window, gc, TRUE,
3516 x, y, width, height);
3518 gdk_gc_set_clip_rectangle (gc, NULL);
3521 gtk_style_apply_default_background (style, window,
3522 widget && !GTK_WIDGET_NO_WINDOW (widget),
3523 state_type, area, x, y, width, height);
3525 if (is_spinbutton_box)
3530 lower_gc = style->dark_gc[state_type];
3531 if (shadow_type == GTK_SHADOW_OUT)
3532 upper_gc = style->light_gc[state_type];
3534 upper_gc = style->dark_gc[state_type];
3538 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
3539 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
3542 gdk_draw_line (window, upper_gc, x, y, x + width - 1, y);
3543 gdk_draw_line (window, lower_gc, x, y + height - 1, x + width - 1, y + height - 1);
3547 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
3548 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
3553 gtk_paint_shadow (style, window, state_type, shadow_type, area, widget, detail,
3554 x, y, width, height);
3556 if (detail && strcmp (detail, "optionmenu") == 0)
3558 GtkRequisition indicator_size;
3559 GtkBorder indicator_spacing;
3562 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
3564 sanitize_size (window, &width, &height);
3566 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
3567 vline_x = x + indicator_size.width + indicator_spacing.left + indicator_spacing.right;
3569 vline_x = x + width - (indicator_size.width + indicator_spacing.left + indicator_spacing.right) - style->xthickness;
3571 gtk_paint_vline (style, window, state_type, area, widget,
3573 y + style->ythickness + 1,
3574 y + height - style->ythickness - 3,
3580 get_darkened_gc (GdkWindow *window,
3581 const GdkColor *color,
3584 GdkColor src = *color;
3585 GdkColor shaded = *color;
3588 gc = gdk_gc_new (window);
3590 while (darken_count)
3592 _gtk_style_shade (&src, &shaded, 0.93);
3597 gdk_gc_set_rgb_fg_color (gc, &shaded);
3603 gtk_default_draw_flat_box (GtkStyle *style,
3605 GtkStateType state_type,
3606 GtkShadowType shadow_type,
3609 const gchar *detail,
3616 GdkGC *freeme = NULL;
3618 sanitize_size (window, &width, &height);
3622 if (state_type == GTK_STATE_SELECTED)
3624 if (!strcmp ("text", detail))
3625 gc1 = style->bg_gc[GTK_STATE_SELECTED];
3626 else if (!strcmp ("cell_even", detail) ||
3627 !strcmp ("cell_odd", detail) ||
3628 !strcmp ("cell_even_ruled", detail) ||
3629 !strcmp ("cell_even_ruled_sorted", detail))
3631 /* This has to be really broken; alex made me do it. -jrb */
3632 if (widget && GTK_WIDGET_HAS_FOCUS (widget))
3633 gc1 = style->base_gc[state_type];
3635 gc1 = style->base_gc[GTK_STATE_ACTIVE];
3637 else if (!strcmp ("cell_odd_ruled", detail) ||
3638 !strcmp ("cell_odd_ruled_sorted", detail))
3640 if (widget && GTK_WIDGET_HAS_FOCUS (widget))
3641 freeme = get_darkened_gc (window, &style->base[state_type], 1);
3643 freeme = get_darkened_gc (window, &style->base[GTK_STATE_ACTIVE], 1);
3648 gc1 = style->bg_gc[state_type];
3653 if (!strcmp ("viewportbin", detail))
3654 gc1 = style->bg_gc[GTK_STATE_NORMAL];
3655 else if (!strcmp ("entry_bg", detail))
3656 gc1 = style->base_gc[state_type];
3658 /* For trees: even rows are base color, odd rows are a shade of
3659 * the base color, the sort column is a shade of the original color
3663 else if (!strcmp ("cell_even", detail) ||
3664 !strcmp ("cell_odd", detail) ||
3665 !strcmp ("cell_even_ruled", detail))
3667 GdkColor *color = NULL;
3669 gtk_widget_style_get (widget,
3670 "even-row-color", &color,
3675 freeme = get_darkened_gc (window, color, 0);
3678 gdk_color_free (color);
3681 gc1 = style->base_gc[state_type];
3683 else if (!strcmp ("cell_odd_ruled", detail))
3685 GdkColor *color = NULL;
3687 gtk_widget_style_get (widget,
3688 "odd-row-color", &color,
3693 freeme = get_darkened_gc (window, color, 0);
3696 gdk_color_free (color);
3700 gtk_widget_style_get (widget,
3701 "even-row-color", &color,
3706 freeme = get_darkened_gc (window, color, 1);
3707 gdk_color_free (color);
3710 freeme = get_darkened_gc (window, &style->base[state_type], 1);
3714 else if (!strcmp ("cell_even_sorted", detail) ||
3715 !strcmp ("cell_odd_sorted", detail) ||
3716 !strcmp ("cell_even_ruled_sorted", detail))
3718 GdkColor *color = NULL;
3720 if (!strcmp ("cell_odd_sorted", detail))
3721 gtk_widget_style_get (widget,
3722 "odd-row-color", &color,
3725 gtk_widget_style_get (widget,
3726 "even-row-color", &color,
3731 freeme = get_darkened_gc (window, color, 1);
3734 gdk_color_free (color);
3738 freeme = get_darkened_gc (window, &style->base[state_type], 1);
3742 else if (!strcmp ("cell_odd_ruled_sorted", detail))
3744 GdkColor *color = NULL;
3746 gtk_widget_style_get (widget,
3747 "odd-row-color", &color,
3752 freeme = get_darkened_gc (window, color, 1);
3755 gdk_color_free (color);
3759 gtk_widget_style_get (widget,
3760 "even-row-color", &color,
3765 freeme = get_darkened_gc (window, color, 2);
3766 gdk_color_free (color);
3769 freeme = get_darkened_gc (window, &style->base[state_type], 2);
3774 gc1 = style->bg_gc[state_type];
3778 gc1 = style->bg_gc[state_type];
3780 if (!style->bg_pixmap[state_type] || gc1 != style->bg_gc[state_type] ||
3781 GDK_IS_PIXMAP (window))
3784 gdk_gc_set_clip_rectangle (gc1, area);
3786 gdk_draw_rectangle (window, gc1, TRUE,
3787 x, y, width, height);
3789 if (detail && !strcmp ("tooltip", detail))
3790 gdk_draw_rectangle (window, style->black_gc, FALSE,
3791 x, y, width - 1, height - 1);
3794 gdk_gc_set_clip_rectangle (gc1, NULL);
3797 gtk_style_apply_default_background (style, window,
3798 widget && !GTK_WIDGET_NO_WINDOW (widget),
3799 state_type, area, x, y, width, height);
3803 g_object_unref (freeme);
3807 gtk_default_draw_check (GtkStyle *style,
3809 GtkStateType state_type,
3810 GtkShadowType shadow_type,
3813 const gchar *detail,
3819 cairo_t *cr = gdk_cairo_create (window);
3820 enum { BUTTON, MENU, CELL } type = BUTTON;
3827 if (strcmp (detail, "cellcheck") == 0)
3829 else if (strcmp (detail, "check") == 0)
3835 gdk_cairo_rectangle (cr, area);
3839 exterior_size = MIN (width, height);
3840 if (exterior_size % 2 == 0) /* Ensure odd */
3843 pad = style->xthickness + MAX (1, (exterior_size - 2 * style->xthickness) / 9);
3844 interior_size = MAX (1, exterior_size - 2 * pad);
3846 if (interior_size < 7)
3849 pad = MAX (0, (exterior_size - interior_size) / 2);
3852 x -= (1 + exterior_size - width) / 2;
3853 y -= (1 + exterior_size - height) / 2;
3860 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3862 gdk_cairo_set_source_color (cr, &style->text[state_type]);
3864 cairo_set_line_width (cr, 1.0);
3865 cairo_rectangle (cr, x + 0.5, y + 0.5, exterior_size - 1, exterior_size - 1);
3868 gdk_cairo_set_source_color (cr, &style->base[state_type]);
3869 cairo_rectangle (cr, x + 1, y + 1, exterior_size - 2, exterior_size - 2);
3881 gdk_cairo_set_source_color (cr, &style->text[state_type]);
3884 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3888 if (shadow_type == GTK_SHADOW_IN)
3890 cairo_translate (cr,
3893 cairo_scale (cr, interior_size / 7., interior_size / 7.);
3895 cairo_move_to (cr, 7.0, 0.0);
3896 cairo_line_to (cr, 7.5, 1.0);
3897 cairo_curve_to (cr, 5.3, 2.0,
3900 cairo_curve_to (cr, 3.0, 5.7,
3903 cairo_line_to (cr, 0.2, 3.5);
3904 cairo_curve_to (cr, 1.1, 3.5,
3907 cairo_curve_to (cr, 1.0, 3.9,
3910 cairo_curve_to (cr, 3.5, 3.1,
3916 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
3918 int line_thickness = MAX (1, (3 + interior_size * 2) / 7);
3920 cairo_rectangle (cr,
3922 y + pad + (1 + interior_size - line_thickness) / 2,
3932 gtk_default_draw_option (GtkStyle *style,
3934 GtkStateType state_type,
3935 GtkShadowType shadow_type,
3938 const gchar *detail,
3944 cairo_t *cr = gdk_cairo_create (window);
3945 enum { BUTTON, MENU, CELL } type = BUTTON;
3950 if (strcmp (detail, "radio") == 0)
3952 else if (strcmp (detail, "option") == 0)
3958 gdk_cairo_rectangle (cr, area);
3962 exterior_size = MIN (width, height);
3963 if (exterior_size % 2 == 0) /* Ensure odd */
3966 x -= (1 + exterior_size - width) / 2;
3967 y -= (1 + exterior_size - height) / 2;
3973 gdk_cairo_set_source_color (cr, &style->base[state_type]);
3976 x + exterior_size / 2.,
3977 y + exterior_size / 2.,
3978 (exterior_size - 1) / 2.,
3981 cairo_fill_preserve (cr);
3984 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3986 gdk_cairo_set_source_color (cr, &style->text[state_type]);
3988 cairo_set_line_width (cr, 1.);
3999 gdk_cairo_set_source_color (cr, &style->text[state_type]);
4004 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
4008 if (shadow_type == GTK_SHADOW_IN)
4010 int pad = style->xthickness + MAX (1, 2 * (exterior_size - 2 * style->xthickness) / 9);
4011 int interior_size = MAX (1, exterior_size - 2 * pad);
4013 if (interior_size < 5)
4016 pad = MAX (0, (exterior_size - interior_size) / 2);
4020 x + pad + interior_size / 2.,
4021 y + pad + interior_size / 2.,
4026 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
4028 int pad = style->xthickness + MAX (1, (exterior_size - 2 * style->xthickness) / 9);
4029 int interior_size = MAX (1, exterior_size - 2 * pad);
4032 if (interior_size < 7)
4035 pad = MAX (0, (exterior_size - interior_size) / 2);
4038 line_thickness = MAX (1, (3 + interior_size * 2) / 7);
4040 cairo_rectangle (cr,
4042 y + pad + (interior_size - line_thickness) / 2.,
4052 gtk_default_draw_tab (GtkStyle *style,
4054 GtkStateType state_type,
4055 GtkShadowType shadow_type,
4058 const gchar *detail,
4064 #define ARROW_SPACE 4
4066 GtkRequisition indicator_size;
4067 GtkBorder indicator_spacing;
4070 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
4072 indicator_size.width += (indicator_size.width % 2) - 1;
4073 arrow_height = indicator_size.width / 2 + 1;
4075 x += (width - indicator_size.width) / 2;
4076 y += (height - (2 * arrow_height + ARROW_SPACE)) / 2;
4078 if (state_type == GTK_STATE_INSENSITIVE)
4080 draw_arrow (window, &style->white, area,
4081 GTK_ARROW_UP, x + 1, y + 1,
4082 indicator_size.width, arrow_height);
4084 draw_arrow (window, &style->white, area,
4085 GTK_ARROW_DOWN, x + 1, y + arrow_height + ARROW_SPACE + 1,
4086 indicator_size.width, arrow_height);
4089 draw_arrow (window, &style->fg[state_type], area,
4091 indicator_size.width, arrow_height);
4094 draw_arrow (window, &style->fg[state_type], area,
4095 GTK_ARROW_DOWN, x, y + arrow_height + ARROW_SPACE,
4096 indicator_size.width, arrow_height);
4100 gtk_default_draw_shadow_gap (GtkStyle *style,
4102 GtkStateType state_type,
4103 GtkShadowType shadow_type,
4106 const gchar *detail,
4111 GtkPositionType gap_side,
4120 sanitize_size (window, &width, &height);
4122 switch (shadow_type)
4124 case GTK_SHADOW_NONE:
4127 gc1 = style->dark_gc[state_type];
4128 gc2 = style->black_gc;
4129 gc3 = style->bg_gc[state_type];
4130 gc4 = style->light_gc[state_type];
4132 case GTK_SHADOW_ETCHED_IN:
4133 gc1 = style->dark_gc[state_type];
4134 gc2 = style->light_gc[state_type];
4135 gc3 = style->dark_gc[state_type];
4136 gc4 = style->light_gc[state_type];
4138 case GTK_SHADOW_OUT:
4139 gc1 = style->light_gc[state_type];
4140 gc2 = style->bg_gc[state_type];
4141 gc3 = style->dark_gc[state_type];
4142 gc4 = style->black_gc;
4144 case GTK_SHADOW_ETCHED_OUT:
4145 gc1 = style->light_gc[state_type];
4146 gc2 = style->dark_gc[state_type];
4147 gc3 = style->light_gc[state_type];
4148 gc4 = style->dark_gc[state_type];
4153 gdk_gc_set_clip_rectangle (gc1, area);
4154 gdk_gc_set_clip_rectangle (gc2, area);
4155 gdk_gc_set_clip_rectangle (gc3, area);
4156 gdk_gc_set_clip_rectangle (gc4, area);
4159 switch (shadow_type)
4161 case GTK_SHADOW_NONE:
4163 case GTK_SHADOW_OUT:
4164 case GTK_SHADOW_ETCHED_IN:
4165 case GTK_SHADOW_ETCHED_OUT:
4169 gdk_draw_line (window, gc1,
4170 x, y, x, y + height - 1);
4171 gdk_draw_line (window, gc2,
4172 x + 1, y, x + 1, y + height - 2);
4174 gdk_draw_line (window, gc3,
4175 x + 1, y + height - 2, x + width - 2, y + height - 2);
4176 gdk_draw_line (window, gc3,
4177 x + width - 2, y, x + width - 2, y + height - 2);
4178 gdk_draw_line (window, gc4,
4179 x, y + height - 1, x + width - 1, y + height - 1);
4180 gdk_draw_line (window, gc4,
4181 x + width - 1, y, x + width - 1, y + height - 1);
4184 gdk_draw_line (window, gc1,
4185 x, y, x + gap_x - 1, y);
4186 gdk_draw_line (window, gc2,
4187 x + 1, y + 1, x + gap_x - 1, y + 1);
4188 gdk_draw_line (window, gc2,
4189 x + gap_x, y, x + gap_x, y);
4191 if ((width - (gap_x + gap_width)) > 0)
4193 gdk_draw_line (window, gc1,
4194 x + gap_x + gap_width, y, x + width - 2, y);
4195 gdk_draw_line (window, gc2,
4196 x + gap_x + gap_width, y + 1, x + width - 3, y + 1);
4197 gdk_draw_line (window, gc2,
4198 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
4201 case GTK_POS_BOTTOM:
4202 gdk_draw_line (window, gc1,
4203 x, y, x + width - 1, y);
4204 gdk_draw_line (window, gc1,
4205 x, y, x, y + height - 1);
4206 gdk_draw_line (window, gc2,
4207 x + 1, y + 1, x + width - 2, y + 1);
4208 gdk_draw_line (window, gc2,
4209 x + 1, y + 1, x + 1, y + height - 1);
4211 gdk_draw_line (window, gc3,
4212 x + width - 2, y + 1, x + width - 2, y + height - 1);
4213 gdk_draw_line (window, gc4,
4214 x + width - 1, y, x + width - 1, y + height - 1);
4217 gdk_draw_line (window, gc4,
4218 x, y + height - 1, x + gap_x - 1, y + height - 1);
4219 gdk_draw_line (window, gc3,
4220 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
4221 gdk_draw_line (window, gc3,
4222 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
4224 if ((width - (gap_x + gap_width)) > 0)
4226 gdk_draw_line (window, gc4,
4227 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
4228 gdk_draw_line (window, gc3,
4229 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
4230 gdk_draw_line (window, gc3,
4231 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
4235 gdk_draw_line (window, gc1,
4236 x, y, x + width - 1, y);
4237 gdk_draw_line (window, gc2,
4238 x, y + 1, x + width - 2, y + 1);
4240 gdk_draw_line (window, gc3,
4241 x, y + height - 2, x + width - 2, y + height - 2);
4242 gdk_draw_line (window, gc3,
4243 x + width - 2, y + 1, x + width - 2, y + height - 2);
4244 gdk_draw_line (window, gc4,
4245 x, y + height - 1, x + width - 1, y + height - 1);
4246 gdk_draw_line (window, gc4,
4247 x + width - 1, y, x + width - 1, y + height - 1);
4250 gdk_draw_line (window, gc1,
4251 x, y, x, y + gap_x - 1);
4252 gdk_draw_line (window, gc2,
4253 x + 1, y + 1, x + 1, y + gap_x - 1);
4254 gdk_draw_line (window, gc2,
4255 x, y + gap_x, x, y + gap_x);
4257 if ((width - (gap_x + gap_width)) > 0)
4259 gdk_draw_line (window, gc1,
4260 x, y + gap_x + gap_width, x, y + height - 2);
4261 gdk_draw_line (window, gc2,
4262 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
4263 gdk_draw_line (window, gc2,
4264 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
4268 gdk_draw_line (window, gc1,
4269 x, y, x + width - 1, y);
4270 gdk_draw_line (window, gc1,
4271 x, y, x, y + height - 1);
4272 gdk_draw_line (window, gc2,
4273 x + 1, y + 1, x + width - 1, y + 1);
4274 gdk_draw_line (window, gc2,
4275 x + 1, y + 1, x + 1, y + height - 2);
4277 gdk_draw_line (window, gc3,
4278 x + 1, y + height - 2, x + width - 1, y + height - 2);
4279 gdk_draw_line (window, gc4,
4280 x, y + height - 1, x + width - 1, y + height - 1);
4283 gdk_draw_line (window, gc4,
4284 x + width - 1, y, x + width - 1, y + gap_x - 1);
4285 gdk_draw_line (window, gc3,
4286 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
4287 gdk_draw_line (window, gc3,
4288 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
4290 if ((width - (gap_x + gap_width)) > 0)
4292 gdk_draw_line (window, gc4,
4293 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
4294 gdk_draw_line (window, gc3,
4295 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
4296 gdk_draw_line (window, gc3,
4297 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
4305 gdk_gc_set_clip_rectangle (gc1, NULL);
4306 gdk_gc_set_clip_rectangle (gc2, NULL);
4307 gdk_gc_set_clip_rectangle (gc3, NULL);
4308 gdk_gc_set_clip_rectangle (gc4, NULL);
4313 gtk_default_draw_box_gap (GtkStyle *style,
4315 GtkStateType state_type,
4316 GtkShadowType shadow_type,
4319 const gchar *detail,
4324 GtkPositionType gap_side,
4333 gtk_style_apply_default_background (style, window,
4334 widget && !GTK_WIDGET_NO_WINDOW (widget),
4335 state_type, area, x, y, width, height);
4337 sanitize_size (window, &width, &height);
4339 switch (shadow_type)
4341 case GTK_SHADOW_NONE:
4344 gc1 = style->dark_gc[state_type];
4345 gc2 = style->black_gc;
4346 gc3 = style->bg_gc[state_type];
4347 gc4 = style->light_gc[state_type];
4349 case GTK_SHADOW_ETCHED_IN:
4350 gc1 = style->dark_gc[state_type];
4351 gc2 = style->light_gc[state_type];
4352 gc3 = style->dark_gc[state_type];
4353 gc4 = style->light_gc[state_type];
4355 case GTK_SHADOW_OUT:
4356 gc1 = style->light_gc[state_type];
4357 gc2 = style->bg_gc[state_type];
4358 gc3 = style->dark_gc[state_type];
4359 gc4 = style->black_gc;
4361 case GTK_SHADOW_ETCHED_OUT:
4362 gc1 = style->light_gc[state_type];
4363 gc2 = style->dark_gc[state_type];
4364 gc3 = style->light_gc[state_type];
4365 gc4 = style->dark_gc[state_type];
4371 gdk_gc_set_clip_rectangle (gc1, area);
4372 gdk_gc_set_clip_rectangle (gc2, area);
4373 gdk_gc_set_clip_rectangle (gc3, area);
4374 gdk_gc_set_clip_rectangle (gc4, area);
4377 switch (shadow_type)
4379 case GTK_SHADOW_NONE:
4381 case GTK_SHADOW_OUT:
4382 case GTK_SHADOW_ETCHED_IN:
4383 case GTK_SHADOW_ETCHED_OUT:
4387 gdk_draw_line (window, gc1,
4388 x, y, x, y + height - 1);
4389 gdk_draw_line (window, gc2,
4390 x + 1, y, x + 1, y + height - 2);
4392 gdk_draw_line (window, gc3,
4393 x + 1, y + height - 2, x + width - 2, y + height - 2);
4394 gdk_draw_line (window, gc3,
4395 x + width - 2, y, x + width - 2, y + height - 2);
4396 gdk_draw_line (window, gc4,
4397 x, y + height - 1, x + width - 1, y + height - 1);
4398 gdk_draw_line (window, gc4,
4399 x + width - 1, y, x + width - 1, y + height - 1);
4402 gdk_draw_line (window, gc1,
4403 x, y, x + gap_x - 1, y);
4404 gdk_draw_line (window, gc2,
4405 x + 1, y + 1, x + gap_x - 1, y + 1);
4406 gdk_draw_line (window, gc2,
4407 x + gap_x, y, x + gap_x, y);
4409 if ((width - (gap_x + gap_width)) > 0)
4411 gdk_draw_line (window, gc1,
4412 x + gap_x + gap_width, y, x + width - 2, y);
4413 gdk_draw_line (window, gc2,
4414 x + gap_x + gap_width, y + 1, x + width - 2, y + 1);
4415 gdk_draw_line (window, gc2,
4416 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
4419 case GTK_POS_BOTTOM:
4420 gdk_draw_line (window, gc1,
4421 x, y, x + width - 1, y);
4422 gdk_draw_line (window, gc1,
4423 x, y, x, y + height - 1);
4424 gdk_draw_line (window, gc2,
4425 x + 1, y + 1, x + width - 2, y + 1);
4426 gdk_draw_line (window, gc2,
4427 x + 1, y + 1, x + 1, y + height - 1);
4429 gdk_draw_line (window, gc3,
4430 x + width - 2, y + 1, x + width - 2, y + height - 1);
4431 gdk_draw_line (window, gc4,
4432 x + width - 1, y, x + width - 1, y + height - 1);
4435 gdk_draw_line (window, gc4,
4436 x, y + height - 1, x + gap_x - 1, y + height - 1);
4437 gdk_draw_line (window, gc3,
4438 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
4439 gdk_draw_line (window, gc3,
4440 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
4442 if ((width - (gap_x + gap_width)) > 0)
4444 gdk_draw_line (window, gc4,
4445 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
4446 gdk_draw_line (window, gc3,
4447 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
4448 gdk_draw_line (window, gc3,
4449 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
4453 gdk_draw_line (window, gc1,
4454 x, y, x + width - 1, y);
4455 gdk_draw_line (window, gc2,
4456 x, y + 1, x + width - 2, y + 1);
4458 gdk_draw_line (window, gc3,
4459 x, y + height - 2, x + width - 2, y + height - 2);
4460 gdk_draw_line (window, gc3,
4461 x + width - 2, y + 1, x + width - 2, y + height - 2);
4462 gdk_draw_line (window, gc4,
4463 x, y + height - 1, x + width - 1, y + height - 1);
4464 gdk_draw_line (window, gc4,
4465 x + width - 1, y, x + width - 1, y + height - 1);
4468 gdk_draw_line (window, gc1,
4469 x, y, x, y + gap_x - 1);
4470 gdk_draw_line (window, gc2,
4471 x + 1, y + 1, x + 1, y + gap_x - 1);
4472 gdk_draw_line (window, gc2,
4473 x, y + gap_x, x, y + gap_x);
4475 if ((height - (gap_x + gap_width)) > 0)
4477 gdk_draw_line (window, gc1,
4478 x, y + gap_x + gap_width, x, y + height - 2);
4479 gdk_draw_line (window, gc2,
4480 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
4481 gdk_draw_line (window, gc2,
4482 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
4486 gdk_draw_line (window, gc1,
4487 x, y, x + width - 1, y);
4488 gdk_draw_line (window, gc1,
4489 x, y, x, y + height - 1);
4490 gdk_draw_line (window, gc2,
4491 x + 1, y + 1, x + width - 1, y + 1);
4492 gdk_draw_line (window, gc2,
4493 x + 1, y + 1, x + 1, y + height - 2);
4495 gdk_draw_line (window, gc3,
4496 x + 1, y + height - 2, x + width - 1, y + height - 2);
4497 gdk_draw_line (window, gc4,
4498 x, y + height - 1, x + width - 1, y + height - 1);
4501 gdk_draw_line (window, gc4,
4502 x + width - 1, y, x + width - 1, y + gap_x - 1);
4503 gdk_draw_line (window, gc3,
4504 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
4505 gdk_draw_line (window, gc3,
4506 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
4508 if ((height - (gap_x + gap_width)) > 0)
4510 gdk_draw_line (window, gc4,
4511 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
4512 gdk_draw_line (window, gc3,
4513 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
4514 gdk_draw_line (window, gc3,
4515 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
4523 gdk_gc_set_clip_rectangle (gc1, NULL);
4524 gdk_gc_set_clip_rectangle (gc2, NULL);
4525 gdk_gc_set_clip_rectangle (gc3, NULL);
4526 gdk_gc_set_clip_rectangle (gc4, NULL);
4531 gtk_default_draw_extension (GtkStyle *style,
4533 GtkStateType state_type,
4534 GtkShadowType shadow_type,
4537 const gchar *detail,
4542 GtkPositionType gap_side)
4549 gtk_style_apply_default_background (style, window,
4550 widget && !GTK_WIDGET_NO_WINDOW (widget),
4551 GTK_STATE_NORMAL, area, x, y, width, height);
4553 sanitize_size (window, &width, &height);
4555 switch (shadow_type)
4557 case GTK_SHADOW_NONE:
4560 gc1 = style->dark_gc[state_type];
4561 gc2 = style->black_gc;
4562 gc3 = style->bg_gc[state_type];
4563 gc4 = style->light_gc[state_type];
4565 case GTK_SHADOW_ETCHED_IN:
4566 gc1 = style->dark_gc[state_type];
4567 gc2 = style->light_gc[state_type];
4568 gc3 = style->dark_gc[state_type];
4569 gc4 = style->light_gc[state_type];
4571 case GTK_SHADOW_OUT:
4572 gc1 = style->light_gc[state_type];
4573 gc2 = style->bg_gc[state_type];
4574 gc3 = style->dark_gc[state_type];
4575 gc4 = style->black_gc;
4577 case GTK_SHADOW_ETCHED_OUT:
4578 gc1 = style->light_gc[state_type];
4579 gc2 = style->dark_gc[state_type];
4580 gc3 = style->light_gc[state_type];
4581 gc4 = style->dark_gc[state_type];
4587 gdk_gc_set_clip_rectangle (gc1, area);
4588 gdk_gc_set_clip_rectangle (gc2, area);
4589 gdk_gc_set_clip_rectangle (gc3, area);
4590 gdk_gc_set_clip_rectangle (gc4, area);
4593 switch (shadow_type)
4595 case GTK_SHADOW_NONE:
4597 case GTK_SHADOW_OUT:
4598 case GTK_SHADOW_ETCHED_IN:
4599 case GTK_SHADOW_ETCHED_OUT:
4603 gtk_style_apply_default_background (style, window,
4604 widget && !GTK_WIDGET_NO_WINDOW (widget),
4606 x + style->xthickness,
4608 width - (2 * style->xthickness),
4609 height - (style->ythickness));
4610 gdk_draw_line (window, gc1,
4611 x, y, x, y + height - 2);
4612 gdk_draw_line (window, gc2,
4613 x + 1, y, x + 1, y + height - 2);
4615 gdk_draw_line (window, gc3,
4616 x + 2, y + height - 2, x + width - 2, y + height - 2);
4617 gdk_draw_line (window, gc3,
4618 x + width - 2, y, x + width - 2, y + height - 2);
4619 gdk_draw_line (window, gc4,
4620 x + 1, y + height - 1, x + width - 2, y + height - 1);
4621 gdk_draw_line (window, gc4,
4622 x + width - 1, y, x + width - 1, y + height - 2);
4624 case GTK_POS_BOTTOM:
4625 gtk_style_apply_default_background (style, window,
4626 widget && !GTK_WIDGET_NO_WINDOW (widget),
4628 x + style->xthickness,
4629 y + style->ythickness,
4630 width - (2 * style->xthickness),
4631 height - (style->ythickness));
4632 gdk_draw_line (window, gc1,
4633 x + 1, y, x + width - 2, y);
4634 gdk_draw_line (window, gc1,
4635 x, y + 1, x, y + height - 1);
4636 gdk_draw_line (window, gc2,
4637 x + 1, y + 1, x + width - 2, y + 1);
4638 gdk_draw_line (window, gc2,
4639 x + 1, y + 1, x + 1, y + height - 1);
4641 gdk_draw_line (window, gc3,
4642 x + width - 2, y + 2, x + width - 2, y + height - 1);
4643 gdk_draw_line (window, gc4,
4644 x + width - 1, y + 1, x + width - 1, y + height - 1);
4647 gtk_style_apply_default_background (style, window,
4648 widget && !GTK_WIDGET_NO_WINDOW (widget),
4651 y + style->ythickness,
4652 width - (style->xthickness),
4653 height - (2 * style->ythickness));
4654 gdk_draw_line (window, gc1,
4655 x, y, x + width - 2, y);
4656 gdk_draw_line (window, gc2,
4657 x + 1, y + 1, x + width - 2, y + 1);
4659 gdk_draw_line (window, gc3,
4660 x, y + height - 2, x + width - 2, y + height - 2);
4661 gdk_draw_line (window, gc3,
4662 x + width - 2, y + 2, x + width - 2, y + height - 2);
4663 gdk_draw_line (window, gc4,
4664 x, y + height - 1, x + width - 2, y + height - 1);
4665 gdk_draw_line (window, gc4,
4666 x + width - 1, y + 1, x + width - 1, y + height - 2);
4669 gtk_style_apply_default_background (style, window,
4670 widget && !GTK_WIDGET_NO_WINDOW (widget),
4672 x + style->xthickness,
4673 y + style->ythickness,
4674 width - (style->xthickness),
4675 height - (2 * style->ythickness));
4676 gdk_draw_line (window, gc1,
4677 x + 1, y, x + width - 1, y);
4678 gdk_draw_line (window, gc1,
4679 x, y + 1, x, y + height - 2);
4680 gdk_draw_line (window, gc2,
4681 x + 1, y + 1, x + width - 1, y + 1);
4682 gdk_draw_line (window, gc2,
4683 x + 1, y + 1, x + 1, y + height - 2);
4685 gdk_draw_line (window, gc3,
4686 x + 2, y + height - 2, x + width - 1, y + height - 2);
4687 gdk_draw_line (window, gc4,
4688 x + 1, y + height - 1, x + width - 1, y + height - 1);
4695 gdk_gc_set_clip_rectangle (gc1, NULL);
4696 gdk_gc_set_clip_rectangle (gc2, NULL);
4697 gdk_gc_set_clip_rectangle (gc3, NULL);
4698 gdk_gc_set_clip_rectangle (gc4, NULL);
4703 gtk_default_draw_focus (GtkStyle *style,
4705 GtkStateType state_type,
4708 const gchar *detail,
4715 gboolean free_dash_list = FALSE;
4716 gint line_width = 1;
4717 gint8 *dash_list = (gint8 *) "\1\1";
4721 gtk_widget_style_get (widget,
4722 "focus-line-width", &line_width,
4723 "focus-line-pattern", (gchar *)&dash_list,
4726 free_dash_list = TRUE;
4729 if (detail && !strcmp (detail, "add-mode"))
4734 dash_list = (gint8 *) "\4\4";
4735 free_dash_list = FALSE;
4738 sanitize_size (window, &width, &height);
4740 cr = gdk_cairo_create (window);
4742 if (detail && !strcmp (detail, "colorwheel_light"))
4743 cairo_set_source_rgb (cr, 0., 0., 0.);
4744 else if (detail && !strcmp (detail, "colorwheel_dark"))
4745 cairo_set_source_rgb (cr, 1., 1., 1.);
4747 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
4749 cairo_set_line_width (cr, line_width);
4753 gint n_dashes = strlen ((const gchar *) dash_list);
4754 gdouble *dashes = g_new (gdouble, n_dashes);
4755 gdouble total_length = 0;
4756 gdouble dash_offset;
4759 for (i = 0; i < n_dashes; i++)
4761 dashes[i] = dash_list[i];
4762 total_length += dash_list[i];
4765 /* The dash offset here aligns the pattern to integer pixels
4766 * by starting the dash at the right side of the left border
4767 * Negative dash offsets in cairo don't work
4768 * (https://bugs.freedesktop.org/show_bug.cgi?id=2729)
4770 dash_offset = - line_width / 2.;
4771 while (dash_offset < 0)
4772 dash_offset += total_length;
4774 cairo_set_dash (cr, dashes, n_dashes, dash_offset);
4780 gdk_cairo_rectangle (cr, area);
4784 cairo_rectangle (cr,
4785 x + line_width / 2.,
4786 y + line_width / 2.,
4788 height - line_width);
4797 gtk_default_draw_slider (GtkStyle *style,
4799 GtkStateType state_type,
4800 GtkShadowType shadow_type,
4803 const gchar *detail,
4808 GtkOrientation orientation)
4810 sanitize_size (window, &width, &height);
4812 gtk_paint_box (style, window, state_type, shadow_type,
4813 area, widget, detail, x, y, width, height);
4816 (strcmp ("hscale", detail) == 0 ||
4817 strcmp ("vscale", detail) == 0))
4819 if (orientation == GTK_ORIENTATION_HORIZONTAL)
4820 gtk_paint_vline (style, window, state_type, area, widget, detail,
4821 y + style->ythickness,
4822 y + height - style->ythickness - 1, x + width / 2);
4824 gtk_paint_hline (style, window, state_type, area, widget, detail,
4825 x + style->xthickness,
4826 x + width - style->xthickness - 1, y + height / 2);
4831 draw_dot (GdkWindow *window,
4838 size = CLAMP (size, 2, 3);
4842 gdk_draw_point (window, light_gc, x, y);
4843 gdk_draw_point (window, light_gc, x+1, y+1);
4847 gdk_draw_point (window, light_gc, x, y);
4848 gdk_draw_point (window, light_gc, x+1, y);
4849 gdk_draw_point (window, light_gc, x, y+1);
4850 gdk_draw_point (window, dark_gc, x+1, y+2);
4851 gdk_draw_point (window, dark_gc, x+2, y+1);
4852 gdk_draw_point (window, dark_gc, x+2, y+2);
4857 gtk_default_draw_handle (GtkStyle *style,
4859 GtkStateType state_type,
4860 GtkShadowType shadow_type,
4863 const gchar *detail,
4868 GtkOrientation orientation)
4871 gint xthick, ythick;
4872 GdkGC *light_gc, *dark_gc;
4873 GdkGC *free_me = NULL;
4878 sanitize_size (window, &width, &height);
4880 gtk_paint_box (style, window, state_type, shadow_type, area, widget,
4881 detail, x, y, width, height);
4884 if (detail && !strcmp (detail, "paned"))
4886 /* we want to ignore the shadow border in paned widgets */
4890 if (state_type == GTK_STATE_SELECTED && widget && !GTK_WIDGET_HAS_FOCUS (widget))
4892 GdkColor unfocused_light;
4894 _gtk_style_shade (&style->base[GTK_STATE_ACTIVE], &unfocused_light,
4897 light_gc = free_me = gdk_gc_new (window);
4898 gdk_gc_set_rgb_fg_color (light_gc, &unfocused_light);
4901 light_gc = style->light_gc[state_type];
4903 dark_gc = style->black_gc;
4907 xthick = style->xthickness;
4908 ythick = style->ythickness;
4910 light_gc = style->light_gc[state_type];
4911 dark_gc = style->dark_gc[state_type];
4914 rect.x = x + xthick;
4915 rect.y = y + ythick;
4916 rect.width = width - (xthick * 2);
4917 rect.height = height - (ythick * 2);
4920 intersect = gdk_rectangle_intersect (area, &rect, &dest);
4930 gdk_gc_set_clip_rectangle (light_gc, &dest);
4931 gdk_gc_set_clip_rectangle (dark_gc, &dest);
4933 if (detail && !strcmp (detail, "paned"))
4935 if (orientation == GTK_ORIENTATION_HORIZONTAL)
4936 for (xx = x + width/2 - 15; xx <= x + width/2 + 15; xx += 5)
4937 draw_dot (window, light_gc, dark_gc, xx, y + height/2 - 1, 3);
4939 for (yy = y + height/2 - 15; yy <= y + height/2 + 15; yy += 5)
4940 draw_dot (window, light_gc, dark_gc, x + width/2 - 1, yy, 3);
4944 for (yy = y + ythick; yy < (y + height - ythick); yy += 3)
4945 for (xx = x + xthick; xx < (x + width - xthick); xx += 6)
4947 draw_dot (window, light_gc, dark_gc, xx, yy, 2);
4948 draw_dot (window, light_gc, dark_gc, xx + 3, yy + 1, 2);
4952 gdk_gc_set_clip_rectangle (light_gc, NULL);
4953 gdk_gc_set_clip_rectangle (dark_gc, NULL);
4957 g_object_unref (free_me);
4961 gtk_default_draw_expander (GtkStyle *style,
4963 GtkStateType state_type,
4966 const gchar *detail,
4969 GtkExpanderStyle expander_style)
4971 #define DEFAULT_EXPANDER_SIZE 12
4975 double vertical_overshoot;
4978 double interp; /* interpolation factor for center position */
4979 double x_double_horz, y_double_horz;
4980 double x_double_vert, y_double_vert;
4981 double x_double, y_double;
4984 cairo_t *cr = gdk_cairo_create (window);
4988 gdk_cairo_rectangle (cr, area);
4993 gtk_widget_class_find_style_property (GTK_WIDGET_GET_CLASS (widget),
4996 gtk_widget_style_get (widget,
4997 "expander-size", &expander_size,
5001 expander_size = DEFAULT_EXPANDER_SIZE;
5003 line_width = MAX (1, expander_size/9);
5005 switch (expander_style)
5007 case GTK_EXPANDER_COLLAPSED:
5008 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 180 : 0;
5011 case GTK_EXPANDER_SEMI_COLLAPSED:
5012 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 150 : 30;
5015 case GTK_EXPANDER_SEMI_EXPANDED:
5016 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 120 : 60;
5019 case GTK_EXPANDER_EXPANDED:
5024 g_assert_not_reached ();
5027 /* Compute distance that the stroke extends beyonds the end
5028 * of the triangle we draw.
5030 vertical_overshoot = line_width / 2.0 * (1. / tan (G_PI / 8));
5032 /* For odd line widths, we end the vertical line of the triangle
5033 * at a half pixel, so we round differently.
5035 if (line_width % 2 == 1)
5036 vertical_overshoot = ceil (0.5 + vertical_overshoot) - 0.5;
5038 vertical_overshoot = ceil (vertical_overshoot);
5040 /* Adjust the size of the triangle we draw so that the entire stroke fits
5042 diameter = MAX (3, expander_size - 2 * vertical_overshoot);
5044 /* If the line width is odd, we want the diameter to be even,
5045 * and vice versa, so force the sum to be odd. This relationship
5046 * makes the point of the triangle look right.
5048 diameter -= (1 - (diameter + line_width) % 2);
5050 radius = diameter / 2.;
5052 /* Adjust the center so that the stroke is properly aligned with
5053 * the pixel grid. The center adjustment is different for the
5054 * horizontal and vertical orientations. For intermediate positions
5055 * we interpolate between the two.
5057 x_double_vert = floor (x - (radius + line_width) / 2.) + (radius + line_width) / 2.;
5058 y_double_vert = y - 0.5;
5060 x_double_horz = x - 0.5;
5061 y_double_horz = floor (y - (radius + line_width) / 2.) + (radius + line_width) / 2.;
5063 x_double = x_double_vert * (1 - interp) + x_double_horz * interp;
5064 y_double = y_double_vert * (1 - interp) + y_double_horz * interp;
5066 cairo_translate (cr, x_double, y_double);
5067 cairo_rotate (cr, degrees * G_PI / 180);
5069 cairo_move_to (cr, - radius / 2., - radius);
5070 cairo_line_to (cr, radius / 2., 0);
5071 cairo_line_to (cr, - radius / 2., radius);
5072 cairo_close_path (cr);
5074 cairo_set_line_width (cr, line_width);
5076 if (state_type == GTK_STATE_PRELIGHT)
5077 gdk_cairo_set_source_color (cr,
5078 &style->fg[GTK_STATE_PRELIGHT]);
5079 else if (state_type == GTK_STATE_ACTIVE)
5080 gdk_cairo_set_source_color (cr,
5081 &style->light[GTK_STATE_ACTIVE]);
5083 gdk_cairo_set_source_color (cr,
5084 &style->base[GTK_STATE_NORMAL]);
5086 cairo_fill_preserve (cr);
5088 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
5094 typedef struct _ByteRange ByteRange;
5103 range_new (guint start,
5106 ByteRange *br = g_new (ByteRange, 1);
5115 get_insensitive_layout (GdkDrawable *drawable,
5116 PangoLayout *layout)
5118 GSList *embossed_ranges = NULL;
5119 GSList *stippled_ranges = NULL;
5120 PangoLayoutIter *iter;
5121 GSList *tmp_list = NULL;
5122 PangoLayout *new_layout;
5123 PangoAttrList *attrs;
5124 GdkBitmap *stipple = NULL;
5126 iter = pango_layout_get_iter (layout);
5130 PangoLayoutRun *run;
5131 PangoAttribute *attr;
5132 gboolean need_stipple = FALSE;
5135 run = pango_layout_iter_get_run_readonly (iter);
5139 tmp_list = run->item->analysis.extra_attrs;
5141 while (tmp_list != NULL)
5143 attr = tmp_list->data;
5144 switch (attr->klass->type)
5146 case PANGO_ATTR_FOREGROUND:
5147 case PANGO_ATTR_BACKGROUND:
5148 need_stipple = TRUE;
5158 tmp_list = g_slist_next (tmp_list);
5161 br = range_new (run->item->offset, run->item->offset + run->item->length);
5164 stippled_ranges = g_slist_prepend (stippled_ranges, br);
5166 embossed_ranges = g_slist_prepend (embossed_ranges, br);
5169 while (pango_layout_iter_next_run (iter));
5171 pango_layout_iter_free (iter);
5173 new_layout = pango_layout_copy (layout);
5175 attrs = pango_layout_get_attributes (new_layout);
5179 /* Create attr list if there wasn't one */
5180 attrs = pango_attr_list_new ();
5181 pango_layout_set_attributes (new_layout, attrs);
5182 pango_attr_list_unref (attrs);
5185 tmp_list = embossed_ranges;
5186 while (tmp_list != NULL)
5188 PangoAttribute *attr;
5189 ByteRange *br = tmp_list->data;
5191 attr = gdk_pango_attr_embossed_new (TRUE);
5193 attr->start_index = br->start;
5194 attr->end_index = br->end;
5196 pango_attr_list_change (attrs, attr);
5200 tmp_list = g_slist_next (tmp_list);
5203 g_slist_free (embossed_ranges);
5205 tmp_list = stippled_ranges;
5206 while (tmp_list != NULL)
5208 PangoAttribute *attr;
5209 ByteRange *br = tmp_list->data;
5211 if (stipple == NULL)
5213 #define gray50_width 2
5214 #define gray50_height 2
5215 static const char gray50_bits[] = {
5219 stipple = gdk_bitmap_create_from_data (drawable,
5220 gray50_bits, gray50_width,
5224 attr = gdk_pango_attr_stipple_new (stipple);
5226 attr->start_index = br->start;
5227 attr->end_index = br->end;
5229 pango_attr_list_change (attrs, attr);
5233 tmp_list = g_slist_next (tmp_list);
5236 g_slist_free (stippled_ranges);
5239 g_object_unref (stipple);
5245 gtk_default_draw_layout (GtkStyle *style,
5247 GtkStateType state_type,
5251 const gchar *detail,
5254 PangoLayout *layout)
5258 gc = use_text ? style->text_gc[state_type] : style->fg_gc[state_type];
5261 gdk_gc_set_clip_rectangle (gc, area);
5263 if (state_type == GTK_STATE_INSENSITIVE)
5267 ins = get_insensitive_layout (window, layout);
5269 gdk_draw_layout (window, gc, x, y, ins);
5271 g_object_unref (ins);
5275 gdk_draw_layout (window, gc, x, y, layout);
5279 gdk_gc_set_clip_rectangle (gc, NULL);
5283 gtk_default_draw_resize_grip (GtkStyle *style,
5285 GtkStateType state_type,
5288 const gchar *detail,
5300 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
5301 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
5302 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
5308 case GDK_WINDOW_EDGE_NORTH_WEST:
5309 /* make it square */
5312 else if (height < width)
5316 case GDK_WINDOW_EDGE_NORTH:
5320 case GDK_WINDOW_EDGE_NORTH_EAST:
5321 /* make it square, aligning to top right */
5324 else if (height < width)
5326 x += (width - height);
5331 case GDK_WINDOW_EDGE_WEST:
5335 case GDK_WINDOW_EDGE_EAST:
5336 /* aligning to right */
5339 x += (width - height);
5343 case GDK_WINDOW_EDGE_SOUTH_WEST:
5344 /* make it square, aligning to bottom left */
5347 y += (height - width);
5350 else if (height < width)
5354 case GDK_WINDOW_EDGE_SOUTH:
5355 /* align to bottom */
5358 y += (height - width);
5362 case GDK_WINDOW_EDGE_SOUTH_EAST:
5363 /* make it square, aligning to bottom right */
5366 y += (height - width);
5369 else if (height < width)
5371 x += (width - height);
5377 g_assert_not_reached ();
5379 /* Clear background */
5381 for (i = 0; i < 4; i++)
5385 points[j].x = (i == 0 || i == 3) ? x : x + width;
5386 points[j].y = (i < 2) ? y : y + height;
5391 gdk_draw_polygon (window, style->bg_gc[state_type], TRUE,
5392 points, skip < 0 ? 4 : 3);
5396 case GDK_WINDOW_EDGE_WEST:
5397 case GDK_WINDOW_EDGE_EAST:
5403 while (xi < x + width)
5405 gdk_draw_line (window,
5406 style->light_gc[state_type],
5411 gdk_draw_line (window,
5412 style->dark_gc[state_type],
5420 case GDK_WINDOW_EDGE_NORTH:
5421 case GDK_WINDOW_EDGE_SOUTH:
5427 while (yi < y + height)
5429 gdk_draw_line (window,
5430 style->light_gc[state_type],
5435 gdk_draw_line (window,
5436 style->dark_gc[state_type],
5444 case GDK_WINDOW_EDGE_NORTH_WEST:
5453 gdk_draw_line (window,
5454 style->dark_gc[state_type],
5461 gdk_draw_line (window,
5462 style->dark_gc[state_type],
5469 gdk_draw_line (window,
5470 style->light_gc[state_type],
5480 case GDK_WINDOW_EDGE_NORTH_EAST:
5487 while (xi < (x + width - 3))
5489 gdk_draw_line (window,
5490 style->light_gc[state_type],
5497 gdk_draw_line (window,
5498 style->dark_gc[state_type],
5505 gdk_draw_line (window,
5506 style->dark_gc[state_type],
5515 case GDK_WINDOW_EDGE_SOUTH_WEST:
5524 gdk_draw_line (window,
5525 style->dark_gc[state_type],
5532 gdk_draw_line (window,
5533 style->dark_gc[state_type],
5540 gdk_draw_line (window,
5541 style->light_gc[state_type],
5551 case GDK_WINDOW_EDGE_SOUTH_EAST:
5558 while (xi < (x + width - 3))
5560 gdk_draw_line (window,
5561 style->light_gc[state_type],
5568 gdk_draw_line (window,
5569 style->dark_gc[state_type],
5576 gdk_draw_line (window,
5577 style->dark_gc[state_type],
5587 g_assert_not_reached ();
5593 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
5594 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
5595 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
5600 _gtk_style_shade (const GdkColor *a,
5608 red = (gdouble) a->red / 65535.0;
5609 green = (gdouble) a->green / 65535.0;
5610 blue = (gdouble) a->blue / 65535.0;
5612 rgb_to_hls (&red, &green, &blue);
5617 else if (green < 0.0)
5623 else if (blue < 0.0)
5626 hls_to_rgb (&red, &green, &blue);
5628 b->red = red * 65535.0;
5629 b->green = green * 65535.0;
5630 b->blue = blue * 65535.0;
5634 rgb_to_hls (gdouble *r,
5675 l = (max + min) / 2;
5682 s = (max - min) / (max + min);
5684 s = (max - min) / (2 - max - min);
5688 h = (green - blue) / delta;
5689 else if (green == max)
5690 h = 2 + (blue - red) / delta;
5691 else if (blue == max)
5692 h = 4 + (red - green) / delta;
5705 hls_to_rgb (gdouble *h,
5718 if (lightness <= 0.5)
5719 m2 = lightness * (1 + saturation);
5721 m2 = lightness + saturation - lightness * saturation;
5722 m1 = 2 * lightness - m2;
5724 if (saturation == 0)
5739 r = m1 + (m2 - m1) * hue / 60;
5743 r = m1 + (m2 - m1) * (240 - hue) / 60;
5754 g = m1 + (m2 - m1) * hue / 60;
5758 g = m1 + (m2 - m1) * (240 - hue) / 60;
5769 b = m1 + (m2 - m1) * hue / 60;
5773 b = m1 + (m2 - m1) * (240 - hue) / 60;
5786 * @style: a #GtkStyle
5787 * @window: a #GdkWindow
5788 * @state_type: a state
5789 * @area: rectangle to which the output is clipped, or %NULL if the
5790 * output should not be clipped
5791 * @widget: the widget (may be %NULL)
5792 * @detail: a style detail (may be %NULL)
5793 * @x1: the starting x coordinate
5794 * @x2: the ending x coordinate
5795 * @y: the y coordinate
5797 * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @window
5798 * using the given style and state.
5801 gtk_paint_hline (GtkStyle *style,
5803 GtkStateType state_type,
5804 const GdkRectangle *area,
5806 const gchar *detail,
5811 g_return_if_fail (GTK_IS_STYLE (style));
5812 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
5813 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5815 GTK_STYLE_GET_CLASS (style)->draw_hline (style, window, state_type,
5816 (GdkRectangle *) area, widget, detail,
5822 * @style: a #GtkStyle
5823 * @window: a #GdkWindow
5824 * @state_type: a state
5825 * @area: rectangle to which the output is clipped, or %NULL if the
5826 * output should not be clipped
5827 * @widget: the widget (may be %NULL)
5828 * @detail: a style detail (may be %NULL)
5829 * @y1_: the starting y coordinate
5830 * @y2_: the ending y coordinate
5831 * @x: the x coordinate
5833 * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @window
5834 * using the given style and state.
5837 gtk_paint_vline (GtkStyle *style,
5839 GtkStateType state_type,
5840 const GdkRectangle *area,
5842 const gchar *detail,
5847 g_return_if_fail (GTK_IS_STYLE (style));
5848 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
5849 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5851 GTK_STYLE_GET_CLASS (style)->draw_vline (style, window, state_type,
5852 (GdkRectangle *) area, widget, detail,
5858 * @style: a #GtkStyle
5859 * @window: a #GdkWindow
5860 * @state_type: a state
5861 * @shadow_type: type of shadow to draw
5862 * @area: clip rectangle or %NULL if the
5863 * output should not be clipped
5864 * @widget: the widget (may be %NULL)
5865 * @detail: a style detail (may be %NULL)
5866 * @x: x origin of the rectangle
5867 * @y: y origin of the rectangle
5868 * @width: width of the rectangle
5869 * @height: width of the rectangle
5871 * Draws a shadow around the given rectangle in @window
5872 * using the given style and state and shadow type.
5875 gtk_paint_shadow (GtkStyle *style,
5877 GtkStateType state_type,
5878 GtkShadowType shadow_type,
5879 const GdkRectangle *area,
5881 const gchar *detail,
5887 g_return_if_fail (GTK_IS_STYLE (style));
5888 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
5889 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5891 GTK_STYLE_GET_CLASS (style)->draw_shadow (style, window, state_type, shadow_type,
5892 (GdkRectangle *) area, widget, detail,
5893 x, y, width, height);
5897 * gtk_paint_polygon:
5898 * @style: a #GtkStyle
5899 * @window: a #GdkWindow
5900 * @state_type: a state
5901 * @shadow_type: type of shadow to draw
5902 * @area: clip rectangle, or %NULL if the
5903 * output should not be clipped
5904 * @widget: the widget (may be %NULL)
5905 * @detail: a style detail (may be %NULL)
5906 * @points: an array of #GdkPoint<!-- -->s
5907 * @n_points: length of @points
5908 * @fill: %TRUE if the polygon should be filled
5910 * Draws a polygon on @window with the given parameters.
5913 gtk_paint_polygon (GtkStyle *style,
5915 GtkStateType state_type,
5916 GtkShadowType shadow_type,
5917 const GdkRectangle *area,
5919 const gchar *detail,
5920 const GdkPoint *points,
5924 g_return_if_fail (GTK_IS_STYLE (style));
5925 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_polygon != NULL);
5926 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5928 GTK_STYLE_GET_CLASS (style)->draw_polygon (style, window, state_type, shadow_type,
5929 (GdkRectangle *) area, widget, detail,
5930 (GdkPoint *) points, n_points, fill);
5935 * @style: a #GtkStyle
5936 * @window: a #GdkWindow
5937 * @state_type: a state
5938 * @shadow_type: the type of shadow to draw
5939 * @area: clip rectangle, or %NULL if the
5940 * output should not be clipped
5941 * @widget: the widget (may be %NULL)
5942 * @detail: a style detail (may be %NULL)
5943 * @arrow_type: the type of arrow to draw
5944 * @fill: %TRUE if the arrow tip should be filled
5945 * @x: x origin of the rectangle to draw the arrow in
5946 * @y: y origin of the rectangle to draw the arrow in
5947 * @width: width of the rectangle to draw the arrow in
5948 * @height: height of the rectangle to draw the arrow in
5950 * Draws an arrow in the given rectangle on @window using the given
5951 * parameters. @arrow_type determines the direction of the arrow.
5954 gtk_paint_arrow (GtkStyle *style,
5956 GtkStateType state_type,
5957 GtkShadowType shadow_type,
5958 const GdkRectangle *area,
5960 const gchar *detail,
5961 GtkArrowType arrow_type,
5968 g_return_if_fail (GTK_IS_STYLE (style));
5969 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
5970 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5972 GTK_STYLE_GET_CLASS (style)->draw_arrow (style, window, state_type, shadow_type,
5973 (GdkRectangle *) area, widget, detail,
5974 arrow_type, fill, x, y, width, height);
5978 * gtk_paint_diamond:
5979 * @style: a #GtkStyle
5980 * @window: a #GdkWindow
5981 * @state_type: a state
5982 * @shadow_type: the type of shadow to draw
5983 * @area: clip rectangle, or %NULL if the
5984 * output should not be clipped
5985 * @widget: the widget (may be %NULL)
5986 * @detail: a style detail (may be %NULL)
5987 * @x: x origin of the rectangle to draw the diamond in
5988 * @y: y origin of the rectangle to draw the diamond in
5989 * @width: width of the rectangle to draw the diamond in
5990 * @height: height of the rectangle to draw the diamond in
5992 * Draws a diamond in the given rectangle on @window using the given
5996 gtk_paint_diamond (GtkStyle *style,
5998 GtkStateType state_type,
5999 GtkShadowType shadow_type,
6000 const GdkRectangle *area,
6002 const gchar *detail,
6008 g_return_if_fail (GTK_IS_STYLE (style));
6009 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
6010 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6012 GTK_STYLE_GET_CLASS (style)->draw_diamond (style, window, state_type, shadow_type,
6013 (GdkRectangle *) area, widget, detail,
6014 x, y, width, height);
6019 * @style: a #GtkStyle
6020 * @window: a #GdkWindow
6021 * @state_type: a state
6022 * @area: clip rectangle, or %NULL if the
6023 * output should not be clipped
6024 * @widget: the widget (may be %NULL)
6025 * @detail: a style detail (may be %NULL)
6028 * @string: the string to draw
6030 * Draws a text string on @window with the given parameters.
6032 * Deprecated: 2.0: Use gtk_paint_layout() instead.
6035 gtk_paint_string (GtkStyle *style,
6037 GtkStateType state_type,
6038 const GdkRectangle *area,
6040 const gchar *detail,
6043 const gchar *string)
6045 g_return_if_fail (GTK_IS_STYLE (style));
6046 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_string != NULL);
6047 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6049 GTK_STYLE_GET_CLASS (style)->draw_string (style, window, state_type,
6050 (GdkRectangle *) area, widget, detail,
6056 * @style: a #GtkStyle
6057 * @window: a #GdkWindow
6058 * @state_type: a state
6059 * @shadow_type: the type of shadow to draw
6060 * @area: clip rectangle, or %NULL if the
6061 * output should not be clipped
6062 * @widget: the widget (may be %NULL)
6063 * @detail: a style detail (may be %NULL)
6064 * @x: x origin of the box
6065 * @y: y origin of the box
6066 * @width: the width of the box
6067 * @height: the height of the box
6069 * Draws a box on @window with the given parameters.
6072 gtk_paint_box (GtkStyle *style,
6074 GtkStateType state_type,
6075 GtkShadowType shadow_type,
6076 const GdkRectangle *area,
6078 const gchar *detail,
6084 g_return_if_fail (GTK_IS_STYLE (style));
6085 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
6086 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6088 GTK_STYLE_GET_CLASS (style)->draw_box (style, window, state_type, shadow_type,
6089 (GdkRectangle *) area, widget, detail,
6090 x, y, width, height);
6094 * gtk_paint_flat_box:
6095 * @style: a #GtkStyle
6096 * @window: a #GdkWindow
6097 * @state_type: a state
6098 * @shadow_type: the type of shadow to draw
6099 * @area: clip rectangle, or %NULL if the
6100 * output should not be clipped
6101 * @widget: the widget (may be %NULL)
6102 * @detail: a style detail (may be %NULL)
6103 * @x: x origin of the box
6104 * @y: y origin of the box
6105 * @width: the width of the box
6106 * @height: the height of the box
6108 * Draws a flat box on @window with the given parameters.
6111 gtk_paint_flat_box (GtkStyle *style,
6113 GtkStateType state_type,
6114 GtkShadowType shadow_type,
6115 const GdkRectangle *area,
6117 const gchar *detail,
6123 g_return_if_fail (GTK_IS_STYLE (style));
6124 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
6125 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6127 GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, window, state_type, shadow_type,
6128 (GdkRectangle *) area, widget, detail,
6129 x, y, width, height);
6134 * @style: a #GtkStyle
6135 * @window: a #GdkWindow
6136 * @state_type: a state
6137 * @shadow_type: the type of shadow to draw
6138 * @area: clip rectangle, or %NULL if the
6139 * output should not be clipped
6140 * @widget: the widget (may be %NULL)
6141 * @detail: a style detail (may be %NULL)
6142 * @x: x origin of the rectangle to draw the check in
6143 * @y: y origin of the rectangle to draw the check in
6144 * @width: the width of the rectangle to draw the check in
6145 * @height: the height of the rectangle to draw the check in
6147 * Draws a check button indicator in the given rectangle on @window with
6148 * the given parameters.
6151 gtk_paint_check (GtkStyle *style,
6153 GtkStateType state_type,
6154 GtkShadowType shadow_type,
6155 const GdkRectangle *area,
6157 const gchar *detail,
6163 g_return_if_fail (GTK_IS_STYLE (style));
6164 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
6165 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6167 GTK_STYLE_GET_CLASS (style)->draw_check (style, window, state_type, shadow_type,
6168 (GdkRectangle *) area, widget, detail,
6169 x, y, width, height);
6174 * @style: a #GtkStyle
6175 * @window: a #GdkWindow
6176 * @state_type: a state
6177 * @shadow_type: the type of shadow to draw
6178 * @area: clip rectangle, or %NULL if the
6179 * output should not be clipped
6180 * @widget: the widget (may be %NULL)
6181 * @detail: a style detail (may be %NULL)
6182 * @x: x origin of the rectangle to draw the option in
6183 * @y: y origin of the rectangle to draw the option in
6184 * @width: the width of the rectangle to draw the option in
6185 * @height: the height of the rectangle to draw the option in
6187 * Draws a radio button indicator in the given rectangle on @window with
6188 * the given parameters.
6191 gtk_paint_option (GtkStyle *style,
6193 GtkStateType state_type,
6194 GtkShadowType shadow_type,
6195 const GdkRectangle *area,
6197 const gchar *detail,
6203 g_return_if_fail (GTK_IS_STYLE (style));
6204 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
6205 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6207 GTK_STYLE_GET_CLASS (style)->draw_option (style, window, state_type, shadow_type,
6208 (GdkRectangle *) area, widget, detail,
6209 x, y, width, height);
6214 * @style: a #GtkStyle
6215 * @window: a #GdkWindow
6216 * @state_type: a state
6217 * @shadow_type: the type of shadow to draw
6218 * @area: clip rectangle, or %NULL if the
6219 * output should not be clipped
6220 * @widget: the widget (may be %NULL)
6221 * @detail: a style detail (may be %NULL)
6222 * @x: x origin of the rectangle to draw the tab in
6223 * @y: y origin of the rectangle to draw the tab in
6224 * @width: the width of the rectangle to draw the tab in
6225 * @height: the height of the rectangle to draw the tab in
6227 * Draws an option menu tab (i.e. the up and down pointing arrows)
6228 * in the given rectangle on @window using the given parameters.
6231 gtk_paint_tab (GtkStyle *style,
6233 GtkStateType state_type,
6234 GtkShadowType shadow_type,
6235 const GdkRectangle *area,
6237 const gchar *detail,
6243 g_return_if_fail (GTK_IS_STYLE (style));
6244 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
6245 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6247 GTK_STYLE_GET_CLASS (style)->draw_tab (style, window, state_type, shadow_type,
6248 (GdkRectangle *) area, widget, detail,
6249 x, y, width, height);
6253 * gtk_paint_shadow_gap:
6254 * @style: a #GtkStyle
6255 * @window: a #GdkWindow
6256 * @state_type: a state
6257 * @shadow_type: type of shadow to draw
6258 * @area: clip rectangle, or %NULL if the
6259 * output should not be clipped
6260 * @widget: the widget (may be %NULL)
6261 * @detail: a style detail (may be %NULL)
6262 * @x: x origin of the rectangle
6263 * @y: y origin of the rectangle
6264 * @width: width of the rectangle
6265 * @height: width of the rectangle
6266 * @gap_side: side in which to leave the gap
6267 * @gap_x: starting position of the gap
6268 * @gap_width: width of the gap
6270 * Draws a shadow around the given rectangle in @window
6271 * using the given style and state and shadow type, leaving a
6275 gtk_paint_shadow_gap (GtkStyle *style,
6277 GtkStateType state_type,
6278 GtkShadowType shadow_type,
6279 const GdkRectangle *area,
6281 const gchar *detail,
6286 GtkPositionType gap_side,
6290 g_return_if_fail (GTK_IS_STYLE (style));
6291 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
6292 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6294 GTK_STYLE_GET_CLASS (style)->draw_shadow_gap (style, window, state_type, shadow_type,
6295 (GdkRectangle *) area, widget, detail,
6296 x, y, width, height, gap_side, gap_x, gap_width);
6301 * gtk_paint_box_gap:
6302 * @style: a #GtkStyle
6303 * @window: a #GdkWindow
6304 * @state_type: a state
6305 * @shadow_type: type of shadow to draw
6306 * @area: clip rectangle, or %NULL if the
6307 * output should not be clipped
6308 * @widget: the widget (may be %NULL)
6309 * @detail: a style detail (may be %NULL)
6310 * @x: x origin of the rectangle
6311 * @y: y origin of the rectangle
6312 * @width: width of the rectangle
6313 * @height: width of the rectangle
6314 * @gap_side: side in which to leave the gap
6315 * @gap_x: starting position of the gap
6316 * @gap_width: width of the gap
6318 * Draws a box in @window using the given style and state and shadow type,
6319 * leaving a gap in one side.
6322 gtk_paint_box_gap (GtkStyle *style,
6324 GtkStateType state_type,
6325 GtkShadowType shadow_type,
6326 const GdkRectangle *area,
6328 const gchar *detail,
6333 GtkPositionType gap_side,
6337 g_return_if_fail (GTK_IS_STYLE (style));
6338 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
6339 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6341 GTK_STYLE_GET_CLASS (style)->draw_box_gap (style, window, state_type, shadow_type,
6342 (GdkRectangle *) area, widget, detail,
6343 x, y, width, height, gap_side, gap_x, gap_width);
6347 * gtk_paint_extension:
6348 * @style: a #GtkStyle
6349 * @window: a #GdkWindow
6350 * @state_type: a state
6351 * @shadow_type: type of shadow to draw
6352 * @area: clip rectangle, or %NULL if the
6353 * output should not be clipped
6354 * @widget: the widget (may be %NULL)
6355 * @detail: a style detail (may be %NULL)
6356 * @x: x origin of the extension
6357 * @y: y origin of the extension
6358 * @width: width of the extension
6359 * @height: width of the extension
6360 * @gap_side: the side on to which the extension is attached
6362 * Draws an extension, i.e. a notebook tab.
6365 gtk_paint_extension (GtkStyle *style,
6367 GtkStateType state_type,
6368 GtkShadowType shadow_type,
6369 const GdkRectangle *area,
6371 const gchar *detail,
6376 GtkPositionType gap_side)
6378 g_return_if_fail (GTK_IS_STYLE (style));
6379 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
6380 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6382 GTK_STYLE_GET_CLASS (style)->draw_extension (style, window, state_type, shadow_type,
6383 (GdkRectangle *) area, widget, detail,
6384 x, y, width, height, gap_side);
6389 * @style: a #GtkStyle
6390 * @window: a #GdkWindow
6391 * @state_type: a state
6392 * @area: clip rectangle, or %NULL if the
6393 * output should not be clipped
6394 * @widget: the widget (may be %NULL)
6395 * @detail: a style detail (may be %NULL)
6396 * @x: the x origin of the rectangle around which to draw a focus indicator
6397 * @y: the y origin of the rectangle around which to draw a focus indicator
6398 * @width: the width of the rectangle around which to draw a focus indicator
6399 * @height: the height of the rectangle around which to draw a focus indicator
6401 * Draws a focus indicator around the given rectangle on @window using the
6405 gtk_paint_focus (GtkStyle *style,
6407 GtkStateType state_type,
6408 const GdkRectangle *area,
6410 const gchar *detail,
6416 g_return_if_fail (GTK_IS_STYLE (style));
6417 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
6418 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6420 GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, state_type,
6421 (GdkRectangle *) area, widget, detail,
6422 x, y, width, height);
6427 * @style: a #GtkStyle
6428 * @window: a #GdkWindow
6429 * @state_type: a state
6430 * @shadow_type: a shadow
6431 * @area: clip rectangle, or %NULL if the
6432 * output should not be clipped
6433 * @widget: the widget (may be %NULL)
6434 * @detail: a style detail (may be %NULL)
6435 * @x: the x origin of the rectangle in which to draw a slider
6436 * @y: the y origin of the rectangle in which to draw a slider
6437 * @width: the width of the rectangle in which to draw a slider
6438 * @height: the height of the rectangle in which to draw a slider
6439 * @orientation: the orientation to be used
6441 * Draws a slider in the given rectangle on @window using the
6442 * given style and orientation.
6445 gtk_paint_slider (GtkStyle *style,
6447 GtkStateType state_type,
6448 GtkShadowType shadow_type,
6449 const GdkRectangle *area,
6451 const gchar *detail,
6456 GtkOrientation orientation)
6458 g_return_if_fail (GTK_IS_STYLE (style));
6459 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
6460 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6462 GTK_STYLE_GET_CLASS (style)->draw_slider (style, window, state_type, shadow_type,
6463 (GdkRectangle *) area, widget, detail,
6464 x, y, width, height, orientation);
6469 * @style: a #GtkStyle
6470 * @window: a #GdkWindow
6471 * @state_type: a state
6472 * @shadow_type: type of shadow to draw
6473 * @area: clip rectangle, or %NULL if the
6474 * output should not be clipped
6475 * @widget: the widget (may be %NULL)
6476 * @detail: a style detail (may be %NULL)
6477 * @x: x origin of the handle
6478 * @y: y origin of the handle
6479 * @width: with of the handle
6480 * @height: height of the handle
6481 * @orientation: the orientation of the handle
6483 * Draws a handle as used in #GtkHandleBox and #GtkPaned.
6486 gtk_paint_handle (GtkStyle *style,
6488 GtkStateType state_type,
6489 GtkShadowType shadow_type,
6490 const GdkRectangle *area,
6492 const gchar *detail,
6497 GtkOrientation orientation)
6499 g_return_if_fail (GTK_IS_STYLE (style));
6500 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
6501 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6503 GTK_STYLE_GET_CLASS (style)->draw_handle (style, window, state_type, shadow_type,
6504 (GdkRectangle *) area, widget, detail,
6505 x, y, width, height, orientation);
6509 * gtk_paint_expander:
6510 * @style: a #GtkStyle
6511 * @window: a #GdkWindow
6512 * @state_type: a state
6513 * @area: clip rectangle, or %NULL if the
6514 * output should not be clipped
6515 * @widget: the widget (may be %NULL)
6516 * @detail: a style detail (may be %NULL)
6517 * @x: the x position to draw the expander at
6518 * @y: the y position to draw the expander at
6519 * @expander_style: the style to draw the expander in; determines
6520 * whether the expander is collapsed, expanded, or in an
6521 * intermediate state.
6523 * Draws an expander as used in #GtkTreeView. @x and @y specify the
6524 * center the expander. The size of the expander is determined by the
6525 * "expander-size" style property of @widget. (If widget is not
6526 * specified or doesn't have an "expander-size" property, an
6527 * unspecified default size will be used, since the caller doesn't
6528 * have sufficient information to position the expander, this is
6529 * likely not useful.) The expander is expander_size pixels tall
6530 * in the collapsed position and expander_size pixels wide in the
6531 * expanded position.
6534 gtk_paint_expander (GtkStyle *style,
6536 GtkStateType state_type,
6537 const GdkRectangle *area,
6539 const gchar *detail,
6542 GtkExpanderStyle expander_style)
6544 g_return_if_fail (GTK_IS_STYLE (style));
6545 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
6546 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6548 GTK_STYLE_GET_CLASS (style)->draw_expander (style, window, state_type,
6549 (GdkRectangle *) area, widget, detail,
6550 x, y, expander_style);
6555 * @style: a #GtkStyle
6556 * @window: a #GdkWindow
6557 * @state_type: a state
6558 * @use_text: whether to use the text or foreground
6559 * graphics context of @style
6560 * @area: clip rectangle, or %NULL if the
6561 * output should not be clipped
6562 * @widget: the widget (may be %NULL)
6563 * @detail: a style detail (may be %NULL)
6566 * @layout: the layout to draw
6568 * Draws a layout on @window using the given parameters.
6571 gtk_paint_layout (GtkStyle *style,
6573 GtkStateType state_type,
6575 const GdkRectangle *area,
6577 const gchar *detail,
6580 PangoLayout *layout)
6582 g_return_if_fail (GTK_IS_STYLE (style));
6583 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
6584 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6586 GTK_STYLE_GET_CLASS (style)->draw_layout (style, window, state_type, use_text,
6587 (GdkRectangle *) area, widget, detail,
6592 * gtk_paint_resize_grip:
6593 * @style: a #GtkStyle
6594 * @window: a #GdkWindow
6595 * @state_type: a state
6596 * @area: clip rectangle, or %NULL if the
6597 * output should not be clipped
6598 * @widget: the widget (may be %NULL)
6599 * @detail: a style detail (may be %NULL)
6600 * @edge: the edge in which to draw the resize grip
6601 * @x: the x origin of the rectangle in which to draw the resize grip
6602 * @y: the y origin of the rectangle in which to draw the resize grip
6603 * @width: the width of the rectangle in which to draw the resize grip
6604 * @height: the height of the rectangle in which to draw the resize grip
6606 * Draws a resize grip in the given rectangle on @window using the given
6610 gtk_paint_resize_grip (GtkStyle *style,
6612 GtkStateType state_type,
6613 const GdkRectangle *area,
6615 const gchar *detail,
6623 g_return_if_fail (GTK_IS_STYLE (style));
6624 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
6625 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6627 GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, window, state_type,
6628 (GdkRectangle *) area, widget, detail,
6629 edge, x, y, width, height);
6635 * Allocates a new #GtkBorder structure and initializes its elements to zero.
6637 * Returns: a new empty #GtkBorder. The newly allocated #GtkBorder should be
6638 * freed with gtk_border_free()
6643 gtk_border_new (void)
6645 return g_slice_new0 (GtkBorder);
6650 * @border_: a #GtkBorder.
6651 * @returns: a copy of @border_.
6653 * Copies a #GtkBorder structure.
6656 gtk_border_copy (const GtkBorder *border)
6658 g_return_val_if_fail (border != NULL, NULL);
6660 return g_slice_dup (GtkBorder, border);
6665 * @border_: a #GtkBorder.
6667 * Frees a #GtkBorder structure.
6670 gtk_border_free (GtkBorder *border)
6672 g_slice_free (GtkBorder, border);
6676 gtk_border_get_type (void)
6678 static GType our_type = 0;
6681 our_type = g_boxed_type_register_static (I_("GtkBorder"),
6682 (GBoxedCopyFunc) gtk_border_copy,
6683 (GBoxedFreeFunc) gtk_border_free);
6689 gtk_style_get_font_internal (GtkStyle *style)
6691 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
6693 if (style->private_font && style->private_font_desc)
6695 if (!style->font_desc ||
6696 !pango_font_description_equal (style->private_font_desc, style->font_desc))
6698 gdk_font_unref (style->private_font);
6699 style->private_font = NULL;
6701 if (style->private_font_desc)
6703 pango_font_description_free (style->private_font_desc);
6704 style->private_font_desc = NULL;
6709 if (!style->private_font)
6711 GdkDisplay *display;
6713 if (style->colormap)
6715 display = gdk_screen_get_display (gdk_colormap_get_screen (style->colormap));
6719 display = gdk_display_get_default ();
6720 GTK_NOTE (MULTIHEAD,
6721 g_warning ("gtk_style_get_font() should not be called on an unattached style"));
6724 if (style->font_desc)
6726 style->private_font = gdk_font_from_description_for_display (display, style->font_desc);
6727 style->private_font_desc = pango_font_description_copy (style->font_desc);
6730 if (!style->private_font)
6731 style->private_font = gdk_font_load_for_display (display, "fixed");
6733 if (!style->private_font)
6734 g_error ("Unable to load \"fixed\" font");
6737 return style->private_font;
6741 * gtk_style_get_font:
6742 * @style: a #GtkStyle
6744 * Gets the #GdkFont to use for the given style. This is
6745 * meant only as a replacement for direct access to @style->font
6746 * and should not be used in new code. New code should
6747 * use @style->font_desc instead.
6749 * Return value: the #GdkFont for the style. This font is owned
6750 * by the style; if you want to keep around a copy, you must
6751 * call gdk_font_ref().
6754 gtk_style_get_font (GtkStyle *style)
6756 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
6758 return gtk_style_get_font_internal (style);
6762 * gtk_style_set_font:
6763 * @style: a #GtkStyle.
6764 * @font: a #GdkFont, or %NULL to use the #GdkFont corresponding
6765 * to style->font_desc.
6767 * Sets the #GdkFont to use for a given style. This is
6768 * meant only as a replacement for direct access to style->font
6769 * and should not be used in new code. New code should
6770 * use style->font_desc instead.
6773 gtk_style_set_font (GtkStyle *style,
6778 g_return_if_fail (GTK_IS_STYLE (style));
6780 old_font = style->private_font;
6782 style->private_font = font;
6784 gdk_font_ref (font);
6787 gdk_font_unref (old_font);
6789 if (style->private_font_desc)
6791 pango_font_description_free (style->private_font_desc);
6792 style->private_font_desc = NULL;
6796 typedef struct _CursorInfo CursorInfo;
6802 GdkGC *secondary_gc;
6806 style_unrealize_cursor_gcs (GtkStyle *style)
6810 cursor_info = g_object_get_data (G_OBJECT (style), "gtk-style-cursor-info");
6813 if (cursor_info->primary_gc)
6814 gtk_gc_release (cursor_info->primary_gc);
6816 if (cursor_info->secondary_gc)
6817 gtk_gc_release (cursor_info->secondary_gc);
6819 g_free (cursor_info);
6820 g_object_set_data (G_OBJECT (style), I_("gtk-style-cursor-info"), NULL);
6825 make_cursor_gc (GtkWidget *widget,
6826 const gchar *property_name,
6827 const GdkColor *fallback)
6829 GdkGCValues gc_values;
6830 GdkGCValuesMask gc_values_mask;
6831 GdkColor *cursor_color;
6833 gtk_widget_style_get (widget, property_name, &cursor_color, NULL);
6835 gc_values_mask = GDK_GC_FOREGROUND;
6838 gc_values.foreground = *cursor_color;
6839 gdk_color_free (cursor_color);
6842 gc_values.foreground = *fallback;
6844 gdk_rgb_find_color (widget->style->colormap, &gc_values.foreground);
6845 return gtk_gc_get (widget->style->depth, widget->style->colormap, &gc_values, gc_values_mask);
6849 get_insertion_cursor_gc (GtkWidget *widget,
6850 gboolean is_primary)
6852 CursorInfo *cursor_info;
6854 cursor_info = g_object_get_data (G_OBJECT (widget->style), "gtk-style-cursor-info");
6857 cursor_info = g_new (CursorInfo, 1);
6858 g_object_set_data (G_OBJECT (widget->style), I_("gtk-style-cursor-info"), cursor_info);
6859 cursor_info->primary_gc = NULL;
6860 cursor_info->secondary_gc = NULL;
6861 cursor_info->for_type = G_TYPE_INVALID;
6864 /* We have to keep track of the type because gtk_widget_style_get()
6865 * can return different results when called on the same property and
6866 * same style but for different widgets. :-(. That is,
6867 * GtkEntry::cursor-color = "red" in a style will modify the cursor
6868 * color for entries but not for text view.
6870 if (cursor_info->for_type != G_OBJECT_TYPE (widget))
6872 cursor_info->for_type = G_OBJECT_TYPE (widget);
6873 if (cursor_info->primary_gc)
6875 gtk_gc_release (cursor_info->primary_gc);
6876 cursor_info->primary_gc = NULL;
6878 if (cursor_info->secondary_gc)
6880 gtk_gc_release (cursor_info->secondary_gc);
6881 cursor_info->secondary_gc = NULL;
6885 /* Cursors in text widgets are drawn only in NORMAL state,
6886 * so we can use text[GTK_STATE_NORMAL] as text color here */
6889 if (!cursor_info->primary_gc)
6890 cursor_info->primary_gc = make_cursor_gc (widget,
6892 &widget->style->text[GTK_STATE_NORMAL]);
6894 return cursor_info->primary_gc;
6898 if (!cursor_info->secondary_gc)
6899 cursor_info->secondary_gc = make_cursor_gc (widget,
6900 "secondary-cursor-color",
6901 /* text_aa is the average of text and base colors,
6902 * in usual black-on-white case it's grey. */
6903 &widget->style->text_aa[GTK_STATE_NORMAL]);
6905 return cursor_info->secondary_gc;
6910 _gtk_widget_get_cursor_gc (GtkWidget *widget)
6912 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
6913 g_return_val_if_fail (GTK_WIDGET_REALIZED (widget), NULL);
6914 return get_insertion_cursor_gc (widget, TRUE);
6918 _gtk_widget_get_cursor_color (GtkWidget *widget,
6921 GdkColor *style_color;
6923 g_return_if_fail (GTK_IS_WIDGET (widget));
6924 g_return_if_fail (color != NULL);
6926 gtk_widget_style_get (widget, "cursor-color", &style_color, NULL);
6930 *color = *style_color;
6931 gdk_color_free (style_color);
6934 *color = widget->style->text[GTK_STATE_NORMAL];
6938 draw_insertion_cursor (GtkWidget *widget,
6939 GdkDrawable *drawable,
6941 const GdkRectangle *location,
6942 GtkTextDirection direction,
6943 gboolean draw_arrow)
6949 gfloat cursor_aspect_ratio;
6952 /* When changing the shape or size of the cursor here,
6953 * propagate the changes to gtktextview.c:text_window_invalidate_cursors().
6956 gtk_widget_style_get (widget, "cursor-aspect-ratio", &cursor_aspect_ratio, NULL);
6958 stem_width = location->height * cursor_aspect_ratio + 1;
6959 arrow_width = stem_width + 1;
6961 /* put (stem_width % 2) on the proper side of the cursor */
6962 if (direction == GTK_TEXT_DIR_LTR)
6963 offset = stem_width / 2;
6965 offset = stem_width - stem_width / 2;
6967 for (i = 0; i < stem_width; i++)
6968 gdk_draw_line (drawable, gc,
6969 location->x + i - offset, location->y,
6970 location->x + i - offset, location->y + location->height - 1);
6974 if (direction == GTK_TEXT_DIR_RTL)
6976 x = location->x - offset - 1;
6977 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
6979 for (i = 0; i < arrow_width; i++)
6981 gdk_draw_line (drawable, gc,
6983 x, y + 2 * arrow_width - i - 1);
6987 else if (direction == GTK_TEXT_DIR_LTR)
6989 x = location->x + stem_width - offset;
6990 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
6992 for (i = 0; i < arrow_width; i++)
6994 gdk_draw_line (drawable, gc,
6996 x, y + 2 * arrow_width - i - 1);
7004 * gtk_draw_insertion_cursor:
7005 * @widget: a #GtkWidget
7006 * @drawable: a #GdkDrawable
7007 * @area: rectangle to which the output is clipped, or %NULL if the
7008 * output should not be clipped
7009 * @location: location where to draw the cursor (@location->width is ignored)
7010 * @is_primary: if the cursor should be the primary cursor color.
7011 * @direction: whether the cursor is left-to-right or
7012 * right-to-left. Should never be #GTK_TEXT_DIR_NONE
7013 * @draw_arrow: %TRUE to draw a directional arrow on the
7014 * cursor. Should be %FALSE unless the cursor is split.
7016 * Draws a text caret on @drawable at @location. This is not a style function
7017 * but merely a convenience function for drawing the standard cursor shape.
7022 gtk_draw_insertion_cursor (GtkWidget *widget,
7023 GdkDrawable *drawable,
7024 const GdkRectangle *area,
7025 const GdkRectangle *location,
7026 gboolean is_primary,
7027 GtkTextDirection direction,
7028 gboolean draw_arrow)
7032 g_return_if_fail (GTK_IS_WIDGET (widget));
7033 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
7034 g_return_if_fail (location != NULL);
7035 g_return_if_fail (direction != GTK_TEXT_DIR_NONE);
7037 gc = get_insertion_cursor_gc (widget, is_primary);
7039 gdk_gc_set_clip_rectangle (gc, area);
7041 draw_insertion_cursor (widget, drawable, gc,
7042 location, direction, draw_arrow);
7045 gdk_gc_set_clip_rectangle (gc, NULL);
7048 #define __GTK_STYLE_C__
7049 #include "gtkaliasdef.c"