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/.
32 #include "gtkmarshalers.h"
33 #undef GTK_DISABLE_DEPRECATED
34 #include "gtkoptionmenu.h"
36 #include "gtkspinbutton.h"
38 #include "gtkwidget.h"
39 #include "gtkthemes.h"
40 #include "gtkiconfactory.h"
41 #include "gtksettings.h" /* _gtk_settings_parse_convert() */
45 #define LIGHTNESS_MULT 1.3
46 #define DARKNESS_MULT 0.7
48 /* --- typedefs & structures --- */
55 #define GTK_STYLE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_STYLE, GtkStylePrivate))
57 typedef struct _GtkStylePrivate GtkStylePrivate;
59 struct _GtkStylePrivate {
63 /* --- prototypes --- */
64 static void gtk_style_finalize (GObject *object);
65 static void gtk_style_realize (GtkStyle *style,
66 GdkColormap *colormap);
67 static void gtk_style_real_realize (GtkStyle *style);
68 static void gtk_style_real_unrealize (GtkStyle *style);
69 static void gtk_style_real_copy (GtkStyle *style,
71 static void gtk_style_real_set_background (GtkStyle *style,
73 GtkStateType state_type);
74 static GtkStyle *gtk_style_real_clone (GtkStyle *style);
75 static void gtk_style_real_init_from_rc (GtkStyle *style,
76 GtkRcStyle *rc_style);
77 static GdkPixbuf *gtk_default_render_icon (GtkStyle *style,
78 const GtkIconSource *source,
79 GtkTextDirection direction,
84 static void gtk_default_draw_hline (GtkStyle *style,
86 GtkStateType state_type,
93 static void gtk_default_draw_vline (GtkStyle *style,
95 GtkStateType state_type,
102 static void gtk_default_draw_shadow (GtkStyle *style,
104 GtkStateType state_type,
105 GtkShadowType shadow_type,
113 static void gtk_default_draw_polygon (GtkStyle *style,
115 GtkStateType state_type,
116 GtkShadowType shadow_type,
123 static void gtk_default_draw_arrow (GtkStyle *style,
125 GtkStateType state_type,
126 GtkShadowType shadow_type,
130 GtkArrowType arrow_type,
136 static void gtk_default_draw_diamond (GtkStyle *style,
138 GtkStateType state_type,
139 GtkShadowType shadow_type,
147 static void gtk_default_draw_string (GtkStyle *style,
149 GtkStateType state_type,
155 const gchar *string);
156 static void gtk_default_draw_box (GtkStyle *style,
158 GtkStateType state_type,
159 GtkShadowType shadow_type,
167 static void gtk_default_draw_flat_box (GtkStyle *style,
169 GtkStateType state_type,
170 GtkShadowType shadow_type,
178 static void gtk_default_draw_check (GtkStyle *style,
180 GtkStateType state_type,
181 GtkShadowType shadow_type,
189 static void gtk_default_draw_option (GtkStyle *style,
191 GtkStateType state_type,
192 GtkShadowType shadow_type,
200 static void gtk_default_draw_tab (GtkStyle *style,
202 GtkStateType state_type,
203 GtkShadowType shadow_type,
211 static void gtk_default_draw_shadow_gap (GtkStyle *style,
213 GtkStateType state_type,
214 GtkShadowType shadow_type,
222 GtkPositionType gap_side,
225 static void gtk_default_draw_box_gap (GtkStyle *style,
227 GtkStateType state_type,
228 GtkShadowType shadow_type,
236 GtkPositionType gap_side,
239 static void gtk_default_draw_extension (GtkStyle *style,
241 GtkStateType state_type,
242 GtkShadowType shadow_type,
250 GtkPositionType gap_side);
251 static void gtk_default_draw_focus (GtkStyle *style,
253 GtkStateType state_type,
261 static void gtk_default_draw_slider (GtkStyle *style,
263 GtkStateType state_type,
264 GtkShadowType shadow_type,
272 GtkOrientation orientation);
273 static void gtk_default_draw_handle (GtkStyle *style,
275 GtkStateType state_type,
276 GtkShadowType shadow_type,
284 GtkOrientation orientation);
285 static void gtk_default_draw_expander (GtkStyle *style,
287 GtkStateType state_type,
293 GtkExpanderStyle expander_style);
294 static void gtk_default_draw_layout (GtkStyle *style,
296 GtkStateType state_type,
303 PangoLayout *layout);
304 static void gtk_default_draw_resize_grip (GtkStyle *style,
306 GtkStateType state_type,
316 static void rgb_to_hls (gdouble *r,
319 static void hls_to_rgb (gdouble *h,
323 static void style_unrealize_cursor_gcs (GtkStyle *style);
325 static GdkFont *gtk_style_get_font_internal (GtkStyle *style);
328 * Data for default check and radio buttons
331 static const GtkRequisition default_option_indicator_size = { 7, 13 };
332 static const GtkBorder default_option_indicator_spacing = { 7, 5, 2, 2 };
334 #define GTK_GRAY 0xdcdc, 0xdada, 0xd5d5
335 #define GTK_DARK_GRAY 0xc4c4, 0xc2c2, 0xbdbd
336 #define GTK_LIGHT_GRAY 0xeeee, 0xebeb, 0xe7e7
337 #define GTK_WHITE 0xffff, 0xffff, 0xffff
338 #define GTK_BLUE 0x4b4b, 0x6969, 0x8383
339 #define GTK_VERY_DARK_GRAY 0x9c9c, 0x9a9a, 0x9494
340 #define GTK_BLACK 0x0000, 0x0000, 0x0000
341 #define GTK_WEAK_GRAY 0x7530, 0x7530, 0x7530
343 /* --- variables --- */
344 static const GdkColor gtk_default_normal_fg = { 0, GTK_BLACK };
345 static const GdkColor gtk_default_active_fg = { 0, GTK_BLACK };
346 static const GdkColor gtk_default_prelight_fg = { 0, GTK_BLACK };
347 static const GdkColor gtk_default_selected_fg = { 0, GTK_WHITE };
348 static const GdkColor gtk_default_insensitive_fg = { 0, GTK_WEAK_GRAY };
350 static const GdkColor gtk_default_normal_bg = { 0, GTK_GRAY };
351 static const GdkColor gtk_default_active_bg = { 0, GTK_DARK_GRAY };
352 static const GdkColor gtk_default_prelight_bg = { 0, GTK_LIGHT_GRAY };
353 static const GdkColor gtk_default_selected_bg = { 0, GTK_BLUE };
354 static const GdkColor gtk_default_insensitive_bg = { 0, GTK_GRAY };
355 static const GdkColor gtk_default_selected_base = { 0, GTK_BLUE };
356 static const GdkColor gtk_default_active_base = { 0, GTK_VERY_DARK_GRAY };
358 /* --- signals --- */
359 static guint realize_signal = 0;
360 static guint unrealize_signal = 0;
362 G_DEFINE_TYPE (GtkStyle, gtk_style, G_TYPE_OBJECT)
364 /* --- functions --- */
367 * _gtk_style_init_for_settings:
368 * @style: a #GtkStyle
369 * @settings: a #GtkSettings
371 * Initializes the font description in @style according to the default
372 * font name of @settings. This is called for gtk_style_new() with
373 * the settings for the default screen (if any); if we are creating
374 * a style for a particular screen, we then call it again in a
375 * location where we know the correct settings.
376 * The reason for this is that gtk_rc_style_create_style() doesn't
377 * take the screen for an argument.
380 _gtk_style_init_for_settings (GtkStyle *style,
381 GtkSettings *settings)
383 const gchar *font_name = _gtk_rc_context_get_default_font_name (settings);
385 if (style->font_desc)
386 pango_font_description_free (style->font_desc);
388 style->font_desc = pango_font_description_from_string (font_name);
390 if (!pango_font_description_get_family (style->font_desc))
392 g_warning ("Default font does not have a family set");
393 pango_font_description_set_family (style->font_desc, "Sans");
395 if (pango_font_description_get_size (style->font_desc) <= 0)
397 g_warning ("Default font does not have a positive size");
398 pango_font_description_set_size (style->font_desc, 10 * PANGO_SCALE);
403 gtk_style_init (GtkStyle *style)
407 GtkSettings *settings = gtk_settings_get_default ();
410 _gtk_style_init_for_settings (style, settings);
412 style->font_desc = pango_font_description_from_string ("Sans 10");
414 style->attach_count = 0;
415 style->colormap = NULL;
418 style->black.red = 0;
419 style->black.green = 0;
420 style->black.blue = 0;
422 style->white.red = 65535;
423 style->white.green = 65535;
424 style->white.blue = 65535;
426 style->black_gc = NULL;
427 style->white_gc = NULL;
429 style->fg[GTK_STATE_NORMAL] = gtk_default_normal_fg;
430 style->fg[GTK_STATE_ACTIVE] = gtk_default_active_fg;
431 style->fg[GTK_STATE_PRELIGHT] = gtk_default_prelight_fg;
432 style->fg[GTK_STATE_SELECTED] = gtk_default_selected_fg;
433 style->fg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
435 style->bg[GTK_STATE_NORMAL] = gtk_default_normal_bg;
436 style->bg[GTK_STATE_ACTIVE] = gtk_default_active_bg;
437 style->bg[GTK_STATE_PRELIGHT] = gtk_default_prelight_bg;
438 style->bg[GTK_STATE_SELECTED] = gtk_default_selected_bg;
439 style->bg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_bg;
441 for (i = 0; i < 4; i++)
443 style->text[i] = style->fg[i];
444 style->base[i] = style->white;
447 style->base[GTK_STATE_SELECTED] = gtk_default_selected_base;
448 style->text[GTK_STATE_SELECTED] = style->white;
449 style->base[GTK_STATE_ACTIVE] = gtk_default_active_base;
450 style->text[GTK_STATE_ACTIVE] = style->white;
451 style->base[GTK_STATE_INSENSITIVE] = gtk_default_prelight_bg;
452 style->text[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
454 for (i = 0; i < 5; i++)
455 style->bg_pixmap[i] = NULL;
457 style->rc_style = NULL;
459 for (i = 0; i < 5; i++)
461 style->fg_gc[i] = NULL;
462 style->bg_gc[i] = NULL;
463 style->light_gc[i] = NULL;
464 style->dark_gc[i] = NULL;
465 style->mid_gc[i] = NULL;
466 style->text_gc[i] = NULL;
467 style->base_gc[i] = NULL;
468 style->text_aa_gc[i] = NULL;
471 style->xthickness = 2;
472 style->ythickness = 2;
474 style->property_cache = NULL;
478 gtk_style_class_init (GtkStyleClass *klass)
480 GObjectClass *object_class = G_OBJECT_CLASS (klass);
482 object_class->finalize = gtk_style_finalize;
484 klass->clone = gtk_style_real_clone;
485 klass->copy = gtk_style_real_copy;
486 klass->init_from_rc = gtk_style_real_init_from_rc;
487 klass->realize = gtk_style_real_realize;
488 klass->unrealize = gtk_style_real_unrealize;
489 klass->set_background = gtk_style_real_set_background;
490 klass->render_icon = gtk_default_render_icon;
492 klass->draw_hline = gtk_default_draw_hline;
493 klass->draw_vline = gtk_default_draw_vline;
494 klass->draw_shadow = gtk_default_draw_shadow;
495 klass->draw_polygon = gtk_default_draw_polygon;
496 klass->draw_arrow = gtk_default_draw_arrow;
497 klass->draw_diamond = gtk_default_draw_diamond;
498 klass->draw_string = gtk_default_draw_string;
499 klass->draw_box = gtk_default_draw_box;
500 klass->draw_flat_box = gtk_default_draw_flat_box;
501 klass->draw_check = gtk_default_draw_check;
502 klass->draw_option = gtk_default_draw_option;
503 klass->draw_tab = gtk_default_draw_tab;
504 klass->draw_shadow_gap = gtk_default_draw_shadow_gap;
505 klass->draw_box_gap = gtk_default_draw_box_gap;
506 klass->draw_extension = gtk_default_draw_extension;
507 klass->draw_focus = gtk_default_draw_focus;
508 klass->draw_slider = gtk_default_draw_slider;
509 klass->draw_handle = gtk_default_draw_handle;
510 klass->draw_expander = gtk_default_draw_expander;
511 klass->draw_layout = gtk_default_draw_layout;
512 klass->draw_resize_grip = gtk_default_draw_resize_grip;
514 g_type_class_add_private (object_class, sizeof (GtkStylePrivate));
518 * @style: the object which received the signal
520 * Emitted when the style has been initialized for a particular
521 * colormap and depth. Connecting to this signal is probably seldom
522 * useful since most of the time applications and widgets only
523 * deal with styles that have been already realized.
527 realize_signal = g_signal_new (I_("realize"),
528 G_TYPE_FROM_CLASS (object_class),
530 G_STRUCT_OFFSET (GtkStyleClass, realize),
532 _gtk_marshal_VOID__VOID,
535 * GtkStyle::unrealize:
536 * @style: the object which received the signal
538 * Emitted when the aspects of the style specific to a particular colormap
539 * and depth are being cleaned up. A connection to this signal can be useful
540 * if a widget wants to cache objects like a #GdkGC as object data on #GtkStyle.
541 * This signal provides a convenient place to free such cached objects.
545 unrealize_signal = g_signal_new (I_("unrealize"),
546 G_TYPE_FROM_CLASS (object_class),
548 G_STRUCT_OFFSET (GtkStyleClass, unrealize),
550 _gtk_marshal_VOID__VOID,
555 clear_property_cache (GtkStyle *style)
557 if (style->property_cache)
561 for (i = 0; i < style->property_cache->len; i++)
563 PropertyValue *node = &g_array_index (style->property_cache, PropertyValue, i);
565 g_param_spec_unref (node->pspec);
566 g_value_unset (&node->value);
568 g_array_free (style->property_cache, TRUE);
569 style->property_cache = NULL;
574 gtk_style_finalize (GObject *object)
576 GtkStyle *style = GTK_STYLE (object);
577 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
579 g_return_if_fail (style->attach_count == 0);
581 clear_property_cache (style);
583 /* All the styles in the list have the same
584 * style->styles pointer. If we delete the
585 * *first* style from the list, we need to update
586 * the style->styles pointers from all the styles.
587 * Otherwise we simply remove the node from
592 if (style->styles->data != style)
593 g_slist_remove (style->styles, style);
596 GSList *tmp_list = style->styles->next;
600 GTK_STYLE (tmp_list->data)->styles = style->styles->next;
601 tmp_list = tmp_list->next;
603 g_slist_free_1 (style->styles);
607 g_slist_foreach (style->icon_factories, (GFunc) g_object_unref, NULL);
608 g_slist_free (style->icon_factories);
610 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_unref, NULL);
611 g_slist_free (priv->color_hashes);
613 pango_font_description_free (style->font_desc);
615 if (style->private_font)
616 gdk_font_unref (style->private_font);
618 if (style->private_font_desc)
619 pango_font_description_free (style->private_font_desc);
622 gtk_rc_style_unref (style->rc_style);
624 G_OBJECT_CLASS (gtk_style_parent_class)->finalize (object);
629 gtk_style_copy (GtkStyle *style)
633 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
635 new_style = GTK_STYLE_GET_CLASS (style)->clone (style);
636 GTK_STYLE_GET_CLASS (style)->copy (new_style, style);
642 gtk_style_duplicate (GtkStyle *style)
646 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
648 new_style = gtk_style_copy (style);
650 /* All the styles in the list have the same
651 * style->styles pointer. When we insert a new
652 * style, we append it to the list to avoid having
653 * to update the existing ones.
655 style->styles = g_slist_append (style->styles, new_style);
656 new_style->styles = style->styles;
663 * @returns: a new #GtkStyle.
665 * Creates a new #GtkStyle.
672 style = g_object_new (GTK_TYPE_STYLE, NULL);
679 * @style: a #GtkStyle.
680 * @window: a #GdkWindow.
681 * @returns: Either @style, or a newly-created #GtkStyle.
682 * If the style is newly created, the style parameter
683 * will be dereferenced, and the new style will have
684 * a reference count belonging to the caller.
686 * Attaches a style to a window; this process allocates the
687 * colors and creates the GC's for the style - it specializes
688 * it to a particular visual and colormap. The process may
689 * involve the creation of a new style if the style has already
690 * been attached to a window with a different style and colormap.
692 * Since this function may return a new object, you have to use it
693 * in the following way:
694 * <literal>style = gtk_style_attach (style, window)</literal>
697 gtk_style_attach (GtkStyle *style,
701 GtkStyle *new_style = NULL;
702 GdkColormap *colormap;
704 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
705 g_return_val_if_fail (window != NULL, NULL);
707 colormap = gdk_drawable_get_colormap (window);
710 style->styles = g_slist_append (NULL, style);
712 styles = style->styles;
715 new_style = styles->data;
717 if (new_style->colormap == colormap)
721 styles = styles->next;
726 styles = style->styles;
730 new_style = styles->data;
732 if (new_style->attach_count == 0)
734 gtk_style_realize (new_style, colormap);
739 styles = styles->next;
745 new_style = gtk_style_duplicate (style);
746 if (gdk_colormap_get_screen (style->colormap) != gdk_colormap_get_screen (colormap) &&
747 new_style->private_font)
749 gdk_font_unref (new_style->private_font);
750 new_style->private_font = NULL;
752 gtk_style_realize (new_style, colormap);
755 /* A style gets a refcount from being attached */
756 if (new_style->attach_count == 0)
757 g_object_ref (new_style);
759 /* Another refcount belongs to the parent */
760 if (style != new_style)
762 g_object_unref (style);
763 g_object_ref (new_style);
766 new_style->attach_count++;
773 * @style: a #GtkStyle
775 * Detaches a style from a window. If the style is not attached
776 * to any windows anymore, it is unrealized. See gtk_style_attach().
780 gtk_style_detach (GtkStyle *style)
782 g_return_if_fail (GTK_IS_STYLE (style));
783 g_return_if_fail (style->attach_count > 0);
785 style->attach_count -= 1;
786 if (style->attach_count == 0)
788 g_signal_emit (style, unrealize_signal, 0);
790 g_object_unref (style->colormap);
791 style->colormap = NULL;
793 if (style->private_font_desc)
795 if (style->private_font)
797 gdk_font_unref (style->private_font);
798 style->private_font = NULL;
801 pango_font_description_free (style->private_font_desc);
802 style->private_font_desc = NULL;
805 g_object_unref (style);
811 * @style: a #GtkStyle.
814 * Deprecated equivalent of g_object_ref().
817 gtk_style_ref (GtkStyle *style)
819 return (GtkStyle *) g_object_ref (style);
824 * @style: a #GtkStyle.
826 * Deprecated equivalent of g_object_unref().
829 gtk_style_unref (GtkStyle *style)
831 g_object_unref (style);
835 gtk_style_realize (GtkStyle *style,
836 GdkColormap *colormap)
838 style->colormap = g_object_ref (colormap);
839 style->depth = gdk_colormap_get_visual (colormap)->depth;
841 g_signal_emit (style, realize_signal, 0);
845 gtk_style_lookup_icon_set (GtkStyle *style,
846 const char *stock_id)
850 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
851 g_return_val_if_fail (stock_id != NULL, NULL);
853 iter = style->icon_factories;
856 GtkIconSet *icon_set = gtk_icon_factory_lookup (GTK_ICON_FACTORY (iter->data),
861 iter = g_slist_next (iter);
864 return gtk_icon_factory_lookup_default (stock_id);
868 * gtk_style_lookup_color:
869 * @style: a #GtkStyle
870 * @color_name: the name of the logical color to look up
871 * @color: the #GdkColor to fill in
873 * Looks up @color_name in the style's logical color mappings,
874 * filling in @color and returning %TRUE if found, otherwise
875 * returning %FALSE. Do not cache the found mapping, because
876 * it depends on the #GtkStyle and might change when a theme
879 * Return value: %TRUE if the mapping was found.
884 gtk_style_lookup_color (GtkStyle *style,
885 const char *color_name,
888 GtkStylePrivate *priv;
891 g_return_val_if_fail (GTK_IS_STYLE (style), FALSE);
892 g_return_val_if_fail (color_name != NULL, FALSE);
893 g_return_val_if_fail (color != NULL, FALSE);
895 priv = GTK_STYLE_GET_PRIVATE (style);
897 for (iter = priv->color_hashes; iter != NULL; iter = iter->next)
899 GHashTable *hash = iter->data;
900 GdkColor *mapping = g_hash_table_lookup (hash, color_name);
904 color->red = mapping->red;
905 color->green = mapping->green;
906 color->blue = mapping->blue;
916 * @style: a #GtkStyle
917 * @window: a #GdkWindow
918 * @state_type: a state
919 * @x1: the starting x coordinate
920 * @x2: the ending x coordinate
921 * @y: the y coordinate
923 * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @window
924 * using the given style and state.
926 * Deprecated: Use gtk_paint_hline() instead.
929 gtk_draw_hline (GtkStyle *style,
931 GtkStateType state_type,
936 g_return_if_fail (GTK_IS_STYLE (style));
937 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
939 GTK_STYLE_GET_CLASS (style)->draw_hline (style, window, state_type, NULL, NULL, NULL, x1, x2, y);
945 * @style: a #GtkStyle
946 * @window: a #GdkWindow
947 * @state_type: a state
948 * @y1_: the starting y coordinate
949 * @y2_: the ending y coordinate
950 * @x: the x coordinate
952 * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @window
953 * using the given style and state.
955 * Deprecated: Use gtk_paint_vline() instead.
958 gtk_draw_vline (GtkStyle *style,
960 GtkStateType state_type,
965 g_return_if_fail (GTK_IS_STYLE (style));
966 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
968 GTK_STYLE_GET_CLASS (style)->draw_vline (style, window, state_type, NULL, NULL, NULL, y1_, y2_, x);
973 * @style: a #GtkStyle
974 * @window: a #GdkWindow
975 * @state_type: a state
976 * @shadow_type: type of shadow to draw
977 * @x: x origin of the rectangle
978 * @y: y origin of the rectangle
979 * @width: width of the rectangle
980 * @height: width of the rectangle
982 * Draws a shadow around the given rectangle in @window
983 * using the given style and state and shadow type.
985 * Deprecated: Use gtk_paint_shadow() instead.
988 gtk_draw_shadow (GtkStyle *style,
990 GtkStateType state_type,
991 GtkShadowType shadow_type,
997 g_return_if_fail (GTK_IS_STYLE (style));
998 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
1000 GTK_STYLE_GET_CLASS (style)->draw_shadow (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1005 * @style: a #GtkStyle
1006 * @window: a #GdkWindow
1007 * @state_type: a state
1008 * @shadow_type: type of shadow to draw
1009 * @points: an array of #GdkPoint<!-- -->s
1010 * @npoints: length of @points
1011 * @fill: %TRUE if the polygon should be filled
1013 * Draws a polygon on @window with the given parameters.
1015 * Deprecated: Use gtk_paint_polygon() instead.
1018 gtk_draw_polygon (GtkStyle *style,
1020 GtkStateType state_type,
1021 GtkShadowType shadow_type,
1026 g_return_if_fail (GTK_IS_STYLE (style));
1027 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_polygon != NULL);
1029 GTK_STYLE_GET_CLASS (style)->draw_polygon (style, window, state_type, shadow_type, NULL, NULL, NULL, points, npoints, fill);
1034 * @style: a #GtkStyle
1035 * @window: a #GdkWindow
1036 * @state_type: a state
1037 * @shadow_type: the type of shadow to draw
1038 * @arrow_type: the type of arrow to draw
1039 * @fill: %TRUE if the arrow tip should be filled
1040 * @x: x origin of the rectangle to draw the arrow in
1041 * @y: y origin of the rectangle to draw the arrow in
1042 * @width: width of the rectangle to draw the arrow in
1043 * @height: height of the rectangle to draw the arrow in
1045 * Draws an arrow in the given rectangle on @window using the given
1046 * parameters. @arrow_type determines the direction of the arrow.
1048 * Deprecated: Use gtk_paint_arrow() instead.
1051 gtk_draw_arrow (GtkStyle *style,
1053 GtkStateType state_type,
1054 GtkShadowType shadow_type,
1055 GtkArrowType arrow_type,
1062 g_return_if_fail (GTK_IS_STYLE (style));
1063 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
1065 GTK_STYLE_GET_CLASS (style)->draw_arrow (style, window, state_type, shadow_type, NULL, NULL, NULL, arrow_type, fill, x, y, width, height);
1070 * @style: a #GtkStyle
1071 * @window: a #GdkWindow
1072 * @state_type: a state
1073 * @shadow_type: the type of shadow to draw
1074 * @x: x origin of the rectangle to draw the diamond in
1075 * @y: y origin of the rectangle to draw the diamond in
1076 * @width: width of the rectangle to draw the diamond in
1077 * @height: height of the rectangle to draw the diamond in
1079 * Draws a diamond in the given rectangle on @window using the given
1082 * Deprecated: Use gtk_paint_diamond() instead.
1085 gtk_draw_diamond (GtkStyle *style,
1087 GtkStateType state_type,
1088 GtkShadowType shadow_type,
1094 g_return_if_fail (GTK_IS_STYLE (style));
1095 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
1097 GTK_STYLE_GET_CLASS (style)->draw_diamond (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1102 * @style: a #GtkStyle
1103 * @window: a #GdkWindow
1104 * @state_type: a state
1107 * @string: the string to draw
1109 * Draws a text string on @window with the given parameters.
1111 * Deprecated: Use gtk_paint_layout() instead.
1114 gtk_draw_string (GtkStyle *style,
1116 GtkStateType state_type,
1119 const gchar *string)
1121 g_return_if_fail (GTK_IS_STYLE (style));
1122 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_string != NULL);
1124 GTK_STYLE_GET_CLASS (style)->draw_string (style, window, state_type, NULL, NULL, NULL, x, y, string);
1129 * @style: a #GtkStyle
1130 * @window: a #GdkWindow
1131 * @state_type: a state
1132 * @shadow_type: the type of shadow to draw
1133 * @x: x origin of the box
1134 * @y: y origin of the box
1135 * @width: the width of the box
1136 * @height: the height of the box
1138 * Draws a box on @window with the given parameters.
1140 * Deprecated: Use gtk_paint_box() instead.
1143 gtk_draw_box (GtkStyle *style,
1145 GtkStateType state_type,
1146 GtkShadowType shadow_type,
1152 g_return_if_fail (GTK_IS_STYLE (style));
1153 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
1155 GTK_STYLE_GET_CLASS (style)->draw_box (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1159 * gtk_draw_flat_box:
1160 * @style: a #GtkStyle
1161 * @window: a #GdkWindow
1162 * @state_type: a state
1163 * @shadow_type: the type of shadow to draw
1164 * @x: x origin of the box
1165 * @y: y origin of the box
1166 * @width: the width of the box
1167 * @height: the height of the box
1169 * Draws a flat box on @window with the given parameters.
1171 * Deprecated: Use gtk_paint_flat_box() instead.
1174 gtk_draw_flat_box (GtkStyle *style,
1176 GtkStateType state_type,
1177 GtkShadowType shadow_type,
1183 g_return_if_fail (GTK_IS_STYLE (style));
1184 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
1186 GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1191 * @style: a #GtkStyle
1192 * @window: a #GdkWindow
1193 * @state_type: a state
1194 * @shadow_type: the type of shadow to draw
1195 * @x: x origin of the rectangle to draw the check in
1196 * @y: y origin of the rectangle to draw the check in
1197 * @width: the width of the rectangle to draw the check in
1198 * @height: the height of the rectangle to draw the check in
1200 * Draws a check button indicator in the given rectangle on @window with
1201 * the given parameters.
1203 * Deprecated: Use gtk_paint_check() instead.
1206 gtk_draw_check (GtkStyle *style,
1208 GtkStateType state_type,
1209 GtkShadowType shadow_type,
1215 g_return_if_fail (GTK_IS_STYLE (style));
1216 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
1218 GTK_STYLE_GET_CLASS (style)->draw_check (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1223 * @style: a #GtkStyle
1224 * @window: a #GdkWindow
1225 * @state_type: a state
1226 * @shadow_type: the type of shadow to draw
1227 * @x: x origin of the rectangle to draw the option in
1228 * @y: y origin of the rectangle to draw the option in
1229 * @width: the width of the rectangle to draw the option in
1230 * @height: the height of the rectangle to draw the option in
1232 * Draws a radio button indicator in the given rectangle on @window with
1233 * the given parameters.
1235 * Deprecated: Use gtk_paint_option() instead.
1238 gtk_draw_option (GtkStyle *style,
1240 GtkStateType state_type,
1241 GtkShadowType shadow_type,
1247 g_return_if_fail (GTK_IS_STYLE (style));
1248 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
1250 GTK_STYLE_GET_CLASS (style)->draw_option (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1255 * @style: a #GtkStyle
1256 * @window: a #GdkWindow
1257 * @state_type: a state
1258 * @shadow_type: the type of shadow to draw
1259 * @x: x origin of the rectangle to draw the tab in
1260 * @y: y origin of the rectangle to draw the tab in
1261 * @width: the width of the rectangle to draw the tab in
1262 * @height: the height of the rectangle to draw the tab in
1264 * Draws an option menu tab (i.e. the up and down pointing arrows)
1265 * in the given rectangle on @window using the given parameters.
1267 * Deprecated: Use gtk_paint_tab() instead.
1270 gtk_draw_tab (GtkStyle *style,
1272 GtkStateType state_type,
1273 GtkShadowType shadow_type,
1279 g_return_if_fail (GTK_IS_STYLE (style));
1280 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
1282 GTK_STYLE_GET_CLASS (style)->draw_tab (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1286 * gtk_draw_shadow_gap:
1287 * @style: a #GtkStyle
1288 * @window: a #GdkWindow
1289 * @state_type: a state
1290 * @shadow_type: type of shadow to draw
1291 * @x: x origin of the rectangle
1292 * @y: y origin of the rectangle
1293 * @width: width of the rectangle
1294 * @height: width of the rectangle
1295 * @gap_side: side in which to leave the gap
1296 * @gap_x: starting position of the gap
1297 * @gap_width: width of the gap
1299 * Draws a shadow around the given rectangle in @window
1300 * using the given style and state and shadow type, leaving a
1303 * Deprecated: Use gtk_paint_shadow_gap() instead.
1306 gtk_draw_shadow_gap (GtkStyle *style,
1308 GtkStateType state_type,
1309 GtkShadowType shadow_type,
1314 GtkPositionType gap_side,
1318 g_return_if_fail (GTK_IS_STYLE (style));
1319 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
1321 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);
1326 * @style: a #GtkStyle
1327 * @window: a #GdkWindow
1328 * @state_type: a state
1329 * @shadow_type: type of shadow to draw
1330 * @x: x origin of the rectangle
1331 * @y: y origin of the rectangle
1332 * @width: width of the rectangle
1333 * @height: width of the rectangle
1334 * @gap_side: side in which to leave the gap
1335 * @gap_x: starting position of the gap
1336 * @gap_width: width of the gap
1338 * Draws a box in @window using the given style and state and shadow type,
1339 * leaving a gap in one side.
1341 * Deprecated: Use gtk_paint_box_gap() instead.
1344 gtk_draw_box_gap (GtkStyle *style,
1346 GtkStateType state_type,
1347 GtkShadowType shadow_type,
1352 GtkPositionType gap_side,
1356 g_return_if_fail (GTK_IS_STYLE (style));
1357 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
1359 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);
1363 * gtk_draw_extension:
1364 * @style: a #GtkStyle
1365 * @window: a #GdkWindow
1366 * @state_type: a state
1367 * @shadow_type: type of shadow to draw
1368 * @x: x origin of the extension
1369 * @y: y origin of the extension
1370 * @width: width of the extension
1371 * @height: width of the extension
1372 * @gap_side: the side on to which the extension is attached
1374 * Draws an extension, i.e. a notebook tab.
1376 * Deprecated: Use gtk_paint_extension() instead.
1379 gtk_draw_extension (GtkStyle *style,
1381 GtkStateType state_type,
1382 GtkShadowType shadow_type,
1387 GtkPositionType gap_side)
1389 g_return_if_fail (GTK_IS_STYLE (style));
1390 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
1392 GTK_STYLE_GET_CLASS (style)->draw_extension (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, gap_side);
1397 * @style: a #GtkStyle
1398 * @window: a #GdkWindow
1399 * @x: the x origin of the rectangle around which to draw a focus indicator
1400 * @y: the y origin of the rectangle around which to draw a focus indicator
1401 * @width: the width of the rectangle around which to draw a focus indicator
1402 * @height: the height of the rectangle around which to draw a focus indicator
1404 * Draws a focus indicator around the given rectangle on @window using the
1407 * Deprecated: Use gtk_paint_focus() instead.
1410 gtk_draw_focus (GtkStyle *style,
1417 g_return_if_fail (GTK_IS_STYLE (style));
1418 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
1420 GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, GTK_STATE_NORMAL, NULL, NULL, NULL, x, y, width, height);
1424 gtk_draw_slider (GtkStyle *style,
1426 GtkStateType state_type,
1427 GtkShadowType shadow_type,
1432 GtkOrientation orientation)
1434 g_return_if_fail (GTK_IS_STYLE (style));
1435 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
1437 GTK_STYLE_GET_CLASS (style)->draw_slider (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, orientation);
1442 * @style: a #GtkStyle
1443 * @window: a #GdkWindow
1444 * @state_type: a state
1445 * @shadow_type: type of shadow to draw
1446 * @x: x origin of the handle
1447 * @y: y origin of the handle
1448 * @width: with of the handle
1449 * @height: height of the handle
1450 * @orientation: the orientation of the handle
1452 * Draws a handle as used in #GtkHandleBox and #GtkPaned.
1454 * Deprecated: Use gtk_paint_handle() instead.
1457 gtk_draw_handle (GtkStyle *style,
1459 GtkStateType state_type,
1460 GtkShadowType shadow_type,
1465 GtkOrientation orientation)
1467 g_return_if_fail (GTK_IS_STYLE (style));
1468 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
1470 GTK_STYLE_GET_CLASS (style)->draw_handle (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, orientation);
1474 * gtk_draw_expander:
1475 * @style: a #GtkStyle
1476 * @window: a #GdkWindow
1477 * @state_type: a state
1478 * @x: the x position to draw the expander at
1479 * @y: the y position to draw the expander at
1480 * @expander_style: the style to draw the expander in
1482 * Draws an expander as used in #GtkTreeView.
1484 * Deprecated: Use gtk_paint_expander() instead.
1487 gtk_draw_expander (GtkStyle *style,
1489 GtkStateType state_type,
1492 GtkExpanderStyle expander_style)
1494 g_return_if_fail (GTK_IS_STYLE (style));
1495 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
1497 GTK_STYLE_GET_CLASS (style)->draw_expander (style, window, state_type,
1499 x, y, expander_style);
1503 gtk_draw_layout (GtkStyle *style,
1505 GtkStateType state_type,
1509 PangoLayout *layout)
1511 g_return_if_fail (GTK_IS_STYLE (style));
1512 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
1514 GTK_STYLE_GET_CLASS (style)->draw_layout (style, window, state_type, use_text,
1520 * gtk_draw_resize_grip:
1521 * @style: a #GtkStyle
1522 * @window: a #GdkWindow
1523 * @state_type: a state
1524 * @edge: the edge in which to draw the resize grip
1525 * @x: the x origin of the rectangle in which to draw the resize grip
1526 * @y: the y origin of the rectangle in which to draw the resize grip
1527 * @width: the width of the rectangle in which to draw the resize grip
1528 * @height: the height of the rectangle in which to draw the resize grip
1530 * Draws a resize grip in the given rectangle on @window using the given
1533 * Deprecated: Use gtk_paint_resize_grip() instead.
1536 gtk_draw_resize_grip (GtkStyle *style,
1538 GtkStateType state_type,
1545 g_return_if_fail (GTK_IS_STYLE (style));
1546 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
1548 GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, window, state_type,
1551 x, y, width, height);
1556 * gtk_style_set_background:
1557 * @style: a #GtkStyle
1558 * @window: a #GdkWindow
1559 * @state_type: a state
1561 * Sets the background of @window to the background color or pixmap
1562 * specified by @style for the given state.
1565 gtk_style_set_background (GtkStyle *style,
1567 GtkStateType state_type)
1569 g_return_if_fail (GTK_IS_STYLE (style));
1570 g_return_if_fail (window != NULL);
1572 GTK_STYLE_GET_CLASS (style)->set_background (style, window, state_type);
1575 /* Default functions */
1577 gtk_style_real_clone (GtkStyle *style)
1579 return g_object_new (G_OBJECT_TYPE (style), NULL);
1583 gtk_style_real_copy (GtkStyle *style,
1586 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
1587 GtkStylePrivate *src_priv = GTK_STYLE_GET_PRIVATE (src);
1590 for (i = 0; i < 5; i++)
1592 style->fg[i] = src->fg[i];
1593 style->bg[i] = src->bg[i];
1594 style->text[i] = src->text[i];
1595 style->base[i] = src->base[i];
1597 if (style->bg_pixmap[i])
1598 g_object_unref (style->bg_pixmap[i]),
1599 style->bg_pixmap[i] = src->bg_pixmap[i];
1600 if (style->bg_pixmap[i])
1601 g_object_ref (style->bg_pixmap[i]);
1604 if (style->private_font)
1605 gdk_font_unref (style->private_font);
1606 style->private_font = src->private_font;
1607 if (style->private_font)
1608 gdk_font_ref (style->private_font);
1610 if (style->font_desc)
1611 pango_font_description_free (style->font_desc);
1613 style->font_desc = pango_font_description_copy (src->font_desc);
1615 style->font_desc = NULL;
1617 style->xthickness = src->xthickness;
1618 style->ythickness = src->ythickness;
1620 if (style->rc_style)
1621 g_object_unref (style->rc_style);
1622 style->rc_style = src->rc_style;
1624 g_object_ref (src->rc_style);
1626 g_slist_foreach (style->icon_factories, (GFunc) g_object_unref, NULL);
1627 g_slist_free (style->icon_factories);
1628 style->icon_factories = g_slist_copy (src->icon_factories);
1629 g_slist_foreach (style->icon_factories, (GFunc) g_object_ref, NULL);
1631 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_unref, NULL);
1632 g_slist_free (priv->color_hashes);
1633 priv->color_hashes = g_slist_copy (src_priv->color_hashes);
1634 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_ref, NULL);
1636 /* don't copy, just clear cache */
1637 clear_property_cache (style);
1641 gtk_style_real_init_from_rc (GtkStyle *style,
1642 GtkRcStyle *rc_style)
1644 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
1647 /* cache _should_ be still empty */
1648 clear_property_cache (style);
1650 if (rc_style->font_desc)
1651 pango_font_description_merge (style->font_desc, rc_style->font_desc, TRUE);
1653 for (i = 0; i < 5; i++)
1655 if (rc_style->color_flags[i] & GTK_RC_FG)
1656 style->fg[i] = rc_style->fg[i];
1657 if (rc_style->color_flags[i] & GTK_RC_BG)
1658 style->bg[i] = rc_style->bg[i];
1659 if (rc_style->color_flags[i] & GTK_RC_TEXT)
1660 style->text[i] = rc_style->text[i];
1661 if (rc_style->color_flags[i] & GTK_RC_BASE)
1662 style->base[i] = rc_style->base[i];
1665 if (rc_style->xthickness >= 0)
1666 style->xthickness = rc_style->xthickness;
1667 if (rc_style->ythickness >= 0)
1668 style->ythickness = rc_style->ythickness;
1670 style->icon_factories = g_slist_copy (rc_style->icon_factories);
1671 g_slist_foreach (style->icon_factories, (GFunc) g_object_ref, NULL);
1673 priv->color_hashes = g_slist_copy (_gtk_rc_style_get_color_hashes (rc_style));
1674 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_ref, NULL);
1678 style_property_values_cmp (gconstpointer bsearch_node1,
1679 gconstpointer bsearch_node2)
1681 const PropertyValue *val1 = bsearch_node1;
1682 const PropertyValue *val2 = bsearch_node2;
1684 if (val1->widget_type == val2->widget_type)
1685 return val1->pspec < val2->pspec ? -1 : val1->pspec == val2->pspec ? 0 : 1;
1687 return val1->widget_type < val2->widget_type ? -1 : 1;
1691 _gtk_style_peek_property_value (GtkStyle *style,
1694 GtkRcPropertyParser parser)
1696 PropertyValue *pcache, key = { 0, NULL, { 0, } };
1697 const GtkRcProperty *rcprop = NULL;
1700 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1701 g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL);
1702 g_return_val_if_fail (g_type_is_a (pspec->owner_type, GTK_TYPE_WIDGET), NULL);
1703 g_return_val_if_fail (g_type_is_a (widget_type, pspec->owner_type), NULL);
1705 key.widget_type = widget_type;
1708 /* need value cache array */
1709 if (!style->property_cache)
1710 style->property_cache = g_array_new (FALSE, FALSE, sizeof (PropertyValue));
1713 pcache = bsearch (&key,
1714 style->property_cache->data, style->property_cache->len,
1715 sizeof (PropertyValue), style_property_values_cmp);
1717 return &pcache->value;
1721 while (i < style->property_cache->len &&
1722 style_property_values_cmp (&key, &g_array_index (style->property_cache, PropertyValue, i)) >= 0)
1725 g_array_insert_val (style->property_cache, i, key);
1726 pcache = &g_array_index (style->property_cache, PropertyValue, i);
1728 /* cache miss, initialize value type, then set contents */
1729 g_param_spec_ref (pcache->pspec);
1730 g_value_init (&pcache->value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1732 /* value provided by rc style? */
1733 if (style->rc_style)
1735 GQuark prop_quark = g_quark_from_string (pspec->name);
1739 rcprop = _gtk_rc_style_lookup_rc_property (style->rc_style,
1740 g_type_qname (widget_type),
1744 widget_type = g_type_parent (widget_type);
1746 while (g_type_is_a (widget_type, pspec->owner_type));
1749 /* when supplied by rc style, we need to convert */
1750 if (rcprop && !_gtk_settings_parse_convert (parser, &rcprop->value,
1751 pspec, &pcache->value))
1753 gchar *contents = g_strdup_value_contents (&rcprop->value);
1755 g_message ("%s: failed to retrieve property `%s::%s' of type `%s' from rc file value \"%s\" of type `%s'",
1756 rcprop->origin ? rcprop->origin : "(for origin information, set GTK_DEBUG)",
1757 g_type_name (pspec->owner_type), pspec->name,
1758 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1760 G_VALUE_TYPE_NAME (&rcprop->value));
1762 rcprop = NULL; /* needs default */
1765 /* not supplied by rc style (or conversion failed), revert to default */
1767 g_param_value_set_default (pspec, &pcache->value);
1769 return &pcache->value;
1773 load_bg_image (GdkColormap *colormap,
1775 const gchar *filename)
1777 if (strcmp (filename, "<parent>") == 0)
1778 return (GdkPixmap*) GDK_PARENT_RELATIVE;
1781 return gdk_pixmap_colormap_create_from_xpm (NULL, colormap, NULL,
1788 gtk_style_real_realize (GtkStyle *style)
1790 GdkGCValues gc_values;
1791 GdkGCValuesMask gc_values_mask;
1795 for (i = 0; i < 5; i++)
1797 _gtk_style_shade (&style->bg[i], &style->light[i], LIGHTNESS_MULT);
1798 _gtk_style_shade (&style->bg[i], &style->dark[i], DARKNESS_MULT);
1800 style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
1801 style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
1802 style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
1804 style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
1805 style->text_aa[i].green = (style->text[i].green + style->base[i].green) / 2;
1806 style->text_aa[i].blue = (style->text[i].blue + style->base[i].blue) / 2;
1809 style->black.red = 0x0000;
1810 style->black.green = 0x0000;
1811 style->black.blue = 0x0000;
1812 gdk_colormap_alloc_color (style->colormap, &style->black, FALSE, TRUE);
1814 style->white.red = 0xffff;
1815 style->white.green = 0xffff;
1816 style->white.blue = 0xffff;
1817 gdk_colormap_alloc_color (style->colormap, &style->white, FALSE, TRUE);
1819 gc_values_mask = GDK_GC_FOREGROUND | GDK_GC_BACKGROUND;
1821 gc_values.foreground = style->black;
1822 gc_values.background = style->white;
1823 style->black_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1825 gc_values.foreground = style->white;
1826 gc_values.background = style->black;
1827 style->white_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1829 gc_values_mask = GDK_GC_FOREGROUND;
1831 for (i = 0; i < 5; i++)
1833 if (style->rc_style && style->rc_style->bg_pixmap_name[i])
1834 style->bg_pixmap[i] = load_bg_image (style->colormap,
1836 style->rc_style->bg_pixmap_name[i]);
1838 if (!gdk_colormap_alloc_color (style->colormap, &style->fg[i], FALSE, TRUE))
1839 g_warning ("unable to allocate color: ( %d %d %d )",
1840 style->fg[i].red, style->fg[i].green, style->fg[i].blue);
1841 if (!gdk_colormap_alloc_color (style->colormap, &style->bg[i], FALSE, TRUE))
1842 g_warning ("unable to allocate color: ( %d %d %d )",
1843 style->bg[i].red, style->bg[i].green, style->bg[i].blue);
1844 if (!gdk_colormap_alloc_color (style->colormap, &style->light[i], FALSE, TRUE))
1845 g_warning ("unable to allocate color: ( %d %d %d )",
1846 style->light[i].red, style->light[i].green, style->light[i].blue);
1847 if (!gdk_colormap_alloc_color (style->colormap, &style->dark[i], FALSE, TRUE))
1848 g_warning ("unable to allocate color: ( %d %d %d )",
1849 style->dark[i].red, style->dark[i].green, style->dark[i].blue);
1850 if (!gdk_colormap_alloc_color (style->colormap, &style->mid[i], FALSE, TRUE))
1851 g_warning ("unable to allocate color: ( %d %d %d )",
1852 style->mid[i].red, style->mid[i].green, style->mid[i].blue);
1853 if (!gdk_colormap_alloc_color (style->colormap, &style->text[i], FALSE, TRUE))
1854 g_warning ("unable to allocate color: ( %d %d %d )",
1855 style->text[i].red, style->text[i].green, style->text[i].blue);
1856 if (!gdk_colormap_alloc_color (style->colormap, &style->base[i], FALSE, TRUE))
1857 g_warning ("unable to allocate color: ( %d %d %d )",
1858 style->base[i].red, style->base[i].green, style->base[i].blue);
1859 if (!gdk_colormap_alloc_color (style->colormap, &style->text_aa[i], FALSE, TRUE))
1860 g_warning ("unable to allocate color: ( %d %d %d )",
1861 style->text_aa[i].red, style->text_aa[i].green, style->text_aa[i].blue);
1863 gc_values.foreground = style->fg[i];
1864 style->fg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1866 gc_values.foreground = style->bg[i];
1867 style->bg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1869 gc_values.foreground = style->light[i];
1870 style->light_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1872 gc_values.foreground = style->dark[i];
1873 style->dark_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1875 gc_values.foreground = style->mid[i];
1876 style->mid_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1878 gc_values.foreground = style->text[i];
1879 style->text_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1881 gc_values.foreground = style->base[i];
1882 style->base_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1884 gc_values.foreground = style->text_aa[i];
1885 style->text_aa_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1890 gtk_style_real_unrealize (GtkStyle *style)
1894 gtk_gc_release (style->black_gc);
1895 gtk_gc_release (style->white_gc);
1897 for (i = 0; i < 5; i++)
1899 gtk_gc_release (style->fg_gc[i]);
1900 gtk_gc_release (style->bg_gc[i]);
1901 gtk_gc_release (style->light_gc[i]);
1902 gtk_gc_release (style->dark_gc[i]);
1903 gtk_gc_release (style->mid_gc[i]);
1904 gtk_gc_release (style->text_gc[i]);
1905 gtk_gc_release (style->base_gc[i]);
1906 gtk_gc_release (style->text_aa_gc[i]);
1908 if (style->bg_pixmap[i] && style->bg_pixmap[i] != (GdkPixmap*) GDK_PARENT_RELATIVE)
1910 g_object_unref (style->bg_pixmap[i]);
1911 style->bg_pixmap[i] = NULL;
1916 gdk_colormap_free_colors (style->colormap, style->fg, 5);
1917 gdk_colormap_free_colors (style->colormap, style->bg, 5);
1918 gdk_colormap_free_colors (style->colormap, style->light, 5);
1919 gdk_colormap_free_colors (style->colormap, style->dark, 5);
1920 gdk_colormap_free_colors (style->colormap, style->mid, 5);
1921 gdk_colormap_free_colors (style->colormap, style->text, 5);
1922 gdk_colormap_free_colors (style->colormap, style->base, 5);
1923 gdk_colormap_free_colors (style->colormap, style->text_aa, 5);
1925 style_unrealize_cursor_gcs (style);
1929 gtk_style_real_set_background (GtkStyle *style,
1931 GtkStateType state_type)
1934 gint parent_relative;
1936 if (style->bg_pixmap[state_type])
1938 if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
1941 parent_relative = TRUE;
1945 pixmap = style->bg_pixmap[state_type];
1946 parent_relative = FALSE;
1949 gdk_window_set_back_pixmap (window, pixmap, parent_relative);
1952 gdk_window_set_background (window, &style->bg[state_type]);
1956 * gtk_style_render_icon:
1957 * @style: a #GtkStyle
1958 * @source: the #GtkIconSource specifying the icon to render
1959 * @direction: a text direction
1961 * @size: the size to render the icon at. A size of (GtkIconSize)-1
1962 * means render at the size of the source and don't scale.
1963 * @widget: the widget
1964 * @detail: a style detail
1965 * @returns: a newly-created #GdkPixbuf containing the rendered icon
1967 * Renders the icon specified by @source at the given @size
1968 * according to the given parameters and returns the result in a
1972 gtk_style_render_icon (GtkStyle *style,
1973 const GtkIconSource *source,
1974 GtkTextDirection direction,
1978 const gchar *detail)
1982 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1983 g_return_val_if_fail (GTK_STYLE_GET_CLASS (style)->render_icon != NULL, NULL);
1985 pixbuf = GTK_STYLE_GET_CLASS (style)->render_icon (style, source, direction, state,
1986 size, widget, detail);
1988 g_return_val_if_fail (pixbuf != NULL, NULL);
1993 /* Default functions */
1995 gtk_style_apply_default_background (GtkStyle *style,
1998 GtkStateType state_type,
2005 GdkRectangle new_rect, old_rect;
2011 old_rect.width = width;
2012 old_rect.height = height;
2014 if (!gdk_rectangle_intersect (area, &old_rect, &new_rect))
2021 new_rect.width = width;
2022 new_rect.height = height;
2025 if (!style->bg_pixmap[state_type] ||
2026 GDK_IS_PIXMAP (window) ||
2027 (!set_bg && style->bg_pixmap[state_type] != (GdkPixmap*) GDK_PARENT_RELATIVE))
2029 GdkGC *gc = style->bg_gc[state_type];
2031 if (style->bg_pixmap[state_type])
2033 gdk_gc_set_fill (gc, GDK_TILED);
2034 gdk_gc_set_tile (gc, style->bg_pixmap[state_type]);
2037 gdk_draw_rectangle (window, gc, TRUE,
2038 new_rect.x, new_rect.y, new_rect.width, new_rect.height);
2039 if (style->bg_pixmap[state_type])
2040 gdk_gc_set_fill (gc, GDK_SOLID);
2046 if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
2047 gdk_window_set_back_pixmap (window, NULL, TRUE);
2049 gdk_window_set_back_pixmap (window, style->bg_pixmap[state_type], FALSE);
2052 gdk_window_clear_area (window,
2053 new_rect.x, new_rect.y,
2054 new_rect.width, new_rect.height);
2059 scale_or_ref (GdkPixbuf *src,
2063 if (width == gdk_pixbuf_get_width (src) &&
2064 height == gdk_pixbuf_get_height (src))
2066 return g_object_ref (src);
2070 return gdk_pixbuf_scale_simple (src,
2072 GDK_INTERP_BILINEAR);
2077 gtk_default_render_icon (GtkStyle *style,
2078 const GtkIconSource *source,
2079 GtkTextDirection direction,
2083 const gchar *detail)
2089 GdkPixbuf *base_pixbuf;
2091 GtkSettings *settings;
2093 /* Oddly, style can be NULL in this function, because
2094 * GtkIconSet can be used without a style and if so
2095 * it uses this function.
2098 base_pixbuf = gtk_icon_source_get_pixbuf (source);
2100 g_return_val_if_fail (base_pixbuf != NULL, NULL);
2102 if (widget && gtk_widget_has_screen (widget))
2104 screen = gtk_widget_get_screen (widget);
2105 settings = gtk_settings_get_for_screen (screen);
2107 else if (style && style->colormap)
2109 screen = gdk_colormap_get_screen (style->colormap);
2110 settings = gtk_settings_get_for_screen (screen);
2114 settings = gtk_settings_get_default ();
2115 GTK_NOTE (MULTIHEAD,
2116 g_warning ("Using the default screen for gtk_default_render_icon()"));
2120 if (size != (GtkIconSize) -1 && !gtk_icon_size_lookup_for_settings (settings, size, &width, &height))
2122 g_warning (G_STRLOC ": invalid icon size '%d'", size);
2126 /* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
2129 if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source))
2130 scaled = scale_or_ref (base_pixbuf, width, height);
2132 scaled = g_object_ref (base_pixbuf);
2134 /* If the state was wildcarded, then generate a state. */
2135 if (gtk_icon_source_get_state_wildcarded (source))
2137 if (state == GTK_STATE_INSENSITIVE)
2139 stated = gdk_pixbuf_copy (scaled);
2141 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
2144 g_object_unref (scaled);
2146 else if (state == GTK_STATE_PRELIGHT)
2148 stated = gdk_pixbuf_copy (scaled);
2150 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
2153 g_object_unref (scaled);
2167 sanitize_size (GdkWindow *window,
2171 if ((*width == -1) && (*height == -1))
2172 gdk_drawable_get_size (window, width, height);
2173 else if (*width == -1)
2174 gdk_drawable_get_size (window, width, NULL);
2175 else if (*height == -1)
2176 gdk_drawable_get_size (window, NULL, height);
2180 gtk_default_draw_hline (GtkStyle *style,
2182 GtkStateType state_type,
2185 const gchar *detail,
2190 gint thickness_light;
2191 gint thickness_dark;
2194 thickness_light = style->ythickness / 2;
2195 thickness_dark = style->ythickness - thickness_light;
2199 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2200 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2203 if (detail && !strcmp (detail, "label"))
2205 if (state_type == GTK_STATE_INSENSITIVE)
2206 gdk_draw_line (window, style->white_gc, x1 + 1, y + 1, x2 + 1, y + 1);
2207 gdk_draw_line (window, style->fg_gc[state_type], x1, y, x2, y);
2211 for (i = 0; i < thickness_dark; i++)
2213 gdk_draw_line (window, style->dark_gc[state_type], x1, y + i, x2 - i - 1, y + i);
2214 gdk_draw_line (window, style->light_gc[state_type], x2 - i, y + i, x2, y + i);
2217 y += thickness_dark;
2218 for (i = 0; i < thickness_light; i++)
2220 gdk_draw_line (window, style->dark_gc[state_type], x1, y + i, x1 + thickness_light - i - 1, y + i);
2221 gdk_draw_line (window, style->light_gc[state_type], x1 + thickness_light - i, y + i, x2, y + i);
2227 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2228 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2234 gtk_default_draw_vline (GtkStyle *style,
2236 GtkStateType state_type,
2239 const gchar *detail,
2244 gint thickness_light;
2245 gint thickness_dark;
2248 thickness_light = style->xthickness / 2;
2249 thickness_dark = style->xthickness - thickness_light;
2253 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2254 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2256 for (i = 0; i < thickness_dark; i++)
2258 gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i, y2 - i - 1);
2259 gdk_draw_line (window, style->light_gc[state_type], x + i, y2 - i, x + i, y2);
2262 x += thickness_dark;
2263 for (i = 0; i < thickness_light; i++)
2265 gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i, y1 + thickness_light - i - 1);
2266 gdk_draw_line (window, style->light_gc[state_type], x + i, y1 + thickness_light - i, x + i, y2);
2270 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2271 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2276 draw_thin_shadow (GtkStyle *style,
2287 sanitize_size (window, &width, &height);
2289 gc1 = style->light_gc[state];
2290 gc2 = style->dark_gc[state];
2294 gdk_gc_set_clip_rectangle (gc1, area);
2295 gdk_gc_set_clip_rectangle (gc2, area);
2298 gdk_draw_line (window, gc1,
2299 x, y + height - 1, x + width - 1, y + height - 1);
2300 gdk_draw_line (window, gc1,
2301 x + width - 1, y, x + width - 1, y + height - 1);
2303 gdk_draw_line (window, gc2,
2304 x, y, x + width - 2, y);
2305 gdk_draw_line (window, gc2,
2306 x, y, x, y + height - 2);
2310 gdk_gc_set_clip_rectangle (gc1, NULL);
2311 gdk_gc_set_clip_rectangle (gc2, NULL);
2316 draw_spinbutton_shadow (GtkStyle *style,
2319 GtkTextDirection direction,
2326 sanitize_size (window, &width, &height);
2330 gdk_gc_set_clip_rectangle (style->black_gc, area);
2331 gdk_gc_set_clip_rectangle (style->bg_gc[state], area);
2332 gdk_gc_set_clip_rectangle (style->dark_gc[state], area);
2333 gdk_gc_set_clip_rectangle (style->light_gc[state], area);
2336 if (direction == GTK_TEXT_DIR_LTR)
2338 gdk_draw_line (window, style->dark_gc[state],
2339 x, y, x + width - 1, y);
2340 gdk_draw_line (window, style->black_gc,
2341 x, y + 1, x + width - 2, y + 1);
2342 gdk_draw_line (window, style->black_gc,
2343 x + width - 2, y + 2, x + width - 2, y + height - 3);
2344 gdk_draw_line (window, style->light_gc[state],
2345 x + width - 1, y + 1, x + width - 1, y + height - 2);
2346 gdk_draw_line (window, style->light_gc[state],
2347 x, y + height - 1, x + width - 1, y + height - 1);
2348 gdk_draw_line (window, style->bg_gc[state],
2349 x, y + height - 2, x + width - 2, y + height - 2);
2350 gdk_draw_line (window, style->black_gc,
2351 x, y + 2, x, y + height - 3);
2355 gdk_draw_line (window, style->dark_gc[state],
2356 x, y, x + width - 1, y);
2357 gdk_draw_line (window, style->dark_gc[state],
2358 x, y + 1, x, y + height - 1);
2359 gdk_draw_line (window, style->black_gc,
2360 x + 1, y + 1, x + width - 1, y + 1);
2361 gdk_draw_line (window, style->black_gc,
2362 x + 1, y + 2, x + 1, y + height - 2);
2363 gdk_draw_line (window, style->black_gc,
2364 x + width - 1, y + 2, x + width - 1, y + height - 3);
2365 gdk_draw_line (window, style->light_gc[state],
2366 x + 1, y + height - 1, x + width - 1, y + height - 1);
2367 gdk_draw_line (window, style->bg_gc[state],
2368 x + 2, y + height - 2, x + width - 1, y + height - 2);
2373 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
2374 gdk_gc_set_clip_rectangle (style->bg_gc[state], NULL);
2375 gdk_gc_set_clip_rectangle (style->dark_gc[state], NULL);
2376 gdk_gc_set_clip_rectangle (style->light_gc[state], NULL);
2381 draw_menu_shadow (GtkStyle *style,
2390 if (style->ythickness > 0)
2392 if (style->ythickness > 1)
2394 gdk_draw_line (window, style->dark_gc[state],
2395 x + 1, y + height - 2, x + width - 2, y + height - 2);
2396 gdk_draw_line (window, style->black_gc,
2397 x, y + height - 1, x + width - 1, y + height - 1);
2401 gdk_draw_line (window, style->dark_gc[state],
2402 x + 1, y + height - 1, x + width - 1, y + height - 1);
2406 if (style->xthickness > 0)
2408 if (style->xthickness > 1)
2410 gdk_draw_line (window, style->dark_gc[state],
2411 x + width - 2, y + 1, x + width - 2, y + height - 2);
2413 gdk_draw_line (window, style->black_gc,
2414 x + width - 1, y, x + width - 1, y + height - 1);
2418 gdk_draw_line (window, style->dark_gc[state],
2419 x + width - 1, y + 1, x + width - 1, y + height - 1);
2423 /* Light around top and left */
2425 if (style->ythickness > 0)
2426 gdk_draw_line (window, style->black_gc,
2427 x, y, x + width - 2, y);
2428 if (style->xthickness > 0)
2429 gdk_draw_line (window, style->black_gc,
2430 x, y, x, y + height - 2);
2432 if (style->ythickness > 1)
2433 gdk_draw_line (window, style->light_gc[state],
2434 x + 1, y + 1, x + width - 3, y + 1);
2435 if (style->xthickness > 1)
2436 gdk_draw_line (window, style->light_gc[state],
2437 x + 1, y + 1, x + 1, y + height - 3);
2440 static GtkTextDirection
2441 get_direction (GtkWidget *widget)
2443 GtkTextDirection dir;
2446 dir = gtk_widget_get_direction (widget);
2448 dir = GTK_TEXT_DIR_LTR;
2455 gtk_default_draw_shadow (GtkStyle *style,
2457 GtkStateType state_type,
2458 GtkShadowType shadow_type,
2461 const gchar *detail,
2469 gint thickness_light;
2470 gint thickness_dark;
2473 if (shadow_type == GTK_SHADOW_IN)
2475 if (detail && strcmp (detail, "buttondefault") == 0)
2477 sanitize_size (window, &width, &height);
2479 gdk_draw_rectangle (window, style->black_gc, FALSE,
2480 x, y, width - 1, height - 1);
2484 if (detail && strcmp (detail, "trough") == 0)
2486 draw_thin_shadow (style, window, state_type, area,
2487 x, y, width, height);
2490 if (GTK_IS_SPIN_BUTTON (widget) &&
2491 detail && strcmp (detail, "spinbutton") == 0)
2493 draw_spinbutton_shadow (style, window, state_type,
2494 get_direction (widget), area, x, y, width, height);
2500 if (shadow_type == GTK_SHADOW_OUT && detail && strcmp (detail, "menu") == 0)
2502 draw_menu_shadow (style, window, state_type, area, x, y, width, height);
2506 sanitize_size (window, &width, &height);
2508 switch (shadow_type)
2510 case GTK_SHADOW_NONE:
2513 case GTK_SHADOW_ETCHED_IN:
2514 gc1 = style->light_gc[state_type];
2515 gc2 = style->dark_gc[state_type];
2517 case GTK_SHADOW_OUT:
2518 case GTK_SHADOW_ETCHED_OUT:
2519 gc1 = style->dark_gc[state_type];
2520 gc2 = style->light_gc[state_type];
2526 gdk_gc_set_clip_rectangle (gc1, area);
2527 gdk_gc_set_clip_rectangle (gc2, area);
2528 if (shadow_type == GTK_SHADOW_IN ||
2529 shadow_type == GTK_SHADOW_OUT)
2531 gdk_gc_set_clip_rectangle (style->black_gc, area);
2532 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
2536 switch (shadow_type)
2538 case GTK_SHADOW_NONE:
2542 /* Light around right and bottom edge */
2544 if (style->ythickness > 0)
2545 gdk_draw_line (window, gc1,
2546 x, y + height - 1, x + width - 1, y + height - 1);
2547 if (style->xthickness > 0)
2548 gdk_draw_line (window, gc1,
2549 x + width - 1, y, x + width - 1, y + height - 1);
2551 if (style->ythickness > 1)
2552 gdk_draw_line (window, style->bg_gc[state_type],
2553 x + 1, y + height - 2, x + width - 2, y + height - 2);
2554 if (style->xthickness > 1)
2555 gdk_draw_line (window, style->bg_gc[state_type],
2556 x + width - 2, y + 1, x + width - 2, y + height - 2);
2558 /* Dark around left and top */
2560 if (style->ythickness > 1)
2561 gdk_draw_line (window, style->black_gc,
2562 x + 1, y + 1, x + width - 2, y + 1);
2563 if (style->xthickness > 1)
2564 gdk_draw_line (window, style->black_gc,
2565 x + 1, y + 1, x + 1, y + height - 2);
2567 if (style->ythickness > 0)
2568 gdk_draw_line (window, gc2,
2569 x, y, x + width - 1, y);
2570 if (style->xthickness > 0)
2571 gdk_draw_line (window, gc2,
2572 x, y, x, y + height - 1);
2575 case GTK_SHADOW_OUT:
2576 /* Dark around right and bottom edge */
2578 if (style->ythickness > 0)
2580 if (style->ythickness > 1)
2582 gdk_draw_line (window, gc1,
2583 x + 1, y + height - 2, x + width - 2, y + height - 2);
2584 gdk_draw_line (window, style->black_gc,
2585 x, y + height - 1, x + width - 1, y + height - 1);
2589 gdk_draw_line (window, gc1,
2590 x + 1, y + height - 1, x + width - 1, y + height - 1);
2594 if (style->xthickness > 0)
2596 if (style->xthickness > 1)
2598 gdk_draw_line (window, gc1,
2599 x + width - 2, y + 1, x + width - 2, y + height - 2);
2601 gdk_draw_line (window, style->black_gc,
2602 x + width - 1, y, x + width - 1, y + height - 1);
2606 gdk_draw_line (window, gc1,
2607 x + width - 1, y + 1, x + width - 1, y + height - 1);
2611 /* Light around top and left */
2613 if (style->ythickness > 0)
2614 gdk_draw_line (window, gc2,
2615 x, y, x + width - 2, y);
2616 if (style->xthickness > 0)
2617 gdk_draw_line (window, gc2,
2618 x, y, x, y + height - 2);
2620 if (style->ythickness > 1)
2621 gdk_draw_line (window, style->bg_gc[state_type],
2622 x + 1, y + 1, x + width - 3, y + 1);
2623 if (style->xthickness > 1)
2624 gdk_draw_line (window, style->bg_gc[state_type],
2625 x + 1, y + 1, x + 1, y + height - 3);
2628 case GTK_SHADOW_ETCHED_IN:
2629 case GTK_SHADOW_ETCHED_OUT:
2630 if (style->xthickness > 0)
2632 if (style->xthickness > 1)
2634 thickness_light = 1;
2637 for (i = 0; i < thickness_dark; i++)
2639 gdk_draw_line (window, gc1,
2643 y + height - i - 1);
2644 gdk_draw_line (window, gc2,
2648 y + height - i - 2);
2651 for (i = 0; i < thickness_light; i++)
2653 gdk_draw_line (window, gc1,
2654 x + thickness_dark + i,
2655 y + thickness_dark + i,
2656 x + thickness_dark + i,
2657 y + height - thickness_dark - i - 1);
2658 gdk_draw_line (window, gc2,
2659 x + width - thickness_light - i - 1,
2660 y + thickness_dark + i,
2661 x + width - thickness_light - i - 1,
2662 y + height - thickness_light - 1);
2667 gdk_draw_line (window,
2668 style->dark_gc[state_type],
2669 x, y, x, y + height);
2670 gdk_draw_line (window,
2671 style->dark_gc[state_type],
2672 x + width, y, x + width, y + height);
2676 if (style->ythickness > 0)
2678 if (style->ythickness > 1)
2680 thickness_light = 1;
2683 for (i = 0; i < thickness_dark; i++)
2685 gdk_draw_line (window, gc1,
2689 y + height - i - 1);
2691 gdk_draw_line (window, gc2,
2698 for (i = 0; i < thickness_light; i++)
2700 gdk_draw_line (window, gc1,
2701 x + thickness_dark + i,
2702 y + thickness_dark + i,
2703 x + width - thickness_dark - i - 2,
2704 y + thickness_dark + i);
2706 gdk_draw_line (window, gc2,
2707 x + thickness_dark + i,
2708 y + height - thickness_light - i - 1,
2709 x + width - thickness_light - 1,
2710 y + height - thickness_light - i - 1);
2715 gdk_draw_line (window,
2716 style->dark_gc[state_type],
2717 x, y, x + width, y);
2718 gdk_draw_line (window,
2719 style->dark_gc[state_type],
2720 x, y + height, x + width, y + height);
2727 if (shadow_type == GTK_SHADOW_IN &&
2728 GTK_IS_SPIN_BUTTON (widget) &&
2729 detail && strcmp (detail, "entry") == 0)
2731 if (get_direction (widget) == GTK_TEXT_DIR_LTR)
2733 gdk_draw_line (window,
2734 style->base_gc[state_type],
2735 x + width - 1, y + 2,
2736 x + width - 1, y + height - 3);
2737 gdk_draw_line (window,
2738 style->base_gc[state_type],
2739 x + width - 2, y + 2,
2740 x + width - 2, y + height - 3);
2741 gdk_draw_point (window,
2743 x + width - 1, y + 1);
2744 gdk_draw_point (window,
2745 style->bg_gc[state_type],
2746 x + width - 1, y + height - 2);
2750 gdk_draw_line (window,
2751 style->base_gc[state_type],
2754 gdk_draw_line (window,
2755 style->base_gc[state_type],
2757 x + 1, y + height - 3);
2758 gdk_draw_point (window,
2761 gdk_draw_line (window,
2762 style->bg_gc[state_type],
2764 x + 1, y + height - 2);
2765 gdk_draw_point (window,
2766 style->light_gc[state_type],
2774 gdk_gc_set_clip_rectangle (gc1, NULL);
2775 gdk_gc_set_clip_rectangle (gc2, NULL);
2776 if (shadow_type == GTK_SHADOW_IN ||
2777 shadow_type == GTK_SHADOW_OUT)
2779 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
2780 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
2786 gtk_default_draw_polygon (GtkStyle *style,
2788 GtkStateType state_type,
2789 GtkShadowType shadow_type,
2792 const gchar *detail,
2797 static const gdouble pi_over_4 = G_PI_4;
2798 static const gdouble pi_3_over_4 = G_PI_4 * 3;
2808 switch (shadow_type)
2811 gc1 = style->bg_gc[state_type];
2812 gc2 = style->dark_gc[state_type];
2813 gc3 = style->light_gc[state_type];
2814 gc4 = style->black_gc;
2816 case GTK_SHADOW_ETCHED_IN:
2817 gc1 = style->light_gc[state_type];
2818 gc2 = style->dark_gc[state_type];
2819 gc3 = style->dark_gc[state_type];
2820 gc4 = style->light_gc[state_type];
2822 case GTK_SHADOW_OUT:
2823 gc1 = style->dark_gc[state_type];
2824 gc2 = style->light_gc[state_type];
2825 gc3 = style->black_gc;
2826 gc4 = style->bg_gc[state_type];
2828 case GTK_SHADOW_ETCHED_OUT:
2829 gc1 = style->dark_gc[state_type];
2830 gc2 = style->light_gc[state_type];
2831 gc3 = style->light_gc[state_type];
2832 gc4 = style->dark_gc[state_type];
2840 gdk_gc_set_clip_rectangle (gc1, area);
2841 gdk_gc_set_clip_rectangle (gc2, area);
2842 gdk_gc_set_clip_rectangle (gc3, area);
2843 gdk_gc_set_clip_rectangle (gc4, area);
2847 gdk_draw_polygon (window, style->bg_gc[state_type], TRUE, points, npoints);
2851 for (i = 0; i < npoints; i++)
2853 if ((points[i].x == points[i+1].x) &&
2854 (points[i].y == points[i+1].y))
2860 angle = atan2 (points[i+1].y - points[i].y,
2861 points[i+1].x - points[i].x);
2864 if ((angle > -pi_3_over_4) && (angle < pi_over_4))
2866 if (angle > -pi_over_4)
2877 gdk_draw_line (window, gc1,
2878 points[i].x-xadjust, points[i].y-yadjust,
2879 points[i+1].x-xadjust, points[i+1].y-yadjust);
2880 gdk_draw_line (window, gc3,
2881 points[i].x, points[i].y,
2882 points[i+1].x, points[i+1].y);
2886 if ((angle < -pi_3_over_4) || (angle > pi_3_over_4))
2897 gdk_draw_line (window, gc4,
2898 points[i].x+xadjust, points[i].y+yadjust,
2899 points[i+1].x+xadjust, points[i+1].y+yadjust);
2900 gdk_draw_line (window, gc2,
2901 points[i].x, points[i].y,
2902 points[i+1].x, points[i+1].y);
2908 gdk_gc_set_clip_rectangle (gc1, NULL);
2909 gdk_gc_set_clip_rectangle (gc2, NULL);
2910 gdk_gc_set_clip_rectangle (gc3, NULL);
2911 gdk_gc_set_clip_rectangle (gc4, NULL);
2916 draw_arrow (GdkWindow *window,
2919 GtkArrowType arrow_type,
2925 cairo_t *cr = gdk_cairo_create (window);
2926 gdk_cairo_set_source_color (cr, color);
2930 gdk_cairo_rectangle (cr, area);
2934 if (arrow_type == GTK_ARROW_DOWN)
2936 cairo_move_to (cr, x, y);
2937 cairo_line_to (cr, x + width, y);
2938 cairo_line_to (cr, x + width / 2., y + height);
2940 else if (arrow_type == GTK_ARROW_UP)
2942 cairo_move_to (cr, x, y + height);
2943 cairo_line_to (cr, x + width / 2., y);
2944 cairo_line_to (cr, x + width, y + height);
2946 else if (arrow_type == GTK_ARROW_LEFT)
2948 cairo_move_to (cr, x + width, y);
2949 cairo_line_to (cr, x + width, y + height);
2950 cairo_line_to (cr, x, y + height / 2.);
2952 else if (arrow_type == GTK_ARROW_RIGHT)
2954 cairo_move_to (cr, x, y);
2955 cairo_line_to (cr, x + width, y + height / 2.);
2956 cairo_line_to (cr, x, y + height);
2959 cairo_close_path (cr);
2966 calculate_arrow_geometry (GtkArrowType arrow_type,
2978 case GTK_ARROW_DOWN:
2988 if (arrow_type == GTK_ARROW_DOWN)
2990 if (*height % 2 == 1 || h % 2 == 0)
2995 if (*height % 2 == 0 || h % 2 == 0)
3000 case GTK_ARROW_RIGHT:
3001 case GTK_ARROW_LEFT:
3011 if (arrow_type == GTK_ARROW_RIGHT)
3013 if (*width % 2 == 1 || w % 2 == 0)
3018 if (*width % 2 == 0 || w % 2 == 0)
3024 /* should not be reached */
3028 *x += (*width - w) / 2;
3029 *y += (*height - h) / 2;
3035 gtk_default_draw_arrow (GtkStyle *style,
3038 GtkShadowType shadow,
3041 const gchar *detail,
3042 GtkArrowType arrow_type,
3049 sanitize_size (window, &width, &height);
3051 calculate_arrow_geometry (arrow_type, &x, &y, &width, &height);
3053 if (detail && strcmp (detail, "menu_scroll_arrow_up") == 0)
3056 if (state == GTK_STATE_INSENSITIVE)
3057 draw_arrow (window, &style->white, area, arrow_type,
3058 x + 1, y + 1, width, height);
3059 draw_arrow (window, &style->fg[state], area, arrow_type,
3060 x, y, width, height);
3064 gtk_default_draw_diamond (GtkStyle *style,
3066 GtkStateType state_type,
3067 GtkShadowType shadow_type,
3070 const gchar *detail,
3078 GdkGC *outer_nw = NULL;
3079 GdkGC *outer_ne = NULL;
3080 GdkGC *outer_sw = NULL;
3081 GdkGC *outer_se = NULL;
3082 GdkGC *middle_nw = NULL;
3083 GdkGC *middle_ne = NULL;
3084 GdkGC *middle_sw = NULL;
3085 GdkGC *middle_se = NULL;
3086 GdkGC *inner_nw = NULL;
3087 GdkGC *inner_ne = NULL;
3088 GdkGC *inner_sw = NULL;
3089 GdkGC *inner_se = NULL;
3091 sanitize_size (window, &width, &height);
3093 half_width = width / 2;
3094 half_height = height / 2;
3098 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
3099 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
3100 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
3101 gdk_gc_set_clip_rectangle (style->black_gc, area);
3104 switch (shadow_type)
3107 inner_sw = inner_se = style->bg_gc[state_type];
3108 middle_sw = middle_se = style->light_gc[state_type];
3109 outer_sw = outer_se = style->light_gc[state_type];
3110 inner_nw = inner_ne = style->black_gc;
3111 middle_nw = middle_ne = style->dark_gc[state_type];
3112 outer_nw = outer_ne = style->dark_gc[state_type];
3115 case GTK_SHADOW_OUT:
3116 inner_sw = inner_se = style->dark_gc[state_type];
3117 middle_sw = middle_se = style->dark_gc[state_type];
3118 outer_sw = outer_se = style->black_gc;
3119 inner_nw = inner_ne = style->bg_gc[state_type];
3120 middle_nw = middle_ne = style->light_gc[state_type];
3121 outer_nw = outer_ne = style->light_gc[state_type];
3124 case GTK_SHADOW_ETCHED_IN:
3125 inner_sw = inner_se = style->bg_gc[state_type];
3126 middle_sw = middle_se = style->dark_gc[state_type];
3127 outer_sw = outer_se = style->light_gc[state_type];
3128 inner_nw = inner_ne = style->bg_gc[state_type];
3129 middle_nw = middle_ne = style->light_gc[state_type];
3130 outer_nw = outer_ne = style->dark_gc[state_type];
3133 case GTK_SHADOW_ETCHED_OUT:
3134 inner_sw = inner_se = style->bg_gc[state_type];
3135 middle_sw = middle_se = style->light_gc[state_type];
3136 outer_sw = outer_se = style->dark_gc[state_type];
3137 inner_nw = inner_ne = style->bg_gc[state_type];
3138 middle_nw = middle_ne = style->dark_gc[state_type];
3139 outer_nw = outer_ne = style->light_gc[state_type];
3149 gdk_draw_line (window, inner_sw,
3150 x + 2, y + half_height,
3151 x + half_width, y + height - 2);
3152 gdk_draw_line (window, inner_se,
3153 x + half_width, y + height - 2,
3154 x + width - 2, y + half_height);
3155 gdk_draw_line (window, middle_sw,
3156 x + 1, y + half_height,
3157 x + half_width, y + height - 1);
3158 gdk_draw_line (window, middle_se,
3159 x + half_width, y + height - 1,
3160 x + width - 1, y + half_height);
3161 gdk_draw_line (window, outer_sw,
3163 x + half_width, y + height);
3164 gdk_draw_line (window, outer_se,
3165 x + half_width, y + height,
3166 x + width, y + half_height);
3168 gdk_draw_line (window, inner_nw,
3169 x + 2, y + half_height,
3170 x + half_width, y + 2);
3171 gdk_draw_line (window, inner_ne,
3172 x + half_width, y + 2,
3173 x + width - 2, y + half_height);
3174 gdk_draw_line (window, middle_nw,
3175 x + 1, y + half_height,
3176 x + half_width, y + 1);
3177 gdk_draw_line (window, middle_ne,
3178 x + half_width, y + 1,
3179 x + width - 1, y + half_height);
3180 gdk_draw_line (window, outer_nw,
3183 gdk_draw_line (window, outer_ne,
3185 x + width, y + half_height);
3190 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
3191 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
3192 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
3193 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
3198 gtk_default_draw_string (GtkStyle *style,
3200 GtkStateType state_type,
3203 const gchar *detail,
3206 const gchar *string)
3210 gdk_gc_set_clip_rectangle (style->white_gc, area);
3211 gdk_gc_set_clip_rectangle (style->fg_gc[state_type], area);
3214 if (state_type == GTK_STATE_INSENSITIVE)
3215 gdk_draw_string (window,
3216 gtk_style_get_font_internal (style),
3217 style->white_gc, x + 1, y + 1, string);
3219 gdk_draw_string (window,
3220 gtk_style_get_font_internal (style),
3221 style->fg_gc[state_type], x, y, string);
3225 gdk_gc_set_clip_rectangle (style->white_gc, NULL);
3226 gdk_gc_set_clip_rectangle (style->fg_gc[state_type], NULL);
3231 option_menu_get_props (GtkWidget *widget,
3232 GtkRequisition *indicator_size,
3233 GtkBorder *indicator_spacing)
3235 GtkRequisition *tmp_size = NULL;
3236 GtkBorder *tmp_spacing = NULL;
3238 if (GTK_IS_OPTION_MENU (widget))
3239 gtk_widget_style_get (widget,
3240 "indicator-size", &tmp_size,
3241 "indicator-spacing", &tmp_spacing,
3246 *indicator_size = *tmp_size;
3250 *indicator_size = default_option_indicator_size;
3254 *indicator_spacing = *tmp_spacing;
3255 g_free (tmp_spacing);
3258 *indicator_spacing = default_option_indicator_spacing;
3262 gtk_default_draw_box (GtkStyle *style,
3264 GtkStateType state_type,
3265 GtkShadowType shadow_type,
3268 const gchar *detail,
3274 gboolean is_spinbutton_box = FALSE;
3276 sanitize_size (window, &width, &height);
3278 if (GTK_IS_SPIN_BUTTON (widget) && detail)
3280 if (strcmp (detail, "spinbutton_up") == 0)
3286 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
3291 is_spinbutton_box = TRUE;
3293 else if (strcmp (detail, "spinbutton_down") == 0)
3298 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
3303 is_spinbutton_box = TRUE;
3307 if (!style->bg_pixmap[state_type] ||
3308 GDK_IS_PIXMAP (window))
3310 GdkGC *gc = style->bg_gc[state_type];
3312 if (state_type == GTK_STATE_SELECTED && detail && strcmp (detail, "paned") == 0)
3314 if (widget && !GTK_WIDGET_HAS_FOCUS (widget))
3315 gc = style->base_gc[GTK_STATE_ACTIVE];
3319 gdk_gc_set_clip_rectangle (gc, area);
3321 gdk_draw_rectangle (window, gc, TRUE,
3322 x, y, width, height);
3324 gdk_gc_set_clip_rectangle (gc, NULL);
3327 gtk_style_apply_default_background (style, window,
3328 widget && !GTK_WIDGET_NO_WINDOW (widget),
3329 state_type, area, x, y, width, height);
3331 if (is_spinbutton_box)
3336 lower_gc = style->dark_gc[state_type];
3337 if (shadow_type == GTK_SHADOW_OUT)
3338 upper_gc = style->light_gc[state_type];
3340 upper_gc = style->dark_gc[state_type];
3344 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
3345 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
3348 gdk_draw_line (window, upper_gc, x, y, x + width - 1, y);
3349 gdk_draw_line (window, lower_gc, x, y + height - 1, x + width - 1, y + height - 1);
3353 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
3354 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
3359 gtk_paint_shadow (style, window, state_type, shadow_type, area, widget, detail,
3360 x, y, width, height);
3362 if (detail && strcmp (detail, "optionmenu") == 0)
3364 GtkRequisition indicator_size;
3365 GtkBorder indicator_spacing;
3368 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
3370 sanitize_size (window, &width, &height);
3372 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
3373 vline_x = x + indicator_size.width + indicator_spacing.left + indicator_spacing.right;
3375 vline_x = x + width - (indicator_size.width + indicator_spacing.left + indicator_spacing.right) - style->xthickness;
3377 gtk_paint_vline (style, window, state_type, area, widget,
3379 y + style->ythickness + 1,
3380 y + height - style->ythickness - 3,
3386 get_darkened_gc (GdkWindow *window,
3390 GdkColor src = *color;
3391 GdkColor shaded = *color;
3394 gc = gdk_gc_new (window);
3396 while (darken_count)
3398 _gtk_style_shade (&src, &shaded, 0.93);
3403 gdk_gc_set_rgb_fg_color (gc, &shaded);
3409 gtk_default_draw_flat_box (GtkStyle *style,
3411 GtkStateType state_type,
3412 GtkShadowType shadow_type,
3415 const gchar *detail,
3422 GdkGC *freeme = NULL;
3424 sanitize_size (window, &width, &height);
3428 if (state_type == GTK_STATE_SELECTED)
3430 if (!strcmp ("text", detail))
3431 gc1 = style->bg_gc[GTK_STATE_SELECTED];
3432 else if (!strcmp ("cell_even", detail) ||
3433 !strcmp ("cell_odd", detail) ||
3434 !strcmp ("cell_even_ruled", detail) ||
3435 !strcmp ("cell_even_ruled_sorted", detail))
3437 /* This has to be really broken; alex made me do it. -jrb */
3438 if (widget && GTK_WIDGET_HAS_FOCUS (widget))
3439 gc1 = style->base_gc[state_type];
3441 gc1 = style->base_gc[GTK_STATE_ACTIVE];
3443 else if (!strcmp ("cell_odd_ruled", detail) ||
3444 !strcmp ("cell_odd_ruled_sorted", detail))
3446 if (widget && GTK_WIDGET_HAS_FOCUS (widget))
3447 freeme = get_darkened_gc (window, &style->base[state_type], 1);
3449 freeme = get_darkened_gc (window, &style->base[GTK_STATE_ACTIVE], 1);
3454 gc1 = style->bg_gc[state_type];
3459 if (!strcmp ("viewportbin", detail))
3460 gc1 = style->bg_gc[GTK_STATE_NORMAL];
3461 else if (!strcmp ("entry_bg", detail))
3462 gc1 = style->base_gc[state_type];
3464 /* For trees: even rows are base color, odd rows are a shade of
3465 * the base color, the sort column is a shade of the original color
3469 else if (!strcmp ("cell_even", detail) ||
3470 !strcmp ("cell_odd", detail) ||
3471 !strcmp ("cell_even_ruled", detail))
3473 GdkColor *color = NULL;
3475 gtk_widget_style_get (widget,
3476 "even-row-color", &color,
3481 freeme = get_darkened_gc (window, color, 0);
3484 gdk_color_free (color);
3487 gc1 = style->base_gc[state_type];
3489 else if (!strcmp ("cell_odd_ruled", detail))
3491 GdkColor *color = NULL;
3493 gtk_widget_style_get (widget,
3494 "odd-row-color", &color,
3499 freeme = get_darkened_gc (window, color, 0);
3502 gdk_color_free (color);
3506 gtk_widget_style_get (widget,
3507 "even-row-color", &color,
3512 freeme = get_darkened_gc (window, color, 1);
3513 gdk_color_free (color);
3516 freeme = get_darkened_gc (window, &style->base[state_type], 1);
3520 else if (!strcmp ("cell_even_sorted", detail) ||
3521 !strcmp ("cell_odd_sorted", detail) ||
3522 !strcmp ("cell_even_ruled_sorted", detail))
3524 GdkColor *color = NULL;
3526 if (!strcmp ("cell_odd_sorted", detail))
3527 gtk_widget_style_get (widget,
3528 "odd-row-color", &color,
3531 gtk_widget_style_get (widget,
3532 "even-row-color", &color,
3537 freeme = get_darkened_gc (window, color, 1);
3540 gdk_color_free (color);
3544 freeme = get_darkened_gc (window, &style->base[state_type], 1);
3548 else if (!strcmp ("cell_odd_ruled_sorted", detail))
3550 GdkColor *color = NULL;
3552 gtk_widget_style_get (widget,
3553 "odd-row-color", &color,
3558 freeme = get_darkened_gc (window, color, 1);
3561 gdk_color_free (color);
3565 gtk_widget_style_get (widget,
3566 "even-row-color", &color,
3571 freeme = get_darkened_gc (window, color, 2);
3572 gdk_color_free (color);
3575 freeme = get_darkened_gc (window, &style->base[state_type], 2);
3580 gc1 = style->bg_gc[state_type];
3584 gc1 = style->bg_gc[state_type];
3586 if (!style->bg_pixmap[state_type] || gc1 != style->bg_gc[state_type] ||
3587 GDK_IS_PIXMAP (window))
3590 gdk_gc_set_clip_rectangle (gc1, area);
3592 gdk_draw_rectangle (window, gc1, TRUE,
3593 x, y, width, height);
3595 if (detail && !strcmp ("tooltip", detail))
3596 gdk_draw_rectangle (window, style->black_gc, FALSE,
3597 x, y, width - 1, height - 1);
3600 gdk_gc_set_clip_rectangle (gc1, NULL);
3603 gtk_style_apply_default_background (style, window,
3604 widget && !GTK_WIDGET_NO_WINDOW (widget),
3605 state_type, area, x, y, width, height);
3609 g_object_unref (freeme);
3613 gtk_default_draw_check (GtkStyle *style,
3615 GtkStateType state_type,
3616 GtkShadowType shadow_type,
3619 const gchar *detail,
3625 cairo_t *cr = gdk_cairo_create (window);
3626 enum { BUTTON, MENU, CELL } type = BUTTON;
3633 if (strcmp (detail, "cellcheck") == 0)
3635 else if (strcmp (detail, "check") == 0)
3641 gdk_cairo_rectangle (cr, area);
3645 exterior_size = MIN (width, height);
3646 if (exterior_size % 2 == 0) /* Ensure odd */
3647 exterior_size -= -1;
3649 pad = style->xthickness + MAX (1, (exterior_size - 2 * style->xthickness) / 9);
3650 interior_size = MAX (1, exterior_size - 2 * pad);
3652 if (interior_size < 7)
3655 pad = MAX (0, (exterior_size - interior_size) / 2);
3658 x -= (1 + exterior_size - width) / 2;
3659 y -= (1 + exterior_size - height) / 2;
3666 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3668 gdk_cairo_set_source_color (cr, &style->text[state_type]);
3670 cairo_set_line_width (cr, 1.0);
3671 cairo_rectangle (cr, x + 0.5, y + 0.5, exterior_size - 1, exterior_size - 1);
3674 gdk_cairo_set_source_color (cr, &style->base[state_type]);
3675 cairo_rectangle (cr, x + 1, y + 1, exterior_size - 2, exterior_size - 2);
3687 gdk_cairo_set_source_color (cr, &style->text[state_type]);
3690 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3694 if (shadow_type == GTK_SHADOW_IN)
3696 cairo_translate (cr,
3699 cairo_scale (cr, interior_size / 7., interior_size / 7.);
3701 cairo_move_to (cr, 7.0, 0.0);
3702 cairo_line_to (cr, 7.5, 1.0);
3703 cairo_curve_to (cr, 5.3, 2.0,
3706 cairo_curve_to (cr, 3.0, 5.7,
3709 cairo_line_to (cr, 0.2, 3.5);
3710 cairo_curve_to (cr, 1.1, 3.5,
3713 cairo_curve_to (cr, 1.0, 3.9,
3716 cairo_curve_to (cr, 3.5, 3.1,
3722 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
3724 int line_thickness = MAX (1, (3 + interior_size * 2) / 7);
3726 cairo_rectangle (cr,
3728 y + pad + (1 + interior_size - line_thickness) / 2,
3738 gtk_default_draw_option (GtkStyle *style,
3740 GtkStateType state_type,
3741 GtkShadowType shadow_type,
3744 const gchar *detail,
3750 cairo_t *cr = gdk_cairo_create (window);
3751 enum { BUTTON, MENU, CELL } type = BUTTON;
3756 if (strcmp (detail, "radio") == 0)
3758 else if (strcmp (detail, "option") == 0)
3764 gdk_cairo_rectangle (cr, area);
3768 exterior_size = MIN (width, height);
3769 if (exterior_size % 2 == 0) /* Ensure odd */
3770 exterior_size -= -1;
3772 x -= (1 + exterior_size - width) / 2;
3773 y -= (1 + exterior_size - height) / 2;
3779 gdk_cairo_set_source_color (cr, &style->base[state_type]);
3782 x + exterior_size / 2.,
3783 y + exterior_size / 2.,
3784 (exterior_size - 1) / 2.,
3787 cairo_fill_preserve (cr);
3790 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3792 gdk_cairo_set_source_color (cr, &style->text[state_type]);
3794 cairo_set_line_width (cr, 1.);
3805 gdk_cairo_set_source_color (cr, &style->text[state_type]);
3810 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3814 if (shadow_type == GTK_SHADOW_IN)
3816 int pad = style->xthickness + MAX (1, 2 * (exterior_size - 2 * style->xthickness) / 9);
3817 int interior_size = MAX (1, exterior_size - 2 * pad);
3819 if (interior_size < 5)
3822 pad = MAX (0, (exterior_size - interior_size) / 2);
3826 x + pad + interior_size / 2.,
3827 y + pad + interior_size / 2.,
3832 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
3834 int pad = style->xthickness + MAX (1, (exterior_size - 2 * style->xthickness) / 9);
3835 int interior_size = MAX (1, exterior_size - 2 * pad);
3838 if (interior_size < 7)
3841 pad = MAX (0, (exterior_size - interior_size) / 2);
3844 line_thickness = MAX (1, (3 + interior_size * 2) / 7);
3846 cairo_rectangle (cr,
3848 y + pad + (interior_size - line_thickness) / 2.,
3858 gtk_default_draw_tab (GtkStyle *style,
3860 GtkStateType state_type,
3861 GtkShadowType shadow_type,
3864 const gchar *detail,
3870 #define ARROW_SPACE 4
3872 GtkRequisition indicator_size;
3873 GtkBorder indicator_spacing;
3876 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
3878 indicator_size.width += (indicator_size.width % 2) - 1;
3879 arrow_height = indicator_size.width / 2 + 1;
3881 x += (width - indicator_size.width) / 2;
3882 y += (height - (2 * arrow_height + ARROW_SPACE)) / 2;
3884 if (state_type == GTK_STATE_INSENSITIVE)
3886 draw_arrow (window, &style->white, area,
3887 GTK_ARROW_UP, x + 1, y + 1,
3888 indicator_size.width, arrow_height);
3890 draw_arrow (window, &style->white, area,
3891 GTK_ARROW_DOWN, x + 1, y + arrow_height + ARROW_SPACE + 1,
3892 indicator_size.width, arrow_height);
3895 draw_arrow (window, &style->fg[state_type], area,
3897 indicator_size.width, arrow_height);
3900 draw_arrow (window, &style->fg[state_type], area,
3901 GTK_ARROW_DOWN, x, y + arrow_height + ARROW_SPACE,
3902 indicator_size.width, arrow_height);
3906 gtk_default_draw_shadow_gap (GtkStyle *style,
3908 GtkStateType state_type,
3909 GtkShadowType shadow_type,
3912 const gchar *detail,
3917 GtkPositionType gap_side,
3926 sanitize_size (window, &width, &height);
3928 switch (shadow_type)
3930 case GTK_SHADOW_NONE:
3933 gc1 = style->dark_gc[state_type];
3934 gc2 = style->black_gc;
3935 gc3 = style->bg_gc[state_type];
3936 gc4 = style->light_gc[state_type];
3938 case GTK_SHADOW_ETCHED_IN:
3939 gc1 = style->dark_gc[state_type];
3940 gc2 = style->light_gc[state_type];
3941 gc3 = style->dark_gc[state_type];
3942 gc4 = style->light_gc[state_type];
3944 case GTK_SHADOW_OUT:
3945 gc1 = style->light_gc[state_type];
3946 gc2 = style->bg_gc[state_type];
3947 gc3 = style->dark_gc[state_type];
3948 gc4 = style->black_gc;
3950 case GTK_SHADOW_ETCHED_OUT:
3951 gc1 = style->light_gc[state_type];
3952 gc2 = style->dark_gc[state_type];
3953 gc3 = style->light_gc[state_type];
3954 gc4 = style->dark_gc[state_type];
3959 gdk_gc_set_clip_rectangle (gc1, area);
3960 gdk_gc_set_clip_rectangle (gc2, area);
3961 gdk_gc_set_clip_rectangle (gc3, area);
3962 gdk_gc_set_clip_rectangle (gc4, area);
3965 switch (shadow_type)
3967 case GTK_SHADOW_NONE:
3969 case GTK_SHADOW_OUT:
3970 case GTK_SHADOW_ETCHED_IN:
3971 case GTK_SHADOW_ETCHED_OUT:
3975 gdk_draw_line (window, gc1,
3976 x, y, x, y + height - 1);
3977 gdk_draw_line (window, gc2,
3978 x + 1, y, x + 1, y + height - 2);
3980 gdk_draw_line (window, gc3,
3981 x + 1, y + height - 2, x + width - 2, y + height - 2);
3982 gdk_draw_line (window, gc3,
3983 x + width - 2, y, x + width - 2, y + height - 2);
3984 gdk_draw_line (window, gc4,
3985 x, y + height - 1, x + width - 1, y + height - 1);
3986 gdk_draw_line (window, gc4,
3987 x + width - 1, y, x + width - 1, y + height - 1);
3990 gdk_draw_line (window, gc1,
3991 x, y, x + gap_x - 1, y);
3992 gdk_draw_line (window, gc2,
3993 x + 1, y + 1, x + gap_x - 1, y + 1);
3994 gdk_draw_line (window, gc2,
3995 x + gap_x, y, x + gap_x, y);
3997 if ((width - (gap_x + gap_width)) > 0)
3999 gdk_draw_line (window, gc1,
4000 x + gap_x + gap_width, y, x + width - 2, y);
4001 gdk_draw_line (window, gc2,
4002 x + gap_x + gap_width, y + 1, x + width - 3, y + 1);
4003 gdk_draw_line (window, gc2,
4004 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
4007 case GTK_POS_BOTTOM:
4008 gdk_draw_line (window, gc1,
4009 x, y, x + width - 1, y);
4010 gdk_draw_line (window, gc1,
4011 x, y, x, y + height - 1);
4012 gdk_draw_line (window, gc2,
4013 x + 1, y + 1, x + width - 2, y + 1);
4014 gdk_draw_line (window, gc2,
4015 x + 1, y + 1, x + 1, y + height - 1);
4017 gdk_draw_line (window, gc3,
4018 x + width - 2, y + 1, x + width - 2, y + height - 1);
4019 gdk_draw_line (window, gc4,
4020 x + width - 1, y, x + width - 1, y + height - 1);
4023 gdk_draw_line (window, gc4,
4024 x, y + height - 1, x + gap_x - 1, y + height - 1);
4025 gdk_draw_line (window, gc3,
4026 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
4027 gdk_draw_line (window, gc3,
4028 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
4030 if ((width - (gap_x + gap_width)) > 0)
4032 gdk_draw_line (window, gc4,
4033 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
4034 gdk_draw_line (window, gc3,
4035 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
4036 gdk_draw_line (window, gc3,
4037 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
4041 gdk_draw_line (window, gc1,
4042 x, y, x + width - 1, y);
4043 gdk_draw_line (window, gc2,
4044 x, y + 1, x + width - 2, y + 1);
4046 gdk_draw_line (window, gc3,
4047 x, y + height - 2, x + width - 2, y + height - 2);
4048 gdk_draw_line (window, gc3,
4049 x + width - 2, y + 1, x + width - 2, y + height - 2);
4050 gdk_draw_line (window, gc4,
4051 x, y + height - 1, x + width - 1, y + height - 1);
4052 gdk_draw_line (window, gc4,
4053 x + width - 1, y, x + width - 1, y + height - 1);
4056 gdk_draw_line (window, gc1,
4057 x, y, x, y + gap_x - 1);
4058 gdk_draw_line (window, gc2,
4059 x + 1, y + 1, x + 1, y + gap_x - 1);
4060 gdk_draw_line (window, gc2,
4061 x, y + gap_x, x, y + gap_x);
4063 if ((width - (gap_x + gap_width)) > 0)
4065 gdk_draw_line (window, gc1,
4066 x, y + gap_x + gap_width, x, y + height - 2);
4067 gdk_draw_line (window, gc2,
4068 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
4069 gdk_draw_line (window, gc2,
4070 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
4074 gdk_draw_line (window, gc1,
4075 x, y, x + width - 1, y);
4076 gdk_draw_line (window, gc1,
4077 x, y, x, y + height - 1);
4078 gdk_draw_line (window, gc2,
4079 x + 1, y + 1, x + width - 1, y + 1);
4080 gdk_draw_line (window, gc2,
4081 x + 1, y + 1, x + 1, y + height - 2);
4083 gdk_draw_line (window, gc3,
4084 x + 1, y + height - 2, x + width - 1, y + height - 2);
4085 gdk_draw_line (window, gc4,
4086 x, y + height - 1, x + width - 1, y + height - 1);
4089 gdk_draw_line (window, gc4,
4090 x + width - 1, y, x + width - 1, y + gap_x - 1);
4091 gdk_draw_line (window, gc3,
4092 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
4093 gdk_draw_line (window, gc3,
4094 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
4096 if ((width - (gap_x + gap_width)) > 0)
4098 gdk_draw_line (window, gc4,
4099 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
4100 gdk_draw_line (window, gc3,
4101 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
4102 gdk_draw_line (window, gc3,
4103 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
4111 gdk_gc_set_clip_rectangle (gc1, NULL);
4112 gdk_gc_set_clip_rectangle (gc2, NULL);
4113 gdk_gc_set_clip_rectangle (gc3, NULL);
4114 gdk_gc_set_clip_rectangle (gc4, NULL);
4119 gtk_default_draw_box_gap (GtkStyle *style,
4121 GtkStateType state_type,
4122 GtkShadowType shadow_type,
4125 const gchar *detail,
4130 GtkPositionType gap_side,
4139 gtk_style_apply_default_background (style, window,
4140 widget && !GTK_WIDGET_NO_WINDOW (widget),
4141 state_type, area, x, y, width, height);
4143 sanitize_size (window, &width, &height);
4145 switch (shadow_type)
4147 case GTK_SHADOW_NONE:
4150 gc1 = style->dark_gc[state_type];
4151 gc2 = style->black_gc;
4152 gc3 = style->bg_gc[state_type];
4153 gc4 = style->light_gc[state_type];
4155 case GTK_SHADOW_ETCHED_IN:
4156 gc1 = style->dark_gc[state_type];
4157 gc2 = style->light_gc[state_type];
4158 gc3 = style->dark_gc[state_type];
4159 gc4 = style->light_gc[state_type];
4161 case GTK_SHADOW_OUT:
4162 gc1 = style->light_gc[state_type];
4163 gc2 = style->bg_gc[state_type];
4164 gc3 = style->dark_gc[state_type];
4165 gc4 = style->black_gc;
4167 case GTK_SHADOW_ETCHED_OUT:
4168 gc1 = style->light_gc[state_type];
4169 gc2 = style->dark_gc[state_type];
4170 gc3 = style->light_gc[state_type];
4171 gc4 = style->dark_gc[state_type];
4177 gdk_gc_set_clip_rectangle (gc1, area);
4178 gdk_gc_set_clip_rectangle (gc2, area);
4179 gdk_gc_set_clip_rectangle (gc3, area);
4180 gdk_gc_set_clip_rectangle (gc4, area);
4183 switch (shadow_type)
4185 case GTK_SHADOW_NONE:
4187 case GTK_SHADOW_OUT:
4188 case GTK_SHADOW_ETCHED_IN:
4189 case GTK_SHADOW_ETCHED_OUT:
4193 gdk_draw_line (window, gc1,
4194 x, y, x, y + height - 1);
4195 gdk_draw_line (window, gc2,
4196 x + 1, y, x + 1, y + height - 2);
4198 gdk_draw_line (window, gc3,
4199 x + 1, y + height - 2, x + width - 2, y + height - 2);
4200 gdk_draw_line (window, gc3,
4201 x + width - 2, y, x + width - 2, y + height - 2);
4202 gdk_draw_line (window, gc4,
4203 x, y + height - 1, x + width - 1, y + height - 1);
4204 gdk_draw_line (window, gc4,
4205 x + width - 1, y, x + width - 1, y + height - 1);
4208 gdk_draw_line (window, gc1,
4209 x, y, x + gap_x - 1, y);
4210 gdk_draw_line (window, gc2,
4211 x + 1, y + 1, x + gap_x - 1, y + 1);
4212 gdk_draw_line (window, gc2,
4213 x + gap_x, y, x + gap_x, y);
4215 if ((width - (gap_x + gap_width)) > 0)
4217 gdk_draw_line (window, gc1,
4218 x + gap_x + gap_width, y, x + width - 2, y);
4219 gdk_draw_line (window, gc2,
4220 x + gap_x + gap_width, y + 1, x + width - 2, y + 1);
4221 gdk_draw_line (window, gc2,
4222 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
4225 case GTK_POS_BOTTOM:
4226 gdk_draw_line (window, gc1,
4227 x, y, x + width - 1, y);
4228 gdk_draw_line (window, gc1,
4229 x, y, x, y + height - 1);
4230 gdk_draw_line (window, gc2,
4231 x + 1, y + 1, x + width - 2, y + 1);
4232 gdk_draw_line (window, gc2,
4233 x + 1, y + 1, x + 1, y + height - 1);
4235 gdk_draw_line (window, gc3,
4236 x + width - 2, y + 1, x + width - 2, y + height - 1);
4237 gdk_draw_line (window, gc4,
4238 x + width - 1, y, x + width - 1, y + height - 1);
4241 gdk_draw_line (window, gc4,
4242 x, y + height - 1, x + gap_x - 1, y + height - 1);
4243 gdk_draw_line (window, gc3,
4244 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
4245 gdk_draw_line (window, gc3,
4246 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
4248 if ((width - (gap_x + gap_width)) > 0)
4250 gdk_draw_line (window, gc4,
4251 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
4252 gdk_draw_line (window, gc3,
4253 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
4254 gdk_draw_line (window, gc3,
4255 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
4259 gdk_draw_line (window, gc1,
4260 x, y, x + width - 1, y);
4261 gdk_draw_line (window, gc2,
4262 x, y + 1, x + width - 2, y + 1);
4264 gdk_draw_line (window, gc3,
4265 x, y + height - 2, x + width - 2, y + height - 2);
4266 gdk_draw_line (window, gc3,
4267 x + width - 2, y + 1, x + width - 2, y + height - 2);
4268 gdk_draw_line (window, gc4,
4269 x, y + height - 1, x + width - 1, y + height - 1);
4270 gdk_draw_line (window, gc4,
4271 x + width - 1, y, x + width - 1, y + height - 1);
4274 gdk_draw_line (window, gc1,
4275 x, y, x, y + gap_x - 1);
4276 gdk_draw_line (window, gc2,
4277 x + 1, y + 1, x + 1, y + gap_x - 1);
4278 gdk_draw_line (window, gc2,
4279 x, y + gap_x, x, y + gap_x);
4281 if ((height - (gap_x + gap_width)) > 0)
4283 gdk_draw_line (window, gc1,
4284 x, y + gap_x + gap_width, x, y + height - 2);
4285 gdk_draw_line (window, gc2,
4286 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
4287 gdk_draw_line (window, gc2,
4288 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
4292 gdk_draw_line (window, gc1,
4293 x, y, x + width - 1, y);
4294 gdk_draw_line (window, gc1,
4295 x, y, x, y + height - 1);
4296 gdk_draw_line (window, gc2,
4297 x + 1, y + 1, x + width - 1, y + 1);
4298 gdk_draw_line (window, gc2,
4299 x + 1, y + 1, x + 1, y + height - 2);
4301 gdk_draw_line (window, gc3,
4302 x + 1, y + height - 2, x + width - 1, y + height - 2);
4303 gdk_draw_line (window, gc4,
4304 x, y + height - 1, x + width - 1, y + height - 1);
4307 gdk_draw_line (window, gc4,
4308 x + width - 1, y, x + width - 1, y + gap_x - 1);
4309 gdk_draw_line (window, gc3,
4310 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
4311 gdk_draw_line (window, gc3,
4312 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
4314 if ((height - (gap_x + gap_width)) > 0)
4316 gdk_draw_line (window, gc4,
4317 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
4318 gdk_draw_line (window, gc3,
4319 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
4320 gdk_draw_line (window, gc3,
4321 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
4329 gdk_gc_set_clip_rectangle (gc1, NULL);
4330 gdk_gc_set_clip_rectangle (gc2, NULL);
4331 gdk_gc_set_clip_rectangle (gc3, NULL);
4332 gdk_gc_set_clip_rectangle (gc4, NULL);
4337 gtk_default_draw_extension (GtkStyle *style,
4339 GtkStateType state_type,
4340 GtkShadowType shadow_type,
4343 const gchar *detail,
4348 GtkPositionType gap_side)
4355 gtk_style_apply_default_background (style, window,
4356 widget && !GTK_WIDGET_NO_WINDOW (widget),
4357 GTK_STATE_NORMAL, area, x, y, width, height);
4359 sanitize_size (window, &width, &height);
4361 switch (shadow_type)
4363 case GTK_SHADOW_NONE:
4366 gc1 = style->dark_gc[state_type];
4367 gc2 = style->black_gc;
4368 gc3 = style->bg_gc[state_type];
4369 gc4 = style->light_gc[state_type];
4371 case GTK_SHADOW_ETCHED_IN:
4372 gc1 = style->dark_gc[state_type];
4373 gc2 = style->light_gc[state_type];
4374 gc3 = style->dark_gc[state_type];
4375 gc4 = style->light_gc[state_type];
4377 case GTK_SHADOW_OUT:
4378 gc1 = style->light_gc[state_type];
4379 gc2 = style->bg_gc[state_type];
4380 gc3 = style->dark_gc[state_type];
4381 gc4 = style->black_gc;
4383 case GTK_SHADOW_ETCHED_OUT:
4384 gc1 = style->light_gc[state_type];
4385 gc2 = style->dark_gc[state_type];
4386 gc3 = style->light_gc[state_type];
4387 gc4 = style->dark_gc[state_type];
4393 gdk_gc_set_clip_rectangle (gc1, area);
4394 gdk_gc_set_clip_rectangle (gc2, area);
4395 gdk_gc_set_clip_rectangle (gc3, area);
4396 gdk_gc_set_clip_rectangle (gc4, area);
4399 switch (shadow_type)
4401 case GTK_SHADOW_NONE:
4403 case GTK_SHADOW_OUT:
4404 case GTK_SHADOW_ETCHED_IN:
4405 case GTK_SHADOW_ETCHED_OUT:
4409 gtk_style_apply_default_background (style, window,
4410 widget && !GTK_WIDGET_NO_WINDOW (widget),
4412 x + style->xthickness,
4414 width - (2 * style->xthickness),
4415 height - (style->ythickness));
4416 gdk_draw_line (window, gc1,
4417 x, y, x, y + height - 2);
4418 gdk_draw_line (window, gc2,
4419 x + 1, y, x + 1, y + height - 2);
4421 gdk_draw_line (window, gc3,
4422 x + 2, y + height - 2, x + width - 2, y + height - 2);
4423 gdk_draw_line (window, gc3,
4424 x + width - 2, y, x + width - 2, y + height - 2);
4425 gdk_draw_line (window, gc4,
4426 x + 1, y + height - 1, x + width - 2, y + height - 1);
4427 gdk_draw_line (window, gc4,
4428 x + width - 1, y, x + width - 1, y + height - 2);
4430 case GTK_POS_BOTTOM:
4431 gtk_style_apply_default_background (style, window,
4432 widget && !GTK_WIDGET_NO_WINDOW (widget),
4434 x + style->xthickness,
4435 y + style->ythickness,
4436 width - (2 * style->xthickness),
4437 height - (style->ythickness));
4438 gdk_draw_line (window, gc1,
4439 x + 1, y, x + width - 2, y);
4440 gdk_draw_line (window, gc1,
4441 x, y + 1, x, y + height - 1);
4442 gdk_draw_line (window, gc2,
4443 x + 1, y + 1, x + width - 2, y + 1);
4444 gdk_draw_line (window, gc2,
4445 x + 1, y + 1, x + 1, y + height - 1);
4447 gdk_draw_line (window, gc3,
4448 x + width - 2, y + 2, x + width - 2, y + height - 1);
4449 gdk_draw_line (window, gc4,
4450 x + width - 1, y + 1, x + width - 1, y + height - 1);
4453 gtk_style_apply_default_background (style, window,
4454 widget && !GTK_WIDGET_NO_WINDOW (widget),
4457 y + style->ythickness,
4458 width - (style->xthickness),
4459 height - (2 * style->ythickness));
4460 gdk_draw_line (window, gc1,
4461 x, y, x + width - 2, y);
4462 gdk_draw_line (window, gc2,
4463 x + 1, y + 1, x + width - 2, y + 1);
4465 gdk_draw_line (window, gc3,
4466 x, y + height - 2, x + width - 2, y + height - 2);
4467 gdk_draw_line (window, gc3,
4468 x + width - 2, y + 2, x + width - 2, y + height - 2);
4469 gdk_draw_line (window, gc4,
4470 x, y + height - 1, x + width - 2, y + height - 1);
4471 gdk_draw_line (window, gc4,
4472 x + width - 1, y + 1, x + width - 1, y + height - 2);
4475 gtk_style_apply_default_background (style, window,
4476 widget && !GTK_WIDGET_NO_WINDOW (widget),
4478 x + style->xthickness,
4479 y + style->ythickness,
4480 width - (style->xthickness),
4481 height - (2 * style->ythickness));
4482 gdk_draw_line (window, gc1,
4483 x + 1, y, x + width - 1, y);
4484 gdk_draw_line (window, gc1,
4485 x, y + 1, x, y + height - 2);
4486 gdk_draw_line (window, gc2,
4487 x + 1, y + 1, x + width - 1, y + 1);
4488 gdk_draw_line (window, gc2,
4489 x + 1, y + 1, x + 1, y + height - 2);
4491 gdk_draw_line (window, gc3,
4492 x + 2, y + height - 2, x + width - 1, y + height - 2);
4493 gdk_draw_line (window, gc4,
4494 x + 1, y + height - 1, x + width - 1, y + height - 1);
4501 gdk_gc_set_clip_rectangle (gc1, NULL);
4502 gdk_gc_set_clip_rectangle (gc2, NULL);
4503 gdk_gc_set_clip_rectangle (gc3, NULL);
4504 gdk_gc_set_clip_rectangle (gc4, NULL);
4509 gtk_default_draw_focus (GtkStyle *style,
4511 GtkStateType state_type,
4514 const gchar *detail,
4521 gboolean free_dash_list = FALSE;
4522 gint line_width = 1;
4523 gint8 *dash_list = "\1\1";
4527 gtk_widget_style_get (widget,
4528 "focus-line-width", &line_width,
4529 "focus-line-pattern", (gchar *)&dash_list,
4532 free_dash_list = TRUE;
4535 if (detail && !strcmp (detail, "add-mode"))
4541 free_dash_list = FALSE;
4544 sanitize_size (window, &width, &height);
4546 cr = gdk_cairo_create (window);
4548 if (detail && !strcmp (detail, "colorwheel_light"))
4549 cairo_set_source_rgb (cr, 0., 0., 0.);
4550 else if (detail && !strcmp (detail, "colorwheel_dark"))
4551 cairo_set_source_rgb (cr, 1., 1., 1.);
4553 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
4555 cairo_set_line_width (cr, line_width);
4559 gint n_dashes = strlen (dash_list);
4560 gdouble *dashes = g_new (gdouble, n_dashes);
4561 gdouble total_length = 0;
4562 gdouble dash_offset;
4565 for (i = 0; i < n_dashes; i++)
4567 dashes[i] = dash_list[i];
4568 total_length += dash_list[i];
4571 /* The dash offset here aligns the pattern to integer pixels
4572 * by starting the dash at the right side of the left border
4573 * Negative dash offsets in cairo don't work
4574 * (https://bugs.freedesktop.org/show_bug.cgi?id=2729)
4576 dash_offset = - line_width / 2.;
4577 while (dash_offset < 0)
4578 dash_offset += total_length;
4580 cairo_set_dash (cr, dashes, n_dashes, dash_offset);
4586 gdk_cairo_rectangle (cr, area);
4590 cairo_rectangle (cr,
4591 x + line_width / 2.,
4592 y + line_width / 2.,
4594 height - line_width);
4603 gtk_default_draw_slider (GtkStyle *style,
4605 GtkStateType state_type,
4606 GtkShadowType shadow_type,
4609 const gchar *detail,
4614 GtkOrientation orientation)
4616 sanitize_size (window, &width, &height);
4618 gtk_paint_box (style, window, state_type, shadow_type,
4619 area, widget, detail, x, y, width, height);
4622 (strcmp ("hscale", detail) == 0 ||
4623 strcmp ("vscale", detail) == 0))
4625 if (orientation == GTK_ORIENTATION_HORIZONTAL)
4626 gtk_paint_vline (style, window, state_type, area, widget, detail,
4627 y + style->ythickness,
4628 y + height - style->ythickness - 1, x + width / 2);
4630 gtk_paint_hline (style, window, state_type, area, widget, detail,
4631 x + style->xthickness,
4632 x + width - style->xthickness - 1, y + height / 2);
4637 draw_dot (GdkWindow *window,
4644 size = CLAMP (size, 2, 3);
4648 gdk_draw_point (window, light_gc, x, y);
4649 gdk_draw_point (window, light_gc, x+1, y+1);
4653 gdk_draw_point (window, light_gc, x, y);
4654 gdk_draw_point (window, light_gc, x+1, y);
4655 gdk_draw_point (window, light_gc, x, y+1);
4656 gdk_draw_point (window, dark_gc, x+1, y+2);
4657 gdk_draw_point (window, dark_gc, x+2, y+1);
4658 gdk_draw_point (window, dark_gc, x+2, y+2);
4663 gtk_default_draw_handle (GtkStyle *style,
4665 GtkStateType state_type,
4666 GtkShadowType shadow_type,
4669 const gchar *detail,
4674 GtkOrientation orientation)
4677 gint xthick, ythick;
4678 GdkGC *light_gc, *dark_gc;
4679 GdkGC *free_me = NULL;
4684 sanitize_size (window, &width, &height);
4686 gtk_paint_box (style, window, state_type, shadow_type, area, widget,
4687 detail, x, y, width, height);
4690 if (detail && !strcmp (detail, "paned"))
4692 /* we want to ignore the shadow border in paned widgets */
4696 if (state_type == GTK_STATE_SELECTED && widget && !GTK_WIDGET_HAS_FOCUS (widget))
4698 GdkColor unfocused_light;
4700 _gtk_style_shade (&style->base[GTK_STATE_ACTIVE], &unfocused_light,
4703 light_gc = free_me = gdk_gc_new (window);
4704 gdk_gc_set_rgb_fg_color (light_gc, &unfocused_light);
4707 light_gc = style->light_gc[state_type];
4709 dark_gc = style->black_gc;
4713 xthick = style->xthickness;
4714 ythick = style->ythickness;
4716 light_gc = style->light_gc[state_type];
4717 dark_gc = style->dark_gc[state_type];
4720 rect.x = x + xthick;
4721 rect.y = y + ythick;
4722 rect.width = width - (xthick * 2);
4723 rect.height = height - (ythick * 2);
4726 intersect = gdk_rectangle_intersect (area, &rect, &dest);
4736 gdk_gc_set_clip_rectangle (light_gc, &dest);
4737 gdk_gc_set_clip_rectangle (dark_gc, &dest);
4739 if (detail && !strcmp (detail, "paned"))
4741 if (orientation == GTK_ORIENTATION_HORIZONTAL)
4742 for (xx = x + width/2 - 15; xx <= x + width/2 + 15; xx += 5)
4743 draw_dot (window, light_gc, dark_gc, xx, y + height/2 - 1, 3);
4745 for (yy = y + height/2 - 15; yy <= y + height/2 + 15; yy += 5)
4746 draw_dot (window, light_gc, dark_gc, x + width/2 - 1, yy, 3);
4750 for (yy = y + ythick; yy < (y + height - ythick); yy += 3)
4751 for (xx = x + xthick; xx < (x + width - xthick); xx += 6)
4753 draw_dot (window, light_gc, dark_gc, xx, yy, 2);
4754 draw_dot (window, light_gc, dark_gc, xx + 3, yy + 1, 2);
4758 gdk_gc_set_clip_rectangle (light_gc, NULL);
4759 gdk_gc_set_clip_rectangle (dark_gc, NULL);
4763 g_object_unref (free_me);
4767 gtk_default_draw_expander (GtkStyle *style,
4769 GtkStateType state_type,
4772 const gchar *detail,
4775 GtkExpanderStyle expander_style)
4777 #define DEFAULT_EXPANDER_SIZE 12
4781 double vertical_overshoot;
4784 double interp; /* interpolation factor for center position */
4785 double x_double_horz, y_double_horz;
4786 double x_double_vert, y_double_vert;
4787 double x_double, y_double;
4790 cairo_t *cr = gdk_cairo_create (window);
4794 gdk_cairo_rectangle (cr, area);
4799 gtk_widget_class_find_style_property (GTK_WIDGET_GET_CLASS (widget),
4802 gtk_widget_style_get (widget,
4803 "expander-size", &expander_size,
4807 expander_size = DEFAULT_EXPANDER_SIZE;
4809 line_width = MAX (1, expander_size/9);
4811 switch (expander_style)
4813 case GTK_EXPANDER_COLLAPSED:
4814 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 180 : 0;
4817 case GTK_EXPANDER_SEMI_COLLAPSED:
4818 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 150 : 30;
4821 case GTK_EXPANDER_SEMI_EXPANDED:
4822 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 120 : 60;
4825 case GTK_EXPANDER_EXPANDED:
4830 g_assert_not_reached ();
4833 /* Compute distance that the stroke extends beyonds the end
4834 * of the triangle we draw.
4836 vertical_overshoot = line_width / 2.0 * (1. / tan (G_PI / 8));
4838 /* For odd line widths, we end the vertical line of the triangle
4839 * at a half pixel, so we round differently.
4841 if (line_width % 2 == 1)
4842 vertical_overshoot = ceil (0.5 + vertical_overshoot) - 0.5;
4844 vertical_overshoot = ceil (vertical_overshoot);
4846 /* Adjust the size of the triangle we draw so that the entire stroke fits
4848 diameter = MAX (3, expander_size - 2 * vertical_overshoot);
4850 /* If the line width is odd, we want the diameter to be even,
4851 * and vice versa, so force the sum to be odd. This relationship
4852 * makes the point of the triangle look right.
4854 diameter -= (1 - (diameter + line_width) % 2);
4856 radius = diameter / 2.;
4858 /* Adjust the center so that the stroke is properly aligned with
4859 * the pixel grid. The center adjustment is different for the
4860 * horizontal and vertical orientations. For intermediate positions
4861 * we interpolate between the two.
4863 x_double_vert = floor (x - (radius + line_width) / 2.) + (radius + line_width) / 2.;
4864 y_double_vert = y - 0.5;
4866 x_double_horz = x - 0.5;
4867 y_double_horz = floor (y - (radius + line_width) / 2.) + (radius + line_width) / 2.;
4869 x_double = x_double_vert * (1 - interp) + x_double_horz * interp;
4870 y_double = y_double_vert * (1 - interp) + y_double_horz * interp;
4872 cairo_translate (cr, x_double, y_double);
4873 cairo_rotate (cr, degrees * G_PI / 180);
4875 cairo_move_to (cr, - radius / 2., - radius);
4876 cairo_line_to (cr, radius / 2., 0);
4877 cairo_line_to (cr, - radius / 2., radius);
4878 cairo_close_path (cr);
4880 cairo_set_line_width (cr, line_width);
4882 if (state_type == GTK_STATE_PRELIGHT)
4883 gdk_cairo_set_source_color (cr,
4884 &style->fg[GTK_STATE_PRELIGHT]);
4885 else if (state_type == GTK_STATE_ACTIVE)
4886 gdk_cairo_set_source_color (cr,
4887 &style->light[GTK_STATE_ACTIVE]);
4889 gdk_cairo_set_source_color (cr,
4890 &style->base[GTK_STATE_NORMAL]);
4892 cairo_fill_preserve (cr);
4894 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
4900 typedef struct _ByteRange ByteRange;
4909 range_new (guint start,
4912 ByteRange *br = g_new (ByteRange, 1);
4921 get_insensitive_layout (GdkDrawable *drawable,
4922 PangoLayout *layout)
4924 GSList *embossed_ranges = NULL;
4925 GSList *stippled_ranges = NULL;
4926 PangoLayoutIter *iter;
4927 GSList *tmp_list = NULL;
4928 PangoLayout *new_layout;
4929 PangoAttrList *attrs;
4930 GdkBitmap *stipple = NULL;
4932 iter = pango_layout_get_iter (layout);
4936 PangoLayoutRun *run;
4937 PangoAttribute *attr;
4938 gboolean need_stipple = FALSE;
4941 run = pango_layout_iter_get_run (iter);
4945 tmp_list = run->item->analysis.extra_attrs;
4947 while (tmp_list != NULL)
4949 attr = tmp_list->data;
4950 switch (attr->klass->type)
4952 case PANGO_ATTR_FOREGROUND:
4953 case PANGO_ATTR_BACKGROUND:
4954 need_stipple = TRUE;
4964 tmp_list = g_slist_next (tmp_list);
4967 br = range_new (run->item->offset, run->item->offset + run->item->length);
4970 stippled_ranges = g_slist_prepend (stippled_ranges, br);
4972 embossed_ranges = g_slist_prepend (embossed_ranges, br);
4975 while (pango_layout_iter_next_run (iter));
4977 pango_layout_iter_free (iter);
4979 new_layout = pango_layout_copy (layout);
4981 attrs = pango_layout_get_attributes (new_layout);
4985 /* Create attr list if there wasn't one */
4986 attrs = pango_attr_list_new ();
4987 pango_layout_set_attributes (new_layout, attrs);
4988 pango_attr_list_unref (attrs);
4991 tmp_list = embossed_ranges;
4992 while (tmp_list != NULL)
4994 PangoAttribute *attr;
4995 ByteRange *br = tmp_list->data;
4997 attr = gdk_pango_attr_embossed_new (TRUE);
4999 attr->start_index = br->start;
5000 attr->end_index = br->end;
5002 pango_attr_list_change (attrs, attr);
5006 tmp_list = g_slist_next (tmp_list);
5009 g_slist_free (embossed_ranges);
5011 tmp_list = stippled_ranges;
5012 while (tmp_list != NULL)
5014 PangoAttribute *attr;
5015 ByteRange *br = tmp_list->data;
5017 if (stipple == NULL)
5019 #define gray50_width 2
5020 #define gray50_height 2
5021 static const char gray50_bits[] = {
5025 stipple = gdk_bitmap_create_from_data (drawable,
5026 gray50_bits, gray50_width,
5030 attr = gdk_pango_attr_stipple_new (stipple);
5032 attr->start_index = br->start;
5033 attr->end_index = br->end;
5035 pango_attr_list_change (attrs, attr);
5039 tmp_list = g_slist_next (tmp_list);
5042 g_slist_free (stippled_ranges);
5045 g_object_unref (stipple);
5051 gtk_default_draw_layout (GtkStyle *style,
5053 GtkStateType state_type,
5057 const gchar *detail,
5060 PangoLayout *layout)
5064 gc = use_text ? style->text_gc[state_type] : style->fg_gc[state_type];
5067 gdk_gc_set_clip_rectangle (gc, area);
5069 if (state_type == GTK_STATE_INSENSITIVE)
5073 ins = get_insensitive_layout (window, layout);
5075 gdk_draw_layout (window, gc, x, y, ins);
5077 g_object_unref (ins);
5081 gdk_draw_layout (window, gc, x, y, layout);
5085 gdk_gc_set_clip_rectangle (gc, NULL);
5089 gtk_default_draw_resize_grip (GtkStyle *style,
5091 GtkStateType state_type,
5094 const gchar *detail,
5106 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
5107 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
5108 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
5114 case GDK_WINDOW_EDGE_NORTH_WEST:
5115 /* make it square */
5118 else if (height < width)
5122 case GDK_WINDOW_EDGE_NORTH:
5126 case GDK_WINDOW_EDGE_NORTH_EAST:
5127 /* make it square, aligning to top right */
5130 else if (height < width)
5132 x += (width - height);
5137 case GDK_WINDOW_EDGE_WEST:
5141 case GDK_WINDOW_EDGE_EAST:
5142 /* aligning to right */
5145 x += (width - height);
5149 case GDK_WINDOW_EDGE_SOUTH_WEST:
5150 /* make it square, aligning to bottom left */
5153 y += (height - width);
5156 else if (height < width)
5160 case GDK_WINDOW_EDGE_SOUTH:
5161 /* align to bottom */
5164 y += (height - width);
5168 case GDK_WINDOW_EDGE_SOUTH_EAST:
5169 /* make it square, aligning to bottom right */
5172 y += (height - width);
5175 else if (height < width)
5177 x += (width - height);
5183 g_assert_not_reached ();
5185 /* Clear background */
5187 for (i = 0; i < 4; i++)
5191 points[j].x = (i == 0 || i == 3) ? x : x + width;
5192 points[j].y = (i < 2) ? y : y + height;
5197 gdk_draw_polygon (window, style->bg_gc[state_type], TRUE,
5198 points, skip < 0 ? 4 : 3);
5202 case GDK_WINDOW_EDGE_WEST:
5203 case GDK_WINDOW_EDGE_EAST:
5209 while (xi < x + width)
5211 gdk_draw_line (window,
5212 style->light_gc[state_type],
5217 gdk_draw_line (window,
5218 style->dark_gc[state_type],
5226 case GDK_WINDOW_EDGE_NORTH:
5227 case GDK_WINDOW_EDGE_SOUTH:
5233 while (yi < y + height)
5235 gdk_draw_line (window,
5236 style->light_gc[state_type],
5241 gdk_draw_line (window,
5242 style->dark_gc[state_type],
5250 case GDK_WINDOW_EDGE_NORTH_WEST:
5259 gdk_draw_line (window,
5260 style->dark_gc[state_type],
5267 gdk_draw_line (window,
5268 style->dark_gc[state_type],
5275 gdk_draw_line (window,
5276 style->light_gc[state_type],
5286 case GDK_WINDOW_EDGE_NORTH_EAST:
5293 while (xi < (x + width - 3))
5295 gdk_draw_line (window,
5296 style->light_gc[state_type],
5303 gdk_draw_line (window,
5304 style->dark_gc[state_type],
5311 gdk_draw_line (window,
5312 style->dark_gc[state_type],
5321 case GDK_WINDOW_EDGE_SOUTH_WEST:
5330 gdk_draw_line (window,
5331 style->dark_gc[state_type],
5338 gdk_draw_line (window,
5339 style->dark_gc[state_type],
5346 gdk_draw_line (window,
5347 style->light_gc[state_type],
5357 case GDK_WINDOW_EDGE_SOUTH_EAST:
5364 while (xi < (x + width - 3))
5366 gdk_draw_line (window,
5367 style->light_gc[state_type],
5374 gdk_draw_line (window,
5375 style->dark_gc[state_type],
5382 gdk_draw_line (window,
5383 style->dark_gc[state_type],
5393 g_assert_not_reached ();
5399 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
5400 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
5401 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
5406 _gtk_style_shade (GdkColor *a,
5414 red = (gdouble) a->red / 65535.0;
5415 green = (gdouble) a->green / 65535.0;
5416 blue = (gdouble) a->blue / 65535.0;
5418 rgb_to_hls (&red, &green, &blue);
5423 else if (green < 0.0)
5429 else if (blue < 0.0)
5432 hls_to_rgb (&red, &green, &blue);
5434 b->red = red * 65535.0;
5435 b->green = green * 65535.0;
5436 b->blue = blue * 65535.0;
5440 rgb_to_hls (gdouble *r,
5481 l = (max + min) / 2;
5488 s = (max - min) / (max + min);
5490 s = (max - min) / (2 - max - min);
5494 h = (green - blue) / delta;
5495 else if (green == max)
5496 h = 2 + (blue - red) / delta;
5497 else if (blue == max)
5498 h = 4 + (red - green) / delta;
5511 hls_to_rgb (gdouble *h,
5524 if (lightness <= 0.5)
5525 m2 = lightness * (1 + saturation);
5527 m2 = lightness + saturation - lightness * saturation;
5528 m1 = 2 * lightness - m2;
5530 if (saturation == 0)
5545 r = m1 + (m2 - m1) * hue / 60;
5549 r = m1 + (m2 - m1) * (240 - hue) / 60;
5560 g = m1 + (m2 - m1) * hue / 60;
5564 g = m1 + (m2 - m1) * (240 - hue) / 60;
5575 b = m1 + (m2 - m1) * hue / 60;
5579 b = m1 + (m2 - m1) * (240 - hue) / 60;
5592 * @style: a #GtkStyle
5593 * @window: a #GdkWindow
5594 * @state_type: a state
5595 * @area: rectangle to which the output is clipped, or %NULL if the
5596 * output should not be clipped
5597 * @widget: the widget (may be %NULL)
5598 * @detail: a style detail (may be %NULL)
5599 * @x1: the starting x coordinate
5600 * @x2: the ending x coordinate
5601 * @y: the y coordinate
5603 * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @window
5604 * using the given style and state.
5607 gtk_paint_hline (GtkStyle *style,
5609 GtkStateType state_type,
5612 const gchar *detail,
5617 g_return_if_fail (GTK_IS_STYLE (style));
5618 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
5619 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5621 GTK_STYLE_GET_CLASS (style)->draw_hline (style, window, state_type, area, widget, detail, x1, x2, y);
5626 * @style: a #GtkStyle
5627 * @window: a #GdkWindow
5628 * @state_type: a state
5629 * @area: rectangle to which the output is clipped, or %NULL if the
5630 * output should not be clipped
5631 * @widget: the widget (may be %NULL)
5632 * @detail: a style detail (may be %NULL)
5633 * @y1_: the starting y coordinate
5634 * @y2_: the ending y coordinate
5635 * @x: the x coordinate
5637 * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @window
5638 * using the given style and state.
5641 gtk_paint_vline (GtkStyle *style,
5643 GtkStateType state_type,
5646 const gchar *detail,
5651 g_return_if_fail (GTK_IS_STYLE (style));
5652 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
5653 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5655 GTK_STYLE_GET_CLASS (style)->draw_vline (style, window, state_type, area, widget, detail, y1_, y2_, x);
5660 * @style: a #GtkStyle
5661 * @window: a #GdkWindow
5662 * @state_type: a state
5663 * @shadow_type: type of shadow to draw
5664 * @area: clip rectangle or %NULL if the
5665 * output should not be clipped
5666 * @widget: the widget (may be %NULL)
5667 * @detail: a style detail (may be %NULL)
5668 * @x: x origin of the rectangle
5669 * @y: y origin of the rectangle
5670 * @width: width of the rectangle
5671 * @height: width of the rectangle
5673 * Draws a shadow around the given rectangle in @window
5674 * using the given style and state and shadow type.
5677 gtk_paint_shadow (GtkStyle *style,
5679 GtkStateType state_type,
5680 GtkShadowType shadow_type,
5683 const gchar *detail,
5689 g_return_if_fail (GTK_IS_STYLE (style));
5690 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
5691 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5693 GTK_STYLE_GET_CLASS (style)->draw_shadow (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
5697 * gtk_paint_polygon:
5698 * @style: a #GtkStyle
5699 * @window: a #GdkWindow
5700 * @state_type: a state
5701 * @shadow_type: type of shadow to draw
5702 * @area: clip rectangle, or %NULL if the
5703 * output should not be clipped
5704 * @widget: the widget (may be %NULL)
5705 * @detail: a style detail (may be %NULL)
5706 * @points: an array of #GdkPoint<!-- -->s
5707 * @npoints: length of @points
5708 * @fill: %TRUE if the polygon should be filled
5710 * Draws a polygon on @window with the given parameters.
5713 gtk_paint_polygon (GtkStyle *style,
5715 GtkStateType state_type,
5716 GtkShadowType shadow_type,
5719 const gchar *detail,
5724 g_return_if_fail (GTK_IS_STYLE (style));
5725 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_polygon != NULL);
5726 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5728 GTK_STYLE_GET_CLASS (style)->draw_polygon (style, window, state_type, shadow_type, area, widget, detail, points, npoints, fill);
5733 * @style: a #GtkStyle
5734 * @window: a #GdkWindow
5735 * @state_type: a state
5736 * @shadow_type: the type of shadow to draw
5737 * @area: clip rectangle, or %NULL if the
5738 * output should not be clipped
5739 * @widget: the widget (may be %NULL)
5740 * @detail: a style detail (may be %NULL)
5741 * @arrow_type: the type of arrow to draw
5742 * @fill: %TRUE if the arrow tip should be filled
5743 * @x: x origin of the rectangle to draw the arrow in
5744 * @y: y origin of the rectangle to draw the arrow in
5745 * @width: width of the rectangle to draw the arrow in
5746 * @height: height of the rectangle to draw the arrow in
5748 * Draws an arrow in the given rectangle on @window using the given
5749 * parameters. @arrow_type determines the direction of the arrow.
5752 gtk_paint_arrow (GtkStyle *style,
5754 GtkStateType state_type,
5755 GtkShadowType shadow_type,
5758 const gchar *detail,
5759 GtkArrowType arrow_type,
5766 g_return_if_fail (GTK_IS_STYLE (style));
5767 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
5768 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5770 GTK_STYLE_GET_CLASS (style)->draw_arrow (style, window, state_type, shadow_type, area, widget, detail, arrow_type, fill, x, y, width, height);
5774 * gtk_paint_diamond:
5775 * @style: a #GtkStyle
5776 * @window: a #GdkWindow
5777 * @state_type: a state
5778 * @shadow_type: the type of shadow to draw
5779 * @area: clip rectangle, or %NULL if the
5780 * output should not be clipped
5781 * @widget: the widget (may be %NULL)
5782 * @detail: a style detail (may be %NULL)
5783 * @x: x origin of the rectangle to draw the diamond in
5784 * @y: y origin of the rectangle to draw the diamond in
5785 * @width: width of the rectangle to draw the diamond in
5786 * @height: height of the rectangle to draw the diamond in
5788 * Draws a diamond in the given rectangle on @window using the given
5792 gtk_paint_diamond (GtkStyle *style,
5794 GtkStateType state_type,
5795 GtkShadowType shadow_type,
5798 const gchar *detail,
5804 g_return_if_fail (GTK_IS_STYLE (style));
5805 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
5806 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5808 GTK_STYLE_GET_CLASS (style)->draw_diamond (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
5813 * @style: a #GtkStyle
5814 * @window: a #GdkWindow
5815 * @state_type: a state
5816 * @area: clip rectangle, or %NULL if the
5817 * output should not be clipped
5818 * @widget: the widget (may be %NULL)
5819 * @detail: a style detail (may be %NULL)
5822 * @string: the string to draw
5824 * Draws a text string on @window with the given parameters.
5826 * Deprecated: Use gtk_paint_layout() instead.
5829 gtk_paint_string (GtkStyle *style,
5831 GtkStateType state_type,
5834 const gchar *detail,
5837 const gchar *string)
5839 g_return_if_fail (GTK_IS_STYLE (style));
5840 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_string != NULL);
5841 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5843 GTK_STYLE_GET_CLASS (style)->draw_string (style, window, state_type, area, widget, detail, x, y, string);
5848 * @style: a #GtkStyle
5849 * @window: a #GdkWindow
5850 * @state_type: a state
5851 * @shadow_type: the type of shadow to draw
5852 * @area: clip rectangle, or %NULL if the
5853 * output should not be clipped
5854 * @widget: the widget (may be %NULL)
5855 * @detail: a style detail (may be %NULL)
5856 * @x: x origin of the box
5857 * @y: y origin of the box
5858 * @width: the width of the box
5859 * @height: the height of the box
5861 * Draws a box on @window with the given parameters.
5864 gtk_paint_box (GtkStyle *style,
5866 GtkStateType state_type,
5867 GtkShadowType shadow_type,
5870 const gchar *detail,
5876 g_return_if_fail (GTK_IS_STYLE (style));
5877 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
5878 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5880 GTK_STYLE_GET_CLASS (style)->draw_box (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
5884 * gtk_paint_flat_box:
5885 * @style: a #GtkStyle
5886 * @window: a #GdkWindow
5887 * @state_type: a state
5888 * @shadow_type: the type of shadow to draw
5889 * @area: clip rectangle, or %NULL if the
5890 * output should not be clipped
5891 * @widget: the widget (may be %NULL)
5892 * @detail: a style detail (may be %NULL)
5893 * @x: x origin of the box
5894 * @y: y origin of the box
5895 * @width: the width of the box
5896 * @height: the height of the box
5898 * Draws a flat box on @window with the given parameters.
5901 gtk_paint_flat_box (GtkStyle *style,
5903 GtkStateType state_type,
5904 GtkShadowType shadow_type,
5907 const gchar *detail,
5913 g_return_if_fail (GTK_IS_STYLE (style));
5914 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
5915 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5917 GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
5922 * @style: a #GtkStyle
5923 * @window: a #GdkWindow
5924 * @state_type: a state
5925 * @shadow_type: the type of shadow to draw
5926 * @area: clip rectangle, or %NULL if the
5927 * output should not be clipped
5928 * @widget: the widget (may be %NULL)
5929 * @detail: a style detail (may be %NULL)
5930 * @x: x origin of the rectangle to draw the check in
5931 * @y: y origin of the rectangle to draw the check in
5932 * @width: the width of the rectangle to draw the check in
5933 * @height: the height of the rectangle to draw the check in
5935 * Draws a check button indicator in the given rectangle on @window with
5936 * the given parameters.
5939 gtk_paint_check (GtkStyle *style,
5941 GtkStateType state_type,
5942 GtkShadowType shadow_type,
5945 const gchar *detail,
5951 g_return_if_fail (GTK_IS_STYLE (style));
5952 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
5953 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5955 GTK_STYLE_GET_CLASS (style)->draw_check (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
5960 * @style: a #GtkStyle
5961 * @window: a #GdkWindow
5962 * @state_type: a state
5963 * @shadow_type: the type of shadow to draw
5964 * @area: clip rectangle, or %NULL if the
5965 * output should not be clipped
5966 * @widget: the widget (may be %NULL)
5967 * @detail: a style detail (may be %NULL)
5968 * @x: x origin of the rectangle to draw the option in
5969 * @y: y origin of the rectangle to draw the option in
5970 * @width: the width of the rectangle to draw the option in
5971 * @height: the height of the rectangle to draw the option in
5973 * Draws a radio button indicator in the given rectangle on @window with
5974 * the given parameters.
5977 gtk_paint_option (GtkStyle *style,
5979 GtkStateType state_type,
5980 GtkShadowType shadow_type,
5983 const gchar *detail,
5989 g_return_if_fail (GTK_IS_STYLE (style));
5990 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
5991 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5993 GTK_STYLE_GET_CLASS (style)->draw_option (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
5998 * @style: a #GtkStyle
5999 * @window: a #GdkWindow
6000 * @state_type: a state
6001 * @shadow_type: the type of shadow to draw
6002 * @area: clip rectangle, or %NULL if the
6003 * output should not be clipped
6004 * @widget: the widget (may be %NULL)
6005 * @detail: a style detail (may be %NULL)
6006 * @x: x origin of the rectangle to draw the tab in
6007 * @y: y origin of the rectangle to draw the tab in
6008 * @width: the width of the rectangle to draw the tab in
6009 * @height: the height of the rectangle to draw the tab in
6011 * Draws an option menu tab (i.e. the up and down pointing arrows)
6012 * in the given rectangle on @window using the given parameters.
6015 gtk_paint_tab (GtkStyle *style,
6017 GtkStateType state_type,
6018 GtkShadowType shadow_type,
6021 const gchar *detail,
6027 g_return_if_fail (GTK_IS_STYLE (style));
6028 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
6029 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6031 GTK_STYLE_GET_CLASS (style)->draw_tab (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
6035 * gtk_paint_shadow_gap:
6036 * @style: a #GtkStyle
6037 * @window: a #GdkWindow
6038 * @state_type: a state
6039 * @shadow_type: type of shadow to draw
6040 * @area: clip rectangle, or %NULL if the
6041 * output should not be clipped
6042 * @widget: the widget (may be %NULL)
6043 * @detail: a style detail (may be %NULL)
6044 * @x: x origin of the rectangle
6045 * @y: y origin of the rectangle
6046 * @width: width of the rectangle
6047 * @height: width of the rectangle
6048 * @gap_side: side in which to leave the gap
6049 * @gap_x: starting position of the gap
6050 * @gap_width: width of the gap
6052 * Draws a shadow around the given rectangle in @window
6053 * using the given style and state and shadow type, leaving a
6057 gtk_paint_shadow_gap (GtkStyle *style,
6059 GtkStateType state_type,
6060 GtkShadowType shadow_type,
6068 GtkPositionType gap_side,
6072 g_return_if_fail (GTK_IS_STYLE (style));
6073 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
6074 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6076 GTK_STYLE_GET_CLASS (style)->draw_shadow_gap (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, gap_side, gap_x, gap_width);
6081 * gtk_paint_box_gap:
6082 * @style: a #GtkStyle
6083 * @window: a #GdkWindow
6084 * @state_type: a state
6085 * @shadow_type: type of shadow to draw
6086 * @area: clip rectangle, or %NULL if the
6087 * output should not be clipped
6088 * @widget: the widget (may be %NULL)
6089 * @detail: a style detail (may be %NULL)
6090 * @x: x origin of the rectangle
6091 * @y: y origin of the rectangle
6092 * @width: width of the rectangle
6093 * @height: width of the rectangle
6094 * @gap_side: side in which to leave the gap
6095 * @gap_x: starting position of the gap
6096 * @gap_width: width of the gap
6098 * Draws a box in @window using the given style and state and shadow type,
6099 * leaving a gap in one side.
6102 gtk_paint_box_gap (GtkStyle *style,
6104 GtkStateType state_type,
6105 GtkShadowType shadow_type,
6113 GtkPositionType gap_side,
6117 g_return_if_fail (GTK_IS_STYLE (style));
6118 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
6119 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6121 GTK_STYLE_GET_CLASS (style)->draw_box_gap (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, gap_side, gap_x, gap_width);
6125 * gtk_paint_extension:
6126 * @style: a #GtkStyle
6127 * @window: a #GdkWindow
6128 * @state_type: a state
6129 * @shadow_type: type of shadow to draw
6130 * @area: clip rectangle, or %NULL if the
6131 * output should not be clipped
6132 * @widget: the widget (may be %NULL)
6133 * @detail: a style detail (may be %NULL)
6134 * @x: x origin of the extension
6135 * @y: y origin of the extension
6136 * @width: width of the extension
6137 * @height: width of the extension
6138 * @gap_side: the side on to which the extension is attached
6140 * Draws an extension, i.e. a notebook tab.
6143 gtk_paint_extension (GtkStyle *style,
6145 GtkStateType state_type,
6146 GtkShadowType shadow_type,
6154 GtkPositionType gap_side)
6156 g_return_if_fail (GTK_IS_STYLE (style));
6157 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
6158 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6160 GTK_STYLE_GET_CLASS (style)->draw_extension (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, gap_side);
6165 * @style: a #GtkStyle
6166 * @window: a #GdkWindow
6167 * @state_type: a state
6168 * @area: clip rectangle, or %NULL if the
6169 * output should not be clipped
6170 * @widget: the widget (may be %NULL)
6171 * @detail: a style detail (may be %NULL)
6172 * @x: the x origin of the rectangle around which to draw a focus indicator
6173 * @y: the y origin of the rectangle around which to draw a focus indicator
6174 * @width: the width of the rectangle around which to draw a focus indicator
6175 * @height: the height of the rectangle around which to draw a focus indicator
6177 * Draws a focus indicator around the given rectangle on @window using the
6181 gtk_paint_focus (GtkStyle *style,
6183 GtkStateType state_type,
6186 const gchar *detail,
6192 g_return_if_fail (GTK_IS_STYLE (style));
6193 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
6194 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6196 GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, state_type, area, widget, detail, x, y, width, height);
6201 * @style: a #GtkStyle
6202 * @window: a #GdkWindow
6203 * @state_type: a state
6204 * @shadow_type: a shadow
6205 * @area: clip rectangle, or %NULL if the
6206 * output should not be clipped
6207 * @widget: the widget (may be %NULL)
6208 * @detail: a style detail (may be %NULL)
6209 * @x: the x origin of the rectangle in which to draw a slider
6210 * @y: the y origin of the rectangle in which to draw a slider
6211 * @width: the width of the rectangle in which to draw a slider
6212 * @height: the height of the rectangle in which to draw a slider
6213 * @orientation: the orientation to be used
6215 * Draws a slider in the given rectangle on @window using the
6216 * given style and orientation.
6219 gtk_paint_slider (GtkStyle *style,
6221 GtkStateType state_type,
6222 GtkShadowType shadow_type,
6225 const gchar *detail,
6230 GtkOrientation orientation)
6232 g_return_if_fail (GTK_IS_STYLE (style));
6233 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
6234 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6236 GTK_STYLE_GET_CLASS (style)->draw_slider (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, orientation);
6241 * @style: a #GtkStyle
6242 * @window: a #GdkWindow
6243 * @state_type: a state
6244 * @shadow_type: type of shadow to draw
6245 * @area: clip rectangle, or %NULL if the
6246 * output should not be clipped
6247 * @widget: the widget (may be %NULL)
6248 * @detail: a style detail (may be %NULL)
6249 * @x: x origin of the handle
6250 * @y: y origin of the handle
6251 * @width: with of the handle
6252 * @height: height of the handle
6253 * @orientation: the orientation of the handle
6255 * Draws a handle as used in #GtkHandleBox and #GtkPaned.
6258 gtk_paint_handle (GtkStyle *style,
6260 GtkStateType state_type,
6261 GtkShadowType shadow_type,
6264 const gchar *detail,
6269 GtkOrientation orientation)
6271 g_return_if_fail (GTK_IS_STYLE (style));
6272 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
6273 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6275 GTK_STYLE_GET_CLASS (style)->draw_handle (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, orientation);
6279 * gtk_paint_expander:
6280 * @style: a #GtkStyle
6281 * @window: a #GdkWindow
6282 * @state_type: a state
6283 * @area: clip rectangle, or %NULL if the
6284 * output should not be clipped
6285 * @widget: the widget (may be %NULL)
6286 * @detail: a style detail (may be %NULL)
6287 * @x: the x position to draw the expander at
6288 * @y: the y position to draw the expander at
6289 * @expander_style: the style to draw the expander in; determines
6290 * whether the expander is collapsed, expanded, or in an
6291 * intermediate state.
6293 * Draws an expander as used in #GtkTreeView. @x and @y specify the
6294 * center the expander. The size of the expander is determined by the
6295 * "expander-size" style property of @widget. (If widget is not
6296 * specified or doesn't have an "expander-size" property, an
6297 * unspecified default size will be used, since the caller doesn't
6298 * have sufficient information to position the expander, this is
6299 * likely not useful.) The expander is expander_size pixels tall
6300 * in the collapsed position and expander_size pixels wide in the
6301 * expanded position.
6304 gtk_paint_expander (GtkStyle *style,
6306 GtkStateType state_type,
6309 const gchar *detail,
6312 GtkExpanderStyle expander_style)
6314 g_return_if_fail (GTK_IS_STYLE (style));
6315 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
6316 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6318 GTK_STYLE_GET_CLASS (style)->draw_expander (style, window, state_type, area,
6319 widget, detail, x, y, expander_style);
6324 * @style: a #GtkStyle
6325 * @window: a #GdkWindow
6326 * @state_type: a state
6327 * @use_text: whether to use the text or foreground
6328 * graphics context of @style
6329 * @area: clip rectangle, or %NULL if the
6330 * output should not be clipped
6331 * @widget: the widget (may be %NULL)
6332 * @detail: a style detail (may be %NULL)
6335 * @layout: the layout to draw
6337 * Draws a layout on @window using the given parameters.
6340 gtk_paint_layout (GtkStyle *style,
6342 GtkStateType state_type,
6346 const gchar *detail,
6349 PangoLayout *layout)
6351 g_return_if_fail (GTK_IS_STYLE (style));
6352 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
6353 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6355 GTK_STYLE_GET_CLASS (style)->draw_layout (style, window, state_type, use_text, area,
6356 widget, detail, x, y, layout);
6360 * gtk_paint_resize_grip:
6361 * @style: a #GtkStyle
6362 * @window: a #GdkWindow
6363 * @state_type: a state
6364 * @area: clip rectangle, or %NULL if the
6365 * output should not be clipped
6366 * @widget: the widget (may be %NULL)
6367 * @detail: a style detail (may be %NULL)
6368 * @edge: the edge in which to draw the resize grip
6369 * @x: the x origin of the rectangle in which to draw the resize grip
6370 * @y: the y origin of the rectangle in which to draw the resize grip
6371 * @width: the width of the rectangle in which to draw the resize grip
6372 * @height: the height of the rectangle in which to draw the resize grip
6374 * Draws a resize grip in the given rectangle on @window using the given
6378 gtk_paint_resize_grip (GtkStyle *style,
6380 GtkStateType state_type,
6383 const gchar *detail,
6391 g_return_if_fail (GTK_IS_STYLE (style));
6392 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
6393 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6395 GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, window, state_type,
6396 area, widget, detail,
6397 edge, x, y, width, height);
6402 * @border_: a #GtkBorder.
6403 * @returns: a copy of @border_.
6405 * Copies a #GtkBorder structure.
6408 gtk_border_copy (const GtkBorder *border)
6410 return (GtkBorder *)g_memdup (border, sizeof (GtkBorder));
6415 * @border_: a #GtkBorder.
6417 * Frees a #GtkBorder structure.
6420 gtk_border_free (GtkBorder *border)
6426 gtk_border_get_type (void)
6428 static GType our_type = 0;
6431 our_type = g_boxed_type_register_static (I_("GtkBorder"),
6432 (GBoxedCopyFunc) gtk_border_copy,
6433 (GBoxedFreeFunc) gtk_border_free);
6439 gtk_style_get_font_internal (GtkStyle *style)
6441 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
6443 if (style->private_font && style->private_font_desc)
6445 if (!style->font_desc ||
6446 !pango_font_description_equal (style->private_font_desc, style->font_desc))
6448 gdk_font_unref (style->private_font);
6449 style->private_font = NULL;
6451 if (style->private_font_desc)
6453 pango_font_description_free (style->private_font_desc);
6454 style->private_font_desc = NULL;
6459 if (!style->private_font)
6461 GdkDisplay *display;
6463 if (style->colormap)
6465 display = gdk_screen_get_display (gdk_colormap_get_screen (style->colormap));
6469 display = gdk_display_get_default ();
6470 GTK_NOTE (MULTIHEAD,
6471 g_warning ("gtk_style_get_font() should not be called on an unattached style"));
6474 if (style->font_desc)
6476 style->private_font = gdk_font_from_description_for_display (display, style->font_desc);
6477 style->private_font_desc = pango_font_description_copy (style->font_desc);
6480 if (!style->private_font)
6481 style->private_font = gdk_font_load_for_display (display, "fixed");
6483 if (!style->private_font)
6484 g_error ("Unable to load \"fixed\" font");
6487 return style->private_font;
6491 * gtk_style_get_font:
6492 * @style: a #GtkStyle
6494 * Gets the #GdkFont to use for the given style. This is
6495 * meant only as a replacement for direct access to @style->font
6496 * and should not be used in new code. New code should
6497 * use @style->font_desc instead.
6499 * Return value: the #GdkFont for the style. This font is owned
6500 * by the style; if you want to keep around a copy, you must
6501 * call gdk_font_ref().
6504 gtk_style_get_font (GtkStyle *style)
6506 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
6508 return gtk_style_get_font_internal (style);
6512 * gtk_style_set_font:
6513 * @style: a #GtkStyle.
6514 * @font: a #GdkFont, or %NULL to use the #GdkFont corresponding
6515 * to style->font_desc.
6517 * Sets the #GdkFont to use for a given style. This is
6518 * meant only as a replacement for direct access to style->font
6519 * and should not be used in new code. New code should
6520 * use style->font_desc instead.
6523 gtk_style_set_font (GtkStyle *style,
6528 g_return_if_fail (GTK_IS_STYLE (style));
6530 old_font = style->private_font;
6532 style->private_font = font;
6534 gdk_font_ref (font);
6537 gdk_font_unref (old_font);
6539 if (style->private_font_desc)
6541 pango_font_description_free (style->private_font_desc);
6542 style->private_font_desc = NULL;
6546 typedef struct _CursorInfo CursorInfo;
6552 GdkGC *secondary_gc;
6556 style_unrealize_cursor_gcs (GtkStyle *style)
6560 cursor_info = g_object_get_data (G_OBJECT (style), "gtk-style-cursor-info");
6563 if (cursor_info->primary_gc)
6564 gtk_gc_release (cursor_info->primary_gc);
6566 if (cursor_info->secondary_gc)
6567 gtk_gc_release (cursor_info->secondary_gc);
6569 g_free (cursor_info);
6570 g_object_set_data (G_OBJECT (style), I_("gtk-style-cursor-info"), NULL);
6575 make_cursor_gc (GtkWidget *widget,
6576 const gchar *property_name,
6577 const GdkColor *fallback)
6579 GdkGCValues gc_values;
6580 GdkGCValuesMask gc_values_mask;
6581 GdkColor *cursor_color;
6583 gtk_widget_style_get (widget, property_name, &cursor_color, NULL);
6585 gc_values_mask = GDK_GC_FOREGROUND;
6588 gc_values.foreground = *cursor_color;
6589 gdk_color_free (cursor_color);
6592 gc_values.foreground = *fallback;
6594 gdk_rgb_find_color (widget->style->colormap, &gc_values.foreground);
6595 return gtk_gc_get (widget->style->depth, widget->style->colormap, &gc_values, gc_values_mask);
6599 get_insertion_cursor_gc (GtkWidget *widget,
6600 gboolean is_primary)
6602 CursorInfo *cursor_info;
6604 cursor_info = g_object_get_data (G_OBJECT (widget->style), "gtk-style-cursor-info");
6607 cursor_info = g_new (CursorInfo, 1);
6608 g_object_set_data (G_OBJECT (widget->style), I_("gtk-style-cursor-info"), cursor_info);
6609 cursor_info->primary_gc = NULL;
6610 cursor_info->secondary_gc = NULL;
6611 cursor_info->for_type = G_TYPE_INVALID;
6614 /* We have to keep track of the type because gtk_widget_style_get()
6615 * can return different results when called on the same property and
6616 * same style but for different widgets. :-(. That is,
6617 * GtkEntry::cursor-color = "red" in a style will modify the cursor
6618 * color for entries but not for text view.
6620 if (cursor_info->for_type != G_OBJECT_TYPE (widget))
6622 cursor_info->for_type = G_OBJECT_TYPE (widget);
6623 if (cursor_info->primary_gc)
6625 gtk_gc_release (cursor_info->primary_gc);
6626 cursor_info->primary_gc = NULL;
6628 if (cursor_info->secondary_gc)
6630 gtk_gc_release (cursor_info->secondary_gc);
6631 cursor_info->secondary_gc = NULL;
6637 if (!cursor_info->primary_gc)
6638 cursor_info->primary_gc = make_cursor_gc (widget,
6640 &widget->style->black);
6642 return cursor_info->primary_gc;
6646 static const GdkColor gray = { 0, 0x8888, 0x8888, 0x8888 };
6648 if (!cursor_info->secondary_gc)
6649 cursor_info->secondary_gc = make_cursor_gc (widget,
6650 "secondary-cursor-color",
6653 return cursor_info->secondary_gc;
6658 draw_insertion_cursor (GtkWidget *widget,
6659 GdkDrawable *drawable,
6661 GdkRectangle *location,
6662 GtkTextDirection direction,
6663 gboolean draw_arrow)
6669 gfloat cursor_aspect_ratio;
6672 /* When changing the shape or size of the cursor here,
6673 * propagate the changes to gtktextview.c:text_window_invalidate_cursors().
6676 gtk_widget_style_get (widget, "cursor-aspect-ratio", &cursor_aspect_ratio, NULL);
6678 stem_width = location->height * cursor_aspect_ratio + 1;
6679 arrow_width = stem_width + 1;
6681 /* put (stem_width % 2) on the proper side of the cursor */
6682 if (direction == GTK_TEXT_DIR_LTR)
6683 offset = stem_width / 2;
6685 offset = stem_width - stem_width / 2;
6687 for (i = 0; i < stem_width; i++)
6688 gdk_draw_line (drawable, gc,
6689 location->x + i - offset, location->y,
6690 location->x + i - offset, location->y + location->height - 1);
6694 if (direction == GTK_TEXT_DIR_RTL)
6696 x = location->x - offset - 1;
6697 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
6699 for (i = 0; i < arrow_width; i++)
6701 gdk_draw_line (drawable, gc,
6703 x, y + 2 * arrow_width - i - 1);
6707 else if (direction == GTK_TEXT_DIR_LTR)
6709 x = location->x + stem_width - offset;
6710 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
6712 for (i = 0; i < arrow_width; i++)
6714 gdk_draw_line (drawable, gc,
6716 x, y + 2 * arrow_width - i - 1);
6724 * gtk_draw_insertion_cursor:
6725 * @widget: a #GtkWidget
6726 * @drawable: a #GdkDrawable
6727 * @area: rectangle to which the output is clipped, or %NULL if the
6728 * output should not be clipped
6729 * @location: location where to draw the cursor (@location->width is ignored)
6730 * @is_primary: if the cursor should be the primary cursor color.
6731 * @direction: whether the cursor is left-to-right or
6732 * right-to-left. Should never be #GTK_TEXT_DIR_NONE
6733 * @draw_arrow: %TRUE to draw a directional arrow on the
6734 * cursor. Should be %FALSE unless the cursor is split.
6736 * Draws a text caret on @drawable at @location. This is not a style function
6737 * but merely a convenience function for drawing the standard cursor shape.
6742 gtk_draw_insertion_cursor (GtkWidget *widget,
6743 GdkDrawable *drawable,
6745 GdkRectangle *location,
6746 gboolean is_primary,
6747 GtkTextDirection direction,
6748 gboolean draw_arrow)
6752 g_return_if_fail (GTK_IS_WIDGET (widget));
6753 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
6754 g_return_if_fail (location != NULL);
6755 g_return_if_fail (direction != GTK_TEXT_DIR_NONE);
6757 gc = get_insertion_cursor_gc (widget, is_primary);
6759 gdk_gc_set_clip_rectangle (gc, area);
6761 draw_insertion_cursor (widget, drawable, gc,
6762 location, direction, draw_arrow);
6765 gdk_gc_set_clip_rectangle (gc, NULL);
6768 #define __GTK_STYLE_C__
6769 #include "gtkaliasdef.c"