1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
31 #include <gobject/gvaluecollector.h>
33 #include "gtkmarshalers.h"
34 #undef GTK_DISABLE_DEPRECATED
35 #include "gtkoptionmenu.h"
37 #include "gtkspinbutton.h"
39 #include "gtkwidget.h"
40 #include "gtkthemes.h"
41 #include "gtkiconfactory.h"
42 #include "gtksettings.h" /* _gtk_settings_parse_convert() */
46 #define LIGHTNESS_MULT 1.3
47 #define DARKNESS_MULT 0.7
49 /* --- typedefs & structures --- */
56 #define GTK_STYLE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_STYLE, GtkStylePrivate))
58 typedef struct _GtkStylePrivate GtkStylePrivate;
60 struct _GtkStylePrivate {
64 /* --- prototypes --- */
65 static void gtk_style_finalize (GObject *object);
66 static void gtk_style_realize (GtkStyle *style,
67 GdkColormap *colormap);
68 static void gtk_style_real_realize (GtkStyle *style);
69 static void gtk_style_real_unrealize (GtkStyle *style);
70 static void gtk_style_real_copy (GtkStyle *style,
72 static void gtk_style_real_set_background (GtkStyle *style,
74 GtkStateType state_type);
75 static GtkStyle *gtk_style_real_clone (GtkStyle *style);
76 static void gtk_style_real_init_from_rc (GtkStyle *style,
77 GtkRcStyle *rc_style);
78 static GdkPixbuf *gtk_default_render_icon (GtkStyle *style,
79 const GtkIconSource *source,
80 GtkTextDirection direction,
85 static void gtk_default_draw_hline (GtkStyle *style,
87 GtkStateType state_type,
94 static void gtk_default_draw_vline (GtkStyle *style,
96 GtkStateType state_type,
103 static void gtk_default_draw_shadow (GtkStyle *style,
105 GtkStateType state_type,
106 GtkShadowType shadow_type,
114 static void gtk_default_draw_polygon (GtkStyle *style,
116 GtkStateType state_type,
117 GtkShadowType shadow_type,
124 static void gtk_default_draw_arrow (GtkStyle *style,
126 GtkStateType state_type,
127 GtkShadowType shadow_type,
131 GtkArrowType arrow_type,
137 static void gtk_default_draw_diamond (GtkStyle *style,
139 GtkStateType state_type,
140 GtkShadowType shadow_type,
148 static void gtk_default_draw_string (GtkStyle *style,
150 GtkStateType state_type,
156 const gchar *string);
157 static void gtk_default_draw_box (GtkStyle *style,
159 GtkStateType state_type,
160 GtkShadowType shadow_type,
168 static void gtk_default_draw_flat_box (GtkStyle *style,
170 GtkStateType state_type,
171 GtkShadowType shadow_type,
179 static void gtk_default_draw_check (GtkStyle *style,
181 GtkStateType state_type,
182 GtkShadowType shadow_type,
190 static void gtk_default_draw_option (GtkStyle *style,
192 GtkStateType state_type,
193 GtkShadowType shadow_type,
201 static void gtk_default_draw_tab (GtkStyle *style,
203 GtkStateType state_type,
204 GtkShadowType shadow_type,
212 static void gtk_default_draw_shadow_gap (GtkStyle *style,
214 GtkStateType state_type,
215 GtkShadowType shadow_type,
223 GtkPositionType gap_side,
226 static void gtk_default_draw_box_gap (GtkStyle *style,
228 GtkStateType state_type,
229 GtkShadowType shadow_type,
237 GtkPositionType gap_side,
240 static void gtk_default_draw_extension (GtkStyle *style,
242 GtkStateType state_type,
243 GtkShadowType shadow_type,
251 GtkPositionType gap_side);
252 static void gtk_default_draw_focus (GtkStyle *style,
254 GtkStateType state_type,
262 static void gtk_default_draw_slider (GtkStyle *style,
264 GtkStateType state_type,
265 GtkShadowType shadow_type,
273 GtkOrientation orientation);
274 static void gtk_default_draw_handle (GtkStyle *style,
276 GtkStateType state_type,
277 GtkShadowType shadow_type,
285 GtkOrientation orientation);
286 static void gtk_default_draw_expander (GtkStyle *style,
288 GtkStateType state_type,
294 GtkExpanderStyle expander_style);
295 static void gtk_default_draw_layout (GtkStyle *style,
297 GtkStateType state_type,
304 PangoLayout *layout);
305 static void gtk_default_draw_resize_grip (GtkStyle *style,
307 GtkStateType state_type,
316 static void gtk_default_draw_spinner (GtkStyle *style,
318 GtkStateType state_type,
325 static void rgb_to_hls (gdouble *r,
328 static void hls_to_rgb (gdouble *h,
332 static void style_unrealize_cursor_gcs (GtkStyle *style);
334 static GdkFont *gtk_style_get_font_internal (GtkStyle *style);
337 * Data for default check and radio buttons
340 static const GtkRequisition default_option_indicator_size = { 7, 13 };
341 static const GtkBorder default_option_indicator_spacing = { 7, 5, 2, 2 };
343 #define GTK_GRAY 0xdcdc, 0xdada, 0xd5d5
344 #define GTK_DARK_GRAY 0xc4c4, 0xc2c2, 0xbdbd
345 #define GTK_LIGHT_GRAY 0xeeee, 0xebeb, 0xe7e7
346 #define GTK_WHITE 0xffff, 0xffff, 0xffff
347 #define GTK_BLUE 0x4b4b, 0x6969, 0x8383
348 #define GTK_VERY_DARK_GRAY 0x9c9c, 0x9a9a, 0x9494
349 #define GTK_BLACK 0x0000, 0x0000, 0x0000
350 #define GTK_WEAK_GRAY 0x7530, 0x7530, 0x7530
352 /* --- variables --- */
353 static const GdkColor gtk_default_normal_fg = { 0, GTK_BLACK };
354 static const GdkColor gtk_default_active_fg = { 0, GTK_BLACK };
355 static const GdkColor gtk_default_prelight_fg = { 0, GTK_BLACK };
356 static const GdkColor gtk_default_selected_fg = { 0, GTK_WHITE };
357 static const GdkColor gtk_default_insensitive_fg = { 0, GTK_WEAK_GRAY };
359 static const GdkColor gtk_default_normal_bg = { 0, GTK_GRAY };
360 static const GdkColor gtk_default_active_bg = { 0, GTK_DARK_GRAY };
361 static const GdkColor gtk_default_prelight_bg = { 0, GTK_LIGHT_GRAY };
362 static const GdkColor gtk_default_selected_bg = { 0, GTK_BLUE };
363 static const GdkColor gtk_default_insensitive_bg = { 0, GTK_GRAY };
364 static const GdkColor gtk_default_selected_base = { 0, GTK_BLUE };
365 static const GdkColor gtk_default_active_base = { 0, GTK_VERY_DARK_GRAY };
367 /* --- signals --- */
368 static guint realize_signal = 0;
369 static guint unrealize_signal = 0;
371 G_DEFINE_TYPE (GtkStyle, gtk_style, G_TYPE_OBJECT)
373 /* --- functions --- */
376 * _gtk_style_init_for_settings:
377 * @style: a #GtkStyle
378 * @settings: a #GtkSettings
380 * Initializes the font description in @style according to the default
381 * font name of @settings. This is called for gtk_style_new() with
382 * the settings for the default screen (if any); if we are creating
383 * a style for a particular screen, we then call it again in a
384 * location where we know the correct settings.
385 * The reason for this is that gtk_rc_style_create_style() doesn't
386 * take the screen for an argument.
389 _gtk_style_init_for_settings (GtkStyle *style,
390 GtkSettings *settings)
392 const gchar *font_name = _gtk_rc_context_get_default_font_name (settings);
394 if (style->font_desc)
395 pango_font_description_free (style->font_desc);
397 style->font_desc = pango_font_description_from_string (font_name);
399 if (!pango_font_description_get_family (style->font_desc))
401 g_warning ("Default font does not have a family set");
402 pango_font_description_set_family (style->font_desc, "Sans");
404 if (pango_font_description_get_size (style->font_desc) <= 0)
406 g_warning ("Default font does not have a positive size");
407 pango_font_description_set_size (style->font_desc, 10 * PANGO_SCALE);
412 gtk_style_init (GtkStyle *style)
416 GtkSettings *settings = gtk_settings_get_default ();
419 _gtk_style_init_for_settings (style, settings);
421 style->font_desc = pango_font_description_from_string ("Sans 10");
423 style->attach_count = 0;
424 style->colormap = NULL;
427 style->black.red = 0;
428 style->black.green = 0;
429 style->black.blue = 0;
431 style->white.red = 65535;
432 style->white.green = 65535;
433 style->white.blue = 65535;
435 style->black_gc = NULL;
436 style->white_gc = NULL;
438 style->fg[GTK_STATE_NORMAL] = gtk_default_normal_fg;
439 style->fg[GTK_STATE_ACTIVE] = gtk_default_active_fg;
440 style->fg[GTK_STATE_PRELIGHT] = gtk_default_prelight_fg;
441 style->fg[GTK_STATE_SELECTED] = gtk_default_selected_fg;
442 style->fg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
444 style->bg[GTK_STATE_NORMAL] = gtk_default_normal_bg;
445 style->bg[GTK_STATE_ACTIVE] = gtk_default_active_bg;
446 style->bg[GTK_STATE_PRELIGHT] = gtk_default_prelight_bg;
447 style->bg[GTK_STATE_SELECTED] = gtk_default_selected_bg;
448 style->bg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_bg;
450 for (i = 0; i < 4; i++)
452 style->text[i] = style->fg[i];
453 style->base[i] = style->white;
456 style->base[GTK_STATE_SELECTED] = gtk_default_selected_base;
457 style->text[GTK_STATE_SELECTED] = style->white;
458 style->base[GTK_STATE_ACTIVE] = gtk_default_active_base;
459 style->text[GTK_STATE_ACTIVE] = style->white;
460 style->base[GTK_STATE_INSENSITIVE] = gtk_default_prelight_bg;
461 style->text[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
463 for (i = 0; i < 5; i++)
464 style->bg_pixmap[i] = NULL;
466 style->rc_style = NULL;
468 for (i = 0; i < 5; i++)
470 style->fg_gc[i] = NULL;
471 style->bg_gc[i] = NULL;
472 style->light_gc[i] = NULL;
473 style->dark_gc[i] = NULL;
474 style->mid_gc[i] = NULL;
475 style->text_gc[i] = NULL;
476 style->base_gc[i] = NULL;
477 style->text_aa_gc[i] = NULL;
480 style->xthickness = 2;
481 style->ythickness = 2;
483 style->property_cache = NULL;
487 gtk_style_class_init (GtkStyleClass *klass)
489 GObjectClass *object_class = G_OBJECT_CLASS (klass);
491 object_class->finalize = gtk_style_finalize;
493 klass->clone = gtk_style_real_clone;
494 klass->copy = gtk_style_real_copy;
495 klass->init_from_rc = gtk_style_real_init_from_rc;
496 klass->realize = gtk_style_real_realize;
497 klass->unrealize = gtk_style_real_unrealize;
498 klass->set_background = gtk_style_real_set_background;
499 klass->render_icon = gtk_default_render_icon;
501 klass->draw_hline = gtk_default_draw_hline;
502 klass->draw_vline = gtk_default_draw_vline;
503 klass->draw_shadow = gtk_default_draw_shadow;
504 klass->draw_polygon = gtk_default_draw_polygon;
505 klass->draw_arrow = gtk_default_draw_arrow;
506 klass->draw_diamond = gtk_default_draw_diamond;
507 klass->draw_string = gtk_default_draw_string;
508 klass->draw_box = gtk_default_draw_box;
509 klass->draw_flat_box = gtk_default_draw_flat_box;
510 klass->draw_check = gtk_default_draw_check;
511 klass->draw_option = gtk_default_draw_option;
512 klass->draw_tab = gtk_default_draw_tab;
513 klass->draw_shadow_gap = gtk_default_draw_shadow_gap;
514 klass->draw_box_gap = gtk_default_draw_box_gap;
515 klass->draw_extension = gtk_default_draw_extension;
516 klass->draw_focus = gtk_default_draw_focus;
517 klass->draw_slider = gtk_default_draw_slider;
518 klass->draw_handle = gtk_default_draw_handle;
519 klass->draw_expander = gtk_default_draw_expander;
520 klass->draw_layout = gtk_default_draw_layout;
521 klass->draw_resize_grip = gtk_default_draw_resize_grip;
522 klass->draw_spinner = gtk_default_draw_spinner;
524 g_type_class_add_private (object_class, sizeof (GtkStylePrivate));
528 * @style: the object which received the signal
530 * Emitted when the style has been initialized for a particular
531 * colormap and depth. Connecting to this signal is probably seldom
532 * useful since most of the time applications and widgets only
533 * deal with styles that have been already realized.
537 realize_signal = g_signal_new (I_("realize"),
538 G_TYPE_FROM_CLASS (object_class),
540 G_STRUCT_OFFSET (GtkStyleClass, realize),
542 _gtk_marshal_VOID__VOID,
545 * GtkStyle::unrealize:
546 * @style: the object which received the signal
548 * Emitted when the aspects of the style specific to a particular colormap
549 * and depth are being cleaned up. A connection to this signal can be useful
550 * if a widget wants to cache objects like a #GdkGC as object data on #GtkStyle.
551 * This signal provides a convenient place to free such cached objects.
555 unrealize_signal = g_signal_new (I_("unrealize"),
556 G_TYPE_FROM_CLASS (object_class),
558 G_STRUCT_OFFSET (GtkStyleClass, unrealize),
560 _gtk_marshal_VOID__VOID,
565 clear_property_cache (GtkStyle *style)
567 if (style->property_cache)
571 for (i = 0; i < style->property_cache->len; i++)
573 PropertyValue *node = &g_array_index (style->property_cache, PropertyValue, i);
575 g_param_spec_unref (node->pspec);
576 g_value_unset (&node->value);
578 g_array_free (style->property_cache, TRUE);
579 style->property_cache = NULL;
584 gtk_style_finalize (GObject *object)
586 GtkStyle *style = GTK_STYLE (object);
587 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
589 g_return_if_fail (style->attach_count == 0);
591 clear_property_cache (style);
593 /* All the styles in the list have the same
594 * style->styles pointer. If we delete the
595 * *first* style from the list, we need to update
596 * the style->styles pointers from all the styles.
597 * Otherwise we simply remove the node from
602 if (style->styles->data != style)
603 style->styles = g_slist_remove (style->styles, style);
606 GSList *tmp_list = style->styles->next;
610 GTK_STYLE (tmp_list->data)->styles = style->styles->next;
611 tmp_list = tmp_list->next;
613 g_slist_free_1 (style->styles);
617 g_slist_foreach (style->icon_factories, (GFunc) g_object_unref, NULL);
618 g_slist_free (style->icon_factories);
620 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_unref, NULL);
621 g_slist_free (priv->color_hashes);
623 pango_font_description_free (style->font_desc);
625 if (style->private_font)
626 gdk_font_unref (style->private_font);
628 if (style->private_font_desc)
629 pango_font_description_free (style->private_font_desc);
632 g_object_unref (style->rc_style);
634 G_OBJECT_CLASS (gtk_style_parent_class)->finalize (object);
640 * @style: a #GtkStyle
642 * Creates a copy of the passed in #GtkStyle object.
644 * Returns: a copy of @style
647 gtk_style_copy (GtkStyle *style)
651 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
653 new_style = GTK_STYLE_GET_CLASS (style)->clone (style);
654 GTK_STYLE_GET_CLASS (style)->copy (new_style, style);
660 gtk_style_duplicate (GtkStyle *style)
664 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
666 new_style = gtk_style_copy (style);
668 /* All the styles in the list have the same
669 * style->styles pointer. When we insert a new
670 * style, we append it to the list to avoid having
671 * to update the existing ones.
673 style->styles = g_slist_append (style->styles, new_style);
674 new_style->styles = style->styles;
681 * @returns: a new #GtkStyle.
683 * Creates a new #GtkStyle.
690 style = g_object_new (GTK_TYPE_STYLE, NULL);
697 * @style: a #GtkStyle.
698 * @window: a #GdkWindow.
700 * Attaches a style to a window; this process allocates the
701 * colors and creates the GC's for the style - it specializes
702 * it to a particular visual and colormap. The process may
703 * involve the creation of a new style if the style has already
704 * been attached to a window with a different style and colormap.
706 * Since this function may return a new object, you have to use it
707 * in the following way:
708 * <literal>style = gtk_style_attach (style, window)</literal>
710 * Returns: Either @style, or a newly-created #GtkStyle.
711 * If the style is newly created, the style parameter
712 * will be unref'ed, and the new style will have
713 * a reference count belonging to the caller.
716 gtk_style_attach (GtkStyle *style,
720 GtkStyle *new_style = NULL;
721 GdkColormap *colormap;
723 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
724 g_return_val_if_fail (window != NULL, NULL);
726 colormap = gdk_drawable_get_colormap (window);
729 style->styles = g_slist_append (NULL, style);
731 styles = style->styles;
734 new_style = styles->data;
736 if (new_style->colormap == colormap)
740 styles = styles->next;
745 styles = style->styles;
749 new_style = styles->data;
751 if (new_style->attach_count == 0)
753 gtk_style_realize (new_style, colormap);
758 styles = styles->next;
764 new_style = gtk_style_duplicate (style);
765 if (gdk_colormap_get_screen (style->colormap) != gdk_colormap_get_screen (colormap) &&
766 new_style->private_font)
768 gdk_font_unref (new_style->private_font);
769 new_style->private_font = NULL;
771 gtk_style_realize (new_style, colormap);
774 /* A style gets a refcount from being attached */
775 if (new_style->attach_count == 0)
776 g_object_ref (new_style);
778 /* Another refcount belongs to the parent */
779 if (style != new_style)
781 g_object_unref (style);
782 g_object_ref (new_style);
785 new_style->attach_count++;
792 * @style: a #GtkStyle
794 * Detaches a style from a window. If the style is not attached
795 * to any windows anymore, it is unrealized. See gtk_style_attach().
799 gtk_style_detach (GtkStyle *style)
801 g_return_if_fail (GTK_IS_STYLE (style));
802 g_return_if_fail (style->attach_count > 0);
804 style->attach_count -= 1;
805 if (style->attach_count == 0)
807 g_signal_emit (style, unrealize_signal, 0);
809 g_object_unref (style->colormap);
810 style->colormap = NULL;
812 if (style->private_font_desc)
814 if (style->private_font)
816 gdk_font_unref (style->private_font);
817 style->private_font = NULL;
820 pango_font_description_free (style->private_font_desc);
821 style->private_font_desc = NULL;
824 g_object_unref (style);
830 * @style: a #GtkStyle.
833 * Increase the reference count of @style.
835 * Deprecated: 2.0: use g_object_ref() instead.
838 gtk_style_ref (GtkStyle *style)
840 return (GtkStyle *) g_object_ref (style);
845 * @style: a #GtkStyle.
847 * Decrease the reference count of @style.
849 * Deprecated: 2.0: use g_object_unref() instead.
852 gtk_style_unref (GtkStyle *style)
854 g_object_unref (style);
858 gtk_style_realize (GtkStyle *style,
859 GdkColormap *colormap)
861 style->colormap = g_object_ref (colormap);
862 style->depth = gdk_colormap_get_visual (colormap)->depth;
864 g_signal_emit (style, realize_signal, 0);
868 * gtk_style_lookup_icon_set:
869 * @style: a #GtkStyle
870 * @stock_id: an icon name
872 * Looks up @stock_id in the icon factories associated with @style
873 * and the default icon factory, returning an icon set if found,
876 * Return value: icon set of @stock_id
879 gtk_style_lookup_icon_set (GtkStyle *style,
880 const char *stock_id)
884 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
885 g_return_val_if_fail (stock_id != NULL, NULL);
887 iter = style->icon_factories;
890 GtkIconSet *icon_set = gtk_icon_factory_lookup (GTK_ICON_FACTORY (iter->data),
895 iter = g_slist_next (iter);
898 return gtk_icon_factory_lookup_default (stock_id);
902 * gtk_style_lookup_color:
903 * @style: a #GtkStyle
904 * @color_name: the name of the logical color to look up
905 * @color: the #GdkColor to fill in
907 * Looks up @color_name in the style's logical color mappings,
908 * filling in @color and returning %TRUE if found, otherwise
909 * returning %FALSE. Do not cache the found mapping, because
910 * it depends on the #GtkStyle and might change when a theme
913 * Return value: %TRUE if the mapping was found.
918 gtk_style_lookup_color (GtkStyle *style,
919 const char *color_name,
922 GtkStylePrivate *priv;
925 g_return_val_if_fail (GTK_IS_STYLE (style), FALSE);
926 g_return_val_if_fail (color_name != NULL, FALSE);
927 g_return_val_if_fail (color != NULL, FALSE);
929 priv = GTK_STYLE_GET_PRIVATE (style);
931 for (iter = priv->color_hashes; iter != NULL; iter = iter->next)
933 GHashTable *hash = iter->data;
934 GdkColor *mapping = g_hash_table_lookup (hash, color_name);
938 color->red = mapping->red;
939 color->green = mapping->green;
940 color->blue = mapping->blue;
950 * @style: a #GtkStyle
951 * @window: a #GdkWindow
952 * @state_type: a state
953 * @x1: the starting x coordinate
954 * @x2: the ending x coordinate
955 * @y: the y coordinate
957 * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @window
958 * using the given style and state.
960 * Deprecated: 2.0: Use gtk_paint_hline() instead.
963 gtk_draw_hline (GtkStyle *style,
965 GtkStateType state_type,
970 g_return_if_fail (GTK_IS_STYLE (style));
971 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
973 GTK_STYLE_GET_CLASS (style)->draw_hline (style, window, state_type, NULL, NULL, NULL, x1, x2, y);
979 * @style: a #GtkStyle
980 * @window: a #GdkWindow
981 * @state_type: a state
982 * @y1_: the starting y coordinate
983 * @y2_: the ending y coordinate
984 * @x: the x coordinate
986 * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @window
987 * using the given style and state.
989 * Deprecated: 2.0: Use gtk_paint_vline() instead.
992 gtk_draw_vline (GtkStyle *style,
994 GtkStateType state_type,
999 g_return_if_fail (GTK_IS_STYLE (style));
1000 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
1002 GTK_STYLE_GET_CLASS (style)->draw_vline (style, window, state_type, NULL, NULL, NULL, y1_, y2_, x);
1007 * @style: a #GtkStyle
1008 * @window: a #GdkWindow
1009 * @state_type: a state
1010 * @shadow_type: type of shadow to draw
1011 * @x: x origin of the rectangle
1012 * @y: y origin of the rectangle
1013 * @width: width of the rectangle
1014 * @height: width of the rectangle
1016 * Draws a shadow around the given rectangle in @window
1017 * using the given style and state and shadow type.
1019 * Deprecated: 2.0: Use gtk_paint_shadow() instead.
1022 gtk_draw_shadow (GtkStyle *style,
1024 GtkStateType state_type,
1025 GtkShadowType shadow_type,
1031 g_return_if_fail (GTK_IS_STYLE (style));
1032 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
1034 GTK_STYLE_GET_CLASS (style)->draw_shadow (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1039 * @style: a #GtkStyle
1040 * @window: a #GdkWindow
1041 * @state_type: a state
1042 * @shadow_type: type of shadow to draw
1043 * @points: an array of #GdkPoint<!-- -->s
1044 * @npoints: length of @points
1045 * @fill: %TRUE if the polygon should be filled
1047 * Draws a polygon on @window with the given parameters.
1049 * Deprecated: 2.0: Use gtk_paint_polygon() instead.
1052 gtk_draw_polygon (GtkStyle *style,
1054 GtkStateType state_type,
1055 GtkShadowType shadow_type,
1060 g_return_if_fail (GTK_IS_STYLE (style));
1061 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_polygon != NULL);
1063 GTK_STYLE_GET_CLASS (style)->draw_polygon (style, window, state_type, shadow_type, NULL, NULL, NULL, points, npoints, fill);
1068 * @style: a #GtkStyle
1069 * @window: a #GdkWindow
1070 * @state_type: a state
1071 * @shadow_type: the type of shadow to draw
1072 * @arrow_type: the type of arrow to draw
1073 * @fill: %TRUE if the arrow tip should be filled
1074 * @x: x origin of the rectangle to draw the arrow in
1075 * @y: y origin of the rectangle to draw the arrow in
1076 * @width: width of the rectangle to draw the arrow in
1077 * @height: height of the rectangle to draw the arrow in
1079 * Draws an arrow in the given rectangle on @window using the given
1080 * parameters. @arrow_type determines the direction of the arrow.
1082 * Deprecated: 2.0: Use gtk_paint_arrow() instead.
1085 gtk_draw_arrow (GtkStyle *style,
1087 GtkStateType state_type,
1088 GtkShadowType shadow_type,
1089 GtkArrowType arrow_type,
1096 g_return_if_fail (GTK_IS_STYLE (style));
1097 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
1099 GTK_STYLE_GET_CLASS (style)->draw_arrow (style, window, state_type, shadow_type, NULL, NULL, NULL, arrow_type, fill, x, y, width, height);
1104 * @style: a #GtkStyle
1105 * @window: a #GdkWindow
1106 * @state_type: a state
1107 * @shadow_type: the type of shadow to draw
1108 * @x: x origin of the rectangle to draw the diamond in
1109 * @y: y origin of the rectangle to draw the diamond in
1110 * @width: width of the rectangle to draw the diamond in
1111 * @height: height of the rectangle to draw the diamond in
1113 * Draws a diamond in the given rectangle on @window using the given
1116 * Deprecated: 2.0: Use gtk_paint_diamond() instead.
1119 gtk_draw_diamond (GtkStyle *style,
1121 GtkStateType state_type,
1122 GtkShadowType shadow_type,
1128 g_return_if_fail (GTK_IS_STYLE (style));
1129 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
1131 GTK_STYLE_GET_CLASS (style)->draw_diamond (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1136 * @style: a #GtkStyle
1137 * @window: a #GdkWindow
1138 * @state_type: a state
1141 * @string: the string to draw
1143 * Draws a text string on @window with the given parameters.
1145 * Deprecated: 2.0: Use gtk_paint_layout() instead.
1148 gtk_draw_string (GtkStyle *style,
1150 GtkStateType state_type,
1153 const gchar *string)
1155 g_return_if_fail (GTK_IS_STYLE (style));
1156 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_string != NULL);
1158 GTK_STYLE_GET_CLASS (style)->draw_string (style, window, state_type, NULL, NULL, NULL, x, y, string);
1163 * @style: a #GtkStyle
1164 * @window: a #GdkWindow
1165 * @state_type: a state
1166 * @shadow_type: the type of shadow to draw
1167 * @x: x origin of the box
1168 * @y: y origin of the box
1169 * @width: the width of the box
1170 * @height: the height of the box
1172 * Draws a box on @window with the given parameters.
1174 * Deprecated: 2.0: Use gtk_paint_box() instead.
1177 gtk_draw_box (GtkStyle *style,
1179 GtkStateType state_type,
1180 GtkShadowType shadow_type,
1186 g_return_if_fail (GTK_IS_STYLE (style));
1187 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
1189 GTK_STYLE_GET_CLASS (style)->draw_box (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1193 * gtk_draw_flat_box:
1194 * @style: a #GtkStyle
1195 * @window: a #GdkWindow
1196 * @state_type: a state
1197 * @shadow_type: the type of shadow to draw
1198 * @x: x origin of the box
1199 * @y: y origin of the box
1200 * @width: the width of the box
1201 * @height: the height of the box
1203 * Draws a flat box on @window with the given parameters.
1205 * Deprecated: 2.0: Use gtk_paint_flat_box() instead.
1208 gtk_draw_flat_box (GtkStyle *style,
1210 GtkStateType state_type,
1211 GtkShadowType shadow_type,
1217 g_return_if_fail (GTK_IS_STYLE (style));
1218 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
1220 GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1225 * @style: a #GtkStyle
1226 * @window: a #GdkWindow
1227 * @state_type: a state
1228 * @shadow_type: the type of shadow to draw
1229 * @x: x origin of the rectangle to draw the check in
1230 * @y: y origin of the rectangle to draw the check in
1231 * @width: the width of the rectangle to draw the check in
1232 * @height: the height of the rectangle to draw the check in
1234 * Draws a check button indicator in the given rectangle on @window with
1235 * the given parameters.
1237 * Deprecated: 2.0: Use gtk_paint_check() instead.
1240 gtk_draw_check (GtkStyle *style,
1242 GtkStateType state_type,
1243 GtkShadowType shadow_type,
1249 g_return_if_fail (GTK_IS_STYLE (style));
1250 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
1252 GTK_STYLE_GET_CLASS (style)->draw_check (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1257 * @style: a #GtkStyle
1258 * @window: a #GdkWindow
1259 * @state_type: a state
1260 * @shadow_type: the type of shadow to draw
1261 * @x: x origin of the rectangle to draw the option in
1262 * @y: y origin of the rectangle to draw the option in
1263 * @width: the width of the rectangle to draw the option in
1264 * @height: the height of the rectangle to draw the option in
1266 * Draws a radio button indicator in the given rectangle on @window with
1267 * the given parameters.
1269 * Deprecated: 2.0: Use gtk_paint_option() instead.
1272 gtk_draw_option (GtkStyle *style,
1274 GtkStateType state_type,
1275 GtkShadowType shadow_type,
1281 g_return_if_fail (GTK_IS_STYLE (style));
1282 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
1284 GTK_STYLE_GET_CLASS (style)->draw_option (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1289 * @style: a #GtkStyle
1290 * @window: a #GdkWindow
1291 * @state_type: a state
1292 * @shadow_type: the type of shadow to draw
1293 * @x: x origin of the rectangle to draw the tab in
1294 * @y: y origin of the rectangle to draw the tab in
1295 * @width: the width of the rectangle to draw the tab in
1296 * @height: the height of the rectangle to draw the tab in
1298 * Draws an option menu tab (i.e. the up and down pointing arrows)
1299 * in the given rectangle on @window using the given parameters.
1301 * Deprecated: 2.0: Use gtk_paint_tab() instead.
1304 gtk_draw_tab (GtkStyle *style,
1306 GtkStateType state_type,
1307 GtkShadowType shadow_type,
1313 g_return_if_fail (GTK_IS_STYLE (style));
1314 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
1316 GTK_STYLE_GET_CLASS (style)->draw_tab (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1320 * gtk_draw_shadow_gap:
1321 * @style: a #GtkStyle
1322 * @window: a #GdkWindow
1323 * @state_type: a state
1324 * @shadow_type: type of shadow to draw
1325 * @x: x origin of the rectangle
1326 * @y: y origin of the rectangle
1327 * @width: width of the rectangle
1328 * @height: width of the rectangle
1329 * @gap_side: side in which to leave the gap
1330 * @gap_x: starting position of the gap
1331 * @gap_width: width of the gap
1333 * Draws a shadow around the given rectangle in @window
1334 * using the given style and state and shadow type, leaving a
1337 * Deprecated: 2.0: Use gtk_paint_shadow_gap() instead.
1340 gtk_draw_shadow_gap (GtkStyle *style,
1342 GtkStateType state_type,
1343 GtkShadowType shadow_type,
1348 GtkPositionType gap_side,
1352 g_return_if_fail (GTK_IS_STYLE (style));
1353 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
1355 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);
1360 * @style: a #GtkStyle
1361 * @window: a #GdkWindow
1362 * @state_type: a state
1363 * @shadow_type: type of shadow to draw
1364 * @x: x origin of the rectangle
1365 * @y: y origin of the rectangle
1366 * @width: width of the rectangle
1367 * @height: width of the rectangle
1368 * @gap_side: side in which to leave the gap
1369 * @gap_x: starting position of the gap
1370 * @gap_width: width of the gap
1372 * Draws a box in @window using the given style and state and shadow type,
1373 * leaving a gap in one side.
1375 * Deprecated: 2.0: Use gtk_paint_box_gap() instead.
1378 gtk_draw_box_gap (GtkStyle *style,
1380 GtkStateType state_type,
1381 GtkShadowType shadow_type,
1386 GtkPositionType gap_side,
1390 g_return_if_fail (GTK_IS_STYLE (style));
1391 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
1393 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);
1397 * gtk_draw_extension:
1398 * @style: a #GtkStyle
1399 * @window: a #GdkWindow
1400 * @state_type: a state
1401 * @shadow_type: type of shadow to draw
1402 * @x: x origin of the extension
1403 * @y: y origin of the extension
1404 * @width: width of the extension
1405 * @height: width of the extension
1406 * @gap_side: the side on to which the extension is attached
1408 * Draws an extension, i.e. a notebook tab.
1410 * Deprecated: 2.0: Use gtk_paint_extension() instead.
1413 gtk_draw_extension (GtkStyle *style,
1415 GtkStateType state_type,
1416 GtkShadowType shadow_type,
1421 GtkPositionType gap_side)
1423 g_return_if_fail (GTK_IS_STYLE (style));
1424 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
1426 GTK_STYLE_GET_CLASS (style)->draw_extension (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, gap_side);
1431 * @style: a #GtkStyle
1432 * @window: a #GdkWindow
1433 * @x: the x origin of the rectangle around which to draw a focus indicator
1434 * @y: the y origin of the rectangle around which to draw a focus indicator
1435 * @width: the width of the rectangle around which to draw a focus indicator
1436 * @height: the height of the rectangle around which to draw a focus indicator
1438 * Draws a focus indicator around the given rectangle on @window using the
1441 * Deprecated: 2.0: Use gtk_paint_focus() instead.
1444 gtk_draw_focus (GtkStyle *style,
1451 g_return_if_fail (GTK_IS_STYLE (style));
1452 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
1454 GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, GTK_STATE_NORMAL, NULL, NULL, NULL, x, y, width, height);
1459 * @style: a #GtkStyle
1460 @window: a #GdkWindow
1461 * @state_type: a state
1462 * @shadow_type: a shadow
1463 * @x: the x origin of the rectangle in which to draw a slider
1464 * @y: the y origin of the rectangle in which to draw a slider
1465 * @width: the width of the rectangle in which to draw a slider
1466 * @height: the height of the rectangle in which to draw a slider
1467 * @orientation: the orientation to be used
1469 * Draws a slider in the given rectangle on @window using the
1470 * given style and orientation.
1473 gtk_draw_slider (GtkStyle *style,
1475 GtkStateType state_type,
1476 GtkShadowType shadow_type,
1481 GtkOrientation orientation)
1483 g_return_if_fail (GTK_IS_STYLE (style));
1484 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
1486 GTK_STYLE_GET_CLASS (style)->draw_slider (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, orientation);
1491 * @style: a #GtkStyle
1492 * @window: a #GdkWindow
1493 * @state_type: a state
1494 * @shadow_type: type of shadow to draw
1495 * @x: x origin of the handle
1496 * @y: y origin of the handle
1497 * @width: with of the handle
1498 * @height: height of the handle
1499 * @orientation: the orientation of the handle
1501 * Draws a handle as used in #GtkHandleBox and #GtkPaned.
1503 * Deprecated: 2.0: Use gtk_paint_handle() instead.
1506 gtk_draw_handle (GtkStyle *style,
1508 GtkStateType state_type,
1509 GtkShadowType shadow_type,
1514 GtkOrientation orientation)
1516 g_return_if_fail (GTK_IS_STYLE (style));
1517 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
1519 GTK_STYLE_GET_CLASS (style)->draw_handle (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, orientation);
1523 * gtk_draw_expander:
1524 * @style: a #GtkStyle
1525 * @window: a #GdkWindow
1526 * @state_type: a state
1527 * @x: the x position to draw the expander at
1528 * @y: the y position to draw the expander at
1529 * @expander_style: the style to draw the expander in
1531 * Draws an expander as used in #GtkTreeView.
1533 * Deprecated: 2.0: Use gtk_paint_expander() instead.
1536 gtk_draw_expander (GtkStyle *style,
1538 GtkStateType state_type,
1541 GtkExpanderStyle expander_style)
1543 g_return_if_fail (GTK_IS_STYLE (style));
1544 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
1546 GTK_STYLE_GET_CLASS (style)->draw_expander (style, window, state_type,
1548 x, y, expander_style);
1553 * @style: a #GtkStyle
1554 * @window: a #GdkWindow
1555 * @state_type: a state
1556 * @use_text: whether to use the text or foreground
1557 * graphics context of @style
1560 * @layout: the layout to draw
1562 * Draws a layout on @window using the given parameters.
1565 gtk_draw_layout (GtkStyle *style,
1567 GtkStateType state_type,
1571 PangoLayout *layout)
1573 g_return_if_fail (GTK_IS_STYLE (style));
1574 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
1576 GTK_STYLE_GET_CLASS (style)->draw_layout (style, window, state_type, use_text,
1582 * gtk_draw_resize_grip:
1583 * @style: a #GtkStyle
1584 * @window: a #GdkWindow
1585 * @state_type: a state
1586 * @edge: the edge in which to draw the resize grip
1587 * @x: the x origin of the rectangle in which to draw the resize grip
1588 * @y: the y origin of the rectangle in which to draw the resize grip
1589 * @width: the width of the rectangle in which to draw the resize grip
1590 * @height: the height of the rectangle in which to draw the resize grip
1592 * Draws a resize grip in the given rectangle on @window using the given
1595 * Deprecated: 2.0: Use gtk_paint_resize_grip() instead.
1598 gtk_draw_resize_grip (GtkStyle *style,
1600 GtkStateType state_type,
1607 g_return_if_fail (GTK_IS_STYLE (style));
1608 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
1610 GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, window, state_type,
1613 x, y, width, height);
1618 * gtk_style_set_background:
1619 * @style: a #GtkStyle
1620 * @window: a #GdkWindow
1621 * @state_type: a state
1623 * Sets the background of @window to the background color or pixmap
1624 * specified by @style for the given state.
1627 gtk_style_set_background (GtkStyle *style,
1629 GtkStateType state_type)
1631 g_return_if_fail (GTK_IS_STYLE (style));
1632 g_return_if_fail (window != NULL);
1634 GTK_STYLE_GET_CLASS (style)->set_background (style, window, state_type);
1637 /* Default functions */
1639 gtk_style_real_clone (GtkStyle *style)
1641 return g_object_new (G_OBJECT_TYPE (style), NULL);
1645 gtk_style_real_copy (GtkStyle *style,
1648 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
1649 GtkStylePrivate *src_priv = GTK_STYLE_GET_PRIVATE (src);
1652 for (i = 0; i < 5; i++)
1654 style->fg[i] = src->fg[i];
1655 style->bg[i] = src->bg[i];
1656 style->text[i] = src->text[i];
1657 style->base[i] = src->base[i];
1659 if (style->bg_pixmap[i])
1660 g_object_unref (style->bg_pixmap[i]),
1661 style->bg_pixmap[i] = src->bg_pixmap[i];
1662 if (style->bg_pixmap[i])
1663 g_object_ref (style->bg_pixmap[i]);
1666 if (style->private_font)
1667 gdk_font_unref (style->private_font);
1668 style->private_font = src->private_font;
1669 if (style->private_font)
1670 gdk_font_ref (style->private_font);
1672 if (style->font_desc)
1673 pango_font_description_free (style->font_desc);
1675 style->font_desc = pango_font_description_copy (src->font_desc);
1677 style->font_desc = NULL;
1679 style->xthickness = src->xthickness;
1680 style->ythickness = src->ythickness;
1682 if (style->rc_style)
1683 g_object_unref (style->rc_style);
1684 style->rc_style = src->rc_style;
1686 g_object_ref (src->rc_style);
1688 g_slist_foreach (style->icon_factories, (GFunc) g_object_unref, NULL);
1689 g_slist_free (style->icon_factories);
1690 style->icon_factories = g_slist_copy (src->icon_factories);
1691 g_slist_foreach (style->icon_factories, (GFunc) g_object_ref, NULL);
1693 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_unref, NULL);
1694 g_slist_free (priv->color_hashes);
1695 priv->color_hashes = g_slist_copy (src_priv->color_hashes);
1696 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_ref, NULL);
1698 /* don't copy, just clear cache */
1699 clear_property_cache (style);
1703 gtk_style_real_init_from_rc (GtkStyle *style,
1704 GtkRcStyle *rc_style)
1706 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
1709 /* cache _should_ be still empty */
1710 clear_property_cache (style);
1712 if (rc_style->font_desc)
1713 pango_font_description_merge (style->font_desc, rc_style->font_desc, TRUE);
1715 for (i = 0; i < 5; i++)
1717 if (rc_style->color_flags[i] & GTK_RC_FG)
1718 style->fg[i] = rc_style->fg[i];
1719 if (rc_style->color_flags[i] & GTK_RC_BG)
1720 style->bg[i] = rc_style->bg[i];
1721 if (rc_style->color_flags[i] & GTK_RC_TEXT)
1722 style->text[i] = rc_style->text[i];
1723 if (rc_style->color_flags[i] & GTK_RC_BASE)
1724 style->base[i] = rc_style->base[i];
1727 if (rc_style->xthickness >= 0)
1728 style->xthickness = rc_style->xthickness;
1729 if (rc_style->ythickness >= 0)
1730 style->ythickness = rc_style->ythickness;
1732 style->icon_factories = g_slist_copy (rc_style->icon_factories);
1733 g_slist_foreach (style->icon_factories, (GFunc) g_object_ref, NULL);
1735 priv->color_hashes = g_slist_copy (_gtk_rc_style_get_color_hashes (rc_style));
1736 g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_ref, NULL);
1740 style_property_values_cmp (gconstpointer bsearch_node1,
1741 gconstpointer bsearch_node2)
1743 const PropertyValue *val1 = bsearch_node1;
1744 const PropertyValue *val2 = bsearch_node2;
1746 if (val1->widget_type == val2->widget_type)
1747 return val1->pspec < val2->pspec ? -1 : val1->pspec == val2->pspec ? 0 : 1;
1749 return val1->widget_type < val2->widget_type ? -1 : 1;
1753 * gtk_style_get_style_property:
1754 * @style: a #GtkStyle
1755 * @widget_type: the #GType of a descendant of #GtkWidget
1756 * @property_name: the name of the style property to get
1757 * @value: a #GValue where the value of the property being
1758 * queried will be stored
1760 * Queries the value of a style property corresponding to a
1761 * widget class is in the given style.
1766 gtk_style_get_style_property (GtkStyle *style,
1768 const gchar *property_name,
1771 GtkWidgetClass *klass;
1773 GtkRcPropertyParser parser;
1774 const GValue *peek_value;
1776 klass = g_type_class_ref (widget_type);
1777 pspec = gtk_widget_class_find_style_property (klass, property_name);
1778 g_type_class_unref (klass);
1782 g_warning ("%s: widget class `%s' has no property named `%s'",
1784 g_type_name (widget_type),
1789 parser = g_param_spec_get_qdata (pspec,
1790 g_quark_from_static_string ("gtk-rc-property-parser"));
1792 peek_value = _gtk_style_peek_property_value (style, widget_type, pspec, parser);
1794 if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec))
1795 g_value_copy (peek_value, value);
1796 else if (g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
1797 g_value_transform (peek_value, value);
1799 g_warning ("can't retrieve style property `%s' of type `%s' as value of type `%s'",
1801 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1802 G_VALUE_TYPE_NAME (value));
1806 * gtk_style_get_valist:
1807 * @style: a #GtkStyle
1808 * @widget_type: the #GType of a descendant of #GtkWidget
1809 * @first_property_name: the name of the first style property to get
1810 * @var_args: a <type>va_list</type> of pairs of property names and
1811 * locations to return the property values, starting with the
1812 * location for @first_property_name.
1814 * Non-vararg variant of gtk_style_get().
1815 * Used primarily by language bindings.
1820 gtk_style_get_valist (GtkStyle *style,
1822 const gchar *first_property_name,
1825 const char *property_name;
1826 GtkWidgetClass *klass;
1828 g_return_if_fail (GTK_IS_STYLE (style));
1830 klass = g_type_class_ref (widget_type);
1832 property_name = first_property_name;
1833 while (property_name)
1836 GtkRcPropertyParser parser;
1837 const GValue *peek_value;
1840 pspec = gtk_widget_class_find_style_property (klass, property_name);
1844 g_warning ("%s: widget class `%s' has no property named `%s'",
1846 g_type_name (widget_type),
1851 parser = g_param_spec_get_qdata (pspec,
1852 g_quark_from_static_string ("gtk-rc-property-parser"));
1854 peek_value = _gtk_style_peek_property_value (style, widget_type, pspec, parser);
1855 G_VALUE_LCOPY (peek_value, var_args, 0, &error);
1858 g_warning ("%s: %s", G_STRLOC, error);
1863 property_name = va_arg (var_args, gchar*);
1866 g_type_class_unref (klass);
1871 * @style: a #GtkStyle
1872 * @widget_type: the #GType of a descendant of #GtkWidget
1873 * @first_property_name: the name of the first style property to get
1874 * @Varargs: pairs of property names and locations to
1875 * return the property values, starting with the location for
1876 * @first_property_name, terminated by %NULL.
1878 * Gets the values of a multiple style properties for @widget_type
1884 gtk_style_get (GtkStyle *style,
1886 const gchar *first_property_name,
1891 va_start (var_args, first_property_name);
1892 gtk_style_get_valist (style, widget_type, first_property_name, var_args);
1897 _gtk_style_peek_property_value (GtkStyle *style,
1900 GtkRcPropertyParser parser)
1902 PropertyValue *pcache, key = { 0, NULL, { 0, } };
1903 const GtkRcProperty *rcprop = NULL;
1906 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1907 g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL);
1908 g_return_val_if_fail (g_type_is_a (pspec->owner_type, GTK_TYPE_WIDGET), NULL);
1909 g_return_val_if_fail (g_type_is_a (widget_type, pspec->owner_type), NULL);
1911 key.widget_type = widget_type;
1914 /* need value cache array */
1915 if (!style->property_cache)
1916 style->property_cache = g_array_new (FALSE, FALSE, sizeof (PropertyValue));
1919 pcache = bsearch (&key,
1920 style->property_cache->data, style->property_cache->len,
1921 sizeof (PropertyValue), style_property_values_cmp);
1923 return &pcache->value;
1927 while (i < style->property_cache->len &&
1928 style_property_values_cmp (&key, &g_array_index (style->property_cache, PropertyValue, i)) >= 0)
1931 g_array_insert_val (style->property_cache, i, key);
1932 pcache = &g_array_index (style->property_cache, PropertyValue, i);
1934 /* cache miss, initialize value type, then set contents */
1935 g_param_spec_ref (pcache->pspec);
1936 g_value_init (&pcache->value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1938 /* value provided by rc style? */
1939 if (style->rc_style)
1941 GQuark prop_quark = g_quark_from_string (pspec->name);
1945 rcprop = _gtk_rc_style_lookup_rc_property (style->rc_style,
1946 g_type_qname (widget_type),
1950 widget_type = g_type_parent (widget_type);
1952 while (g_type_is_a (widget_type, pspec->owner_type));
1955 /* when supplied by rc style, we need to convert */
1956 if (rcprop && !_gtk_settings_parse_convert (parser, &rcprop->value,
1957 pspec, &pcache->value))
1959 gchar *contents = g_strdup_value_contents (&rcprop->value);
1961 g_message ("%s: failed to retrieve property `%s::%s' of type `%s' from rc file value \"%s\" of type `%s'",
1962 rcprop->origin ? rcprop->origin : "(for origin information, set GTK_DEBUG)",
1963 g_type_name (pspec->owner_type), pspec->name,
1964 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1966 G_VALUE_TYPE_NAME (&rcprop->value));
1968 rcprop = NULL; /* needs default */
1971 /* not supplied by rc style (or conversion failed), revert to default */
1973 g_param_value_set_default (pspec, &pcache->value);
1975 return &pcache->value;
1979 load_bg_image (GdkColormap *colormap,
1981 const gchar *filename)
1983 if (strcmp (filename, "<parent>") == 0)
1984 return (GdkPixmap*) GDK_PARENT_RELATIVE;
1987 return gdk_pixmap_colormap_create_from_xpm (NULL, colormap, NULL,
1994 gtk_style_real_realize (GtkStyle *style)
1996 GdkGCValues gc_values;
1997 GdkGCValuesMask gc_values_mask;
2001 for (i = 0; i < 5; i++)
2003 _gtk_style_shade (&style->bg[i], &style->light[i], LIGHTNESS_MULT);
2004 _gtk_style_shade (&style->bg[i], &style->dark[i], DARKNESS_MULT);
2006 style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
2007 style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
2008 style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
2010 style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
2011 style->text_aa[i].green = (style->text[i].green + style->base[i].green) / 2;
2012 style->text_aa[i].blue = (style->text[i].blue + style->base[i].blue) / 2;
2015 style->black.red = 0x0000;
2016 style->black.green = 0x0000;
2017 style->black.blue = 0x0000;
2018 gdk_colormap_alloc_color (style->colormap, &style->black, FALSE, TRUE);
2020 style->white.red = 0xffff;
2021 style->white.green = 0xffff;
2022 style->white.blue = 0xffff;
2023 gdk_colormap_alloc_color (style->colormap, &style->white, FALSE, TRUE);
2025 gc_values_mask = GDK_GC_FOREGROUND | GDK_GC_BACKGROUND;
2027 gc_values.foreground = style->black;
2028 gc_values.background = style->white;
2029 style->black_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
2031 gc_values.foreground = style->white;
2032 gc_values.background = style->black;
2033 style->white_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
2035 gc_values_mask = GDK_GC_FOREGROUND;
2037 for (i = 0; i < 5; i++)
2039 if (style->rc_style && style->rc_style->bg_pixmap_name[i])
2040 style->bg_pixmap[i] = load_bg_image (style->colormap,
2042 style->rc_style->bg_pixmap_name[i]);
2044 if (!gdk_colormap_alloc_color (style->colormap, &style->fg[i], FALSE, TRUE))
2045 g_warning ("unable to allocate color: ( %d %d %d )",
2046 style->fg[i].red, style->fg[i].green, style->fg[i].blue);
2047 if (!gdk_colormap_alloc_color (style->colormap, &style->bg[i], FALSE, TRUE))
2048 g_warning ("unable to allocate color: ( %d %d %d )",
2049 style->bg[i].red, style->bg[i].green, style->bg[i].blue);
2050 if (!gdk_colormap_alloc_color (style->colormap, &style->light[i], FALSE, TRUE))
2051 g_warning ("unable to allocate color: ( %d %d %d )",
2052 style->light[i].red, style->light[i].green, style->light[i].blue);
2053 if (!gdk_colormap_alloc_color (style->colormap, &style->dark[i], FALSE, TRUE))
2054 g_warning ("unable to allocate color: ( %d %d %d )",
2055 style->dark[i].red, style->dark[i].green, style->dark[i].blue);
2056 if (!gdk_colormap_alloc_color (style->colormap, &style->mid[i], FALSE, TRUE))
2057 g_warning ("unable to allocate color: ( %d %d %d )",
2058 style->mid[i].red, style->mid[i].green, style->mid[i].blue);
2059 if (!gdk_colormap_alloc_color (style->colormap, &style->text[i], FALSE, TRUE))
2060 g_warning ("unable to allocate color: ( %d %d %d )",
2061 style->text[i].red, style->text[i].green, style->text[i].blue);
2062 if (!gdk_colormap_alloc_color (style->colormap, &style->base[i], FALSE, TRUE))
2063 g_warning ("unable to allocate color: ( %d %d %d )",
2064 style->base[i].red, style->base[i].green, style->base[i].blue);
2065 if (!gdk_colormap_alloc_color (style->colormap, &style->text_aa[i], FALSE, TRUE))
2066 g_warning ("unable to allocate color: ( %d %d %d )",
2067 style->text_aa[i].red, style->text_aa[i].green, style->text_aa[i].blue);
2069 gc_values.foreground = style->fg[i];
2070 style->fg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
2072 gc_values.foreground = style->bg[i];
2073 style->bg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
2075 gc_values.foreground = style->light[i];
2076 style->light_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
2078 gc_values.foreground = style->dark[i];
2079 style->dark_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
2081 gc_values.foreground = style->mid[i];
2082 style->mid_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
2084 gc_values.foreground = style->text[i];
2085 style->text_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
2087 gc_values.foreground = style->base[i];
2088 style->base_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
2090 gc_values.foreground = style->text_aa[i];
2091 style->text_aa_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
2096 gtk_style_real_unrealize (GtkStyle *style)
2100 gtk_gc_release (style->black_gc);
2101 gtk_gc_release (style->white_gc);
2103 for (i = 0; i < 5; i++)
2105 gtk_gc_release (style->fg_gc[i]);
2106 gtk_gc_release (style->bg_gc[i]);
2107 gtk_gc_release (style->light_gc[i]);
2108 gtk_gc_release (style->dark_gc[i]);
2109 gtk_gc_release (style->mid_gc[i]);
2110 gtk_gc_release (style->text_gc[i]);
2111 gtk_gc_release (style->base_gc[i]);
2112 gtk_gc_release (style->text_aa_gc[i]);
2114 if (style->bg_pixmap[i] && style->bg_pixmap[i] != (GdkPixmap*) GDK_PARENT_RELATIVE)
2116 g_object_unref (style->bg_pixmap[i]);
2117 style->bg_pixmap[i] = NULL;
2122 gdk_colormap_free_colors (style->colormap, style->fg, 5);
2123 gdk_colormap_free_colors (style->colormap, style->bg, 5);
2124 gdk_colormap_free_colors (style->colormap, style->light, 5);
2125 gdk_colormap_free_colors (style->colormap, style->dark, 5);
2126 gdk_colormap_free_colors (style->colormap, style->mid, 5);
2127 gdk_colormap_free_colors (style->colormap, style->text, 5);
2128 gdk_colormap_free_colors (style->colormap, style->base, 5);
2129 gdk_colormap_free_colors (style->colormap, style->text_aa, 5);
2131 style_unrealize_cursor_gcs (style);
2135 gtk_style_real_set_background (GtkStyle *style,
2137 GtkStateType state_type)
2140 gint parent_relative;
2142 if (style->bg_pixmap[state_type])
2144 if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
2147 parent_relative = TRUE;
2151 pixmap = style->bg_pixmap[state_type];
2152 parent_relative = FALSE;
2155 gdk_window_set_back_pixmap (window, pixmap, parent_relative);
2158 gdk_window_set_background (window, &style->bg[state_type]);
2162 * gtk_style_render_icon:
2163 * @style: a #GtkStyle
2164 * @source: the #GtkIconSource specifying the icon to render
2165 * @direction: a text direction
2167 * @size: the size to render the icon at. A size of (GtkIconSize)-1
2168 * means render at the size of the source and don't scale.
2169 * @widget: the widget
2170 * @detail: a style detail
2171 * @returns: a newly-created #GdkPixbuf containing the rendered icon
2173 * Renders the icon specified by @source at the given @size
2174 * according to the given parameters and returns the result in a
2178 gtk_style_render_icon (GtkStyle *style,
2179 const GtkIconSource *source,
2180 GtkTextDirection direction,
2184 const gchar *detail)
2188 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
2189 g_return_val_if_fail (GTK_STYLE_GET_CLASS (style)->render_icon != NULL, NULL);
2191 pixbuf = GTK_STYLE_GET_CLASS (style)->render_icon (style, source, direction, state,
2192 size, widget, detail);
2194 g_return_val_if_fail (pixbuf != NULL, NULL);
2199 /* Default functions */
2201 gtk_style_apply_default_background (GtkStyle *style,
2204 GtkStateType state_type,
2205 const GdkRectangle *area,
2211 GdkRectangle new_rect, old_rect;
2217 old_rect.width = width;
2218 old_rect.height = height;
2220 if (!gdk_rectangle_intersect (area, &old_rect, &new_rect))
2227 new_rect.width = width;
2228 new_rect.height = height;
2231 if (!style->bg_pixmap[state_type] ||
2232 GDK_IS_PIXMAP (window) ||
2233 (!set_bg && style->bg_pixmap[state_type] != (GdkPixmap*) GDK_PARENT_RELATIVE))
2235 GdkGC *gc = style->bg_gc[state_type];
2237 if (style->bg_pixmap[state_type])
2239 gdk_gc_set_fill (gc, GDK_TILED);
2240 gdk_gc_set_tile (gc, style->bg_pixmap[state_type]);
2243 gdk_draw_rectangle (window, gc, TRUE,
2244 new_rect.x, new_rect.y, new_rect.width, new_rect.height);
2245 if (style->bg_pixmap[state_type])
2246 gdk_gc_set_fill (gc, GDK_SOLID);
2252 if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
2253 gdk_window_set_back_pixmap (window, NULL, TRUE);
2255 gdk_window_set_back_pixmap (window, style->bg_pixmap[state_type], FALSE);
2258 gdk_window_clear_area (window,
2259 new_rect.x, new_rect.y,
2260 new_rect.width, new_rect.height);
2265 scale_or_ref (GdkPixbuf *src,
2269 if (width == gdk_pixbuf_get_width (src) &&
2270 height == gdk_pixbuf_get_height (src))
2272 return g_object_ref (src);
2276 return gdk_pixbuf_scale_simple (src,
2278 GDK_INTERP_BILINEAR);
2283 gtk_default_render_icon (GtkStyle *style,
2284 const GtkIconSource *source,
2285 GtkTextDirection direction,
2289 const gchar *detail)
2295 GdkPixbuf *base_pixbuf;
2297 GtkSettings *settings;
2299 /* Oddly, style can be NULL in this function, because
2300 * GtkIconSet can be used without a style and if so
2301 * it uses this function.
2304 base_pixbuf = gtk_icon_source_get_pixbuf (source);
2306 g_return_val_if_fail (base_pixbuf != NULL, NULL);
2308 if (widget && gtk_widget_has_screen (widget))
2310 screen = gtk_widget_get_screen (widget);
2311 settings = gtk_settings_get_for_screen (screen);
2313 else if (style && style->colormap)
2315 screen = gdk_colormap_get_screen (style->colormap);
2316 settings = gtk_settings_get_for_screen (screen);
2320 settings = gtk_settings_get_default ();
2321 GTK_NOTE (MULTIHEAD,
2322 g_warning ("Using the default screen for gtk_default_render_icon()"));
2326 if (size != (GtkIconSize) -1 && !gtk_icon_size_lookup_for_settings (settings, size, &width, &height))
2328 g_warning (G_STRLOC ": invalid icon size '%d'", size);
2332 /* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
2335 if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source))
2336 scaled = scale_or_ref (base_pixbuf, width, height);
2338 scaled = g_object_ref (base_pixbuf);
2340 /* If the state was wildcarded, then generate a state. */
2341 if (gtk_icon_source_get_state_wildcarded (source))
2343 if (state == GTK_STATE_INSENSITIVE)
2345 stated = gdk_pixbuf_copy (scaled);
2347 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
2350 g_object_unref (scaled);
2352 else if (state == GTK_STATE_PRELIGHT)
2354 stated = gdk_pixbuf_copy (scaled);
2356 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
2359 g_object_unref (scaled);
2373 sanitize_size (GdkWindow *window,
2377 if ((*width == -1) && (*height == -1))
2378 gdk_drawable_get_size (window, width, height);
2379 else if (*width == -1)
2380 gdk_drawable_get_size (window, width, NULL);
2381 else if (*height == -1)
2382 gdk_drawable_get_size (window, NULL, height);
2386 gtk_default_draw_hline (GtkStyle *style,
2388 GtkStateType state_type,
2391 const gchar *detail,
2396 gint thickness_light;
2397 gint thickness_dark;
2400 thickness_light = style->ythickness / 2;
2401 thickness_dark = style->ythickness - thickness_light;
2405 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2406 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2409 if (detail && !strcmp (detail, "label"))
2411 if (state_type == GTK_STATE_INSENSITIVE)
2412 gdk_draw_line (window, style->white_gc, x1 + 1, y + 1, x2 + 1, y + 1);
2413 gdk_draw_line (window, style->fg_gc[state_type], x1, y, x2, y);
2417 for (i = 0; i < thickness_dark; i++)
2419 gdk_draw_line (window, style->dark_gc[state_type], x1, y + i, x2 - i - 1, y + i);
2420 gdk_draw_line (window, style->light_gc[state_type], x2 - i, y + i, x2, y + i);
2423 y += thickness_dark;
2424 for (i = 0; i < thickness_light; i++)
2426 gdk_draw_line (window, style->dark_gc[state_type], x1, y + i, x1 + thickness_light - i - 1, y + i);
2427 gdk_draw_line (window, style->light_gc[state_type], x1 + thickness_light - i, y + i, x2, y + i);
2433 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2434 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2440 gtk_default_draw_vline (GtkStyle *style,
2442 GtkStateType state_type,
2445 const gchar *detail,
2450 gint thickness_light;
2451 gint thickness_dark;
2454 thickness_light = style->xthickness / 2;
2455 thickness_dark = style->xthickness - thickness_light;
2459 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2460 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2462 for (i = 0; i < thickness_dark; i++)
2464 gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i, y2 - i - 1);
2465 gdk_draw_line (window, style->light_gc[state_type], x + i, y2 - i, x + i, y2);
2468 x += thickness_dark;
2469 for (i = 0; i < thickness_light; i++)
2471 gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i, y1 + thickness_light - i - 1);
2472 gdk_draw_line (window, style->light_gc[state_type], x + i, y1 + thickness_light - i, x + i, y2);
2476 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2477 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2482 draw_thin_shadow (GtkStyle *style,
2493 sanitize_size (window, &width, &height);
2495 gc1 = style->light_gc[state];
2496 gc2 = style->dark_gc[state];
2500 gdk_gc_set_clip_rectangle (gc1, area);
2501 gdk_gc_set_clip_rectangle (gc2, area);
2504 gdk_draw_line (window, gc1,
2505 x, y + height - 1, x + width - 1, y + height - 1);
2506 gdk_draw_line (window, gc1,
2507 x + width - 1, y, x + width - 1, y + height - 1);
2509 gdk_draw_line (window, gc2,
2510 x, y, x + width - 2, y);
2511 gdk_draw_line (window, gc2,
2512 x, y, x, y + height - 2);
2516 gdk_gc_set_clip_rectangle (gc1, NULL);
2517 gdk_gc_set_clip_rectangle (gc2, NULL);
2522 draw_spinbutton_shadow (GtkStyle *style,
2525 GtkTextDirection direction,
2532 sanitize_size (window, &width, &height);
2536 gdk_gc_set_clip_rectangle (style->black_gc, area);
2537 gdk_gc_set_clip_rectangle (style->bg_gc[state], area);
2538 gdk_gc_set_clip_rectangle (style->dark_gc[state], area);
2539 gdk_gc_set_clip_rectangle (style->light_gc[state], area);
2542 if (direction == GTK_TEXT_DIR_LTR)
2544 gdk_draw_line (window, style->dark_gc[state],
2545 x, y, x + width - 1, y);
2546 gdk_draw_line (window, style->black_gc,
2547 x, y + 1, x + width - 2, y + 1);
2548 gdk_draw_line (window, style->black_gc,
2549 x + width - 2, y + 2, x + width - 2, y + height - 3);
2550 gdk_draw_line (window, style->light_gc[state],
2551 x + width - 1, y + 1, x + width - 1, y + height - 2);
2552 gdk_draw_line (window, style->light_gc[state],
2553 x, y + height - 1, x + width - 1, y + height - 1);
2554 gdk_draw_line (window, style->bg_gc[state],
2555 x, y + height - 2, x + width - 2, y + height - 2);
2556 gdk_draw_line (window, style->black_gc,
2557 x, y + 2, x, y + height - 3);
2561 gdk_draw_line (window, style->dark_gc[state],
2562 x, y, x + width - 1, y);
2563 gdk_draw_line (window, style->dark_gc[state],
2564 x, y + 1, x, y + height - 1);
2565 gdk_draw_line (window, style->black_gc,
2566 x + 1, y + 1, x + width - 1, y + 1);
2567 gdk_draw_line (window, style->black_gc,
2568 x + 1, y + 2, x + 1, y + height - 2);
2569 gdk_draw_line (window, style->black_gc,
2570 x + width - 1, y + 2, x + width - 1, y + height - 3);
2571 gdk_draw_line (window, style->light_gc[state],
2572 x + 1, y + height - 1, x + width - 1, y + height - 1);
2573 gdk_draw_line (window, style->bg_gc[state],
2574 x + 2, y + height - 2, x + width - 1, y + height - 2);
2579 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
2580 gdk_gc_set_clip_rectangle (style->bg_gc[state], NULL);
2581 gdk_gc_set_clip_rectangle (style->dark_gc[state], NULL);
2582 gdk_gc_set_clip_rectangle (style->light_gc[state], NULL);
2587 draw_menu_shadow (GtkStyle *style,
2596 if (style->ythickness > 0)
2598 if (style->ythickness > 1)
2600 gdk_draw_line (window, style->dark_gc[state],
2601 x + 1, y + height - 2, x + width - 2, y + height - 2);
2602 gdk_draw_line (window, style->black_gc,
2603 x, y + height - 1, x + width - 1, y + height - 1);
2607 gdk_draw_line (window, style->dark_gc[state],
2608 x + 1, y + height - 1, x + width - 1, y + height - 1);
2612 if (style->xthickness > 0)
2614 if (style->xthickness > 1)
2616 gdk_draw_line (window, style->dark_gc[state],
2617 x + width - 2, y + 1, x + width - 2, y + height - 2);
2619 gdk_draw_line (window, style->black_gc,
2620 x + width - 1, y, x + width - 1, y + height - 1);
2624 gdk_draw_line (window, style->dark_gc[state],
2625 x + width - 1, y + 1, x + width - 1, y + height - 1);
2629 /* Light around top and left */
2631 if (style->ythickness > 0)
2632 gdk_draw_line (window, style->black_gc,
2633 x, y, x + width - 2, y);
2634 if (style->xthickness > 0)
2635 gdk_draw_line (window, style->black_gc,
2636 x, y, x, y + height - 2);
2638 if (style->ythickness > 1)
2639 gdk_draw_line (window, style->light_gc[state],
2640 x + 1, y + 1, x + width - 3, y + 1);
2641 if (style->xthickness > 1)
2642 gdk_draw_line (window, style->light_gc[state],
2643 x + 1, y + 1, x + 1, y + height - 3);
2646 static GtkTextDirection
2647 get_direction (GtkWidget *widget)
2649 GtkTextDirection dir;
2652 dir = gtk_widget_get_direction (widget);
2654 dir = GTK_TEXT_DIR_LTR;
2661 gtk_default_draw_shadow (GtkStyle *style,
2663 GtkStateType state_type,
2664 GtkShadowType shadow_type,
2667 const gchar *detail,
2675 gint thickness_light;
2676 gint thickness_dark;
2679 if (shadow_type == GTK_SHADOW_IN)
2681 if (detail && strcmp (detail, "buttondefault") == 0)
2683 sanitize_size (window, &width, &height);
2685 gdk_draw_rectangle (window, style->black_gc, FALSE,
2686 x, y, width - 1, height - 1);
2690 if (detail && strcmp (detail, "trough") == 0)
2692 draw_thin_shadow (style, window, state_type, area,
2693 x, y, width, height);
2696 if (GTK_IS_SPIN_BUTTON (widget) &&
2697 detail && strcmp (detail, "spinbutton") == 0)
2699 draw_spinbutton_shadow (style, window, state_type,
2700 get_direction (widget), area, x, y, width, height);
2706 if (shadow_type == GTK_SHADOW_OUT && detail && strcmp (detail, "menu") == 0)
2708 draw_menu_shadow (style, window, state_type, area, x, y, width, height);
2712 sanitize_size (window, &width, &height);
2714 switch (shadow_type)
2716 case GTK_SHADOW_NONE:
2719 case GTK_SHADOW_ETCHED_IN:
2720 gc1 = style->light_gc[state_type];
2721 gc2 = style->dark_gc[state_type];
2723 case GTK_SHADOW_OUT:
2724 case GTK_SHADOW_ETCHED_OUT:
2725 gc1 = style->dark_gc[state_type];
2726 gc2 = style->light_gc[state_type];
2732 gdk_gc_set_clip_rectangle (gc1, area);
2733 gdk_gc_set_clip_rectangle (gc2, area);
2734 if (shadow_type == GTK_SHADOW_IN ||
2735 shadow_type == GTK_SHADOW_OUT)
2737 gdk_gc_set_clip_rectangle (style->black_gc, area);
2738 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
2742 switch (shadow_type)
2744 case GTK_SHADOW_NONE:
2748 /* Light around right and bottom edge */
2750 if (style->ythickness > 0)
2751 gdk_draw_line (window, gc1,
2752 x, y + height - 1, x + width - 1, y + height - 1);
2753 if (style->xthickness > 0)
2754 gdk_draw_line (window, gc1,
2755 x + width - 1, y, x + width - 1, y + height - 1);
2757 if (style->ythickness > 1)
2758 gdk_draw_line (window, style->bg_gc[state_type],
2759 x + 1, y + height - 2, x + width - 2, y + height - 2);
2760 if (style->xthickness > 1)
2761 gdk_draw_line (window, style->bg_gc[state_type],
2762 x + width - 2, y + 1, x + width - 2, y + height - 2);
2764 /* Dark around left and top */
2766 if (style->ythickness > 1)
2767 gdk_draw_line (window, style->black_gc,
2768 x + 1, y + 1, x + width - 2, y + 1);
2769 if (style->xthickness > 1)
2770 gdk_draw_line (window, style->black_gc,
2771 x + 1, y + 1, x + 1, y + height - 2);
2773 if (style->ythickness > 0)
2774 gdk_draw_line (window, gc2,
2775 x, y, x + width - 1, y);
2776 if (style->xthickness > 0)
2777 gdk_draw_line (window, gc2,
2778 x, y, x, y + height - 1);
2781 case GTK_SHADOW_OUT:
2782 /* Dark around right and bottom edge */
2784 if (style->ythickness > 0)
2786 if (style->ythickness > 1)
2788 gdk_draw_line (window, gc1,
2789 x + 1, y + height - 2, x + width - 2, y + height - 2);
2790 gdk_draw_line (window, style->black_gc,
2791 x, y + height - 1, x + width - 1, y + height - 1);
2795 gdk_draw_line (window, gc1,
2796 x + 1, y + height - 1, x + width - 1, y + height - 1);
2800 if (style->xthickness > 0)
2802 if (style->xthickness > 1)
2804 gdk_draw_line (window, gc1,
2805 x + width - 2, y + 1, x + width - 2, y + height - 2);
2807 gdk_draw_line (window, style->black_gc,
2808 x + width - 1, y, x + width - 1, y + height - 1);
2812 gdk_draw_line (window, gc1,
2813 x + width - 1, y + 1, x + width - 1, y + height - 1);
2817 /* Light around top and left */
2819 if (style->ythickness > 0)
2820 gdk_draw_line (window, gc2,
2821 x, y, x + width - 2, y);
2822 if (style->xthickness > 0)
2823 gdk_draw_line (window, gc2,
2824 x, y, x, y + height - 2);
2826 if (style->ythickness > 1)
2827 gdk_draw_line (window, style->bg_gc[state_type],
2828 x + 1, y + 1, x + width - 3, y + 1);
2829 if (style->xthickness > 1)
2830 gdk_draw_line (window, style->bg_gc[state_type],
2831 x + 1, y + 1, x + 1, y + height - 3);
2834 case GTK_SHADOW_ETCHED_IN:
2835 case GTK_SHADOW_ETCHED_OUT:
2836 if (style->xthickness > 0)
2838 if (style->xthickness > 1)
2840 thickness_light = 1;
2843 for (i = 0; i < thickness_dark; i++)
2845 gdk_draw_line (window, gc1,
2849 y + height - i - 1);
2850 gdk_draw_line (window, gc2,
2854 y + height - i - 2);
2857 for (i = 0; i < thickness_light; i++)
2859 gdk_draw_line (window, gc1,
2860 x + thickness_dark + i,
2861 y + thickness_dark + i,
2862 x + thickness_dark + i,
2863 y + height - thickness_dark - i - 1);
2864 gdk_draw_line (window, gc2,
2865 x + width - thickness_light - i - 1,
2866 y + thickness_dark + i,
2867 x + width - thickness_light - i - 1,
2868 y + height - thickness_light - 1);
2873 gdk_draw_line (window,
2874 style->dark_gc[state_type],
2875 x, y, x, y + height);
2876 gdk_draw_line (window,
2877 style->dark_gc[state_type],
2878 x + width, y, x + width, y + height);
2882 if (style->ythickness > 0)
2884 if (style->ythickness > 1)
2886 thickness_light = 1;
2889 for (i = 0; i < thickness_dark; i++)
2891 gdk_draw_line (window, gc1,
2895 y + height - i - 1);
2897 gdk_draw_line (window, gc2,
2904 for (i = 0; i < thickness_light; i++)
2906 gdk_draw_line (window, gc1,
2907 x + thickness_dark + i,
2908 y + thickness_dark + i,
2909 x + width - thickness_dark - i - 2,
2910 y + thickness_dark + i);
2912 gdk_draw_line (window, gc2,
2913 x + thickness_dark + i,
2914 y + height - thickness_light - i - 1,
2915 x + width - thickness_light - 1,
2916 y + height - thickness_light - i - 1);
2921 gdk_draw_line (window,
2922 style->dark_gc[state_type],
2923 x, y, x + width, y);
2924 gdk_draw_line (window,
2925 style->dark_gc[state_type],
2926 x, y + height, x + width, y + height);
2933 if (shadow_type == GTK_SHADOW_IN &&
2934 GTK_IS_SPIN_BUTTON (widget) &&
2935 detail && strcmp (detail, "entry") == 0)
2937 if (get_direction (widget) == GTK_TEXT_DIR_LTR)
2939 gdk_draw_line (window,
2940 style->base_gc[state_type],
2941 x + width - 1, y + 2,
2942 x + width - 1, y + height - 3);
2943 gdk_draw_line (window,
2944 style->base_gc[state_type],
2945 x + width - 2, y + 2,
2946 x + width - 2, y + height - 3);
2947 gdk_draw_point (window,
2949 x + width - 1, y + 1);
2950 gdk_draw_point (window,
2951 style->bg_gc[state_type],
2952 x + width - 1, y + height - 2);
2956 gdk_draw_line (window,
2957 style->base_gc[state_type],
2960 gdk_draw_line (window,
2961 style->base_gc[state_type],
2963 x + 1, y + height - 3);
2964 gdk_draw_point (window,
2967 gdk_draw_line (window,
2968 style->bg_gc[state_type],
2970 x + 1, y + height - 2);
2971 gdk_draw_point (window,
2972 style->light_gc[state_type],
2980 gdk_gc_set_clip_rectangle (gc1, NULL);
2981 gdk_gc_set_clip_rectangle (gc2, NULL);
2982 if (shadow_type == GTK_SHADOW_IN ||
2983 shadow_type == GTK_SHADOW_OUT)
2985 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
2986 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
2992 gtk_default_draw_polygon (GtkStyle *style,
2994 GtkStateType state_type,
2995 GtkShadowType shadow_type,
2998 const gchar *detail,
3003 static const gdouble pi_over_4 = G_PI_4;
3004 static const gdouble pi_3_over_4 = G_PI_4 * 3;
3014 switch (shadow_type)
3017 gc1 = style->bg_gc[state_type];
3018 gc2 = style->dark_gc[state_type];
3019 gc3 = style->light_gc[state_type];
3020 gc4 = style->black_gc;
3022 case GTK_SHADOW_ETCHED_IN:
3023 gc1 = style->light_gc[state_type];
3024 gc2 = style->dark_gc[state_type];
3025 gc3 = style->dark_gc[state_type];
3026 gc4 = style->light_gc[state_type];
3028 case GTK_SHADOW_OUT:
3029 gc1 = style->dark_gc[state_type];
3030 gc2 = style->light_gc[state_type];
3031 gc3 = style->black_gc;
3032 gc4 = style->bg_gc[state_type];
3034 case GTK_SHADOW_ETCHED_OUT:
3035 gc1 = style->dark_gc[state_type];
3036 gc2 = style->light_gc[state_type];
3037 gc3 = style->light_gc[state_type];
3038 gc4 = style->dark_gc[state_type];
3046 gdk_gc_set_clip_rectangle (gc1, area);
3047 gdk_gc_set_clip_rectangle (gc2, area);
3048 gdk_gc_set_clip_rectangle (gc3, area);
3049 gdk_gc_set_clip_rectangle (gc4, area);
3053 gdk_draw_polygon (window, style->bg_gc[state_type], TRUE, points, npoints);
3057 for (i = 0; i < npoints; i++)
3059 if ((points[i].x == points[i+1].x) &&
3060 (points[i].y == points[i+1].y))
3066 angle = atan2 (points[i+1].y - points[i].y,
3067 points[i+1].x - points[i].x);
3070 if ((angle > -pi_3_over_4) && (angle < pi_over_4))
3072 if (angle > -pi_over_4)
3083 gdk_draw_line (window, gc1,
3084 points[i].x-xadjust, points[i].y-yadjust,
3085 points[i+1].x-xadjust, points[i+1].y-yadjust);
3086 gdk_draw_line (window, gc3,
3087 points[i].x, points[i].y,
3088 points[i+1].x, points[i+1].y);
3092 if ((angle < -pi_3_over_4) || (angle > pi_3_over_4))
3103 gdk_draw_line (window, gc4,
3104 points[i].x+xadjust, points[i].y+yadjust,
3105 points[i+1].x+xadjust, points[i+1].y+yadjust);
3106 gdk_draw_line (window, gc2,
3107 points[i].x, points[i].y,
3108 points[i+1].x, points[i+1].y);
3114 gdk_gc_set_clip_rectangle (gc1, NULL);
3115 gdk_gc_set_clip_rectangle (gc2, NULL);
3116 gdk_gc_set_clip_rectangle (gc3, NULL);
3117 gdk_gc_set_clip_rectangle (gc4, NULL);
3122 draw_arrow (GdkWindow *window,
3125 GtkArrowType arrow_type,
3131 cairo_t *cr = gdk_cairo_create (window);
3132 gdk_cairo_set_source_color (cr, color);
3136 gdk_cairo_rectangle (cr, area);
3140 if (arrow_type == GTK_ARROW_DOWN)
3142 cairo_move_to (cr, x, y);
3143 cairo_line_to (cr, x + width, y);
3144 cairo_line_to (cr, x + width / 2., y + height);
3146 else if (arrow_type == GTK_ARROW_UP)
3148 cairo_move_to (cr, x, y + height);
3149 cairo_line_to (cr, x + width / 2., y);
3150 cairo_line_to (cr, x + width, y + height);
3152 else if (arrow_type == GTK_ARROW_LEFT)
3154 cairo_move_to (cr, x + width, y);
3155 cairo_line_to (cr, x + width, y + height);
3156 cairo_line_to (cr, x, y + height / 2.);
3158 else if (arrow_type == GTK_ARROW_RIGHT)
3160 cairo_move_to (cr, x, y);
3161 cairo_line_to (cr, x + width, y + height / 2.);
3162 cairo_line_to (cr, x, y + height);
3165 cairo_close_path (cr);
3172 calculate_arrow_geometry (GtkArrowType arrow_type,
3184 case GTK_ARROW_DOWN:
3194 if (arrow_type == GTK_ARROW_DOWN)
3196 if (*height % 2 == 1 || h % 2 == 0)
3201 if (*height % 2 == 0 || h % 2 == 0)
3206 case GTK_ARROW_RIGHT:
3207 case GTK_ARROW_LEFT:
3217 if (arrow_type == GTK_ARROW_RIGHT)
3219 if (*width % 2 == 1 || w % 2 == 0)
3224 if (*width % 2 == 0 || w % 2 == 0)
3230 /* should not be reached */
3234 *x += (*width - w) / 2;
3235 *y += (*height - h) / 2;
3241 gtk_default_draw_arrow (GtkStyle *style,
3244 GtkShadowType shadow,
3247 const gchar *detail,
3248 GtkArrowType arrow_type,
3255 sanitize_size (window, &width, &height);
3257 calculate_arrow_geometry (arrow_type, &x, &y, &width, &height);
3259 if (detail && strcmp (detail, "menu_scroll_arrow_up") == 0)
3262 if (state == GTK_STATE_INSENSITIVE)
3263 draw_arrow (window, &style->white, area, arrow_type,
3264 x + 1, y + 1, width, height);
3265 draw_arrow (window, &style->fg[state], area, arrow_type,
3266 x, y, width, height);
3270 gtk_default_draw_diamond (GtkStyle *style,
3272 GtkStateType state_type,
3273 GtkShadowType shadow_type,
3276 const gchar *detail,
3284 GdkGC *outer_nw = NULL;
3285 GdkGC *outer_ne = NULL;
3286 GdkGC *outer_sw = NULL;
3287 GdkGC *outer_se = NULL;
3288 GdkGC *middle_nw = NULL;
3289 GdkGC *middle_ne = NULL;
3290 GdkGC *middle_sw = NULL;
3291 GdkGC *middle_se = NULL;
3292 GdkGC *inner_nw = NULL;
3293 GdkGC *inner_ne = NULL;
3294 GdkGC *inner_sw = NULL;
3295 GdkGC *inner_se = NULL;
3297 sanitize_size (window, &width, &height);
3299 half_width = width / 2;
3300 half_height = height / 2;
3304 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
3305 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
3306 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
3307 gdk_gc_set_clip_rectangle (style->black_gc, area);
3310 switch (shadow_type)
3313 inner_sw = inner_se = style->bg_gc[state_type];
3314 middle_sw = middle_se = style->light_gc[state_type];
3315 outer_sw = outer_se = style->light_gc[state_type];
3316 inner_nw = inner_ne = style->black_gc;
3317 middle_nw = middle_ne = style->dark_gc[state_type];
3318 outer_nw = outer_ne = style->dark_gc[state_type];
3321 case GTK_SHADOW_OUT:
3322 inner_sw = inner_se = style->dark_gc[state_type];
3323 middle_sw = middle_se = style->dark_gc[state_type];
3324 outer_sw = outer_se = style->black_gc;
3325 inner_nw = inner_ne = style->bg_gc[state_type];
3326 middle_nw = middle_ne = style->light_gc[state_type];
3327 outer_nw = outer_ne = style->light_gc[state_type];
3330 case GTK_SHADOW_ETCHED_IN:
3331 inner_sw = inner_se = style->bg_gc[state_type];
3332 middle_sw = middle_se = style->dark_gc[state_type];
3333 outer_sw = outer_se = style->light_gc[state_type];
3334 inner_nw = inner_ne = style->bg_gc[state_type];
3335 middle_nw = middle_ne = style->light_gc[state_type];
3336 outer_nw = outer_ne = style->dark_gc[state_type];
3339 case GTK_SHADOW_ETCHED_OUT:
3340 inner_sw = inner_se = style->bg_gc[state_type];
3341 middle_sw = middle_se = style->light_gc[state_type];
3342 outer_sw = outer_se = style->dark_gc[state_type];
3343 inner_nw = inner_ne = style->bg_gc[state_type];
3344 middle_nw = middle_ne = style->dark_gc[state_type];
3345 outer_nw = outer_ne = style->light_gc[state_type];
3355 gdk_draw_line (window, inner_sw,
3356 x + 2, y + half_height,
3357 x + half_width, y + height - 2);
3358 gdk_draw_line (window, inner_se,
3359 x + half_width, y + height - 2,
3360 x + width - 2, y + half_height);
3361 gdk_draw_line (window, middle_sw,
3362 x + 1, y + half_height,
3363 x + half_width, y + height - 1);
3364 gdk_draw_line (window, middle_se,
3365 x + half_width, y + height - 1,
3366 x + width - 1, y + half_height);
3367 gdk_draw_line (window, outer_sw,
3369 x + half_width, y + height);
3370 gdk_draw_line (window, outer_se,
3371 x + half_width, y + height,
3372 x + width, y + half_height);
3374 gdk_draw_line (window, inner_nw,
3375 x + 2, y + half_height,
3376 x + half_width, y + 2);
3377 gdk_draw_line (window, inner_ne,
3378 x + half_width, y + 2,
3379 x + width - 2, y + half_height);
3380 gdk_draw_line (window, middle_nw,
3381 x + 1, y + half_height,
3382 x + half_width, y + 1);
3383 gdk_draw_line (window, middle_ne,
3384 x + half_width, y + 1,
3385 x + width - 1, y + half_height);
3386 gdk_draw_line (window, outer_nw,
3389 gdk_draw_line (window, outer_ne,
3391 x + width, y + half_height);
3396 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
3397 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
3398 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
3399 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
3404 gtk_default_draw_string (GtkStyle *style,
3406 GtkStateType state_type,
3409 const gchar *detail,
3412 const gchar *string)
3416 gdk_gc_set_clip_rectangle (style->white_gc, area);
3417 gdk_gc_set_clip_rectangle (style->fg_gc[state_type], area);
3420 if (state_type == GTK_STATE_INSENSITIVE)
3421 gdk_draw_string (window,
3422 gtk_style_get_font_internal (style),
3423 style->white_gc, x + 1, y + 1, string);
3425 gdk_draw_string (window,
3426 gtk_style_get_font_internal (style),
3427 style->fg_gc[state_type], x, y, string);
3431 gdk_gc_set_clip_rectangle (style->white_gc, NULL);
3432 gdk_gc_set_clip_rectangle (style->fg_gc[state_type], NULL);
3437 option_menu_get_props (GtkWidget *widget,
3438 GtkRequisition *indicator_size,
3439 GtkBorder *indicator_spacing)
3441 GtkRequisition *tmp_size = NULL;
3442 GtkBorder *tmp_spacing = NULL;
3444 if (GTK_IS_OPTION_MENU (widget))
3445 gtk_widget_style_get (widget,
3446 "indicator-size", &tmp_size,
3447 "indicator-spacing", &tmp_spacing,
3452 *indicator_size = *tmp_size;
3453 gtk_requisition_free (tmp_size);
3456 *indicator_size = default_option_indicator_size;
3460 *indicator_spacing = *tmp_spacing;
3461 gtk_border_free (tmp_spacing);
3464 *indicator_spacing = default_option_indicator_spacing;
3468 gtk_default_draw_box (GtkStyle *style,
3470 GtkStateType state_type,
3471 GtkShadowType shadow_type,
3474 const gchar *detail,
3480 gboolean is_spinbutton_box = FALSE;
3482 sanitize_size (window, &width, &height);
3484 if (GTK_IS_SPIN_BUTTON (widget) && detail)
3486 if (strcmp (detail, "spinbutton_up") == 0)
3492 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
3497 is_spinbutton_box = TRUE;
3499 else if (strcmp (detail, "spinbutton_down") == 0)
3504 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
3509 is_spinbutton_box = TRUE;
3513 if (!style->bg_pixmap[state_type] ||
3514 GDK_IS_PIXMAP (window))
3516 GdkGC *gc = style->bg_gc[state_type];
3518 if (state_type == GTK_STATE_SELECTED && detail && strcmp (detail, "paned") == 0)
3520 if (widget && !GTK_WIDGET_HAS_FOCUS (widget))
3521 gc = style->base_gc[GTK_STATE_ACTIVE];
3525 gdk_gc_set_clip_rectangle (gc, area);
3527 gdk_draw_rectangle (window, gc, TRUE,
3528 x, y, width, height);
3530 gdk_gc_set_clip_rectangle (gc, NULL);
3533 gtk_style_apply_default_background (style, window,
3534 widget && !GTK_WIDGET_NO_WINDOW (widget),
3535 state_type, area, x, y, width, height);
3537 if (is_spinbutton_box)
3542 lower_gc = style->dark_gc[state_type];
3543 if (shadow_type == GTK_SHADOW_OUT)
3544 upper_gc = style->light_gc[state_type];
3546 upper_gc = style->dark_gc[state_type];
3550 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
3551 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
3554 gdk_draw_line (window, upper_gc, x, y, x + width - 1, y);
3555 gdk_draw_line (window, lower_gc, x, y + height - 1, x + width - 1, y + height - 1);
3559 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
3560 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
3565 gtk_paint_shadow (style, window, state_type, shadow_type, area, widget, detail,
3566 x, y, width, height);
3568 if (detail && strcmp (detail, "optionmenu") == 0)
3570 GtkRequisition indicator_size;
3571 GtkBorder indicator_spacing;
3574 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
3576 sanitize_size (window, &width, &height);
3578 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
3579 vline_x = x + indicator_size.width + indicator_spacing.left + indicator_spacing.right;
3581 vline_x = x + width - (indicator_size.width + indicator_spacing.left + indicator_spacing.right) - style->xthickness;
3583 gtk_paint_vline (style, window, state_type, area, widget,
3585 y + style->ythickness + 1,
3586 y + height - style->ythickness - 3,
3592 get_darkened_gc (GdkWindow *window,
3593 const GdkColor *color,
3596 GdkColor src = *color;
3597 GdkColor shaded = *color;
3600 gc = gdk_gc_new (window);
3602 while (darken_count)
3604 _gtk_style_shade (&src, &shaded, 0.93);
3609 gdk_gc_set_rgb_fg_color (gc, &shaded);
3615 gtk_default_draw_flat_box (GtkStyle *style,
3617 GtkStateType state_type,
3618 GtkShadowType shadow_type,
3621 const gchar *detail,
3628 GdkGC *freeme = NULL;
3630 sanitize_size (window, &width, &height);
3634 if (state_type == GTK_STATE_SELECTED)
3636 if (!strcmp ("text", detail))
3637 gc1 = style->bg_gc[GTK_STATE_SELECTED];
3638 else if (!strcmp ("cell_even", detail) ||
3639 !strcmp ("cell_odd", detail) ||
3640 !strcmp ("cell_even_ruled", detail) ||
3641 !strcmp ("cell_even_ruled_sorted", detail))
3643 /* This has to be really broken; alex made me do it. -jrb */
3644 if (widget && GTK_WIDGET_HAS_FOCUS (widget))
3645 gc1 = style->base_gc[state_type];
3647 gc1 = style->base_gc[GTK_STATE_ACTIVE];
3649 else if (!strcmp ("cell_odd_ruled", detail) ||
3650 !strcmp ("cell_odd_ruled_sorted", detail))
3652 if (widget && GTK_WIDGET_HAS_FOCUS (widget))
3653 freeme = get_darkened_gc (window, &style->base[state_type], 1);
3655 freeme = get_darkened_gc (window, &style->base[GTK_STATE_ACTIVE], 1);
3660 gc1 = style->bg_gc[state_type];
3665 if (!strcmp ("viewportbin", detail))
3666 gc1 = style->bg_gc[GTK_STATE_NORMAL];
3667 else if (!strcmp ("entry_bg", detail))
3668 gc1 = style->base_gc[state_type];
3670 /* For trees: even rows are base color, odd rows are a shade of
3671 * the base color, the sort column is a shade of the original color
3675 else if (!strcmp ("cell_even", detail) ||
3676 !strcmp ("cell_odd", detail) ||
3677 !strcmp ("cell_even_ruled", detail))
3679 GdkColor *color = NULL;
3681 gtk_widget_style_get (widget,
3682 "even-row-color", &color,
3687 freeme = get_darkened_gc (window, color, 0);
3690 gdk_color_free (color);
3693 gc1 = style->base_gc[state_type];
3695 else if (!strcmp ("cell_odd_ruled", detail))
3697 GdkColor *color = NULL;
3699 gtk_widget_style_get (widget,
3700 "odd-row-color", &color,
3705 freeme = get_darkened_gc (window, color, 0);
3708 gdk_color_free (color);
3712 gtk_widget_style_get (widget,
3713 "even-row-color", &color,
3718 freeme = get_darkened_gc (window, color, 1);
3719 gdk_color_free (color);
3722 freeme = get_darkened_gc (window, &style->base[state_type], 1);
3726 else if (!strcmp ("cell_even_sorted", detail) ||
3727 !strcmp ("cell_odd_sorted", detail) ||
3728 !strcmp ("cell_even_ruled_sorted", detail))
3730 GdkColor *color = NULL;
3732 if (!strcmp ("cell_odd_sorted", detail))
3733 gtk_widget_style_get (widget,
3734 "odd-row-color", &color,
3737 gtk_widget_style_get (widget,
3738 "even-row-color", &color,
3743 freeme = get_darkened_gc (window, color, 1);
3746 gdk_color_free (color);
3750 freeme = get_darkened_gc (window, &style->base[state_type], 1);
3754 else if (!strcmp ("cell_odd_ruled_sorted", detail))
3756 GdkColor *color = NULL;
3758 gtk_widget_style_get (widget,
3759 "odd-row-color", &color,
3764 freeme = get_darkened_gc (window, color, 1);
3767 gdk_color_free (color);
3771 gtk_widget_style_get (widget,
3772 "even-row-color", &color,
3777 freeme = get_darkened_gc (window, color, 2);
3778 gdk_color_free (color);
3781 freeme = get_darkened_gc (window, &style->base[state_type], 2);
3786 gc1 = style->bg_gc[state_type];
3790 gc1 = style->bg_gc[state_type];
3792 if (!style->bg_pixmap[state_type] || gc1 != style->bg_gc[state_type] ||
3793 GDK_IS_PIXMAP (window))
3796 gdk_gc_set_clip_rectangle (gc1, area);
3798 gdk_draw_rectangle (window, gc1, TRUE,
3799 x, y, width, height);
3801 if (detail && !strcmp ("tooltip", detail))
3802 gdk_draw_rectangle (window, style->black_gc, FALSE,
3803 x, y, width - 1, height - 1);
3806 gdk_gc_set_clip_rectangle (gc1, NULL);
3809 gtk_style_apply_default_background (style, window,
3810 widget && !GTK_WIDGET_NO_WINDOW (widget),
3811 state_type, area, x, y, width, height);
3815 g_object_unref (freeme);
3819 gtk_default_draw_check (GtkStyle *style,
3821 GtkStateType state_type,
3822 GtkShadowType shadow_type,
3825 const gchar *detail,
3831 cairo_t *cr = gdk_cairo_create (window);
3832 enum { BUTTON, MENU, CELL } type = BUTTON;
3839 if (strcmp (detail, "cellcheck") == 0)
3841 else if (strcmp (detail, "check") == 0)
3847 gdk_cairo_rectangle (cr, area);
3851 exterior_size = MIN (width, height);
3852 if (exterior_size % 2 == 0) /* Ensure odd */
3855 pad = style->xthickness + MAX (1, (exterior_size - 2 * style->xthickness) / 9);
3856 interior_size = MAX (1, exterior_size - 2 * pad);
3858 if (interior_size < 7)
3861 pad = MAX (0, (exterior_size - interior_size) / 2);
3864 x -= (1 + exterior_size - width) / 2;
3865 y -= (1 + exterior_size - height) / 2;
3872 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3874 gdk_cairo_set_source_color (cr, &style->text[state_type]);
3876 cairo_set_line_width (cr, 1.0);
3877 cairo_rectangle (cr, x + 0.5, y + 0.5, exterior_size - 1, exterior_size - 1);
3880 gdk_cairo_set_source_color (cr, &style->base[state_type]);
3881 cairo_rectangle (cr, x + 1, y + 1, exterior_size - 2, exterior_size - 2);
3893 gdk_cairo_set_source_color (cr, &style->text[state_type]);
3896 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3900 if (shadow_type == GTK_SHADOW_IN)
3902 cairo_translate (cr,
3905 cairo_scale (cr, interior_size / 7., interior_size / 7.);
3907 cairo_move_to (cr, 7.0, 0.0);
3908 cairo_line_to (cr, 7.5, 1.0);
3909 cairo_curve_to (cr, 5.3, 2.0,
3912 cairo_curve_to (cr, 3.0, 5.7,
3915 cairo_line_to (cr, 0.2, 3.5);
3916 cairo_curve_to (cr, 1.1, 3.5,
3919 cairo_curve_to (cr, 1.0, 3.9,
3922 cairo_curve_to (cr, 3.5, 3.1,
3928 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
3930 int line_thickness = MAX (1, (3 + interior_size * 2) / 7);
3932 cairo_rectangle (cr,
3934 y + pad + (1 + interior_size - line_thickness) / 2,
3944 gtk_default_draw_option (GtkStyle *style,
3946 GtkStateType state_type,
3947 GtkShadowType shadow_type,
3950 const gchar *detail,
3956 cairo_t *cr = gdk_cairo_create (window);
3957 enum { BUTTON, MENU, CELL } type = BUTTON;
3962 if (strcmp (detail, "radio") == 0)
3964 else if (strcmp (detail, "option") == 0)
3970 gdk_cairo_rectangle (cr, area);
3974 exterior_size = MIN (width, height);
3975 if (exterior_size % 2 == 0) /* Ensure odd */
3978 x -= (1 + exterior_size - width) / 2;
3979 y -= (1 + exterior_size - height) / 2;
3985 gdk_cairo_set_source_color (cr, &style->base[state_type]);
3988 x + exterior_size / 2.,
3989 y + exterior_size / 2.,
3990 (exterior_size - 1) / 2.,
3993 cairo_fill_preserve (cr);
3996 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3998 gdk_cairo_set_source_color (cr, &style->text[state_type]);
4000 cairo_set_line_width (cr, 1.);
4011 gdk_cairo_set_source_color (cr, &style->text[state_type]);
4016 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
4020 if (shadow_type == GTK_SHADOW_IN)
4022 int pad = style->xthickness + MAX (1, 2 * (exterior_size - 2 * style->xthickness) / 9);
4023 int interior_size = MAX (1, exterior_size - 2 * pad);
4025 if (interior_size < 5)
4028 pad = MAX (0, (exterior_size - interior_size) / 2);
4032 x + pad + interior_size / 2.,
4033 y + pad + interior_size / 2.,
4038 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
4040 int pad = style->xthickness + MAX (1, (exterior_size - 2 * style->xthickness) / 9);
4041 int interior_size = MAX (1, exterior_size - 2 * pad);
4044 if (interior_size < 7)
4047 pad = MAX (0, (exterior_size - interior_size) / 2);
4050 line_thickness = MAX (1, (3 + interior_size * 2) / 7);
4052 cairo_rectangle (cr,
4054 y + pad + (interior_size - line_thickness) / 2.,
4064 gtk_default_draw_tab (GtkStyle *style,
4066 GtkStateType state_type,
4067 GtkShadowType shadow_type,
4070 const gchar *detail,
4076 #define ARROW_SPACE 4
4078 GtkRequisition indicator_size;
4079 GtkBorder indicator_spacing;
4082 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
4084 indicator_size.width += (indicator_size.width % 2) - 1;
4085 arrow_height = indicator_size.width / 2 + 1;
4087 x += (width - indicator_size.width) / 2;
4088 y += (height - (2 * arrow_height + ARROW_SPACE)) / 2;
4090 if (state_type == GTK_STATE_INSENSITIVE)
4092 draw_arrow (window, &style->white, area,
4093 GTK_ARROW_UP, x + 1, y + 1,
4094 indicator_size.width, arrow_height);
4096 draw_arrow (window, &style->white, area,
4097 GTK_ARROW_DOWN, x + 1, y + arrow_height + ARROW_SPACE + 1,
4098 indicator_size.width, arrow_height);
4101 draw_arrow (window, &style->fg[state_type], area,
4103 indicator_size.width, arrow_height);
4106 draw_arrow (window, &style->fg[state_type], area,
4107 GTK_ARROW_DOWN, x, y + arrow_height + ARROW_SPACE,
4108 indicator_size.width, arrow_height);
4112 gtk_default_draw_shadow_gap (GtkStyle *style,
4114 GtkStateType state_type,
4115 GtkShadowType shadow_type,
4118 const gchar *detail,
4123 GtkPositionType gap_side,
4132 sanitize_size (window, &width, &height);
4134 switch (shadow_type)
4136 case GTK_SHADOW_NONE:
4139 gc1 = style->dark_gc[state_type];
4140 gc2 = style->black_gc;
4141 gc3 = style->bg_gc[state_type];
4142 gc4 = style->light_gc[state_type];
4144 case GTK_SHADOW_ETCHED_IN:
4145 gc1 = style->dark_gc[state_type];
4146 gc2 = style->light_gc[state_type];
4147 gc3 = style->dark_gc[state_type];
4148 gc4 = style->light_gc[state_type];
4150 case GTK_SHADOW_OUT:
4151 gc1 = style->light_gc[state_type];
4152 gc2 = style->bg_gc[state_type];
4153 gc3 = style->dark_gc[state_type];
4154 gc4 = style->black_gc;
4156 case GTK_SHADOW_ETCHED_OUT:
4157 gc1 = style->light_gc[state_type];
4158 gc2 = style->dark_gc[state_type];
4159 gc3 = style->light_gc[state_type];
4160 gc4 = style->dark_gc[state_type];
4165 gdk_gc_set_clip_rectangle (gc1, area);
4166 gdk_gc_set_clip_rectangle (gc2, area);
4167 gdk_gc_set_clip_rectangle (gc3, area);
4168 gdk_gc_set_clip_rectangle (gc4, area);
4171 switch (shadow_type)
4173 case GTK_SHADOW_NONE:
4175 case GTK_SHADOW_OUT:
4176 case GTK_SHADOW_ETCHED_IN:
4177 case GTK_SHADOW_ETCHED_OUT:
4181 gdk_draw_line (window, gc1,
4182 x, y, x, y + height - 1);
4183 gdk_draw_line (window, gc2,
4184 x + 1, y, x + 1, y + height - 2);
4186 gdk_draw_line (window, gc3,
4187 x + 1, y + height - 2, x + width - 2, y + height - 2);
4188 gdk_draw_line (window, gc3,
4189 x + width - 2, y, x + width - 2, y + height - 2);
4190 gdk_draw_line (window, gc4,
4191 x, y + height - 1, x + width - 1, y + height - 1);
4192 gdk_draw_line (window, gc4,
4193 x + width - 1, y, x + width - 1, y + height - 1);
4196 gdk_draw_line (window, gc1,
4197 x, y, x + gap_x - 1, y);
4198 gdk_draw_line (window, gc2,
4199 x + 1, y + 1, x + gap_x - 1, y + 1);
4200 gdk_draw_line (window, gc2,
4201 x + gap_x, y, x + gap_x, y);
4203 if ((width - (gap_x + gap_width)) > 0)
4205 gdk_draw_line (window, gc1,
4206 x + gap_x + gap_width, y, x + width - 2, y);
4207 gdk_draw_line (window, gc2,
4208 x + gap_x + gap_width, y + 1, x + width - 3, y + 1);
4209 gdk_draw_line (window, gc2,
4210 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
4213 case GTK_POS_BOTTOM:
4214 gdk_draw_line (window, gc1,
4215 x, y, x + width - 1, y);
4216 gdk_draw_line (window, gc1,
4217 x, y, x, y + height - 1);
4218 gdk_draw_line (window, gc2,
4219 x + 1, y + 1, x + width - 2, y + 1);
4220 gdk_draw_line (window, gc2,
4221 x + 1, y + 1, x + 1, y + height - 1);
4223 gdk_draw_line (window, gc3,
4224 x + width - 2, y + 1, x + width - 2, y + height - 1);
4225 gdk_draw_line (window, gc4,
4226 x + width - 1, y, x + width - 1, y + height - 1);
4229 gdk_draw_line (window, gc4,
4230 x, y + height - 1, x + gap_x - 1, y + height - 1);
4231 gdk_draw_line (window, gc3,
4232 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
4233 gdk_draw_line (window, gc3,
4234 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
4236 if ((width - (gap_x + gap_width)) > 0)
4238 gdk_draw_line (window, gc4,
4239 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
4240 gdk_draw_line (window, gc3,
4241 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
4242 gdk_draw_line (window, gc3,
4243 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
4247 gdk_draw_line (window, gc1,
4248 x, y, x + width - 1, y);
4249 gdk_draw_line (window, gc2,
4250 x, y + 1, x + width - 2, y + 1);
4252 gdk_draw_line (window, gc3,
4253 x, y + height - 2, x + width - 2, y + height - 2);
4254 gdk_draw_line (window, gc3,
4255 x + width - 2, y + 1, x + width - 2, y + height - 2);
4256 gdk_draw_line (window, gc4,
4257 x, y + height - 1, x + width - 1, y + height - 1);
4258 gdk_draw_line (window, gc4,
4259 x + width - 1, y, x + width - 1, y + height - 1);
4262 gdk_draw_line (window, gc1,
4263 x, y, x, y + gap_x - 1);
4264 gdk_draw_line (window, gc2,
4265 x + 1, y + 1, x + 1, y + gap_x - 1);
4266 gdk_draw_line (window, gc2,
4267 x, y + gap_x, x, y + gap_x);
4269 if ((width - (gap_x + gap_width)) > 0)
4271 gdk_draw_line (window, gc1,
4272 x, y + gap_x + gap_width, x, y + height - 2);
4273 gdk_draw_line (window, gc2,
4274 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
4275 gdk_draw_line (window, gc2,
4276 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
4280 gdk_draw_line (window, gc1,
4281 x, y, x + width - 1, y);
4282 gdk_draw_line (window, gc1,
4283 x, y, x, y + height - 1);
4284 gdk_draw_line (window, gc2,
4285 x + 1, y + 1, x + width - 1, y + 1);
4286 gdk_draw_line (window, gc2,
4287 x + 1, y + 1, x + 1, y + height - 2);
4289 gdk_draw_line (window, gc3,
4290 x + 1, y + height - 2, x + width - 1, y + height - 2);
4291 gdk_draw_line (window, gc4,
4292 x, y + height - 1, x + width - 1, y + height - 1);
4295 gdk_draw_line (window, gc4,
4296 x + width - 1, y, x + width - 1, y + gap_x - 1);
4297 gdk_draw_line (window, gc3,
4298 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
4299 gdk_draw_line (window, gc3,
4300 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
4302 if ((width - (gap_x + gap_width)) > 0)
4304 gdk_draw_line (window, gc4,
4305 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
4306 gdk_draw_line (window, gc3,
4307 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
4308 gdk_draw_line (window, gc3,
4309 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
4317 gdk_gc_set_clip_rectangle (gc1, NULL);
4318 gdk_gc_set_clip_rectangle (gc2, NULL);
4319 gdk_gc_set_clip_rectangle (gc3, NULL);
4320 gdk_gc_set_clip_rectangle (gc4, NULL);
4325 gtk_default_draw_box_gap (GtkStyle *style,
4327 GtkStateType state_type,
4328 GtkShadowType shadow_type,
4331 const gchar *detail,
4336 GtkPositionType gap_side,
4345 gtk_style_apply_default_background (style, window,
4346 widget && !GTK_WIDGET_NO_WINDOW (widget),
4347 state_type, area, x, y, width, height);
4349 sanitize_size (window, &width, &height);
4351 switch (shadow_type)
4353 case GTK_SHADOW_NONE:
4356 gc1 = style->dark_gc[state_type];
4357 gc2 = style->black_gc;
4358 gc3 = style->bg_gc[state_type];
4359 gc4 = style->light_gc[state_type];
4361 case GTK_SHADOW_ETCHED_IN:
4362 gc1 = style->dark_gc[state_type];
4363 gc2 = style->light_gc[state_type];
4364 gc3 = style->dark_gc[state_type];
4365 gc4 = style->light_gc[state_type];
4367 case GTK_SHADOW_OUT:
4368 gc1 = style->light_gc[state_type];
4369 gc2 = style->bg_gc[state_type];
4370 gc3 = style->dark_gc[state_type];
4371 gc4 = style->black_gc;
4373 case GTK_SHADOW_ETCHED_OUT:
4374 gc1 = style->light_gc[state_type];
4375 gc2 = style->dark_gc[state_type];
4376 gc3 = style->light_gc[state_type];
4377 gc4 = style->dark_gc[state_type];
4383 gdk_gc_set_clip_rectangle (gc1, area);
4384 gdk_gc_set_clip_rectangle (gc2, area);
4385 gdk_gc_set_clip_rectangle (gc3, area);
4386 gdk_gc_set_clip_rectangle (gc4, area);
4389 switch (shadow_type)
4391 case GTK_SHADOW_NONE:
4393 case GTK_SHADOW_OUT:
4394 case GTK_SHADOW_ETCHED_IN:
4395 case GTK_SHADOW_ETCHED_OUT:
4399 gdk_draw_line (window, gc1,
4400 x, y, x, y + height - 1);
4401 gdk_draw_line (window, gc2,
4402 x + 1, y, x + 1, y + height - 2);
4404 gdk_draw_line (window, gc3,
4405 x + 1, y + height - 2, x + width - 2, y + height - 2);
4406 gdk_draw_line (window, gc3,
4407 x + width - 2, y, x + width - 2, y + height - 2);
4408 gdk_draw_line (window, gc4,
4409 x, y + height - 1, x + width - 1, y + height - 1);
4410 gdk_draw_line (window, gc4,
4411 x + width - 1, y, x + width - 1, y + height - 1);
4414 gdk_draw_line (window, gc1,
4415 x, y, x + gap_x - 1, y);
4416 gdk_draw_line (window, gc2,
4417 x + 1, y + 1, x + gap_x - 1, y + 1);
4418 gdk_draw_line (window, gc2,
4419 x + gap_x, y, x + gap_x, y);
4421 if ((width - (gap_x + gap_width)) > 0)
4423 gdk_draw_line (window, gc1,
4424 x + gap_x + gap_width, y, x + width - 2, y);
4425 gdk_draw_line (window, gc2,
4426 x + gap_x + gap_width, y + 1, x + width - 2, y + 1);
4427 gdk_draw_line (window, gc2,
4428 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
4431 case GTK_POS_BOTTOM:
4432 gdk_draw_line (window, gc1,
4433 x, y, x + width - 1, y);
4434 gdk_draw_line (window, gc1,
4435 x, y, x, y + height - 1);
4436 gdk_draw_line (window, gc2,
4437 x + 1, y + 1, x + width - 2, y + 1);
4438 gdk_draw_line (window, gc2,
4439 x + 1, y + 1, x + 1, y + height - 1);
4441 gdk_draw_line (window, gc3,
4442 x + width - 2, y + 1, x + width - 2, y + height - 1);
4443 gdk_draw_line (window, gc4,
4444 x + width - 1, y, x + width - 1, y + height - 1);
4447 gdk_draw_line (window, gc4,
4448 x, y + height - 1, x + gap_x - 1, y + height - 1);
4449 gdk_draw_line (window, gc3,
4450 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
4451 gdk_draw_line (window, gc3,
4452 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
4454 if ((width - (gap_x + gap_width)) > 0)
4456 gdk_draw_line (window, gc4,
4457 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
4458 gdk_draw_line (window, gc3,
4459 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
4460 gdk_draw_line (window, gc3,
4461 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
4465 gdk_draw_line (window, gc1,
4466 x, y, x + width - 1, y);
4467 gdk_draw_line (window, gc2,
4468 x, y + 1, x + width - 2, y + 1);
4470 gdk_draw_line (window, gc3,
4471 x, y + height - 2, x + width - 2, y + height - 2);
4472 gdk_draw_line (window, gc3,
4473 x + width - 2, y + 1, x + width - 2, y + height - 2);
4474 gdk_draw_line (window, gc4,
4475 x, y + height - 1, x + width - 1, y + height - 1);
4476 gdk_draw_line (window, gc4,
4477 x + width - 1, y, x + width - 1, y + height - 1);
4480 gdk_draw_line (window, gc1,
4481 x, y, x, y + gap_x - 1);
4482 gdk_draw_line (window, gc2,
4483 x + 1, y + 1, x + 1, y + gap_x - 1);
4484 gdk_draw_line (window, gc2,
4485 x, y + gap_x, x, y + gap_x);
4487 if ((height - (gap_x + gap_width)) > 0)
4489 gdk_draw_line (window, gc1,
4490 x, y + gap_x + gap_width, x, y + height - 2);
4491 gdk_draw_line (window, gc2,
4492 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
4493 gdk_draw_line (window, gc2,
4494 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
4498 gdk_draw_line (window, gc1,
4499 x, y, x + width - 1, y);
4500 gdk_draw_line (window, gc1,
4501 x, y, x, y + height - 1);
4502 gdk_draw_line (window, gc2,
4503 x + 1, y + 1, x + width - 1, y + 1);
4504 gdk_draw_line (window, gc2,
4505 x + 1, y + 1, x + 1, y + height - 2);
4507 gdk_draw_line (window, gc3,
4508 x + 1, y + height - 2, x + width - 1, y + height - 2);
4509 gdk_draw_line (window, gc4,
4510 x, y + height - 1, x + width - 1, y + height - 1);
4513 gdk_draw_line (window, gc4,
4514 x + width - 1, y, x + width - 1, y + gap_x - 1);
4515 gdk_draw_line (window, gc3,
4516 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
4517 gdk_draw_line (window, gc3,
4518 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
4520 if ((height - (gap_x + gap_width)) > 0)
4522 gdk_draw_line (window, gc4,
4523 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
4524 gdk_draw_line (window, gc3,
4525 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
4526 gdk_draw_line (window, gc3,
4527 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
4535 gdk_gc_set_clip_rectangle (gc1, NULL);
4536 gdk_gc_set_clip_rectangle (gc2, NULL);
4537 gdk_gc_set_clip_rectangle (gc3, NULL);
4538 gdk_gc_set_clip_rectangle (gc4, NULL);
4543 gtk_default_draw_extension (GtkStyle *style,
4545 GtkStateType state_type,
4546 GtkShadowType shadow_type,
4549 const gchar *detail,
4554 GtkPositionType gap_side)
4561 gtk_style_apply_default_background (style, window,
4562 widget && !GTK_WIDGET_NO_WINDOW (widget),
4563 GTK_STATE_NORMAL, area, x, y, width, height);
4565 sanitize_size (window, &width, &height);
4567 switch (shadow_type)
4569 case GTK_SHADOW_NONE:
4572 gc1 = style->dark_gc[state_type];
4573 gc2 = style->black_gc;
4574 gc3 = style->bg_gc[state_type];
4575 gc4 = style->light_gc[state_type];
4577 case GTK_SHADOW_ETCHED_IN:
4578 gc1 = style->dark_gc[state_type];
4579 gc2 = style->light_gc[state_type];
4580 gc3 = style->dark_gc[state_type];
4581 gc4 = style->light_gc[state_type];
4583 case GTK_SHADOW_OUT:
4584 gc1 = style->light_gc[state_type];
4585 gc2 = style->bg_gc[state_type];
4586 gc3 = style->dark_gc[state_type];
4587 gc4 = style->black_gc;
4589 case GTK_SHADOW_ETCHED_OUT:
4590 gc1 = style->light_gc[state_type];
4591 gc2 = style->dark_gc[state_type];
4592 gc3 = style->light_gc[state_type];
4593 gc4 = style->dark_gc[state_type];
4599 gdk_gc_set_clip_rectangle (gc1, area);
4600 gdk_gc_set_clip_rectangle (gc2, area);
4601 gdk_gc_set_clip_rectangle (gc3, area);
4602 gdk_gc_set_clip_rectangle (gc4, area);
4605 switch (shadow_type)
4607 case GTK_SHADOW_NONE:
4609 case GTK_SHADOW_OUT:
4610 case GTK_SHADOW_ETCHED_IN:
4611 case GTK_SHADOW_ETCHED_OUT:
4615 gtk_style_apply_default_background (style, window,
4616 widget && !GTK_WIDGET_NO_WINDOW (widget),
4618 x + style->xthickness,
4620 width - (2 * style->xthickness),
4621 height - (style->ythickness));
4622 gdk_draw_line (window, gc1,
4623 x, y, x, y + height - 2);
4624 gdk_draw_line (window, gc2,
4625 x + 1, y, x + 1, y + height - 2);
4627 gdk_draw_line (window, gc3,
4628 x + 2, y + height - 2, x + width - 2, y + height - 2);
4629 gdk_draw_line (window, gc3,
4630 x + width - 2, y, x + width - 2, y + height - 2);
4631 gdk_draw_line (window, gc4,
4632 x + 1, y + height - 1, x + width - 2, y + height - 1);
4633 gdk_draw_line (window, gc4,
4634 x + width - 1, y, x + width - 1, y + height - 2);
4636 case GTK_POS_BOTTOM:
4637 gtk_style_apply_default_background (style, window,
4638 widget && !GTK_WIDGET_NO_WINDOW (widget),
4640 x + style->xthickness,
4641 y + style->ythickness,
4642 width - (2 * style->xthickness),
4643 height - (style->ythickness));
4644 gdk_draw_line (window, gc1,
4645 x + 1, y, x + width - 2, y);
4646 gdk_draw_line (window, gc1,
4647 x, y + 1, x, y + height - 1);
4648 gdk_draw_line (window, gc2,
4649 x + 1, y + 1, x + width - 2, y + 1);
4650 gdk_draw_line (window, gc2,
4651 x + 1, y + 1, x + 1, y + height - 1);
4653 gdk_draw_line (window, gc3,
4654 x + width - 2, y + 2, x + width - 2, y + height - 1);
4655 gdk_draw_line (window, gc4,
4656 x + width - 1, y + 1, x + width - 1, y + height - 1);
4659 gtk_style_apply_default_background (style, window,
4660 widget && !GTK_WIDGET_NO_WINDOW (widget),
4663 y + style->ythickness,
4664 width - (style->xthickness),
4665 height - (2 * style->ythickness));
4666 gdk_draw_line (window, gc1,
4667 x, y, x + width - 2, y);
4668 gdk_draw_line (window, gc2,
4669 x + 1, y + 1, x + width - 2, y + 1);
4671 gdk_draw_line (window, gc3,
4672 x, y + height - 2, x + width - 2, y + height - 2);
4673 gdk_draw_line (window, gc3,
4674 x + width - 2, y + 2, x + width - 2, y + height - 2);
4675 gdk_draw_line (window, gc4,
4676 x, y + height - 1, x + width - 2, y + height - 1);
4677 gdk_draw_line (window, gc4,
4678 x + width - 1, y + 1, x + width - 1, y + height - 2);
4681 gtk_style_apply_default_background (style, window,
4682 widget && !GTK_WIDGET_NO_WINDOW (widget),
4684 x + style->xthickness,
4685 y + style->ythickness,
4686 width - (style->xthickness),
4687 height - (2 * style->ythickness));
4688 gdk_draw_line (window, gc1,
4689 x + 1, y, x + width - 1, y);
4690 gdk_draw_line (window, gc1,
4691 x, y + 1, x, y + height - 2);
4692 gdk_draw_line (window, gc2,
4693 x + 1, y + 1, x + width - 1, y + 1);
4694 gdk_draw_line (window, gc2,
4695 x + 1, y + 1, x + 1, y + height - 2);
4697 gdk_draw_line (window, gc3,
4698 x + 2, y + height - 2, x + width - 1, y + height - 2);
4699 gdk_draw_line (window, gc4,
4700 x + 1, y + height - 1, x + width - 1, y + height - 1);
4707 gdk_gc_set_clip_rectangle (gc1, NULL);
4708 gdk_gc_set_clip_rectangle (gc2, NULL);
4709 gdk_gc_set_clip_rectangle (gc3, NULL);
4710 gdk_gc_set_clip_rectangle (gc4, NULL);
4715 gtk_default_draw_focus (GtkStyle *style,
4717 GtkStateType state_type,
4720 const gchar *detail,
4727 gboolean free_dash_list = FALSE;
4728 gint line_width = 1;
4729 gint8 *dash_list = (gint8 *) "\1\1";
4733 gtk_widget_style_get (widget,
4734 "focus-line-width", &line_width,
4735 "focus-line-pattern", (gchar *)&dash_list,
4738 free_dash_list = TRUE;
4741 if (detail && !strcmp (detail, "add-mode"))
4746 dash_list = (gint8 *) "\4\4";
4747 free_dash_list = FALSE;
4750 sanitize_size (window, &width, &height);
4752 cr = gdk_cairo_create (window);
4754 if (detail && !strcmp (detail, "colorwheel_light"))
4755 cairo_set_source_rgb (cr, 0., 0., 0.);
4756 else if (detail && !strcmp (detail, "colorwheel_dark"))
4757 cairo_set_source_rgb (cr, 1., 1., 1.);
4759 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
4761 cairo_set_line_width (cr, line_width);
4765 gint n_dashes = strlen ((const gchar *) dash_list);
4766 gdouble *dashes = g_new (gdouble, n_dashes);
4767 gdouble total_length = 0;
4768 gdouble dash_offset;
4771 for (i = 0; i < n_dashes; i++)
4773 dashes[i] = dash_list[i];
4774 total_length += dash_list[i];
4777 /* The dash offset here aligns the pattern to integer pixels
4778 * by starting the dash at the right side of the left border
4779 * Negative dash offsets in cairo don't work
4780 * (https://bugs.freedesktop.org/show_bug.cgi?id=2729)
4782 dash_offset = - line_width / 2.;
4783 while (dash_offset < 0)
4784 dash_offset += total_length;
4786 cairo_set_dash (cr, dashes, n_dashes, dash_offset);
4792 gdk_cairo_rectangle (cr, area);
4796 cairo_rectangle (cr,
4797 x + line_width / 2.,
4798 y + line_width / 2.,
4800 height - line_width);
4809 gtk_default_draw_slider (GtkStyle *style,
4811 GtkStateType state_type,
4812 GtkShadowType shadow_type,
4815 const gchar *detail,
4820 GtkOrientation orientation)
4822 sanitize_size (window, &width, &height);
4824 gtk_paint_box (style, window, state_type, shadow_type,
4825 area, widget, detail, x, y, width, height);
4828 (strcmp ("hscale", detail) == 0 ||
4829 strcmp ("vscale", detail) == 0))
4831 if (orientation == GTK_ORIENTATION_HORIZONTAL)
4832 gtk_paint_vline (style, window, state_type, area, widget, detail,
4833 y + style->ythickness,
4834 y + height - style->ythickness - 1, x + width / 2);
4836 gtk_paint_hline (style, window, state_type, area, widget, detail,
4837 x + style->xthickness,
4838 x + width - style->xthickness - 1, y + height / 2);
4843 draw_dot (GdkWindow *window,
4850 size = CLAMP (size, 2, 3);
4854 gdk_draw_point (window, light_gc, x, y);
4855 gdk_draw_point (window, light_gc, x+1, y+1);
4859 gdk_draw_point (window, light_gc, x, y);
4860 gdk_draw_point (window, light_gc, x+1, y);
4861 gdk_draw_point (window, light_gc, x, y+1);
4862 gdk_draw_point (window, dark_gc, x+1, y+2);
4863 gdk_draw_point (window, dark_gc, x+2, y+1);
4864 gdk_draw_point (window, dark_gc, x+2, y+2);
4869 gtk_default_draw_handle (GtkStyle *style,
4871 GtkStateType state_type,
4872 GtkShadowType shadow_type,
4875 const gchar *detail,
4880 GtkOrientation orientation)
4883 gint xthick, ythick;
4884 GdkGC *light_gc, *dark_gc;
4885 GdkGC *free_me = NULL;
4890 sanitize_size (window, &width, &height);
4892 gtk_paint_box (style, window, state_type, shadow_type, area, widget,
4893 detail, x, y, width, height);
4896 if (detail && !strcmp (detail, "paned"))
4898 /* we want to ignore the shadow border in paned widgets */
4902 if (state_type == GTK_STATE_SELECTED && widget && !GTK_WIDGET_HAS_FOCUS (widget))
4904 GdkColor unfocused_light;
4906 _gtk_style_shade (&style->base[GTK_STATE_ACTIVE], &unfocused_light,
4909 light_gc = free_me = gdk_gc_new (window);
4910 gdk_gc_set_rgb_fg_color (light_gc, &unfocused_light);
4913 light_gc = style->light_gc[state_type];
4915 dark_gc = style->black_gc;
4919 xthick = style->xthickness;
4920 ythick = style->ythickness;
4922 light_gc = style->light_gc[state_type];
4923 dark_gc = style->dark_gc[state_type];
4926 rect.x = x + xthick;
4927 rect.y = y + ythick;
4928 rect.width = width - (xthick * 2);
4929 rect.height = height - (ythick * 2);
4932 intersect = gdk_rectangle_intersect (area, &rect, &dest);
4942 gdk_gc_set_clip_rectangle (light_gc, &dest);
4943 gdk_gc_set_clip_rectangle (dark_gc, &dest);
4945 if (detail && !strcmp (detail, "paned"))
4947 if (orientation == GTK_ORIENTATION_HORIZONTAL)
4948 for (xx = x + width/2 - 15; xx <= x + width/2 + 15; xx += 5)
4949 draw_dot (window, light_gc, dark_gc, xx, y + height/2 - 1, 3);
4951 for (yy = y + height/2 - 15; yy <= y + height/2 + 15; yy += 5)
4952 draw_dot (window, light_gc, dark_gc, x + width/2 - 1, yy, 3);
4956 for (yy = y + ythick; yy < (y + height - ythick); yy += 3)
4957 for (xx = x + xthick; xx < (x + width - xthick); xx += 6)
4959 draw_dot (window, light_gc, dark_gc, xx, yy, 2);
4960 draw_dot (window, light_gc, dark_gc, xx + 3, yy + 1, 2);
4964 gdk_gc_set_clip_rectangle (light_gc, NULL);
4965 gdk_gc_set_clip_rectangle (dark_gc, NULL);
4969 g_object_unref (free_me);
4973 gtk_default_draw_expander (GtkStyle *style,
4975 GtkStateType state_type,
4978 const gchar *detail,
4981 GtkExpanderStyle expander_style)
4983 #define DEFAULT_EXPANDER_SIZE 12
4987 double vertical_overshoot;
4990 double interp; /* interpolation factor for center position */
4991 double x_double_horz, y_double_horz;
4992 double x_double_vert, y_double_vert;
4993 double x_double, y_double;
4996 cairo_t *cr = gdk_cairo_create (window);
5000 gdk_cairo_rectangle (cr, area);
5005 gtk_widget_class_find_style_property (GTK_WIDGET_GET_CLASS (widget),
5008 gtk_widget_style_get (widget,
5009 "expander-size", &expander_size,
5013 expander_size = DEFAULT_EXPANDER_SIZE;
5015 line_width = MAX (1, expander_size/9);
5017 switch (expander_style)
5019 case GTK_EXPANDER_COLLAPSED:
5020 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 180 : 0;
5023 case GTK_EXPANDER_SEMI_COLLAPSED:
5024 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 150 : 30;
5027 case GTK_EXPANDER_SEMI_EXPANDED:
5028 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 120 : 60;
5031 case GTK_EXPANDER_EXPANDED:
5036 g_assert_not_reached ();
5039 /* Compute distance that the stroke extends beyonds the end
5040 * of the triangle we draw.
5042 vertical_overshoot = line_width / 2.0 * (1. / tan (G_PI / 8));
5044 /* For odd line widths, we end the vertical line of the triangle
5045 * at a half pixel, so we round differently.
5047 if (line_width % 2 == 1)
5048 vertical_overshoot = ceil (0.5 + vertical_overshoot) - 0.5;
5050 vertical_overshoot = ceil (vertical_overshoot);
5052 /* Adjust the size of the triangle we draw so that the entire stroke fits
5054 diameter = MAX (3, expander_size - 2 * vertical_overshoot);
5056 /* If the line width is odd, we want the diameter to be even,
5057 * and vice versa, so force the sum to be odd. This relationship
5058 * makes the point of the triangle look right.
5060 diameter -= (1 - (diameter + line_width) % 2);
5062 radius = diameter / 2.;
5064 /* Adjust the center so that the stroke is properly aligned with
5065 * the pixel grid. The center adjustment is different for the
5066 * horizontal and vertical orientations. For intermediate positions
5067 * we interpolate between the two.
5069 x_double_vert = floor (x - (radius + line_width) / 2.) + (radius + line_width) / 2.;
5070 y_double_vert = y - 0.5;
5072 x_double_horz = x - 0.5;
5073 y_double_horz = floor (y - (radius + line_width) / 2.) + (radius + line_width) / 2.;
5075 x_double = x_double_vert * (1 - interp) + x_double_horz * interp;
5076 y_double = y_double_vert * (1 - interp) + y_double_horz * interp;
5078 cairo_translate (cr, x_double, y_double);
5079 cairo_rotate (cr, degrees * G_PI / 180);
5081 cairo_move_to (cr, - radius / 2., - radius);
5082 cairo_line_to (cr, radius / 2., 0);
5083 cairo_line_to (cr, - radius / 2., radius);
5084 cairo_close_path (cr);
5086 cairo_set_line_width (cr, line_width);
5088 if (state_type == GTK_STATE_PRELIGHT)
5089 gdk_cairo_set_source_color (cr,
5090 &style->fg[GTK_STATE_PRELIGHT]);
5091 else if (state_type == GTK_STATE_ACTIVE)
5092 gdk_cairo_set_source_color (cr,
5093 &style->light[GTK_STATE_ACTIVE]);
5095 gdk_cairo_set_source_color (cr,
5096 &style->base[GTK_STATE_NORMAL]);
5098 cairo_fill_preserve (cr);
5100 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
5106 typedef struct _ByteRange ByteRange;
5115 range_new (guint start,
5118 ByteRange *br = g_new (ByteRange, 1);
5127 get_insensitive_layout (GdkDrawable *drawable,
5128 PangoLayout *layout)
5130 GSList *embossed_ranges = NULL;
5131 GSList *stippled_ranges = NULL;
5132 PangoLayoutIter *iter;
5133 GSList *tmp_list = NULL;
5134 PangoLayout *new_layout;
5135 PangoAttrList *attrs;
5136 GdkBitmap *stipple = NULL;
5138 iter = pango_layout_get_iter (layout);
5142 PangoLayoutRun *run;
5143 PangoAttribute *attr;
5144 gboolean need_stipple = FALSE;
5147 run = pango_layout_iter_get_run_readonly (iter);
5151 tmp_list = run->item->analysis.extra_attrs;
5153 while (tmp_list != NULL)
5155 attr = tmp_list->data;
5156 switch (attr->klass->type)
5158 case PANGO_ATTR_FOREGROUND:
5159 case PANGO_ATTR_BACKGROUND:
5160 need_stipple = TRUE;
5170 tmp_list = g_slist_next (tmp_list);
5173 br = range_new (run->item->offset, run->item->offset + run->item->length);
5176 stippled_ranges = g_slist_prepend (stippled_ranges, br);
5178 embossed_ranges = g_slist_prepend (embossed_ranges, br);
5181 while (pango_layout_iter_next_run (iter));
5183 pango_layout_iter_free (iter);
5185 new_layout = pango_layout_copy (layout);
5187 attrs = pango_layout_get_attributes (new_layout);
5191 /* Create attr list if there wasn't one */
5192 attrs = pango_attr_list_new ();
5193 pango_layout_set_attributes (new_layout, attrs);
5194 pango_attr_list_unref (attrs);
5197 tmp_list = embossed_ranges;
5198 while (tmp_list != NULL)
5200 PangoAttribute *attr;
5201 ByteRange *br = tmp_list->data;
5203 attr = gdk_pango_attr_embossed_new (TRUE);
5205 attr->start_index = br->start;
5206 attr->end_index = br->end;
5208 pango_attr_list_change (attrs, attr);
5212 tmp_list = g_slist_next (tmp_list);
5215 g_slist_free (embossed_ranges);
5217 tmp_list = stippled_ranges;
5218 while (tmp_list != NULL)
5220 PangoAttribute *attr;
5221 ByteRange *br = tmp_list->data;
5223 if (stipple == NULL)
5225 #define gray50_width 2
5226 #define gray50_height 2
5227 static const char gray50_bits[] = {
5231 stipple = gdk_bitmap_create_from_data (drawable,
5232 gray50_bits, gray50_width,
5236 attr = gdk_pango_attr_stipple_new (stipple);
5238 attr->start_index = br->start;
5239 attr->end_index = br->end;
5241 pango_attr_list_change (attrs, attr);
5245 tmp_list = g_slist_next (tmp_list);
5248 g_slist_free (stippled_ranges);
5251 g_object_unref (stipple);
5257 gtk_default_draw_layout (GtkStyle *style,
5259 GtkStateType state_type,
5263 const gchar *detail,
5266 PangoLayout *layout)
5270 gc = use_text ? style->text_gc[state_type] : style->fg_gc[state_type];
5273 gdk_gc_set_clip_rectangle (gc, area);
5275 if (state_type == GTK_STATE_INSENSITIVE)
5279 ins = get_insensitive_layout (window, layout);
5281 gdk_draw_layout (window, gc, x, y, ins);
5283 g_object_unref (ins);
5287 gdk_draw_layout (window, gc, x, y, layout);
5291 gdk_gc_set_clip_rectangle (gc, NULL);
5295 gtk_default_draw_resize_grip (GtkStyle *style,
5297 GtkStateType state_type,
5300 const gchar *detail,
5312 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
5313 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
5314 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
5320 case GDK_WINDOW_EDGE_NORTH_WEST:
5321 /* make it square */
5324 else if (height < width)
5328 case GDK_WINDOW_EDGE_NORTH:
5332 case GDK_WINDOW_EDGE_NORTH_EAST:
5333 /* make it square, aligning to top right */
5336 else if (height < width)
5338 x += (width - height);
5343 case GDK_WINDOW_EDGE_WEST:
5347 case GDK_WINDOW_EDGE_EAST:
5348 /* aligning to right */
5351 x += (width - height);
5355 case GDK_WINDOW_EDGE_SOUTH_WEST:
5356 /* make it square, aligning to bottom left */
5359 y += (height - width);
5362 else if (height < width)
5366 case GDK_WINDOW_EDGE_SOUTH:
5367 /* align to bottom */
5370 y += (height - width);
5374 case GDK_WINDOW_EDGE_SOUTH_EAST:
5375 /* make it square, aligning to bottom right */
5378 y += (height - width);
5381 else if (height < width)
5383 x += (width - height);
5389 g_assert_not_reached ();
5391 /* Clear background */
5393 for (i = 0; i < 4; i++)
5397 points[j].x = (i == 0 || i == 3) ? x : x + width;
5398 points[j].y = (i < 2) ? y : y + height;
5403 gdk_draw_polygon (window, style->bg_gc[state_type], TRUE,
5404 points, skip < 0 ? 4 : 3);
5408 case GDK_WINDOW_EDGE_WEST:
5409 case GDK_WINDOW_EDGE_EAST:
5415 while (xi < x + width)
5417 gdk_draw_line (window,
5418 style->light_gc[state_type],
5423 gdk_draw_line (window,
5424 style->dark_gc[state_type],
5432 case GDK_WINDOW_EDGE_NORTH:
5433 case GDK_WINDOW_EDGE_SOUTH:
5439 while (yi < y + height)
5441 gdk_draw_line (window,
5442 style->light_gc[state_type],
5447 gdk_draw_line (window,
5448 style->dark_gc[state_type],
5456 case GDK_WINDOW_EDGE_NORTH_WEST:
5465 gdk_draw_line (window,
5466 style->dark_gc[state_type],
5473 gdk_draw_line (window,
5474 style->dark_gc[state_type],
5481 gdk_draw_line (window,
5482 style->light_gc[state_type],
5492 case GDK_WINDOW_EDGE_NORTH_EAST:
5499 while (xi < (x + width - 3))
5501 gdk_draw_line (window,
5502 style->light_gc[state_type],
5509 gdk_draw_line (window,
5510 style->dark_gc[state_type],
5517 gdk_draw_line (window,
5518 style->dark_gc[state_type],
5527 case GDK_WINDOW_EDGE_SOUTH_WEST:
5536 gdk_draw_line (window,
5537 style->dark_gc[state_type],
5544 gdk_draw_line (window,
5545 style->dark_gc[state_type],
5552 gdk_draw_line (window,
5553 style->light_gc[state_type],
5563 case GDK_WINDOW_EDGE_SOUTH_EAST:
5570 while (xi < (x + width - 3))
5572 gdk_draw_line (window,
5573 style->light_gc[state_type],
5580 gdk_draw_line (window,
5581 style->dark_gc[state_type],
5588 gdk_draw_line (window,
5589 style->dark_gc[state_type],
5599 g_assert_not_reached ();
5605 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
5606 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
5607 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
5612 gtk_default_draw_spinner (GtkStyle *style,
5614 GtkStateType state_type,
5630 gtk_style_get (style, GTK_TYPE_SPINNER,
5631 "num-steps", &num_steps,
5633 real_step = step % num_steps;
5635 /* get cairo context */
5636 cr = gdk_cairo_create (window);
5638 /* set a clip region for the expose event */
5639 cairo_rectangle (cr, x, y, width, height);
5642 cairo_translate (cr, x, y);
5644 /* draw clip region */
5645 cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
5647 color = &style->fg[state_type];
5650 radius = MIN (width / 2, height / 2);
5651 half = num_steps / 2;
5653 for (i = 0; i < num_steps; i++)
5655 gint inset = 0.7 * radius;
5657 /* transparency is a function of time and intial value */
5658 gdouble t = (gdouble) ((i + num_steps - real_step)
5659 % num_steps) / num_steps;
5663 cairo_set_source_rgba (cr,
5664 color->red / 65535.,
5665 color->green / 65535.,
5666 color->blue / 65535.,
5669 cairo_set_line_width (cr, 2.0);
5671 dx + (radius - inset) * cos (i * G_PI / half),
5672 dy + (radius - inset) * sin (i * G_PI / half));
5674 dx + radius * cos (i * G_PI / half),
5675 dy + radius * sin (i * G_PI / half));
5686 _gtk_style_shade (const GdkColor *a,
5694 red = (gdouble) a->red / 65535.0;
5695 green = (gdouble) a->green / 65535.0;
5696 blue = (gdouble) a->blue / 65535.0;
5698 rgb_to_hls (&red, &green, &blue);
5703 else if (green < 0.0)
5709 else if (blue < 0.0)
5712 hls_to_rgb (&red, &green, &blue);
5714 b->red = red * 65535.0;
5715 b->green = green * 65535.0;
5716 b->blue = blue * 65535.0;
5720 rgb_to_hls (gdouble *r,
5761 l = (max + min) / 2;
5768 s = (max - min) / (max + min);
5770 s = (max - min) / (2 - max - min);
5774 h = (green - blue) / delta;
5775 else if (green == max)
5776 h = 2 + (blue - red) / delta;
5777 else if (blue == max)
5778 h = 4 + (red - green) / delta;
5791 hls_to_rgb (gdouble *h,
5804 if (lightness <= 0.5)
5805 m2 = lightness * (1 + saturation);
5807 m2 = lightness + saturation - lightness * saturation;
5808 m1 = 2 * lightness - m2;
5810 if (saturation == 0)
5825 r = m1 + (m2 - m1) * hue / 60;
5829 r = m1 + (m2 - m1) * (240 - hue) / 60;
5840 g = m1 + (m2 - m1) * hue / 60;
5844 g = m1 + (m2 - m1) * (240 - hue) / 60;
5855 b = m1 + (m2 - m1) * hue / 60;
5859 b = m1 + (m2 - m1) * (240 - hue) / 60;
5872 * @style: a #GtkStyle
5873 * @window: a #GdkWindow
5874 * @state_type: a state
5875 * @area: rectangle to which the output is clipped, or %NULL if the
5876 * output should not be clipped
5877 * @widget: the widget (may be %NULL)
5878 * @detail: a style detail (may be %NULL)
5879 * @x1: the starting x coordinate
5880 * @x2: the ending x coordinate
5881 * @y: the y coordinate
5883 * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @window
5884 * using the given style and state.
5887 gtk_paint_hline (GtkStyle *style,
5889 GtkStateType state_type,
5890 const GdkRectangle *area,
5892 const gchar *detail,
5897 g_return_if_fail (GTK_IS_STYLE (style));
5898 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
5899 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5901 GTK_STYLE_GET_CLASS (style)->draw_hline (style, window, state_type,
5902 (GdkRectangle *) area, widget, detail,
5908 * @style: a #GtkStyle
5909 * @window: a #GdkWindow
5910 * @state_type: a state
5911 * @area: rectangle to which the output is clipped, or %NULL if the
5912 * output should not be clipped
5913 * @widget: the widget (may be %NULL)
5914 * @detail: a style detail (may be %NULL)
5915 * @y1_: the starting y coordinate
5916 * @y2_: the ending y coordinate
5917 * @x: the x coordinate
5919 * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @window
5920 * using the given style and state.
5923 gtk_paint_vline (GtkStyle *style,
5925 GtkStateType state_type,
5926 const GdkRectangle *area,
5928 const gchar *detail,
5933 g_return_if_fail (GTK_IS_STYLE (style));
5934 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
5935 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5937 GTK_STYLE_GET_CLASS (style)->draw_vline (style, window, state_type,
5938 (GdkRectangle *) area, widget, detail,
5944 * @style: a #GtkStyle
5945 * @window: a #GdkWindow
5946 * @state_type: a state
5947 * @shadow_type: type of shadow to draw
5948 * @area: clip rectangle or %NULL if the
5949 * output should not be clipped
5950 * @widget: the widget (may be %NULL)
5951 * @detail: a style detail (may be %NULL)
5952 * @x: x origin of the rectangle
5953 * @y: y origin of the rectangle
5954 * @width: width of the rectangle
5955 * @height: width of the rectangle
5957 * Draws a shadow around the given rectangle in @window
5958 * using the given style and state and shadow type.
5961 gtk_paint_shadow (GtkStyle *style,
5963 GtkStateType state_type,
5964 GtkShadowType shadow_type,
5965 const GdkRectangle *area,
5967 const gchar *detail,
5973 g_return_if_fail (GTK_IS_STYLE (style));
5974 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
5975 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5977 GTK_STYLE_GET_CLASS (style)->draw_shadow (style, window, state_type, shadow_type,
5978 (GdkRectangle *) area, widget, detail,
5979 x, y, width, height);
5983 * gtk_paint_polygon:
5984 * @style: a #GtkStyle
5985 * @window: a #GdkWindow
5986 * @state_type: a state
5987 * @shadow_type: type of shadow to draw
5988 * @area: clip rectangle, or %NULL if the
5989 * output should not be clipped
5990 * @widget: the widget (may be %NULL)
5991 * @detail: a style detail (may be %NULL)
5992 * @points: an array of #GdkPoint<!-- -->s
5993 * @n_points: length of @points
5994 * @fill: %TRUE if the polygon should be filled
5996 * Draws a polygon on @window with the given parameters.
5999 gtk_paint_polygon (GtkStyle *style,
6001 GtkStateType state_type,
6002 GtkShadowType shadow_type,
6003 const GdkRectangle *area,
6005 const gchar *detail,
6006 const GdkPoint *points,
6010 g_return_if_fail (GTK_IS_STYLE (style));
6011 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_polygon != NULL);
6012 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6014 GTK_STYLE_GET_CLASS (style)->draw_polygon (style, window, state_type, shadow_type,
6015 (GdkRectangle *) area, widget, detail,
6016 (GdkPoint *) points, n_points, fill);
6021 * @style: a #GtkStyle
6022 * @window: a #GdkWindow
6023 * @state_type: a state
6024 * @shadow_type: the type of shadow to draw
6025 * @area: clip rectangle, or %NULL if the
6026 * output should not be clipped
6027 * @widget: the widget (may be %NULL)
6028 * @detail: a style detail (may be %NULL)
6029 * @arrow_type: the type of arrow to draw
6030 * @fill: %TRUE if the arrow tip should be filled
6031 * @x: x origin of the rectangle to draw the arrow in
6032 * @y: y origin of the rectangle to draw the arrow in
6033 * @width: width of the rectangle to draw the arrow in
6034 * @height: height of the rectangle to draw the arrow in
6036 * Draws an arrow in the given rectangle on @window using the given
6037 * parameters. @arrow_type determines the direction of the arrow.
6040 gtk_paint_arrow (GtkStyle *style,
6042 GtkStateType state_type,
6043 GtkShadowType shadow_type,
6044 const GdkRectangle *area,
6046 const gchar *detail,
6047 GtkArrowType arrow_type,
6054 g_return_if_fail (GTK_IS_STYLE (style));
6055 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
6056 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6058 GTK_STYLE_GET_CLASS (style)->draw_arrow (style, window, state_type, shadow_type,
6059 (GdkRectangle *) area, widget, detail,
6060 arrow_type, fill, x, y, width, height);
6064 * gtk_paint_diamond:
6065 * @style: a #GtkStyle
6066 * @window: a #GdkWindow
6067 * @state_type: a state
6068 * @shadow_type: the type of shadow to draw
6069 * @area: clip rectangle, or %NULL if the
6070 * output should not be clipped
6071 * @widget: the widget (may be %NULL)
6072 * @detail: a style detail (may be %NULL)
6073 * @x: x origin of the rectangle to draw the diamond in
6074 * @y: y origin of the rectangle to draw the diamond in
6075 * @width: width of the rectangle to draw the diamond in
6076 * @height: height of the rectangle to draw the diamond in
6078 * Draws a diamond in the given rectangle on @window using the given
6082 gtk_paint_diamond (GtkStyle *style,
6084 GtkStateType state_type,
6085 GtkShadowType shadow_type,
6086 const GdkRectangle *area,
6088 const gchar *detail,
6094 g_return_if_fail (GTK_IS_STYLE (style));
6095 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
6096 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6098 GTK_STYLE_GET_CLASS (style)->draw_diamond (style, window, state_type, shadow_type,
6099 (GdkRectangle *) area, widget, detail,
6100 x, y, width, height);
6105 * @style: a #GtkStyle
6106 * @window: a #GdkWindow
6107 * @state_type: a state
6108 * @area: clip rectangle, or %NULL if the
6109 * output should not be clipped
6110 * @widget: the widget (may be %NULL)
6111 * @detail: a style detail (may be %NULL)
6114 * @string: the string to draw
6116 * Draws a text string on @window with the given parameters.
6118 * Deprecated: 2.0: Use gtk_paint_layout() instead.
6121 gtk_paint_string (GtkStyle *style,
6123 GtkStateType state_type,
6124 const GdkRectangle *area,
6126 const gchar *detail,
6129 const gchar *string)
6131 g_return_if_fail (GTK_IS_STYLE (style));
6132 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_string != NULL);
6133 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6135 GTK_STYLE_GET_CLASS (style)->draw_string (style, window, state_type,
6136 (GdkRectangle *) area, widget, detail,
6142 * @style: a #GtkStyle
6143 * @window: a #GdkWindow
6144 * @state_type: a state
6145 * @shadow_type: the type of shadow to draw
6146 * @area: clip rectangle, or %NULL if the
6147 * output should not be clipped
6148 * @widget: the widget (may be %NULL)
6149 * @detail: a style detail (may be %NULL)
6150 * @x: x origin of the box
6151 * @y: y origin of the box
6152 * @width: the width of the box
6153 * @height: the height of the box
6155 * Draws a box on @window with the given parameters.
6158 gtk_paint_box (GtkStyle *style,
6160 GtkStateType state_type,
6161 GtkShadowType shadow_type,
6162 const GdkRectangle *area,
6164 const gchar *detail,
6170 g_return_if_fail (GTK_IS_STYLE (style));
6171 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
6172 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6174 GTK_STYLE_GET_CLASS (style)->draw_box (style, window, state_type, shadow_type,
6175 (GdkRectangle *) area, widget, detail,
6176 x, y, width, height);
6180 * gtk_paint_flat_box:
6181 * @style: a #GtkStyle
6182 * @window: a #GdkWindow
6183 * @state_type: a state
6184 * @shadow_type: the type of shadow to draw
6185 * @area: clip rectangle, or %NULL if the
6186 * output should not be clipped
6187 * @widget: the widget (may be %NULL)
6188 * @detail: a style detail (may be %NULL)
6189 * @x: x origin of the box
6190 * @y: y origin of the box
6191 * @width: the width of the box
6192 * @height: the height of the box
6194 * Draws a flat box on @window with the given parameters.
6197 gtk_paint_flat_box (GtkStyle *style,
6199 GtkStateType state_type,
6200 GtkShadowType shadow_type,
6201 const GdkRectangle *area,
6203 const gchar *detail,
6209 g_return_if_fail (GTK_IS_STYLE (style));
6210 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
6211 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6213 GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, window, state_type, shadow_type,
6214 (GdkRectangle *) area, widget, detail,
6215 x, y, width, height);
6220 * @style: a #GtkStyle
6221 * @window: a #GdkWindow
6222 * @state_type: a state
6223 * @shadow_type: the type of shadow to draw
6224 * @area: clip rectangle, or %NULL if the
6225 * output should not be clipped
6226 * @widget: the widget (may be %NULL)
6227 * @detail: a style detail (may be %NULL)
6228 * @x: x origin of the rectangle to draw the check in
6229 * @y: y origin of the rectangle to draw the check in
6230 * @width: the width of the rectangle to draw the check in
6231 * @height: the height of the rectangle to draw the check in
6233 * Draws a check button indicator in the given rectangle on @window with
6234 * the given parameters.
6237 gtk_paint_check (GtkStyle *style,
6239 GtkStateType state_type,
6240 GtkShadowType shadow_type,
6241 const GdkRectangle *area,
6243 const gchar *detail,
6249 g_return_if_fail (GTK_IS_STYLE (style));
6250 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
6251 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6253 GTK_STYLE_GET_CLASS (style)->draw_check (style, window, state_type, shadow_type,
6254 (GdkRectangle *) area, widget, detail,
6255 x, y, width, height);
6260 * @style: a #GtkStyle
6261 * @window: a #GdkWindow
6262 * @state_type: a state
6263 * @shadow_type: the type of shadow to draw
6264 * @area: clip rectangle, or %NULL if the
6265 * output should not be clipped
6266 * @widget: the widget (may be %NULL)
6267 * @detail: a style detail (may be %NULL)
6268 * @x: x origin of the rectangle to draw the option in
6269 * @y: y origin of the rectangle to draw the option in
6270 * @width: the width of the rectangle to draw the option in
6271 * @height: the height of the rectangle to draw the option in
6273 * Draws a radio button indicator in the given rectangle on @window with
6274 * the given parameters.
6277 gtk_paint_option (GtkStyle *style,
6279 GtkStateType state_type,
6280 GtkShadowType shadow_type,
6281 const GdkRectangle *area,
6283 const gchar *detail,
6289 g_return_if_fail (GTK_IS_STYLE (style));
6290 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
6291 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6293 GTK_STYLE_GET_CLASS (style)->draw_option (style, window, state_type, shadow_type,
6294 (GdkRectangle *) area, widget, detail,
6295 x, y, width, height);
6300 * @style: a #GtkStyle
6301 * @window: a #GdkWindow
6302 * @state_type: a state
6303 * @shadow_type: the type of shadow to draw
6304 * @area: clip rectangle, or %NULL if the
6305 * output should not be clipped
6306 * @widget: the widget (may be %NULL)
6307 * @detail: a style detail (may be %NULL)
6308 * @x: x origin of the rectangle to draw the tab in
6309 * @y: y origin of the rectangle to draw the tab in
6310 * @width: the width of the rectangle to draw the tab in
6311 * @height: the height of the rectangle to draw the tab in
6313 * Draws an option menu tab (i.e. the up and down pointing arrows)
6314 * in the given rectangle on @window using the given parameters.
6317 gtk_paint_tab (GtkStyle *style,
6319 GtkStateType state_type,
6320 GtkShadowType shadow_type,
6321 const GdkRectangle *area,
6323 const gchar *detail,
6329 g_return_if_fail (GTK_IS_STYLE (style));
6330 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
6331 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6333 GTK_STYLE_GET_CLASS (style)->draw_tab (style, window, state_type, shadow_type,
6334 (GdkRectangle *) area, widget, detail,
6335 x, y, width, height);
6339 * gtk_paint_shadow_gap:
6340 * @style: a #GtkStyle
6341 * @window: a #GdkWindow
6342 * @state_type: a state
6343 * @shadow_type: type of shadow to draw
6344 * @area: clip rectangle, or %NULL if the
6345 * output should not be clipped
6346 * @widget: the widget (may be %NULL)
6347 * @detail: a style detail (may be %NULL)
6348 * @x: x origin of the rectangle
6349 * @y: y origin of the rectangle
6350 * @width: width of the rectangle
6351 * @height: width of the rectangle
6352 * @gap_side: side in which to leave the gap
6353 * @gap_x: starting position of the gap
6354 * @gap_width: width of the gap
6356 * Draws a shadow around the given rectangle in @window
6357 * using the given style and state and shadow type, leaving a
6361 gtk_paint_shadow_gap (GtkStyle *style,
6363 GtkStateType state_type,
6364 GtkShadowType shadow_type,
6365 const GdkRectangle *area,
6367 const gchar *detail,
6372 GtkPositionType gap_side,
6376 g_return_if_fail (GTK_IS_STYLE (style));
6377 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
6378 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6380 GTK_STYLE_GET_CLASS (style)->draw_shadow_gap (style, window, state_type, shadow_type,
6381 (GdkRectangle *) area, widget, detail,
6382 x, y, width, height, gap_side, gap_x, gap_width);
6387 * gtk_paint_box_gap:
6388 * @style: a #GtkStyle
6389 * @window: a #GdkWindow
6390 * @state_type: a state
6391 * @shadow_type: type of shadow to draw
6392 * @area: clip rectangle, or %NULL if the
6393 * output should not be clipped
6394 * @widget: the widget (may be %NULL)
6395 * @detail: a style detail (may be %NULL)
6396 * @x: x origin of the rectangle
6397 * @y: y origin of the rectangle
6398 * @width: width of the rectangle
6399 * @height: width of the rectangle
6400 * @gap_side: side in which to leave the gap
6401 * @gap_x: starting position of the gap
6402 * @gap_width: width of the gap
6404 * Draws a box in @window using the given style and state and shadow type,
6405 * leaving a gap in one side.
6408 gtk_paint_box_gap (GtkStyle *style,
6410 GtkStateType state_type,
6411 GtkShadowType shadow_type,
6412 const GdkRectangle *area,
6414 const gchar *detail,
6419 GtkPositionType gap_side,
6423 g_return_if_fail (GTK_IS_STYLE (style));
6424 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
6425 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6427 GTK_STYLE_GET_CLASS (style)->draw_box_gap (style, window, state_type, shadow_type,
6428 (GdkRectangle *) area, widget, detail,
6429 x, y, width, height, gap_side, gap_x, gap_width);
6433 * gtk_paint_extension:
6434 * @style: a #GtkStyle
6435 * @window: a #GdkWindow
6436 * @state_type: a state
6437 * @shadow_type: type of shadow to draw
6438 * @area: clip rectangle, or %NULL if the
6439 * output should not be clipped
6440 * @widget: the widget (may be %NULL)
6441 * @detail: a style detail (may be %NULL)
6442 * @x: x origin of the extension
6443 * @y: y origin of the extension
6444 * @width: width of the extension
6445 * @height: width of the extension
6446 * @gap_side: the side on to which the extension is attached
6448 * Draws an extension, i.e. a notebook tab.
6451 gtk_paint_extension (GtkStyle *style,
6453 GtkStateType state_type,
6454 GtkShadowType shadow_type,
6455 const GdkRectangle *area,
6457 const gchar *detail,
6462 GtkPositionType gap_side)
6464 g_return_if_fail (GTK_IS_STYLE (style));
6465 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
6466 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6468 GTK_STYLE_GET_CLASS (style)->draw_extension (style, window, state_type, shadow_type,
6469 (GdkRectangle *) area, widget, detail,
6470 x, y, width, height, gap_side);
6475 * @style: a #GtkStyle
6476 * @window: a #GdkWindow
6477 * @state_type: a state
6478 * @area: clip rectangle, or %NULL if the
6479 * output should not be clipped
6480 * @widget: the widget (may be %NULL)
6481 * @detail: a style detail (may be %NULL)
6482 * @x: the x origin of the rectangle around which to draw a focus indicator
6483 * @y: the y origin of the rectangle around which to draw a focus indicator
6484 * @width: the width of the rectangle around which to draw a focus indicator
6485 * @height: the height of the rectangle around which to draw a focus indicator
6487 * Draws a focus indicator around the given rectangle on @window using the
6491 gtk_paint_focus (GtkStyle *style,
6493 GtkStateType state_type,
6494 const GdkRectangle *area,
6496 const gchar *detail,
6502 g_return_if_fail (GTK_IS_STYLE (style));
6503 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
6504 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6506 GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, state_type,
6507 (GdkRectangle *) area, widget, detail,
6508 x, y, width, height);
6513 * @style: a #GtkStyle
6514 * @window: a #GdkWindow
6515 * @state_type: a state
6516 * @shadow_type: a shadow
6517 * @area: clip rectangle, or %NULL if the
6518 * output should not be clipped
6519 * @widget: the widget (may be %NULL)
6520 * @detail: a style detail (may be %NULL)
6521 * @x: the x origin of the rectangle in which to draw a slider
6522 * @y: the y origin of the rectangle in which to draw a slider
6523 * @width: the width of the rectangle in which to draw a slider
6524 * @height: the height of the rectangle in which to draw a slider
6525 * @orientation: the orientation to be used
6527 * Draws a slider in the given rectangle on @window using the
6528 * given style and orientation.
6531 gtk_paint_slider (GtkStyle *style,
6533 GtkStateType state_type,
6534 GtkShadowType shadow_type,
6535 const GdkRectangle *area,
6537 const gchar *detail,
6542 GtkOrientation orientation)
6544 g_return_if_fail (GTK_IS_STYLE (style));
6545 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
6546 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6548 GTK_STYLE_GET_CLASS (style)->draw_slider (style, window, state_type, shadow_type,
6549 (GdkRectangle *) area, widget, detail,
6550 x, y, width, height, orientation);
6555 * @style: a #GtkStyle
6556 * @window: a #GdkWindow
6557 * @state_type: a state
6558 * @shadow_type: type of shadow to draw
6559 * @area: clip rectangle, or %NULL if the
6560 * output should not be clipped
6561 * @widget: the widget (may be %NULL)
6562 * @detail: a style detail (may be %NULL)
6563 * @x: x origin of the handle
6564 * @y: y origin of the handle
6565 * @width: with of the handle
6566 * @height: height of the handle
6567 * @orientation: the orientation of the handle
6569 * Draws a handle as used in #GtkHandleBox and #GtkPaned.
6572 gtk_paint_handle (GtkStyle *style,
6574 GtkStateType state_type,
6575 GtkShadowType shadow_type,
6576 const GdkRectangle *area,
6578 const gchar *detail,
6583 GtkOrientation orientation)
6585 g_return_if_fail (GTK_IS_STYLE (style));
6586 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
6587 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6589 GTK_STYLE_GET_CLASS (style)->draw_handle (style, window, state_type, shadow_type,
6590 (GdkRectangle *) area, widget, detail,
6591 x, y, width, height, orientation);
6595 * gtk_paint_expander:
6596 * @style: a #GtkStyle
6597 * @window: a #GdkWindow
6598 * @state_type: a state
6599 * @area: clip rectangle, or %NULL if the
6600 * output should not be clipped
6601 * @widget: the widget (may be %NULL)
6602 * @detail: a style detail (may be %NULL)
6603 * @x: the x position to draw the expander at
6604 * @y: the y position to draw the expander at
6605 * @expander_style: the style to draw the expander in; determines
6606 * whether the expander is collapsed, expanded, or in an
6607 * intermediate state.
6609 * Draws an expander as used in #GtkTreeView. @x and @y specify the
6610 * center the expander. The size of the expander is determined by the
6611 * "expander-size" style property of @widget. (If widget is not
6612 * specified or doesn't have an "expander-size" property, an
6613 * unspecified default size will be used, since the caller doesn't
6614 * have sufficient information to position the expander, this is
6615 * likely not useful.) The expander is expander_size pixels tall
6616 * in the collapsed position and expander_size pixels wide in the
6617 * expanded position.
6620 gtk_paint_expander (GtkStyle *style,
6622 GtkStateType state_type,
6623 const GdkRectangle *area,
6625 const gchar *detail,
6628 GtkExpanderStyle expander_style)
6630 g_return_if_fail (GTK_IS_STYLE (style));
6631 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
6632 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6634 GTK_STYLE_GET_CLASS (style)->draw_expander (style, window, state_type,
6635 (GdkRectangle *) area, widget, detail,
6636 x, y, expander_style);
6641 * @style: a #GtkStyle
6642 * @window: a #GdkWindow
6643 * @state_type: a state
6644 * @use_text: whether to use the text or foreground
6645 * graphics context of @style
6646 * @area: clip rectangle, or %NULL if the
6647 * output should not be clipped
6648 * @widget: the widget (may be %NULL)
6649 * @detail: a style detail (may be %NULL)
6652 * @layout: the layout to draw
6654 * Draws a layout on @window using the given parameters.
6657 gtk_paint_layout (GtkStyle *style,
6659 GtkStateType state_type,
6661 const GdkRectangle *area,
6663 const gchar *detail,
6666 PangoLayout *layout)
6668 g_return_if_fail (GTK_IS_STYLE (style));
6669 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
6670 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6672 GTK_STYLE_GET_CLASS (style)->draw_layout (style, window, state_type, use_text,
6673 (GdkRectangle *) area, widget, detail,
6678 * gtk_paint_resize_grip:
6679 * @style: a #GtkStyle
6680 * @window: a #GdkWindow
6681 * @state_type: a state
6682 * @area: clip rectangle, or %NULL if the
6683 * output should not be clipped
6684 * @widget: the widget (may be %NULL)
6685 * @detail: a style detail (may be %NULL)
6686 * @edge: the edge in which to draw the resize grip
6687 * @x: the x origin of the rectangle in which to draw the resize grip
6688 * @y: the y origin of the rectangle in which to draw the resize grip
6689 * @width: the width of the rectangle in which to draw the resize grip
6690 * @height: the height of the rectangle in which to draw the resize grip
6692 * Draws a resize grip in the given rectangle on @window using the given
6696 gtk_paint_resize_grip (GtkStyle *style,
6698 GtkStateType state_type,
6699 const GdkRectangle *area,
6701 const gchar *detail,
6709 g_return_if_fail (GTK_IS_STYLE (style));
6710 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
6711 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6713 GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, window, state_type,
6714 (GdkRectangle *) area, widget, detail,
6715 edge, x, y, width, height);
6719 * gtk_paint_spinner:
6720 * @style: a #GtkStyle
6721 * @window: a #GdkWindow
6722 * @state_type: a state
6723 * @widget: the widget
6724 * @step: the nth step, a value between 0 and GtkSpinner::num-steps
6725 * @x: the x origin of the rectangle in which to draw the resize grip
6726 * @y: the y origin of the rectangle in which to draw the resize grip
6727 * @width: the width of the rectangle in which to draw the resize grip
6728 * @height: the height of the rectangle in which to draw the resize grip
6730 * Draws a spinner on @window using the given parameters.
6733 gtk_paint_spinner (GtkStyle *style,
6735 GtkStateType state_type,
6742 g_return_if_fail (GTK_IS_STYLE (style));
6743 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_spinner != NULL);
6744 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6746 GTK_STYLE_GET_CLASS (style)->draw_spinner (style, window, state_type,
6747 step, x, y, width, height);
6753 * Allocates a new #GtkBorder structure and initializes its elements to zero.
6755 * Returns: a new empty #GtkBorder. The newly allocated #GtkBorder should be
6756 * freed with gtk_border_free()
6761 gtk_border_new (void)
6763 return g_slice_new0 (GtkBorder);
6768 * @border_: a #GtkBorder.
6769 * @returns: a copy of @border_.
6771 * Copies a #GtkBorder structure.
6774 gtk_border_copy (const GtkBorder *border)
6776 g_return_val_if_fail (border != NULL, NULL);
6778 return g_slice_dup (GtkBorder, border);
6783 * @border_: a #GtkBorder.
6785 * Frees a #GtkBorder structure.
6788 gtk_border_free (GtkBorder *border)
6790 g_slice_free (GtkBorder, border);
6794 gtk_border_get_type (void)
6796 static GType our_type = 0;
6799 our_type = g_boxed_type_register_static (I_("GtkBorder"),
6800 (GBoxedCopyFunc) gtk_border_copy,
6801 (GBoxedFreeFunc) gtk_border_free);
6807 gtk_style_get_font_internal (GtkStyle *style)
6809 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
6811 if (style->private_font && style->private_font_desc)
6813 if (!style->font_desc ||
6814 !pango_font_description_equal (style->private_font_desc, style->font_desc))
6816 gdk_font_unref (style->private_font);
6817 style->private_font = NULL;
6819 if (style->private_font_desc)
6821 pango_font_description_free (style->private_font_desc);
6822 style->private_font_desc = NULL;
6827 if (!style->private_font)
6829 GdkDisplay *display;
6831 if (style->colormap)
6833 display = gdk_screen_get_display (gdk_colormap_get_screen (style->colormap));
6837 display = gdk_display_get_default ();
6838 GTK_NOTE (MULTIHEAD,
6839 g_warning ("gtk_style_get_font() should not be called on an unattached style"));
6842 if (style->font_desc)
6844 style->private_font = gdk_font_from_description_for_display (display, style->font_desc);
6845 style->private_font_desc = pango_font_description_copy (style->font_desc);
6848 if (!style->private_font)
6849 style->private_font = gdk_font_load_for_display (display, "fixed");
6851 if (!style->private_font)
6852 g_error ("Unable to load \"fixed\" font");
6855 return style->private_font;
6859 * gtk_style_get_font:
6860 * @style: a #GtkStyle
6862 * Gets the #GdkFont to use for the given style. This is
6863 * meant only as a replacement for direct access to @style->font
6864 * and should not be used in new code. New code should
6865 * use @style->font_desc instead.
6867 * Return value: the #GdkFont for the style. This font is owned
6868 * by the style; if you want to keep around a copy, you must
6869 * call gdk_font_ref().
6872 gtk_style_get_font (GtkStyle *style)
6874 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
6876 return gtk_style_get_font_internal (style);
6880 * gtk_style_set_font:
6881 * @style: a #GtkStyle.
6882 * @font: a #GdkFont, or %NULL to use the #GdkFont corresponding
6883 * to style->font_desc.
6885 * Sets the #GdkFont to use for a given style. This is
6886 * meant only as a replacement for direct access to style->font
6887 * and should not be used in new code. New code should
6888 * use style->font_desc instead.
6891 gtk_style_set_font (GtkStyle *style,
6896 g_return_if_fail (GTK_IS_STYLE (style));
6898 old_font = style->private_font;
6900 style->private_font = font;
6902 gdk_font_ref (font);
6905 gdk_font_unref (old_font);
6907 if (style->private_font_desc)
6909 pango_font_description_free (style->private_font_desc);
6910 style->private_font_desc = NULL;
6914 typedef struct _CursorInfo CursorInfo;
6920 GdkGC *secondary_gc;
6924 style_unrealize_cursor_gcs (GtkStyle *style)
6928 cursor_info = g_object_get_data (G_OBJECT (style), "gtk-style-cursor-info");
6931 if (cursor_info->primary_gc)
6932 gtk_gc_release (cursor_info->primary_gc);
6934 if (cursor_info->secondary_gc)
6935 gtk_gc_release (cursor_info->secondary_gc);
6937 g_free (cursor_info);
6938 g_object_set_data (G_OBJECT (style), I_("gtk-style-cursor-info"), NULL);
6943 make_cursor_gc (GtkWidget *widget,
6944 const gchar *property_name,
6945 const GdkColor *fallback)
6947 GdkGCValues gc_values;
6948 GdkGCValuesMask gc_values_mask;
6949 GdkColor *cursor_color;
6951 gtk_widget_style_get (widget, property_name, &cursor_color, NULL);
6953 gc_values_mask = GDK_GC_FOREGROUND;
6956 gc_values.foreground = *cursor_color;
6957 gdk_color_free (cursor_color);
6960 gc_values.foreground = *fallback;
6962 gdk_rgb_find_color (widget->style->colormap, &gc_values.foreground);
6963 return gtk_gc_get (widget->style->depth, widget->style->colormap, &gc_values, gc_values_mask);
6967 get_insertion_cursor_gc (GtkWidget *widget,
6968 gboolean is_primary)
6970 CursorInfo *cursor_info;
6972 cursor_info = g_object_get_data (G_OBJECT (widget->style), "gtk-style-cursor-info");
6975 cursor_info = g_new (CursorInfo, 1);
6976 g_object_set_data (G_OBJECT (widget->style), I_("gtk-style-cursor-info"), cursor_info);
6977 cursor_info->primary_gc = NULL;
6978 cursor_info->secondary_gc = NULL;
6979 cursor_info->for_type = G_TYPE_INVALID;
6982 /* We have to keep track of the type because gtk_widget_style_get()
6983 * can return different results when called on the same property and
6984 * same style but for different widgets. :-(. That is,
6985 * GtkEntry::cursor-color = "red" in a style will modify the cursor
6986 * color for entries but not for text view.
6988 if (cursor_info->for_type != G_OBJECT_TYPE (widget))
6990 cursor_info->for_type = G_OBJECT_TYPE (widget);
6991 if (cursor_info->primary_gc)
6993 gtk_gc_release (cursor_info->primary_gc);
6994 cursor_info->primary_gc = NULL;
6996 if (cursor_info->secondary_gc)
6998 gtk_gc_release (cursor_info->secondary_gc);
6999 cursor_info->secondary_gc = NULL;
7003 /* Cursors in text widgets are drawn only in NORMAL state,
7004 * so we can use text[GTK_STATE_NORMAL] as text color here */
7007 if (!cursor_info->primary_gc)
7008 cursor_info->primary_gc = make_cursor_gc (widget,
7010 &widget->style->text[GTK_STATE_NORMAL]);
7012 return cursor_info->primary_gc;
7016 if (!cursor_info->secondary_gc)
7017 cursor_info->secondary_gc = make_cursor_gc (widget,
7018 "secondary-cursor-color",
7019 /* text_aa is the average of text and base colors,
7020 * in usual black-on-white case it's grey. */
7021 &widget->style->text_aa[GTK_STATE_NORMAL]);
7023 return cursor_info->secondary_gc;
7028 _gtk_widget_get_cursor_gc (GtkWidget *widget)
7030 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
7031 g_return_val_if_fail (GTK_WIDGET_REALIZED (widget), NULL);
7032 return get_insertion_cursor_gc (widget, TRUE);
7036 _gtk_widget_get_cursor_color (GtkWidget *widget,
7039 GdkColor *style_color;
7041 g_return_if_fail (GTK_IS_WIDGET (widget));
7042 g_return_if_fail (color != NULL);
7044 gtk_widget_style_get (widget, "cursor-color", &style_color, NULL);
7048 *color = *style_color;
7049 gdk_color_free (style_color);
7052 *color = widget->style->text[GTK_STATE_NORMAL];
7056 draw_insertion_cursor (GtkWidget *widget,
7057 GdkDrawable *drawable,
7059 const GdkRectangle *location,
7060 GtkTextDirection direction,
7061 gboolean draw_arrow)
7067 gfloat cursor_aspect_ratio;
7070 /* When changing the shape or size of the cursor here,
7071 * propagate the changes to gtktextview.c:text_window_invalidate_cursors().
7074 gtk_widget_style_get (widget, "cursor-aspect-ratio", &cursor_aspect_ratio, NULL);
7076 stem_width = location->height * cursor_aspect_ratio + 1;
7077 arrow_width = stem_width + 1;
7079 /* put (stem_width % 2) on the proper side of the cursor */
7080 if (direction == GTK_TEXT_DIR_LTR)
7081 offset = stem_width / 2;
7083 offset = stem_width - stem_width / 2;
7085 for (i = 0; i < stem_width; i++)
7086 gdk_draw_line (drawable, gc,
7087 location->x + i - offset, location->y,
7088 location->x + i - offset, location->y + location->height - 1);
7092 if (direction == GTK_TEXT_DIR_RTL)
7094 x = location->x - offset - 1;
7095 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
7097 for (i = 0; i < arrow_width; i++)
7099 gdk_draw_line (drawable, gc,
7101 x, y + 2 * arrow_width - i - 1);
7105 else if (direction == GTK_TEXT_DIR_LTR)
7107 x = location->x + stem_width - offset;
7108 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
7110 for (i = 0; i < arrow_width; i++)
7112 gdk_draw_line (drawable, gc,
7114 x, y + 2 * arrow_width - i - 1);
7122 * gtk_draw_insertion_cursor:
7123 * @widget: a #GtkWidget
7124 * @drawable: a #GdkDrawable
7125 * @area: rectangle to which the output is clipped, or %NULL if the
7126 * output should not be clipped
7127 * @location: location where to draw the cursor (@location->width is ignored)
7128 * @is_primary: if the cursor should be the primary cursor color.
7129 * @direction: whether the cursor is left-to-right or
7130 * right-to-left. Should never be #GTK_TEXT_DIR_NONE
7131 * @draw_arrow: %TRUE to draw a directional arrow on the
7132 * cursor. Should be %FALSE unless the cursor is split.
7134 * Draws a text caret on @drawable at @location. This is not a style function
7135 * but merely a convenience function for drawing the standard cursor shape.
7140 gtk_draw_insertion_cursor (GtkWidget *widget,
7141 GdkDrawable *drawable,
7142 const GdkRectangle *area,
7143 const GdkRectangle *location,
7144 gboolean is_primary,
7145 GtkTextDirection direction,
7146 gboolean draw_arrow)
7150 g_return_if_fail (GTK_IS_WIDGET (widget));
7151 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
7152 g_return_if_fail (location != NULL);
7153 g_return_if_fail (direction != GTK_TEXT_DIR_NONE);
7155 gc = get_insertion_cursor_gc (widget, is_primary);
7157 gdk_gc_set_clip_rectangle (gc, area);
7159 draw_insertion_cursor (widget, drawable, gc,
7160 location, direction, draw_arrow);
7163 gdk_gc_set_clip_rectangle (gc, NULL);
7166 #define __GTK_STYLE_C__
7167 #include "gtkaliasdef.c"