1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
32 #include "gtkmarshalers.h"
34 #include "gtkspinbutton.h"
36 #include "gtkwidget.h"
37 #include "gtkthemes.h"
38 #include "gtkiconfactory.h"
39 #include "gtksettings.h" /* _gtk_settings_parse_convert() */
43 #define LIGHTNESS_MULT 1.3
44 #define DARKNESS_MULT 0.7
46 /* --- typedefs & structures --- */
53 /* --- prototypes --- */
54 static void gtk_style_init (GtkStyle *style);
55 static void gtk_style_class_init (GtkStyleClass *klass);
56 static void gtk_style_finalize (GObject *object);
57 static void gtk_style_realize (GtkStyle *style,
58 GdkColormap *colormap);
59 static void gtk_style_real_realize (GtkStyle *style);
60 static void gtk_style_real_unrealize (GtkStyle *style);
61 static void gtk_style_real_copy (GtkStyle *style,
63 static void gtk_style_real_set_background (GtkStyle *style,
65 GtkStateType state_type);
66 static GtkStyle *gtk_style_real_clone (GtkStyle *style);
67 static void gtk_style_real_init_from_rc (GtkStyle *style,
68 GtkRcStyle *rc_style);
69 static GdkPixbuf *gtk_default_render_icon (GtkStyle *style,
70 const GtkIconSource *source,
71 GtkTextDirection direction,
76 static void gtk_default_draw_hline (GtkStyle *style,
78 GtkStateType state_type,
85 static void gtk_default_draw_vline (GtkStyle *style,
87 GtkStateType state_type,
94 static void gtk_default_draw_shadow (GtkStyle *style,
96 GtkStateType state_type,
97 GtkShadowType shadow_type,
105 static void gtk_default_draw_polygon (GtkStyle *style,
107 GtkStateType state_type,
108 GtkShadowType shadow_type,
115 static void gtk_default_draw_arrow (GtkStyle *style,
117 GtkStateType state_type,
118 GtkShadowType shadow_type,
122 GtkArrowType arrow_type,
128 static void gtk_default_draw_diamond (GtkStyle *style,
130 GtkStateType state_type,
131 GtkShadowType shadow_type,
139 static void gtk_default_draw_string (GtkStyle *style,
141 GtkStateType state_type,
147 const gchar *string);
148 static void gtk_default_draw_box (GtkStyle *style,
150 GtkStateType state_type,
151 GtkShadowType shadow_type,
159 static void gtk_default_draw_flat_box (GtkStyle *style,
161 GtkStateType state_type,
162 GtkShadowType shadow_type,
170 static void gtk_default_draw_check (GtkStyle *style,
172 GtkStateType state_type,
173 GtkShadowType shadow_type,
181 static void gtk_default_draw_option (GtkStyle *style,
183 GtkStateType state_type,
184 GtkShadowType shadow_type,
192 static void gtk_default_draw_tab (GtkStyle *style,
194 GtkStateType state_type,
195 GtkShadowType shadow_type,
203 static void gtk_default_draw_shadow_gap (GtkStyle *style,
205 GtkStateType state_type,
206 GtkShadowType shadow_type,
214 GtkPositionType gap_side,
217 static void gtk_default_draw_box_gap (GtkStyle *style,
219 GtkStateType state_type,
220 GtkShadowType shadow_type,
228 GtkPositionType gap_side,
231 static void gtk_default_draw_extension (GtkStyle *style,
233 GtkStateType state_type,
234 GtkShadowType shadow_type,
242 GtkPositionType gap_side);
243 static void gtk_default_draw_focus (GtkStyle *style,
245 GtkStateType state_type,
253 static void gtk_default_draw_slider (GtkStyle *style,
255 GtkStateType state_type,
256 GtkShadowType shadow_type,
264 GtkOrientation orientation);
265 static void gtk_default_draw_handle (GtkStyle *style,
267 GtkStateType state_type,
268 GtkShadowType shadow_type,
276 GtkOrientation orientation);
277 static void gtk_default_draw_expander (GtkStyle *style,
279 GtkStateType state_type,
285 GtkExpanderStyle expander_style);
286 static void gtk_default_draw_layout (GtkStyle *style,
288 GtkStateType state_type,
295 PangoLayout *layout);
296 static void gtk_default_draw_resize_grip (GtkStyle *style,
298 GtkStateType state_type,
308 static void gtk_style_shade (GdkColor *a,
311 static void rgb_to_hls (gdouble *r,
314 static void hls_to_rgb (gdouble *h,
318 static void style_unrealize_cursor_gcs (GtkStyle *style);
320 static GdkFont *gtk_style_get_font_internal (GtkStyle *style);
323 * Data for default check and radio buttons
326 static const GtkRequisition default_option_indicator_size = { 7, 13 };
327 static const GtkBorder default_option_indicator_spacing = { 7, 5, 2, 2 };
329 #define GTK_GRAY 0xdcdc, 0xdada, 0xd5d5
330 #define GTK_DARK_GRAY 0xc4c4, 0xc2c2, 0xbdbd
331 #define GTK_LIGHT_GRAY 0xeeee, 0xebeb, 0xe7e7
332 #define GTK_WHITE 0xffff, 0xffff, 0xffff
333 #define GTK_BLUE 0x4b4b, 0x6969, 0x8383
334 #define GTK_VERY_DARK_GRAY 0x9c9c, 0x9a9a, 0x9494
335 #define GTK_BLACK 0x0000, 0x0000, 0x0000
336 #define GTK_WEAK_GRAY 0x7530, 0x7530, 0x7530
338 /* --- variables --- */
339 static const GdkColor gtk_default_normal_fg = { 0, GTK_BLACK };
340 static const GdkColor gtk_default_active_fg = { 0, GTK_BLACK };
341 static const GdkColor gtk_default_prelight_fg = { 0, GTK_BLACK };
342 static const GdkColor gtk_default_selected_fg = { 0, GTK_WHITE };
343 static const GdkColor gtk_default_insensitive_fg = { 0, GTK_WEAK_GRAY };
345 static const GdkColor gtk_default_normal_bg = { 0, GTK_GRAY };
346 static const GdkColor gtk_default_active_bg = { 0, GTK_DARK_GRAY };
347 static const GdkColor gtk_default_prelight_bg = { 0, GTK_LIGHT_GRAY };
348 static const GdkColor gtk_default_selected_bg = { 0, GTK_BLUE };
349 static const GdkColor gtk_default_insensitive_bg = { 0, GTK_GRAY };
350 static const GdkColor gtk_default_selected_base = { 0, GTK_BLUE };
351 static const GdkColor gtk_default_active_base = { 0, GTK_VERY_DARK_GRAY };
353 static gpointer parent_class = NULL;
355 /* --- signals --- */
356 static guint realize_signal = 0;
357 static guint unrealize_signal = 0;
359 /* --- functions --- */
361 gtk_style_get_type (void)
363 static GType style_type = 0;
367 static const GTypeInfo style_info =
369 sizeof (GtkStyleClass),
370 (GBaseInitFunc) NULL,
371 (GBaseFinalizeFunc) NULL,
372 (GClassInitFunc) gtk_style_class_init,
373 NULL, /* class_finalize */
374 NULL, /* class_data */
377 (GInstanceInitFunc) gtk_style_init,
380 style_type = g_type_register_static (G_TYPE_OBJECT, I_("GtkStyle"),
388 * _gtk_style_init_for_settings:
389 * @style: a #GtkStyle
390 * @settings: a #GtkSettings
392 * Initializes the font description in @style according to the default
393 * font name of @settings. This is called for gtk_style_new() with
394 * the settings for the default screen (if any); if we are creating
395 * a style for a particular screen, we then call it again in a
396 * location where we know the correct settings.
397 * The reason for this is that gtk_rc_style_create_style() doesn't
398 * take the screen for an argument.
401 _gtk_style_init_for_settings (GtkStyle *style,
402 GtkSettings *settings)
404 const gchar *font_name = _gtk_rc_context_get_default_font_name (settings);
406 if (style->font_desc)
407 pango_font_description_free (style->font_desc);
409 style->font_desc = pango_font_description_from_string (font_name);
411 if (!pango_font_description_get_family (style->font_desc))
413 g_warning ("Default font does not have a family set");
414 pango_font_description_set_family (style->font_desc, "Sans");
416 if (pango_font_description_get_size (style->font_desc) <= 0)
418 g_warning ("Default font does not have a positive size");
419 pango_font_description_set_size (style->font_desc, 10 * PANGO_SCALE);
424 gtk_style_init (GtkStyle *style)
428 GtkSettings *settings = gtk_settings_get_default ();
431 _gtk_style_init_for_settings (style, settings);
433 style->font_desc = pango_font_description_from_string ("Sans 10");
435 style->attach_count = 0;
436 style->colormap = NULL;
439 style->black.red = 0;
440 style->black.green = 0;
441 style->black.blue = 0;
443 style->white.red = 65535;
444 style->white.green = 65535;
445 style->white.blue = 65535;
447 style->black_gc = NULL;
448 style->white_gc = NULL;
450 style->fg[GTK_STATE_NORMAL] = gtk_default_normal_fg;
451 style->fg[GTK_STATE_ACTIVE] = gtk_default_active_fg;
452 style->fg[GTK_STATE_PRELIGHT] = gtk_default_prelight_fg;
453 style->fg[GTK_STATE_SELECTED] = gtk_default_selected_fg;
454 style->fg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
456 style->bg[GTK_STATE_NORMAL] = gtk_default_normal_bg;
457 style->bg[GTK_STATE_ACTIVE] = gtk_default_active_bg;
458 style->bg[GTK_STATE_PRELIGHT] = gtk_default_prelight_bg;
459 style->bg[GTK_STATE_SELECTED] = gtk_default_selected_bg;
460 style->bg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_bg;
462 for (i = 0; i < 4; i++)
464 style->text[i] = style->fg[i];
465 style->base[i] = style->white;
468 style->base[GTK_STATE_SELECTED] = gtk_default_selected_base;
469 style->text[GTK_STATE_SELECTED] = style->white;
470 style->base[GTK_STATE_ACTIVE] = gtk_default_active_base;
471 style->text[GTK_STATE_ACTIVE] = style->white;
472 style->base[GTK_STATE_INSENSITIVE] = gtk_default_prelight_bg;
473 style->text[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
475 for (i = 0; i < 5; i++)
476 style->bg_pixmap[i] = NULL;
478 style->rc_style = NULL;
480 for (i = 0; i < 5; i++)
482 style->fg_gc[i] = NULL;
483 style->bg_gc[i] = NULL;
484 style->light_gc[i] = NULL;
485 style->dark_gc[i] = NULL;
486 style->mid_gc[i] = NULL;
487 style->text_gc[i] = NULL;
488 style->base_gc[i] = NULL;
489 style->text_aa_gc[i] = NULL;
492 style->xthickness = 2;
493 style->ythickness = 2;
495 style->property_cache = NULL;
499 gtk_style_class_init (GtkStyleClass *klass)
501 GObjectClass *object_class = G_OBJECT_CLASS (klass);
503 parent_class = g_type_class_peek_parent (klass);
505 object_class->finalize = gtk_style_finalize;
507 klass->clone = gtk_style_real_clone;
508 klass->copy = gtk_style_real_copy;
509 klass->init_from_rc = gtk_style_real_init_from_rc;
510 klass->realize = gtk_style_real_realize;
511 klass->unrealize = gtk_style_real_unrealize;
512 klass->set_background = gtk_style_real_set_background;
513 klass->render_icon = gtk_default_render_icon;
515 klass->draw_hline = gtk_default_draw_hline;
516 klass->draw_vline = gtk_default_draw_vline;
517 klass->draw_shadow = gtk_default_draw_shadow;
518 klass->draw_polygon = gtk_default_draw_polygon;
519 klass->draw_arrow = gtk_default_draw_arrow;
520 klass->draw_diamond = gtk_default_draw_diamond;
521 klass->draw_string = gtk_default_draw_string;
522 klass->draw_box = gtk_default_draw_box;
523 klass->draw_flat_box = gtk_default_draw_flat_box;
524 klass->draw_check = gtk_default_draw_check;
525 klass->draw_option = gtk_default_draw_option;
526 klass->draw_tab = gtk_default_draw_tab;
527 klass->draw_shadow_gap = gtk_default_draw_shadow_gap;
528 klass->draw_box_gap = gtk_default_draw_box_gap;
529 klass->draw_extension = gtk_default_draw_extension;
530 klass->draw_focus = gtk_default_draw_focus;
531 klass->draw_slider = gtk_default_draw_slider;
532 klass->draw_handle = gtk_default_draw_handle;
533 klass->draw_expander = gtk_default_draw_expander;
534 klass->draw_layout = gtk_default_draw_layout;
535 klass->draw_resize_grip = gtk_default_draw_resize_grip;
540 * @style: the object which received the signal
542 * Emitted when the style has been initialized for a particular
543 * colormap and depth. Connecting to this signal is probably seldom
544 * useful since most of the time applications and widgets only
545 * deal with styles that have been already realized.
549 realize_signal = g_signal_new (I_("realize"),
550 G_TYPE_FROM_CLASS (object_class),
552 G_STRUCT_OFFSET (GtkStyleClass, realize),
554 _gtk_marshal_VOID__VOID,
557 * GtkStyle::unrealize:
558 * @style: the object which received the signal
560 * Emitted when the aspects of the style specific to a particular colormap
561 * and depth are being cleaned up. A connection to this signal can be useful
562 * if a widget wants to cache objects like a #GdkGC as object data on #GtkStyle.
563 * This signal provides a convenient place to free such cached objects.
567 unrealize_signal = g_signal_new (I_("unrealize"),
568 G_TYPE_FROM_CLASS (object_class),
570 G_STRUCT_OFFSET (GtkStyleClass, unrealize),
572 _gtk_marshal_VOID__VOID,
577 clear_property_cache (GtkStyle *style)
579 if (style->property_cache)
583 for (i = 0; i < style->property_cache->len; i++)
585 PropertyValue *node = &g_array_index (style->property_cache, PropertyValue, i);
587 g_param_spec_unref (node->pspec);
588 g_value_unset (&node->value);
590 g_array_free (style->property_cache, TRUE);
591 style->property_cache = NULL;
596 gtk_style_finalize (GObject *object)
598 GtkStyle *style = GTK_STYLE (object);
600 g_return_if_fail (style->attach_count == 0);
602 clear_property_cache (style);
604 /* All the styles in the list have the same
605 * style->styles pointer. If we delete the
606 * *first* style from the list, we need to update
607 * the style->styles pointers from all the styles.
608 * Otherwise we simply remove the node from
613 if (style->styles->data != style)
614 g_slist_remove (style->styles, style);
617 GSList *tmp_list = style->styles->next;
621 GTK_STYLE (tmp_list->data)->styles = style->styles->next;
622 tmp_list = tmp_list->next;
624 g_slist_free_1 (style->styles);
628 if (style->icon_factories)
630 GSList *tmp_list = style->icon_factories;
634 g_object_unref (tmp_list->data);
635 tmp_list = tmp_list->next;
638 g_slist_free (style->icon_factories);
641 pango_font_description_free (style->font_desc);
643 if (style->private_font)
644 gdk_font_unref (style->private_font);
646 if (style->private_font_desc)
647 pango_font_description_free (style->private_font_desc);
650 gtk_rc_style_unref (style->rc_style);
652 G_OBJECT_CLASS (parent_class)->finalize (object);
657 gtk_style_copy (GtkStyle *style)
661 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
663 new_style = GTK_STYLE_GET_CLASS (style)->clone (style);
664 GTK_STYLE_GET_CLASS (style)->copy (new_style, style);
670 gtk_style_duplicate (GtkStyle *style)
674 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
676 new_style = gtk_style_copy (style);
678 /* All the styles in the list have the same
679 * style->styles pointer. When we insert a new
680 * style, we append it to the list to avoid having
681 * to update the existing ones.
683 style->styles = g_slist_append (style->styles, new_style);
684 new_style->styles = style->styles;
691 * @returns: a new #GtkStyle.
693 * Creates a new #GtkStyle.
700 style = g_object_new (GTK_TYPE_STYLE, NULL);
707 * @style: a #GtkStyle.
708 * @window: a #GdkWindow.
709 * @returns: Either @style, or a newly-created #GtkStyle.
710 * If the style is newly created, the style parameter
711 * will be dereferenced, and the new style will have
712 * a reference count belonging to the caller.
714 * Attaches a style to a window; this process allocates the
715 * colors and creates the GC's for the style - it specializes
716 * it to a particular visual and colormap. The process may
717 * involve the creation of a new style if the style has already
718 * been attached to a window with a different style and colormap.
720 * Since this function may return a new object, you have to use it
721 * in the following way:
722 * <literal>style = gtk_style_attach (style, window)</literal>
725 gtk_style_attach (GtkStyle *style,
729 GtkStyle *new_style = NULL;
730 GdkColormap *colormap;
732 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
733 g_return_val_if_fail (window != NULL, NULL);
735 colormap = gdk_drawable_get_colormap (window);
738 style->styles = g_slist_append (NULL, style);
740 styles = style->styles;
743 new_style = styles->data;
745 if (new_style->colormap == colormap)
749 styles = styles->next;
754 styles = style->styles;
758 new_style = styles->data;
760 if (new_style->attach_count == 0)
762 gtk_style_realize (new_style, colormap);
767 styles = styles->next;
773 new_style = gtk_style_duplicate (style);
774 if (gdk_colormap_get_screen (style->colormap) != gdk_colormap_get_screen (colormap) &&
775 new_style->private_font)
777 gdk_font_unref (new_style->private_font);
778 new_style->private_font = NULL;
780 gtk_style_realize (new_style, colormap);
783 /* A style gets a refcount from being attached */
784 if (new_style->attach_count == 0)
785 g_object_ref (new_style);
787 /* Another refcount belongs to the parent */
788 if (style != new_style)
790 g_object_unref (style);
791 g_object_ref (new_style);
794 new_style->attach_count++;
801 * @style: a #GtkStyle
803 * Detaches a style from a window. If the style is not attached
804 * to any windows anymore, it is unrealized. See gtk_style_attach().
808 gtk_style_detach (GtkStyle *style)
810 g_return_if_fail (GTK_IS_STYLE (style));
811 g_return_if_fail (style->attach_count > 0);
813 style->attach_count -= 1;
814 if (style->attach_count == 0)
816 g_signal_emit (style, unrealize_signal, 0);
818 g_object_unref (style->colormap);
819 style->colormap = NULL;
821 if (style->private_font_desc)
823 if (style->private_font)
825 gdk_font_unref (style->private_font);
826 style->private_font = NULL;
829 pango_font_description_free (style->private_font_desc);
830 style->private_font_desc = NULL;
833 g_object_unref (style);
839 * @style: a #GtkStyle.
842 * Deprecated equivalent of g_object_ref().
845 gtk_style_ref (GtkStyle *style)
847 return (GtkStyle *) g_object_ref (style);
852 * @style: a #GtkStyle.
854 * Deprecated equivalent of g_object_unref().
857 gtk_style_unref (GtkStyle *style)
859 g_object_unref (style);
863 gtk_style_realize (GtkStyle *style,
864 GdkColormap *colormap)
866 g_return_if_fail (GTK_IS_STYLE (style));
867 g_return_if_fail (GDK_IS_COLORMAP (colormap));
869 style->colormap = g_object_ref (colormap);
870 style->depth = gdk_colormap_get_visual (colormap)->depth;
872 g_signal_emit (style, realize_signal, 0);
876 gtk_style_lookup_icon_set (GtkStyle *style,
877 const char *stock_id)
881 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
882 g_return_val_if_fail (stock_id != NULL, NULL);
884 iter = style->icon_factories;
887 GtkIconSet *icon_set = gtk_icon_factory_lookup (GTK_ICON_FACTORY (iter->data),
892 iter = g_slist_next (iter);
895 return gtk_icon_factory_lookup_default (stock_id);
900 * @style: a #GtkStyle
901 * @window: a #GdkWindow
902 * @state_type: a state
903 * @x1: the starting x coordinate
904 * @x2: the ending x coordinate
905 * @y: the y coordinate
907 * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @window
908 * using the given style and state.
910 * Deprecated: Use gtk_paint_hline() instead.
913 gtk_draw_hline (GtkStyle *style,
915 GtkStateType state_type,
920 g_return_if_fail (GTK_IS_STYLE (style));
921 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
923 GTK_STYLE_GET_CLASS (style)->draw_hline (style, window, state_type, NULL, NULL, NULL, x1, x2, y);
929 * @style: a #GtkStyle
930 * @window: a #GdkWindow
931 * @state_type: a state
932 * @y1_: the starting y coordinate
933 * @y2_: the ending y coordinate
934 * @x: the x coordinate
936 * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @window
937 * using the given style and state.
939 * Deprecated: Use gtk_paint_vline() instead.
942 gtk_draw_vline (GtkStyle *style,
944 GtkStateType state_type,
949 g_return_if_fail (GTK_IS_STYLE (style));
950 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
952 GTK_STYLE_GET_CLASS (style)->draw_vline (style, window, state_type, NULL, NULL, NULL, y1_, y2_, x);
957 * @style: a #GtkStyle
958 * @window: a #GdkWindow
959 * @state_type: a state
960 * @shadow_type: type of shadow to draw
961 * @x: x origin of the rectangle
962 * @y: y origin of the rectangle
963 * @width: width of the rectangle
964 * @height: width of the rectangle
966 * Draws a shadow around the given rectangle in @window
967 * using the given style and state and shadow type.
969 * Deprecated: Use gtk_paint_shadow() instead.
972 gtk_draw_shadow (GtkStyle *style,
974 GtkStateType state_type,
975 GtkShadowType shadow_type,
981 g_return_if_fail (GTK_IS_STYLE (style));
982 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
984 GTK_STYLE_GET_CLASS (style)->draw_shadow (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
989 * @style: a #GtkStyle
990 * @window: a #GdkWindow
991 * @state_type: a state
992 * @shadow_type: type of shadow to draw
993 * @points: an array of #GdkPoint<!-- -->s
994 * @npoints: length of @points
995 * @fill: %TRUE if the polygon should be filled
997 * Draws a polygon on @window with the given parameters.
999 * Deprecated: Use gtk_paint_polygon() instead.
1002 gtk_draw_polygon (GtkStyle *style,
1004 GtkStateType state_type,
1005 GtkShadowType shadow_type,
1010 g_return_if_fail (GTK_IS_STYLE (style));
1011 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_polygon != NULL);
1013 GTK_STYLE_GET_CLASS (style)->draw_polygon (style, window, state_type, shadow_type, NULL, NULL, NULL, points, npoints, fill);
1018 * @style: a #GtkStyle
1019 * @window: a #GdkWindow
1020 * @state_type: a state
1021 * @shadow_type: the type of shadow to draw
1022 * @arrow_type: the type of arrow to draw
1023 * @fill: %TRUE if the arrow tip should be filled
1024 * @x: x origin of the rectangle to draw the arrow in
1025 * @y: y origin of the rectangle to draw the arrow in
1026 * @width: width of the rectangle to draw the arrow in
1027 * @height: height of the rectangle to draw the arrow in
1029 * Draws an arrow in the given rectangle on @window using the given
1030 * parameters. @arrow_type determines the direction of the arrow.
1032 * Deprecated: Use gtk_paint_arrow() instead.
1035 gtk_draw_arrow (GtkStyle *style,
1037 GtkStateType state_type,
1038 GtkShadowType shadow_type,
1039 GtkArrowType arrow_type,
1046 g_return_if_fail (GTK_IS_STYLE (style));
1047 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
1049 GTK_STYLE_GET_CLASS (style)->draw_arrow (style, window, state_type, shadow_type, NULL, NULL, NULL, arrow_type, fill, x, y, width, height);
1054 * @style: a #GtkStyle
1055 * @window: a #GdkWindow
1056 * @state_type: a state
1057 * @shadow_type: the type of shadow to draw
1058 * @x: x origin of the rectangle to draw the diamond in
1059 * @y: y origin of the rectangle to draw the diamond in
1060 * @width: width of the rectangle to draw the diamond in
1061 * @height: height of the rectangle to draw the diamond in
1063 * Draws a diamond in the given rectangle on @window using the given
1066 * Deprecated: Use gtk_paint_diamond() instead.
1069 gtk_draw_diamond (GtkStyle *style,
1071 GtkStateType state_type,
1072 GtkShadowType shadow_type,
1078 g_return_if_fail (GTK_IS_STYLE (style));
1079 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
1081 GTK_STYLE_GET_CLASS (style)->draw_diamond (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1086 * @style: a #GtkStyle
1087 * @window: a #GdkWindow
1088 * @state_type: a state
1091 * @string: the string to draw
1093 * Draws a text string on @window with the given parameters.
1095 * Deprecated: Use gtk_paint_layout() instead.
1098 gtk_draw_string (GtkStyle *style,
1100 GtkStateType state_type,
1103 const gchar *string)
1105 g_return_if_fail (GTK_IS_STYLE (style));
1106 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_string != NULL);
1108 GTK_STYLE_GET_CLASS (style)->draw_string (style, window, state_type, NULL, NULL, NULL, x, y, string);
1113 * @style: a #GtkStyle
1114 * @window: a #GdkWindow
1115 * @state_type: a state
1116 * @shadow_type: the type of shadow to draw
1117 * @x: x origin of the box
1118 * @y: y origin of the box
1119 * @width: the width of the box
1120 * @height: the height of the box
1122 * Draws a box on @window with the given parameters.
1124 * Deprecated: Use gtk_paint_box() instead.
1127 gtk_draw_box (GtkStyle *style,
1129 GtkStateType state_type,
1130 GtkShadowType shadow_type,
1136 g_return_if_fail (GTK_IS_STYLE (style));
1137 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
1139 GTK_STYLE_GET_CLASS (style)->draw_box (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1143 * gtk_draw_flat_box:
1144 * @style: a #GtkStyle
1145 * @window: a #GdkWindow
1146 * @state_type: a state
1147 * @shadow_type: the type of shadow to draw
1148 * @x: x origin of the box
1149 * @y: y origin of the box
1150 * @width: the width of the box
1151 * @height: the height of the box
1153 * Draws a flat box on @window with the given parameters.
1155 * Deprecated: Use gtk_paint_flat_box() instead.
1158 gtk_draw_flat_box (GtkStyle *style,
1160 GtkStateType state_type,
1161 GtkShadowType shadow_type,
1167 g_return_if_fail (GTK_IS_STYLE (style));
1168 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
1170 GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1175 * @style: a #GtkStyle
1176 * @window: a #GdkWindow
1177 * @state_type: a state
1178 * @shadow_type: the type of shadow to draw
1179 * @x: x origin of the rectangle to draw the check in
1180 * @y: y origin of the rectangle to draw the check in
1181 * @width: the width of the rectangle to draw the check in
1182 * @height: the height of the rectangle to draw the check in
1184 * Draws a check button indicator in the given rectangle on @window with
1185 * the given parameters.
1187 * Deprecated: Use gtk_paint_check() instead.
1190 gtk_draw_check (GtkStyle *style,
1192 GtkStateType state_type,
1193 GtkShadowType shadow_type,
1199 g_return_if_fail (GTK_IS_STYLE (style));
1200 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
1202 GTK_STYLE_GET_CLASS (style)->draw_check (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1207 * @style: a #GtkStyle
1208 * @window: a #GdkWindow
1209 * @state_type: a state
1210 * @shadow_type: the type of shadow to draw
1211 * @x: x origin of the rectangle to draw the option in
1212 * @y: y origin of the rectangle to draw the option in
1213 * @width: the width of the rectangle to draw the option in
1214 * @height: the height of the rectangle to draw the option in
1216 * Draws a radio button indicator in the given rectangle on @window with
1217 * the given parameters.
1219 * Deprecated: Use gtk_paint_option() instead.
1222 gtk_draw_option (GtkStyle *style,
1224 GtkStateType state_type,
1225 GtkShadowType shadow_type,
1231 g_return_if_fail (GTK_IS_STYLE (style));
1232 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
1234 GTK_STYLE_GET_CLASS (style)->draw_option (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1239 * @style: a #GtkStyle
1240 * @window: a #GdkWindow
1241 * @state_type: a state
1242 * @shadow_type: the type of shadow to draw
1243 * @x: x origin of the rectangle to draw the tab in
1244 * @y: y origin of the rectangle to draw the tab in
1245 * @width: the width of the rectangle to draw the tab in
1246 * @height: the height of the rectangle to draw the tab in
1248 * Draws an option menu tab (i.e. the up and down pointing arrows)
1249 * in the given rectangle on @window using the given parameters.
1251 * Deprecated: Use gtk_paint_tab() instead.
1254 gtk_draw_tab (GtkStyle *style,
1256 GtkStateType state_type,
1257 GtkShadowType shadow_type,
1263 g_return_if_fail (GTK_IS_STYLE (style));
1264 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
1266 GTK_STYLE_GET_CLASS (style)->draw_tab (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1270 * gtk_draw_shadow_gap:
1271 * @style: a #GtkStyle
1272 * @window: a #GdkWindow
1273 * @state_type: a state
1274 * @shadow_type: type of shadow to draw
1275 * @x: x origin of the rectangle
1276 * @y: y origin of the rectangle
1277 * @width: width of the rectangle
1278 * @height: width of the rectangle
1279 * @gap_side: side in which to leave the gap
1280 * @gap_x: starting position of the gap
1281 * @gap_width: width of the gap
1283 * Draws a shadow around the given rectangle in @window
1284 * using the given style and state and shadow type, leaving a
1287 * Deprecated: Use gtk_paint_shadow_gap() instead.
1290 gtk_draw_shadow_gap (GtkStyle *style,
1292 GtkStateType state_type,
1293 GtkShadowType shadow_type,
1298 GtkPositionType gap_side,
1302 g_return_if_fail (GTK_IS_STYLE (style));
1303 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
1305 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);
1310 * @style: a #GtkStyle
1311 * @window: a #GdkWindow
1312 * @state_type: a state
1313 * @shadow_type: type of shadow to draw
1314 * @x: x origin of the rectangle
1315 * @y: y origin of the rectangle
1316 * @width: width of the rectangle
1317 * @height: width of the rectangle
1318 * @gap_side: side in which to leave the gap
1319 * @gap_x: starting position of the gap
1320 * @gap_width: width of the gap
1322 * Draws a box in @window using the given style and state and shadow type,
1323 * leaving a gap in one side.
1325 * Deprecated: Use gtk_paint_box_gap() instead.
1328 gtk_draw_box_gap (GtkStyle *style,
1330 GtkStateType state_type,
1331 GtkShadowType shadow_type,
1336 GtkPositionType gap_side,
1340 g_return_if_fail (GTK_IS_STYLE (style));
1341 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
1343 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);
1347 * gtk_draw_extension:
1348 * @style: a #GtkStyle
1349 * @window: a #GdkWindow
1350 * @state_type: a state
1351 * @shadow_type: type of shadow to draw
1352 * @x: x origin of the extension
1353 * @y: y origin of the extension
1354 * @width: width of the extension
1355 * @height: width of the extension
1356 * @gap_side: the side on to which the extension is attached
1358 * Draws an extension, i.e. a notebook tab.
1360 * Deprecated: Use gtk_paint_extension() instead.
1363 gtk_draw_extension (GtkStyle *style,
1365 GtkStateType state_type,
1366 GtkShadowType shadow_type,
1371 GtkPositionType gap_side)
1373 g_return_if_fail (GTK_IS_STYLE (style));
1374 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
1376 GTK_STYLE_GET_CLASS (style)->draw_extension (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, gap_side);
1381 * @style: a #GtkStyle
1382 * @window: a #GdkWindow
1383 * @x: the x origin of the rectangle around which to draw a focus indicator
1384 * @y: the y origin of the rectangle around which to draw a focus indicator
1385 * @width: the width of the rectangle around which to draw a focus indicator
1386 * @height: the height of the rectangle around which to draw a focus indicator
1388 * Draws a focus indicator around the given rectangle on @window using the
1391 * Deprecated: Use gtk_paint_focus() instead.
1394 gtk_draw_focus (GtkStyle *style,
1401 g_return_if_fail (GTK_IS_STYLE (style));
1402 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
1404 GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, GTK_STATE_NORMAL, NULL, NULL, NULL, x, y, width, height);
1408 gtk_draw_slider (GtkStyle *style,
1410 GtkStateType state_type,
1411 GtkShadowType shadow_type,
1416 GtkOrientation orientation)
1418 g_return_if_fail (GTK_IS_STYLE (style));
1419 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
1421 GTK_STYLE_GET_CLASS (style)->draw_slider (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, orientation);
1426 * @style: a #GtkStyle
1427 * @window: a #GdkWindow
1428 * @state_type: a state
1429 * @shadow_type: type of shadow to draw
1430 * @x: x origin of the handle
1431 * @y: y origin of the handle
1432 * @width: with of the handle
1433 * @height: height of the handle
1434 * @orientation: the orientation of the handle
1436 * Draws a handle as used in #GtkHandleBox and #GtkPaned.
1438 * Deprecated: Use gtk_paint_handle() instead.
1441 gtk_draw_handle (GtkStyle *style,
1443 GtkStateType state_type,
1444 GtkShadowType shadow_type,
1449 GtkOrientation orientation)
1451 g_return_if_fail (GTK_IS_STYLE (style));
1452 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
1454 GTK_STYLE_GET_CLASS (style)->draw_handle (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, orientation);
1458 * gtk_draw_expander:
1459 * @style: a #GtkStyle
1460 * @window: a #GdkWindow
1461 * @state_type: a state
1462 * @x: the x position to draw the expander at
1463 * @y: the y position to draw the expander at
1464 * @expander_style: the style to draw the expander in
1466 * Draws an expander as used in #GtkTreeView.
1468 * Deprecated: Use gtk_paint_expander() instead.
1471 gtk_draw_expander (GtkStyle *style,
1473 GtkStateType state_type,
1476 GtkExpanderStyle expander_style)
1478 g_return_if_fail (GTK_IS_STYLE (style));
1479 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
1481 GTK_STYLE_GET_CLASS (style)->draw_expander (style, window, state_type,
1483 x, y, expander_style);
1487 gtk_draw_layout (GtkStyle *style,
1489 GtkStateType state_type,
1493 PangoLayout *layout)
1495 g_return_if_fail (GTK_IS_STYLE (style));
1496 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
1498 GTK_STYLE_GET_CLASS (style)->draw_layout (style, window, state_type, use_text,
1504 * gtk_draw_resize_grip:
1505 * @style: a #GtkStyle
1506 * @window: a #GdkWindow
1507 * @state_type: a state
1508 * @edge: the edge in which to draw the resize grip
1509 * @x: the x origin of the rectangle in which to draw the resize grip
1510 * @y: the y origin of the rectangle in which to draw the resize grip
1511 * @width: the width of the rectangle in which to draw the resize grip
1512 * @height: the height of the rectangle in which to draw the resize grip
1514 * Draws a resize grip in the given rectangle on @window using the given
1517 * Deprecated: Use gtk_paint_resize_grip() instead.
1520 gtk_draw_resize_grip (GtkStyle *style,
1522 GtkStateType state_type,
1529 g_return_if_fail (GTK_IS_STYLE (style));
1530 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
1532 GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, window, state_type,
1535 x, y, width, height);
1540 * gtk_style_set_background:
1541 * @style: a #GtkStyle
1542 * @window: a #GdkWindow
1543 * @state_type: a state
1545 * Sets the background of @window to the background color or pixmap
1546 * specified by @style for the given state.
1549 gtk_style_set_background (GtkStyle *style,
1551 GtkStateType state_type)
1553 g_return_if_fail (GTK_IS_STYLE (style));
1554 g_return_if_fail (window != NULL);
1556 GTK_STYLE_GET_CLASS (style)->set_background (style, window, state_type);
1559 /* Default functions */
1561 gtk_style_real_clone (GtkStyle *style)
1563 return g_object_new (G_OBJECT_TYPE (style), NULL);
1567 gtk_style_real_copy (GtkStyle *style,
1572 for (i = 0; i < 5; i++)
1574 style->fg[i] = src->fg[i];
1575 style->bg[i] = src->bg[i];
1576 style->text[i] = src->text[i];
1577 style->base[i] = src->base[i];
1579 if (style->bg_pixmap[i])
1580 g_object_unref (style->bg_pixmap[i]),
1581 style->bg_pixmap[i] = src->bg_pixmap[i];
1582 if (style->bg_pixmap[i])
1583 g_object_ref (style->bg_pixmap[i]);
1586 if (style->private_font)
1587 gdk_font_unref (style->private_font);
1588 style->private_font = src->private_font;
1589 if (style->private_font)
1590 gdk_font_ref (style->private_font);
1592 if (style->font_desc)
1593 pango_font_description_free (style->font_desc);
1595 style->font_desc = pango_font_description_copy (src->font_desc);
1597 style->font_desc = NULL;
1599 style->xthickness = src->xthickness;
1600 style->ythickness = src->ythickness;
1602 if (style->rc_style)
1603 gtk_rc_style_unref (style->rc_style);
1604 style->rc_style = src->rc_style;
1606 gtk_rc_style_ref (src->rc_style);
1608 /* don't copy, just clear cache */
1609 clear_property_cache (style);
1613 gtk_style_real_init_from_rc (GtkStyle *style,
1614 GtkRcStyle *rc_style)
1618 /* cache _should_ be still empty */
1619 clear_property_cache (style);
1621 if (rc_style->font_desc)
1622 pango_font_description_merge (style->font_desc, rc_style->font_desc, TRUE);
1624 for (i = 0; i < 5; i++)
1626 if (rc_style->color_flags[i] & GTK_RC_FG)
1627 style->fg[i] = rc_style->fg[i];
1628 if (rc_style->color_flags[i] & GTK_RC_BG)
1629 style->bg[i] = rc_style->bg[i];
1630 if (rc_style->color_flags[i] & GTK_RC_TEXT)
1631 style->text[i] = rc_style->text[i];
1632 if (rc_style->color_flags[i] & GTK_RC_BASE)
1633 style->base[i] = rc_style->base[i];
1636 if (rc_style->xthickness >= 0)
1637 style->xthickness = rc_style->xthickness;
1638 if (rc_style->ythickness >= 0)
1639 style->ythickness = rc_style->ythickness;
1641 if (rc_style->icon_factories)
1645 style->icon_factories = g_slist_copy (rc_style->icon_factories);
1647 iter = style->icon_factories;
1648 while (iter != NULL)
1650 g_object_ref (iter->data);
1651 iter = g_slist_next (iter);
1657 style_property_values_cmp (gconstpointer bsearch_node1,
1658 gconstpointer bsearch_node2)
1660 const PropertyValue *val1 = bsearch_node1;
1661 const PropertyValue *val2 = bsearch_node2;
1663 if (val1->widget_type == val2->widget_type)
1664 return val1->pspec < val2->pspec ? -1 : val1->pspec == val2->pspec ? 0 : 1;
1666 return val1->widget_type < val2->widget_type ? -1 : 1;
1670 _gtk_style_peek_property_value (GtkStyle *style,
1673 GtkRcPropertyParser parser)
1675 PropertyValue *pcache, key = { 0, NULL, { 0, } };
1676 const GtkRcProperty *rcprop = NULL;
1679 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1680 g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL);
1681 g_return_val_if_fail (g_type_is_a (pspec->owner_type, GTK_TYPE_WIDGET), NULL);
1682 g_return_val_if_fail (g_type_is_a (widget_type, pspec->owner_type), NULL);
1684 key.widget_type = widget_type;
1687 /* need value cache array */
1688 if (!style->property_cache)
1689 style->property_cache = g_array_new (FALSE, FALSE, sizeof (PropertyValue));
1692 pcache = bsearch (&key,
1693 style->property_cache->data, style->property_cache->len,
1694 sizeof (PropertyValue), style_property_values_cmp);
1696 return &pcache->value;
1700 while (i < style->property_cache->len &&
1701 style_property_values_cmp (&key, &g_array_index (style->property_cache, PropertyValue, i)) >= 0)
1704 g_array_insert_val (style->property_cache, i, key);
1705 pcache = &g_array_index (style->property_cache, PropertyValue, i);
1707 /* cache miss, initialize value type, then set contents */
1708 g_param_spec_ref (pcache->pspec);
1709 g_value_init (&pcache->value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1711 /* value provided by rc style? */
1712 if (style->rc_style)
1714 GQuark prop_quark = g_quark_from_string (pspec->name);
1718 rcprop = _gtk_rc_style_lookup_rc_property (style->rc_style,
1719 g_type_qname (widget_type),
1723 widget_type = g_type_parent (widget_type);
1725 while (g_type_is_a (widget_type, pspec->owner_type));
1728 /* when supplied by rc style, we need to convert */
1729 if (rcprop && !_gtk_settings_parse_convert (parser, &rcprop->value,
1730 pspec, &pcache->value))
1732 gchar *contents = g_strdup_value_contents (&rcprop->value);
1734 g_message ("%s: failed to retrieve property `%s::%s' of type `%s' from rc file value \"%s\" of type `%s'",
1736 g_type_name (pspec->owner_type), pspec->name,
1737 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1739 G_VALUE_TYPE_NAME (&rcprop->value));
1741 rcprop = NULL; /* needs default */
1744 /* not supplied by rc style (or conversion failed), revert to default */
1746 g_param_value_set_default (pspec, &pcache->value);
1748 return &pcache->value;
1752 load_bg_image (GdkColormap *colormap,
1754 const gchar *filename)
1756 if (strcmp (filename, "<parent>") == 0)
1757 return (GdkPixmap*) GDK_PARENT_RELATIVE;
1760 return gdk_pixmap_colormap_create_from_xpm (NULL, colormap, NULL,
1767 gtk_style_real_realize (GtkStyle *style)
1769 GdkGCValues gc_values;
1770 GdkGCValuesMask gc_values_mask;
1774 for (i = 0; i < 5; i++)
1776 gtk_style_shade (&style->bg[i], &style->light[i], LIGHTNESS_MULT);
1777 gtk_style_shade (&style->bg[i], &style->dark[i], DARKNESS_MULT);
1779 style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
1780 style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
1781 style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
1783 style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
1784 style->text_aa[i].green = (style->text[i].green + style->base[i].green) / 2;
1785 style->text_aa[i].blue = (style->text[i].blue + style->base[i].blue) / 2;
1788 style->black.red = 0x0000;
1789 style->black.green = 0x0000;
1790 style->black.blue = 0x0000;
1791 gdk_colormap_alloc_color (style->colormap, &style->black, FALSE, TRUE);
1793 style->white.red = 0xffff;
1794 style->white.green = 0xffff;
1795 style->white.blue = 0xffff;
1796 gdk_colormap_alloc_color (style->colormap, &style->white, FALSE, TRUE);
1798 gc_values_mask = GDK_GC_FOREGROUND | GDK_GC_BACKGROUND;
1800 gc_values.foreground = style->black;
1801 gc_values.background = style->white;
1802 style->black_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1804 gc_values.foreground = style->white;
1805 gc_values.background = style->black;
1806 style->white_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1808 gc_values_mask = GDK_GC_FOREGROUND;
1810 for (i = 0; i < 5; i++)
1812 if (style->rc_style && style->rc_style->bg_pixmap_name[i])
1813 style->bg_pixmap[i] = load_bg_image (style->colormap,
1815 style->rc_style->bg_pixmap_name[i]);
1817 if (!gdk_colormap_alloc_color (style->colormap, &style->fg[i], FALSE, TRUE))
1818 g_warning ("unable to allocate color: ( %d %d %d )",
1819 style->fg[i].red, style->fg[i].green, style->fg[i].blue);
1820 if (!gdk_colormap_alloc_color (style->colormap, &style->bg[i], FALSE, TRUE))
1821 g_warning ("unable to allocate color: ( %d %d %d )",
1822 style->bg[i].red, style->bg[i].green, style->bg[i].blue);
1823 if (!gdk_colormap_alloc_color (style->colormap, &style->light[i], FALSE, TRUE))
1824 g_warning ("unable to allocate color: ( %d %d %d )",
1825 style->light[i].red, style->light[i].green, style->light[i].blue);
1826 if (!gdk_colormap_alloc_color (style->colormap, &style->dark[i], FALSE, TRUE))
1827 g_warning ("unable to allocate color: ( %d %d %d )",
1828 style->dark[i].red, style->dark[i].green, style->dark[i].blue);
1829 if (!gdk_colormap_alloc_color (style->colormap, &style->mid[i], FALSE, TRUE))
1830 g_warning ("unable to allocate color: ( %d %d %d )",
1831 style->mid[i].red, style->mid[i].green, style->mid[i].blue);
1832 if (!gdk_colormap_alloc_color (style->colormap, &style->text[i], FALSE, TRUE))
1833 g_warning ("unable to allocate color: ( %d %d %d )",
1834 style->text[i].red, style->text[i].green, style->text[i].blue);
1835 if (!gdk_colormap_alloc_color (style->colormap, &style->base[i], FALSE, TRUE))
1836 g_warning ("unable to allocate color: ( %d %d %d )",
1837 style->base[i].red, style->base[i].green, style->base[i].blue);
1838 if (!gdk_colormap_alloc_color (style->colormap, &style->text_aa[i], FALSE, TRUE))
1839 g_warning ("unable to allocate color: ( %d %d %d )",
1840 style->text_aa[i].red, style->text_aa[i].green, style->text_aa[i].blue);
1842 gc_values.foreground = style->fg[i];
1843 style->fg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1845 gc_values.foreground = style->bg[i];
1846 style->bg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1848 gc_values.foreground = style->light[i];
1849 style->light_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1851 gc_values.foreground = style->dark[i];
1852 style->dark_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1854 gc_values.foreground = style->mid[i];
1855 style->mid_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1857 gc_values.foreground = style->text[i];
1858 style->text_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1860 gc_values.foreground = style->base[i];
1861 style->base_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1863 gc_values.foreground = style->text_aa[i];
1864 style->text_aa_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1869 gtk_style_real_unrealize (GtkStyle *style)
1873 gtk_gc_release (style->black_gc);
1874 gtk_gc_release (style->white_gc);
1876 for (i = 0; i < 5; i++)
1878 gtk_gc_release (style->fg_gc[i]);
1879 gtk_gc_release (style->bg_gc[i]);
1880 gtk_gc_release (style->light_gc[i]);
1881 gtk_gc_release (style->dark_gc[i]);
1882 gtk_gc_release (style->mid_gc[i]);
1883 gtk_gc_release (style->text_gc[i]);
1884 gtk_gc_release (style->base_gc[i]);
1885 gtk_gc_release (style->text_aa_gc[i]);
1887 if (style->bg_pixmap[i] && style->bg_pixmap[i] != (GdkPixmap*) GDK_PARENT_RELATIVE)
1889 g_object_unref (style->bg_pixmap[i]);
1890 style->bg_pixmap[i] = NULL;
1895 gdk_colormap_free_colors (style->colormap, style->fg, 5);
1896 gdk_colormap_free_colors (style->colormap, style->bg, 5);
1897 gdk_colormap_free_colors (style->colormap, style->light, 5);
1898 gdk_colormap_free_colors (style->colormap, style->dark, 5);
1899 gdk_colormap_free_colors (style->colormap, style->mid, 5);
1900 gdk_colormap_free_colors (style->colormap, style->text, 5);
1901 gdk_colormap_free_colors (style->colormap, style->base, 5);
1902 gdk_colormap_free_colors (style->colormap, style->text_aa, 5);
1904 style_unrealize_cursor_gcs (style);
1908 gtk_style_real_set_background (GtkStyle *style,
1910 GtkStateType state_type)
1913 gint parent_relative;
1915 if (style->bg_pixmap[state_type])
1917 if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
1920 parent_relative = TRUE;
1924 pixmap = style->bg_pixmap[state_type];
1925 parent_relative = FALSE;
1928 gdk_window_set_back_pixmap (window, pixmap, parent_relative);
1931 gdk_window_set_background (window, &style->bg[state_type]);
1935 * gtk_style_render_icon:
1936 * @style: a #GtkStyle
1937 * @source: the #GtkIconSource specifying the icon to render
1938 * @direction: a text direction
1940 * @size: the size to render the icon at. A size of (GtkIconSize)-1
1941 * means render at the size of the source and don't scale.
1942 * @widget: the widget
1943 * @detail: a style detail
1944 * @returns: a newly-created #GdkPixbuf containing the rendered icon
1946 * Renders the icon specified by @source at the given @size
1947 * according to the given parameters and returns the result in a
1951 gtk_style_render_icon (GtkStyle *style,
1952 const GtkIconSource *source,
1953 GtkTextDirection direction,
1957 const gchar *detail)
1961 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1962 g_return_val_if_fail (GTK_STYLE_GET_CLASS (style)->render_icon != NULL, NULL);
1964 pixbuf = GTK_STYLE_GET_CLASS (style)->render_icon (style, source, direction, state,
1965 size, widget, detail);
1967 g_return_val_if_fail (pixbuf != NULL, NULL);
1972 /* Default functions */
1974 gtk_style_apply_default_background (GtkStyle *style,
1977 GtkStateType state_type,
1984 GdkRectangle new_rect, old_rect;
1990 old_rect.width = width;
1991 old_rect.height = height;
1993 if (!gdk_rectangle_intersect (area, &old_rect, &new_rect))
2000 new_rect.width = width;
2001 new_rect.height = height;
2004 if (!style->bg_pixmap[state_type] ||
2005 GDK_IS_PIXMAP (window) ||
2006 (!set_bg && style->bg_pixmap[state_type] != (GdkPixmap*) GDK_PARENT_RELATIVE))
2008 GdkGC *gc = style->bg_gc[state_type];
2010 if (style->bg_pixmap[state_type])
2012 gdk_gc_set_fill (gc, GDK_TILED);
2013 gdk_gc_set_tile (gc, style->bg_pixmap[state_type]);
2016 gdk_draw_rectangle (window, gc, TRUE,
2017 new_rect.x, new_rect.y, new_rect.width, new_rect.height);
2018 if (style->bg_pixmap[state_type])
2019 gdk_gc_set_fill (gc, GDK_SOLID);
2025 if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
2026 gdk_window_set_back_pixmap (window, NULL, TRUE);
2028 gdk_window_set_back_pixmap (window, style->bg_pixmap[state_type], FALSE);
2031 gdk_window_clear_area (window,
2032 new_rect.x, new_rect.y,
2033 new_rect.width, new_rect.height);
2038 scale_or_ref (GdkPixbuf *src,
2042 if (width == gdk_pixbuf_get_width (src) &&
2043 height == gdk_pixbuf_get_height (src))
2045 return g_object_ref (src);
2049 return gdk_pixbuf_scale_simple (src,
2051 GDK_INTERP_BILINEAR);
2056 gtk_default_render_icon (GtkStyle *style,
2057 const GtkIconSource *source,
2058 GtkTextDirection direction,
2062 const gchar *detail)
2068 GdkPixbuf *base_pixbuf;
2070 GtkSettings *settings;
2072 /* Oddly, style can be NULL in this function, because
2073 * GtkIconSet can be used without a style and if so
2074 * it uses this function.
2077 base_pixbuf = gtk_icon_source_get_pixbuf (source);
2079 g_return_val_if_fail (base_pixbuf != NULL, NULL);
2081 if (widget && gtk_widget_has_screen (widget))
2083 screen = gtk_widget_get_screen (widget);
2084 settings = gtk_settings_get_for_screen (screen);
2086 else if (style && style->colormap)
2088 screen = gdk_colormap_get_screen (style->colormap);
2089 settings = gtk_settings_get_for_screen (screen);
2093 settings = gtk_settings_get_default ();
2094 GTK_NOTE (MULTIHEAD,
2095 g_warning ("Using the default screen for gtk_default_render_icon()"));
2099 if (size != (GtkIconSize) -1 && !gtk_icon_size_lookup_for_settings (settings, size, &width, &height))
2101 g_warning (G_STRLOC ": invalid icon size '%d'", size);
2105 /* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
2108 if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source))
2109 scaled = scale_or_ref (base_pixbuf, width, height);
2111 scaled = g_object_ref (base_pixbuf);
2113 /* If the state was wildcarded, then generate a state. */
2114 if (gtk_icon_source_get_state_wildcarded (source))
2116 if (state == GTK_STATE_INSENSITIVE)
2118 stated = gdk_pixbuf_copy (scaled);
2120 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
2123 g_object_unref (scaled);
2125 else if (state == GTK_STATE_PRELIGHT)
2127 stated = gdk_pixbuf_copy (scaled);
2129 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
2132 g_object_unref (scaled);
2146 sanitize_size (GdkWindow *window,
2150 if ((*width == -1) && (*height == -1))
2151 gdk_drawable_get_size (window, width, height);
2152 else if (*width == -1)
2153 gdk_drawable_get_size (window, width, NULL);
2154 else if (*height == -1)
2155 gdk_drawable_get_size (window, NULL, height);
2159 gtk_default_draw_hline (GtkStyle *style,
2161 GtkStateType state_type,
2164 const gchar *detail,
2169 gint thickness_light;
2170 gint thickness_dark;
2173 g_return_if_fail (GTK_IS_STYLE (style));
2174 g_return_if_fail (window != NULL);
2176 thickness_light = style->ythickness / 2;
2177 thickness_dark = style->ythickness - thickness_light;
2181 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2182 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2185 if (detail && !strcmp (detail, "label"))
2187 if (state_type == GTK_STATE_INSENSITIVE)
2188 gdk_draw_line (window, style->white_gc, x1 + 1, y + 1, x2 + 1, y + 1);
2189 gdk_draw_line (window, style->fg_gc[state_type], x1, y, x2, y);
2193 for (i = 0; i < thickness_dark; i++)
2195 gdk_draw_line (window, style->dark_gc[state_type], x1, y + i, x2 - i - 1, y + i);
2196 gdk_draw_line (window, style->light_gc[state_type], x2 - i, y + i, x2, y + i);
2199 y += thickness_dark;
2200 for (i = 0; i < thickness_light; i++)
2202 gdk_draw_line (window, style->dark_gc[state_type], x1, y + i, x1 + thickness_light - i - 1, y + i);
2203 gdk_draw_line (window, style->light_gc[state_type], x1 + thickness_light - i, y + i, x2, y + i);
2209 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2210 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2216 gtk_default_draw_vline (GtkStyle *style,
2218 GtkStateType state_type,
2221 const gchar *detail,
2226 gint thickness_light;
2227 gint thickness_dark;
2230 g_return_if_fail (GTK_IS_STYLE (style));
2231 g_return_if_fail (window != NULL);
2233 thickness_light = style->xthickness / 2;
2234 thickness_dark = style->xthickness - thickness_light;
2238 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2239 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2241 for (i = 0; i < thickness_dark; i++)
2243 gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i, y2 - i - 1);
2244 gdk_draw_line (window, style->light_gc[state_type], x + i, y2 - i, x + i, y2);
2247 x += thickness_dark;
2248 for (i = 0; i < thickness_light; i++)
2250 gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i, y1 + thickness_light - i - 1);
2251 gdk_draw_line (window, style->light_gc[state_type], x + i, y1 + thickness_light - i, x + i, y2);
2255 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2256 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2261 draw_thin_shadow (GtkStyle *style,
2272 sanitize_size (window, &width, &height);
2274 gc1 = style->light_gc[state];
2275 gc2 = style->dark_gc[state];
2279 gdk_gc_set_clip_rectangle (gc1, area);
2280 gdk_gc_set_clip_rectangle (gc2, area);
2283 gdk_draw_line (window, gc1,
2284 x, y + height - 1, x + width - 1, y + height - 1);
2285 gdk_draw_line (window, gc1,
2286 x + width - 1, y, x + width - 1, y + height - 1);
2288 gdk_draw_line (window, gc2,
2289 x, y, x + width - 2, y);
2290 gdk_draw_line (window, gc2,
2291 x, y, x, y + height - 2);
2295 gdk_gc_set_clip_rectangle (gc1, NULL);
2296 gdk_gc_set_clip_rectangle (gc2, NULL);
2301 draw_spinbutton_shadow (GtkStyle *style,
2304 GtkTextDirection direction,
2311 sanitize_size (window, &width, &height);
2315 gdk_gc_set_clip_rectangle (style->black_gc, area);
2316 gdk_gc_set_clip_rectangle (style->bg_gc[state], area);
2317 gdk_gc_set_clip_rectangle (style->dark_gc[state], area);
2318 gdk_gc_set_clip_rectangle (style->light_gc[state], area);
2321 if (direction == GTK_TEXT_DIR_LTR)
2323 gdk_draw_line (window, style->dark_gc[state],
2324 x, y, x + width - 1, y);
2325 gdk_draw_line (window, style->black_gc,
2326 x, y + 1, x + width - 2, y + 1);
2327 gdk_draw_line (window, style->black_gc,
2328 x + width - 2, y + 2, x + width - 2, y + height - 3);
2329 gdk_draw_line (window, style->light_gc[state],
2330 x + width - 1, y + 1, x + width - 1, y + height - 2);
2331 gdk_draw_line (window, style->light_gc[state],
2332 x, y + height - 1, x + width - 1, y + height - 1);
2333 gdk_draw_line (window, style->bg_gc[state],
2334 x, y + height - 2, x + width - 2, y + height - 2);
2335 gdk_draw_line (window, style->black_gc,
2336 x, y + 2, x, y + height - 3);
2340 gdk_draw_line (window, style->dark_gc[state],
2341 x, y, x + width - 1, y);
2342 gdk_draw_line (window, style->dark_gc[state],
2343 x, y + 1, x, y + height - 1);
2344 gdk_draw_line (window, style->black_gc,
2345 x + 1, y + 1, x + width - 1, y + 1);
2346 gdk_draw_line (window, style->black_gc,
2347 x + 1, y + 2, x + 1, y + height - 2);
2348 gdk_draw_line (window, style->black_gc,
2349 x + width - 1, y + 2, x + width - 1, y + height - 3);
2350 gdk_draw_line (window, style->light_gc[state],
2351 x + 1, y + height - 1, x + width - 1, y + height - 1);
2352 gdk_draw_line (window, style->bg_gc[state],
2353 x + 2, y + height - 2, x + width - 1, y + height - 2);
2358 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
2359 gdk_gc_set_clip_rectangle (style->bg_gc[state], NULL);
2360 gdk_gc_set_clip_rectangle (style->dark_gc[state], NULL);
2361 gdk_gc_set_clip_rectangle (style->light_gc[state], NULL);
2366 draw_menu_shadow (GtkStyle *style,
2375 if (style->ythickness > 0)
2377 if (style->ythickness > 1)
2379 gdk_draw_line (window, style->dark_gc[state],
2380 x + 1, y + height - 2, x + width - 2, y + height - 2);
2381 gdk_draw_line (window, style->black_gc,
2382 x, y + height - 1, x + width - 1, y + height - 1);
2386 gdk_draw_line (window, style->dark_gc[state],
2387 x + 1, y + height - 1, x + width - 1, y + height - 1);
2391 if (style->xthickness > 0)
2393 if (style->xthickness > 1)
2395 gdk_draw_line (window, style->dark_gc[state],
2396 x + width - 2, y + 1, x + width - 2, y + height - 2);
2398 gdk_draw_line (window, style->black_gc,
2399 x + width - 1, y, x + width - 1, y + height - 1);
2403 gdk_draw_line (window, style->dark_gc[state],
2404 x + width - 1, y + 1, x + width - 1, y + height - 1);
2408 /* Light around top and left */
2410 if (style->ythickness > 0)
2411 gdk_draw_line (window, style->black_gc,
2412 x, y, x + width - 2, y);
2413 if (style->xthickness > 0)
2414 gdk_draw_line (window, style->black_gc,
2415 x, y, x, y + height - 2);
2417 if (style->ythickness > 1)
2418 gdk_draw_line (window, style->light_gc[state],
2419 x + 1, y + 1, x + width - 3, y + 1);
2420 if (style->xthickness > 1)
2421 gdk_draw_line (window, style->light_gc[state],
2422 x + 1, y + 1, x + 1, y + height - 3);
2425 static GtkTextDirection
2426 get_direction (GtkWidget *widget)
2428 GtkTextDirection dir;
2431 dir = gtk_widget_get_direction (widget);
2433 dir = GTK_TEXT_DIR_LTR;
2440 gtk_default_draw_shadow (GtkStyle *style,
2442 GtkStateType state_type,
2443 GtkShadowType shadow_type,
2446 const gchar *detail,
2454 gint thickness_light;
2455 gint thickness_dark;
2458 g_return_if_fail (GTK_IS_STYLE (style));
2459 g_return_if_fail (window != NULL);
2461 if (shadow_type == GTK_SHADOW_IN)
2463 if (detail && (strcmp (detail, "buttondefault") == 0))
2465 sanitize_size (window, &width, &height);
2467 gdk_draw_rectangle (window, style->black_gc, FALSE,
2468 x, y, width - 1, height - 1);
2472 if (detail && strcmp (detail, "trough") == 0)
2474 draw_thin_shadow (style, window, state_type, area,
2475 x, y, width, height);
2478 if (widget && GTK_IS_SPIN_BUTTON (widget) &&
2479 detail && strcmp (detail, "spinbutton") == 0)
2481 draw_spinbutton_shadow (style, window, state_type,
2482 get_direction (widget), area, x, y, width, height);
2488 if (shadow_type == GTK_SHADOW_OUT && detail && strcmp (detail, "menu") == 0)
2490 draw_menu_shadow (style, window, state_type, area, x, y, width, height);
2494 sanitize_size (window, &width, &height);
2496 switch (shadow_type)
2498 case GTK_SHADOW_NONE:
2501 case GTK_SHADOW_ETCHED_IN:
2502 gc1 = style->light_gc[state_type];
2503 gc2 = style->dark_gc[state_type];
2505 case GTK_SHADOW_OUT:
2506 case GTK_SHADOW_ETCHED_OUT:
2507 gc1 = style->dark_gc[state_type];
2508 gc2 = style->light_gc[state_type];
2514 gdk_gc_set_clip_rectangle (gc1, area);
2515 gdk_gc_set_clip_rectangle (gc2, area);
2516 if (shadow_type == GTK_SHADOW_IN ||
2517 shadow_type == GTK_SHADOW_OUT)
2519 gdk_gc_set_clip_rectangle (style->black_gc, area);
2520 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
2524 switch (shadow_type)
2526 case GTK_SHADOW_NONE:
2530 /* Light around right and bottom edge */
2532 if (style->ythickness > 0)
2533 gdk_draw_line (window, gc1,
2534 x, y + height - 1, x + width - 1, y + height - 1);
2535 if (style->xthickness > 0)
2536 gdk_draw_line (window, gc1,
2537 x + width - 1, y, x + width - 1, y + height - 1);
2539 if (style->ythickness > 1)
2540 gdk_draw_line (window, style->bg_gc[state_type],
2541 x + 1, y + height - 2, x + width - 2, y + height - 2);
2542 if (style->xthickness > 1)
2543 gdk_draw_line (window, style->bg_gc[state_type],
2544 x + width - 2, y + 1, x + width - 2, y + height - 2);
2546 /* Dark around left and top */
2548 if (style->ythickness > 1)
2549 gdk_draw_line (window, style->black_gc,
2550 x + 1, y + 1, x + width - 2, y + 1);
2551 if (style->xthickness > 1)
2552 gdk_draw_line (window, style->black_gc,
2553 x + 1, y + 1, x + 1, y + height - 2);
2555 if (style->ythickness > 0)
2556 gdk_draw_line (window, gc2,
2557 x, y, x + width - 1, y);
2558 if (style->xthickness > 0)
2559 gdk_draw_line (window, gc2,
2560 x, y, x, y + height - 1);
2563 case GTK_SHADOW_OUT:
2564 /* Dark around right and bottom edge */
2566 if (style->ythickness > 0)
2568 if (style->ythickness > 1)
2570 gdk_draw_line (window, gc1,
2571 x + 1, y + height - 2, x + width - 2, y + height - 2);
2572 gdk_draw_line (window, style->black_gc,
2573 x, y + height - 1, x + width - 1, y + height - 1);
2577 gdk_draw_line (window, gc1,
2578 x + 1, y + height - 1, x + width - 1, y + height - 1);
2582 if (style->xthickness > 0)
2584 if (style->xthickness > 1)
2586 gdk_draw_line (window, gc1,
2587 x + width - 2, y + 1, x + width - 2, y + height - 2);
2589 gdk_draw_line (window, style->black_gc,
2590 x + width - 1, y, x + width - 1, y + height - 1);
2594 gdk_draw_line (window, gc1,
2595 x + width - 1, y + 1, x + width - 1, y + height - 1);
2599 /* Light around top and left */
2601 if (style->ythickness > 0)
2602 gdk_draw_line (window, gc2,
2603 x, y, x + width - 2, y);
2604 if (style->xthickness > 0)
2605 gdk_draw_line (window, gc2,
2606 x, y, x, y + height - 2);
2608 if (style->ythickness > 1)
2609 gdk_draw_line (window, style->bg_gc[state_type],
2610 x + 1, y + 1, x + width - 3, y + 1);
2611 if (style->xthickness > 1)
2612 gdk_draw_line (window, style->bg_gc[state_type],
2613 x + 1, y + 1, x + 1, y + height - 3);
2616 case GTK_SHADOW_ETCHED_IN:
2617 case GTK_SHADOW_ETCHED_OUT:
2618 if (style->xthickness > 0)
2620 if (style->xthickness > 1)
2622 thickness_light = 1;
2625 for (i = 0; i < thickness_dark; i++)
2627 gdk_draw_line (window, gc1,
2631 y + height - i - 1);
2632 gdk_draw_line (window, gc2,
2636 y + height - i - 2);
2639 for (i = 0; i < thickness_light; i++)
2641 gdk_draw_line (window, gc1,
2642 x + thickness_dark + i,
2643 y + thickness_dark + i,
2644 x + thickness_dark + i,
2645 y + height - thickness_dark - i - 1);
2646 gdk_draw_line (window, gc2,
2647 x + width - thickness_light - i - 1,
2648 y + thickness_dark + i,
2649 x + width - thickness_light - i - 1,
2650 y + height - thickness_light - 1);
2655 gdk_draw_line (window,
2656 style->dark_gc[state_type],
2657 x, y, x, y + height);
2658 gdk_draw_line (window,
2659 style->dark_gc[state_type],
2660 x + width, y, x + width, y + height);
2664 if (style->ythickness > 0)
2666 if (style->ythickness > 1)
2668 thickness_light = 1;
2671 for (i = 0; i < thickness_dark; i++)
2673 gdk_draw_line (window, gc1,
2677 y + height - i - 1);
2679 gdk_draw_line (window, gc2,
2686 for (i = 0; i < thickness_light; i++)
2688 gdk_draw_line (window, gc1,
2689 x + thickness_dark + i,
2690 y + thickness_dark + i,
2691 x + width - thickness_dark - i - 2,
2692 y + thickness_dark + i);
2694 gdk_draw_line (window, gc2,
2695 x + thickness_dark + i,
2696 y + height - thickness_light - i - 1,
2697 x + width - thickness_light - 1,
2698 y + height - thickness_light - i - 1);
2703 gdk_draw_line (window,
2704 style->dark_gc[state_type],
2705 x, y, x + width, y);
2706 gdk_draw_line (window,
2707 style->dark_gc[state_type],
2708 x, y + height, x + width, y + height);
2715 if (shadow_type == GTK_SHADOW_IN &&
2716 widget && GTK_IS_SPIN_BUTTON (widget) &&
2717 detail && strcmp (detail, "entry") == 0)
2719 if (get_direction (widget) == GTK_TEXT_DIR_LTR)
2721 gdk_draw_line (window,
2722 style->base_gc[state_type],
2723 x + width - 1, y + 2,
2724 x + width - 1, y + height - 3);
2725 gdk_draw_line (window,
2726 style->base_gc[state_type],
2727 x + width - 2, y + 2,
2728 x + width - 2, y + height - 3);
2729 gdk_draw_point (window,
2731 x + width - 1, y + 1);
2732 gdk_draw_point (window,
2733 style->bg_gc[state_type],
2734 x + width - 1, y + height - 2);
2738 gdk_draw_line (window,
2739 style->base_gc[state_type],
2742 gdk_draw_line (window,
2743 style->base_gc[state_type],
2745 x + 1, y + height - 3);
2746 gdk_draw_point (window,
2749 gdk_draw_line (window,
2750 style->bg_gc[state_type],
2752 x + 1, y + height - 2);
2753 gdk_draw_point (window,
2754 style->light_gc[state_type],
2762 gdk_gc_set_clip_rectangle (gc1, NULL);
2763 gdk_gc_set_clip_rectangle (gc2, NULL);
2764 if (shadow_type == GTK_SHADOW_IN ||
2765 shadow_type == GTK_SHADOW_OUT)
2767 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
2768 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
2774 gtk_default_draw_polygon (GtkStyle *style,
2776 GtkStateType state_type,
2777 GtkShadowType shadow_type,
2780 const gchar *detail,
2785 static const gdouble pi_over_4 = G_PI_4;
2786 static const gdouble pi_3_over_4 = G_PI_4 * 3;
2796 g_return_if_fail (GTK_IS_STYLE (style));
2797 g_return_if_fail (window != NULL);
2798 g_return_if_fail (points != NULL);
2800 switch (shadow_type)
2803 gc1 = style->bg_gc[state_type];
2804 gc2 = style->dark_gc[state_type];
2805 gc3 = style->light_gc[state_type];
2806 gc4 = style->black_gc;
2808 case GTK_SHADOW_ETCHED_IN:
2809 gc1 = style->light_gc[state_type];
2810 gc2 = style->dark_gc[state_type];
2811 gc3 = style->dark_gc[state_type];
2812 gc4 = style->light_gc[state_type];
2814 case GTK_SHADOW_OUT:
2815 gc1 = style->dark_gc[state_type];
2816 gc2 = style->light_gc[state_type];
2817 gc3 = style->black_gc;
2818 gc4 = style->bg_gc[state_type];
2820 case GTK_SHADOW_ETCHED_OUT:
2821 gc1 = style->dark_gc[state_type];
2822 gc2 = style->light_gc[state_type];
2823 gc3 = style->light_gc[state_type];
2824 gc4 = style->dark_gc[state_type];
2832 gdk_gc_set_clip_rectangle (gc1, area);
2833 gdk_gc_set_clip_rectangle (gc2, area);
2834 gdk_gc_set_clip_rectangle (gc3, area);
2835 gdk_gc_set_clip_rectangle (gc4, area);
2839 gdk_draw_polygon (window, style->bg_gc[state_type], TRUE, points, npoints);
2843 for (i = 0; i < npoints; i++)
2845 if ((points[i].x == points[i+1].x) &&
2846 (points[i].y == points[i+1].y))
2852 angle = atan2 (points[i+1].y - points[i].y,
2853 points[i+1].x - points[i].x);
2856 if ((angle > -pi_3_over_4) && (angle < pi_over_4))
2858 if (angle > -pi_over_4)
2869 gdk_draw_line (window, gc1,
2870 points[i].x-xadjust, points[i].y-yadjust,
2871 points[i+1].x-xadjust, points[i+1].y-yadjust);
2872 gdk_draw_line (window, gc3,
2873 points[i].x, points[i].y,
2874 points[i+1].x, points[i+1].y);
2878 if ((angle < -pi_3_over_4) || (angle > pi_3_over_4))
2889 gdk_draw_line (window, gc4,
2890 points[i].x+xadjust, points[i].y+yadjust,
2891 points[i+1].x+xadjust, points[i+1].y+yadjust);
2892 gdk_draw_line (window, gc2,
2893 points[i].x, points[i].y,
2894 points[i+1].x, points[i+1].y);
2900 gdk_gc_set_clip_rectangle (gc1, NULL);
2901 gdk_gc_set_clip_rectangle (gc2, NULL);
2902 gdk_gc_set_clip_rectangle (gc3, NULL);
2903 gdk_gc_set_clip_rectangle (gc4, NULL);
2908 draw_arrow (GdkWindow *window,
2911 GtkArrowType arrow_type,
2917 cairo_t *cr = gdk_cairo_create (window);
2918 gdk_cairo_set_source_color (cr, color);
2922 gdk_cairo_rectangle (cr, area);
2926 if (arrow_type == GTK_ARROW_DOWN)
2928 cairo_move_to (cr, x, y);
2929 cairo_line_to (cr, x + width, y);
2930 cairo_line_to (cr, x + width / 2., y + height);
2932 else if (arrow_type == GTK_ARROW_UP)
2934 cairo_move_to (cr, x, y + height);
2935 cairo_line_to (cr, x + width / 2., y);
2936 cairo_line_to (cr, x + width, y + height);
2938 else if (arrow_type == GTK_ARROW_LEFT)
2940 cairo_move_to (cr, x + width, y);
2941 cairo_line_to (cr, x + width, y + height);
2942 cairo_line_to (cr, x, y + height / 2.);
2944 else if (arrow_type == GTK_ARROW_RIGHT)
2946 cairo_move_to (cr, x, y);
2947 cairo_line_to (cr, x + width, y + height / 2.);
2948 cairo_line_to (cr, x, y + height);
2951 cairo_close_path (cr);
2958 calculate_arrow_geometry (GtkArrowType arrow_type,
2970 case GTK_ARROW_DOWN:
2980 if (arrow_type == GTK_ARROW_DOWN)
2982 if (*height % 2 == 1 || h % 2 == 0)
2987 if (*height % 2 == 0 || h % 2 == 0)
2992 case GTK_ARROW_RIGHT:
2993 case GTK_ARROW_LEFT:
3003 if (arrow_type == GTK_ARROW_RIGHT)
3005 if (*width % 2 == 1 || w % 2 == 0)
3010 if (*width % 2 == 0 || w % 2 == 0)
3016 /* should not be reached */
3020 *x += (*width - w) / 2;
3021 *y += (*height - h) / 2;
3027 gtk_default_draw_arrow (GtkStyle *style,
3030 GtkShadowType shadow,
3033 const gchar *detail,
3034 GtkArrowType arrow_type,
3041 sanitize_size (window, &width, &height);
3043 calculate_arrow_geometry (arrow_type, &x, &y, &width, &height);
3045 if (detail && strcmp (detail, "menu_scroll_arrow_up") == 0)
3048 if (state == GTK_STATE_INSENSITIVE)
3049 draw_arrow (window, &style->white, area, arrow_type,
3050 x + 1, y + 1, width, height);
3051 draw_arrow (window, &style->fg[state], area, arrow_type,
3052 x, y, width, height);
3056 gtk_default_draw_diamond (GtkStyle *style,
3058 GtkStateType state_type,
3059 GtkShadowType shadow_type,
3062 const gchar *detail,
3070 GdkGC *outer_nw = NULL;
3071 GdkGC *outer_ne = NULL;
3072 GdkGC *outer_sw = NULL;
3073 GdkGC *outer_se = NULL;
3074 GdkGC *middle_nw = NULL;
3075 GdkGC *middle_ne = NULL;
3076 GdkGC *middle_sw = NULL;
3077 GdkGC *middle_se = NULL;
3078 GdkGC *inner_nw = NULL;
3079 GdkGC *inner_ne = NULL;
3080 GdkGC *inner_sw = NULL;
3081 GdkGC *inner_se = NULL;
3083 g_return_if_fail (GTK_IS_STYLE (style));
3084 g_return_if_fail (window != NULL);
3086 sanitize_size (window, &width, &height);
3088 half_width = width / 2;
3089 half_height = height / 2;
3093 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
3094 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
3095 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
3096 gdk_gc_set_clip_rectangle (style->black_gc, area);
3099 switch (shadow_type)
3102 inner_sw = inner_se = style->bg_gc[state_type];
3103 middle_sw = middle_se = style->light_gc[state_type];
3104 outer_sw = outer_se = style->light_gc[state_type];
3105 inner_nw = inner_ne = style->black_gc;
3106 middle_nw = middle_ne = style->dark_gc[state_type];
3107 outer_nw = outer_ne = style->dark_gc[state_type];
3110 case GTK_SHADOW_OUT:
3111 inner_sw = inner_se = style->dark_gc[state_type];
3112 middle_sw = middle_se = style->dark_gc[state_type];
3113 outer_sw = outer_se = style->black_gc;
3114 inner_nw = inner_ne = style->bg_gc[state_type];
3115 middle_nw = middle_ne = style->light_gc[state_type];
3116 outer_nw = outer_ne = style->light_gc[state_type];
3119 case GTK_SHADOW_ETCHED_IN:
3120 inner_sw = inner_se = style->bg_gc[state_type];
3121 middle_sw = middle_se = style->dark_gc[state_type];
3122 outer_sw = outer_se = style->light_gc[state_type];
3123 inner_nw = inner_ne = style->bg_gc[state_type];
3124 middle_nw = middle_ne = style->light_gc[state_type];
3125 outer_nw = outer_ne = style->dark_gc[state_type];
3128 case GTK_SHADOW_ETCHED_OUT:
3129 inner_sw = inner_se = style->bg_gc[state_type];
3130 middle_sw = middle_se = style->light_gc[state_type];
3131 outer_sw = outer_se = style->dark_gc[state_type];
3132 inner_nw = inner_ne = style->bg_gc[state_type];
3133 middle_nw = middle_ne = style->dark_gc[state_type];
3134 outer_nw = outer_ne = style->light_gc[state_type];
3144 gdk_draw_line (window, inner_sw,
3145 x + 2, y + half_height,
3146 x + half_width, y + height - 2);
3147 gdk_draw_line (window, inner_se,
3148 x + half_width, y + height - 2,
3149 x + width - 2, y + half_height);
3150 gdk_draw_line (window, middle_sw,
3151 x + 1, y + half_height,
3152 x + half_width, y + height - 1);
3153 gdk_draw_line (window, middle_se,
3154 x + half_width, y + height - 1,
3155 x + width - 1, y + half_height);
3156 gdk_draw_line (window, outer_sw,
3158 x + half_width, y + height);
3159 gdk_draw_line (window, outer_se,
3160 x + half_width, y + height,
3161 x + width, y + half_height);
3163 gdk_draw_line (window, inner_nw,
3164 x + 2, y + half_height,
3165 x + half_width, y + 2);
3166 gdk_draw_line (window, inner_ne,
3167 x + half_width, y + 2,
3168 x + width - 2, y + half_height);
3169 gdk_draw_line (window, middle_nw,
3170 x + 1, y + half_height,
3171 x + half_width, y + 1);
3172 gdk_draw_line (window, middle_ne,
3173 x + half_width, y + 1,
3174 x + width - 1, y + half_height);
3175 gdk_draw_line (window, outer_nw,
3178 gdk_draw_line (window, outer_ne,
3180 x + width, y + half_height);
3185 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
3186 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
3187 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
3188 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
3193 gtk_default_draw_string (GtkStyle *style,
3195 GtkStateType state_type,
3198 const gchar *detail,
3201 const gchar *string)
3203 g_return_if_fail (GTK_IS_STYLE (style));
3204 g_return_if_fail (window != NULL);
3208 gdk_gc_set_clip_rectangle (style->white_gc, area);
3209 gdk_gc_set_clip_rectangle (style->fg_gc[state_type], area);
3212 if (state_type == GTK_STATE_INSENSITIVE)
3213 gdk_draw_string (window,
3214 gtk_style_get_font_internal (style),
3215 style->white_gc, x + 1, y + 1, string);
3217 gdk_draw_string (window,
3218 gtk_style_get_font_internal (style),
3219 style->fg_gc[state_type], x, y, string);
3223 gdk_gc_set_clip_rectangle (style->white_gc, NULL);
3224 gdk_gc_set_clip_rectangle (style->fg_gc[state_type], NULL);
3229 option_menu_get_props (GtkWidget *widget,
3230 GtkRequisition *indicator_size,
3231 GtkBorder *indicator_spacing)
3233 GtkRequisition *tmp_size = NULL;
3234 GtkBorder *tmp_spacing = NULL;
3237 gtk_widget_style_get (widget,
3238 "indicator-size", &tmp_size,
3239 "indicator-spacing", &tmp_spacing,
3244 *indicator_size = *tmp_size;
3248 *indicator_size = default_option_indicator_size;
3252 *indicator_spacing = *tmp_spacing;
3253 g_free (tmp_spacing);
3256 *indicator_spacing = default_option_indicator_spacing;
3260 gtk_default_draw_box (GtkStyle *style,
3262 GtkStateType state_type,
3263 GtkShadowType shadow_type,
3266 const gchar *detail,
3272 gboolean is_spinbutton_box = FALSE;
3274 g_return_if_fail (GTK_IS_STYLE (style));
3275 g_return_if_fail (window != NULL);
3277 sanitize_size (window, &width, &height);
3279 if (widget && GTK_IS_SPIN_BUTTON (widget) && detail)
3281 if (strcmp (detail, "spinbutton_up") == 0)
3287 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
3292 is_spinbutton_box = TRUE;
3294 else if (strcmp (detail, "spinbutton_down") == 0)
3299 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
3304 is_spinbutton_box = TRUE;
3308 if (!style->bg_pixmap[state_type] ||
3309 GDK_IS_PIXMAP (window))
3311 GdkGC *gc = style->bg_gc[state_type];
3313 if (state_type == GTK_STATE_SELECTED && detail && strcmp (detail, "paned") == 0)
3315 if (widget && !GTK_WIDGET_HAS_FOCUS (widget))
3316 gc = style->base_gc[GTK_STATE_ACTIVE];
3320 gdk_gc_set_clip_rectangle (gc, area);
3322 gdk_draw_rectangle (window, gc, TRUE,
3323 x, y, width, height);
3325 gdk_gc_set_clip_rectangle (gc, NULL);
3328 gtk_style_apply_default_background (style, window,
3329 widget && !GTK_WIDGET_NO_WINDOW (widget),
3330 state_type, area, x, y, width, height);
3332 if (is_spinbutton_box)
3337 lower_gc = style->dark_gc[state_type];
3338 if (shadow_type == GTK_SHADOW_OUT)
3339 upper_gc = style->light_gc[state_type];
3341 upper_gc = style->dark_gc[state_type];
3345 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
3346 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
3349 gdk_draw_line (window, upper_gc, x, y, x + width - 1, y);
3350 gdk_draw_line (window, lower_gc, x, y + height - 1, x + width - 1, y + height - 1);
3354 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
3355 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
3360 gtk_paint_shadow (style, window, state_type, shadow_type, area, widget, detail,
3361 x, y, width, height);
3363 if (detail && strcmp (detail, "optionmenu") == 0)
3365 GtkRequisition indicator_size;
3366 GtkBorder indicator_spacing;
3369 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
3371 sanitize_size (window, &width, &height);
3373 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
3374 vline_x = x + indicator_size.width + indicator_spacing.left + indicator_spacing.right;
3376 vline_x = x + width - (indicator_size.width + indicator_spacing.left + indicator_spacing.right) - style->xthickness;
3378 gtk_paint_vline (style, window, state_type, area, widget,
3380 y + style->ythickness + 1,
3381 y + height - style->ythickness - 3,
3387 get_darkened_gc (GdkWindow *window,
3391 GdkColor src = *color;
3392 GdkColor shaded = *color;
3395 gc = gdk_gc_new (window);
3397 while (darken_count)
3399 gtk_style_shade (&src, &shaded, 0.93);
3404 gdk_gc_set_rgb_fg_color (gc, &shaded);
3410 gtk_default_draw_flat_box (GtkStyle *style,
3412 GtkStateType state_type,
3413 GtkShadowType shadow_type,
3416 const gchar *detail,
3423 GdkGC *freeme = NULL;
3425 g_return_if_fail (GTK_IS_STYLE (style));
3426 g_return_if_fail (window != NULL);
3428 sanitize_size (window, &width, &height);
3432 if (state_type == GTK_STATE_SELECTED)
3434 if (!strcmp ("text", detail))
3435 gc1 = style->bg_gc[GTK_STATE_SELECTED];
3436 else if (!strncmp ("cell_even", detail, strlen ("cell_even")) ||
3437 !strncmp ("cell_odd", detail, strlen ("cell_odd")))
3439 /* This has to be really broken; alex made me do it. -jrb */
3440 if (GTK_WIDGET_HAS_FOCUS (widget))
3441 gc1 = style->base_gc[state_type];
3443 gc1 = style->base_gc[GTK_STATE_ACTIVE];
3447 gc1 = style->bg_gc[state_type];
3452 if (!strcmp ("viewportbin", detail))
3453 gc1 = style->bg_gc[GTK_STATE_NORMAL];
3454 else if (!strcmp ("entry_bg", detail))
3455 gc1 = style->base_gc[state_type];
3457 /* For trees: even rows are base color, odd rows are a shade of
3458 * the base color, the sort column is a shade of the original color
3462 else if (!strcmp ("cell_even", detail) ||
3463 !strcmp ("cell_odd", detail) ||
3464 !strcmp ("cell_even_ruled", detail))
3466 GdkColor *color = NULL;
3468 gtk_widget_style_get (widget,
3469 "even-row-color", &color,
3474 freeme = get_darkened_gc (window, color, 0);
3477 gdk_color_free (color);
3480 gc1 = style->base_gc[state_type];
3482 else if (!strcmp ("cell_odd_ruled", detail))
3486 gtk_widget_style_get (widget,
3487 "odd-row-color", &color,
3492 freeme = get_darkened_gc (window, color, 0);
3495 gdk_color_free (color);
3499 gtk_widget_style_get (widget,
3500 "even-row-color", &color,
3505 freeme = get_darkened_gc (window, color, 1);
3506 gdk_color_free (color);
3509 freeme = get_darkened_gc (window, &style->base[state_type], 1);
3513 else if (!strcmp ("cell_even_sorted", detail) ||
3514 !strcmp ("cell_odd_sorted", detail) ||
3515 !strcmp ("cell_even_ruled_sorted", detail))
3517 GdkColor *color = NULL;
3519 if (!strcmp ("cell_odd_sorted", detail))
3520 gtk_widget_style_get (widget,
3521 "odd-row-color", &color,
3524 gtk_widget_style_get (widget,
3525 "even-row-color", &color,
3530 freeme = get_darkened_gc (window, color, 1);
3533 gdk_color_free (color);
3537 freeme = get_darkened_gc (window, &style->base[state_type], 1);
3541 else if (!strcmp ("cell_odd_ruled_sorted", detail))
3543 GdkColor *color = NULL;
3545 gtk_widget_style_get (widget,
3546 "odd-row-color", &color,
3551 freeme = get_darkened_gc (window, color, 1);
3554 gdk_color_free (color);
3558 gtk_widget_style_get (widget,
3559 "even-row-color", &color,
3564 freeme = get_darkened_gc (window, color, 2);
3565 gdk_color_free (color);
3568 freeme = get_darkened_gc (window, &style->base[state_type], 2);
3573 gc1 = style->bg_gc[state_type];
3577 gc1 = style->bg_gc[state_type];
3579 if (!style->bg_pixmap[state_type] || gc1 != style->bg_gc[state_type] ||
3580 GDK_IS_PIXMAP (window))
3583 gdk_gc_set_clip_rectangle (gc1, area);
3585 gdk_draw_rectangle (window, gc1, TRUE,
3586 x, y, width, height);
3588 if (detail && !strcmp ("tooltip", detail))
3589 gdk_draw_rectangle (window, style->black_gc, FALSE,
3590 x, y, width - 1, height - 1);
3593 gdk_gc_set_clip_rectangle (gc1, NULL);
3596 gtk_style_apply_default_background (style, window,
3597 widget && !GTK_WIDGET_NO_WINDOW (widget),
3598 state_type, area, x, y, width, height);
3602 g_object_unref (freeme);
3606 gtk_default_draw_check (GtkStyle *style,
3608 GtkStateType state_type,
3609 GtkShadowType shadow_type,
3612 const gchar *detail,
3618 cairo_t *cr = gdk_cairo_create (window);
3619 enum { BUTTON, MENU, CELL } type = BUTTON;
3626 if (strcmp (detail, "cellcheck") == 0)
3628 else if (strcmp (detail, "check") == 0)
3634 gdk_cairo_rectangle (cr, area);
3638 exterior_size = MIN (width, height);
3639 if (exterior_size % 2 == 0) /* Ensure odd */
3640 exterior_size -= -1;
3642 pad = style->xthickness + MAX (1, (exterior_size - 2 * style->xthickness) / 9);
3643 interior_size = MAX (1, exterior_size - 2 * pad);
3645 if (interior_size < 7)
3648 pad = MAX (0, (exterior_size - interior_size) / 2);
3651 x -= (1 + exterior_size - width) / 2;
3652 y -= (1 + exterior_size - height) / 2;
3659 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3661 gdk_cairo_set_source_color (cr, &style->text[state_type]);
3663 cairo_set_line_width (cr, 1.0);
3664 cairo_rectangle (cr, x + 0.5, y + 0.5, exterior_size - 1, exterior_size - 1);
3667 gdk_cairo_set_source_color (cr, &style->base[state_type]);
3668 cairo_rectangle (cr, x + 1, y + 1, exterior_size - 2, exterior_size - 2);
3680 gdk_cairo_set_source_color (cr, &style->text[state_type]);
3683 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3687 if (shadow_type == GTK_SHADOW_IN)
3689 cairo_translate (cr,
3692 cairo_scale (cr, interior_size / 7., interior_size / 7.);
3694 cairo_move_to (cr, 7.0, 0.0);
3695 cairo_line_to (cr, 7.5, 1.0);
3696 cairo_curve_to (cr, 5.3, 2.0,
3699 cairo_curve_to (cr, 3.0, 5.7,
3702 cairo_line_to (cr, 0.2, 3.5);
3703 cairo_curve_to (cr, 1.1, 3.5,
3706 cairo_curve_to (cr, 1.0, 3.9,
3709 cairo_curve_to (cr, 3.5, 3.1,
3715 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
3717 int line_thickness = MAX (1, (3 + interior_size * 2) / 7);
3719 cairo_rectangle (cr,
3721 y + pad + (1 + interior_size - line_thickness) / 2,
3731 gtk_default_draw_option (GtkStyle *style,
3733 GtkStateType state_type,
3734 GtkShadowType shadow_type,
3737 const gchar *detail,
3743 cairo_t *cr = gdk_cairo_create (window);
3744 enum { BUTTON, MENU, CELL } type = BUTTON;
3749 if (strcmp (detail, "radio") == 0)
3751 else if (strcmp (detail, "option") == 0)
3757 gdk_cairo_rectangle (cr, area);
3761 exterior_size = MIN (width, height);
3762 if (exterior_size % 2 == 0) /* Ensure odd */
3763 exterior_size -= -1;
3765 x -= (1 + exterior_size - width) / 2;
3766 y -= (1 + exterior_size - height) / 2;
3772 gdk_cairo_set_source_color (cr, &style->base[state_type]);
3775 x + exterior_size / 2.,
3776 y + exterior_size / 2.,
3777 (exterior_size - 1) / 2.,
3780 cairo_fill_preserve (cr);
3783 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3785 gdk_cairo_set_source_color (cr, &style->text[state_type]);
3787 cairo_set_line_width (cr, 1.);
3798 gdk_cairo_set_source_color (cr, &style->text[state_type]);
3803 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3807 if (shadow_type == GTK_SHADOW_IN)
3809 int pad = style->xthickness + MAX (1, 2 * (exterior_size - 2 * style->xthickness) / 9);
3810 int interior_size = MAX (1, exterior_size - 2 * pad);
3812 if (interior_size < 5)
3815 pad = MAX (0, (exterior_size - interior_size) / 2);
3819 x + pad + interior_size / 2.,
3820 y + pad + interior_size / 2.,
3825 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
3827 int pad = style->xthickness + MAX (1, (exterior_size - 2 * style->xthickness) / 9);
3828 int interior_size = MAX (1, exterior_size - 2 * pad);
3831 if (interior_size < 7)
3834 pad = MAX (0, (exterior_size - interior_size) / 2);
3837 line_thickness = MAX (1, (3 + interior_size * 2) / 7);
3839 cairo_rectangle (cr,
3841 y + pad + (interior_size - line_thickness) / 2.,
3851 gtk_default_draw_tab (GtkStyle *style,
3853 GtkStateType state_type,
3854 GtkShadowType shadow_type,
3857 const gchar *detail,
3863 #define ARROW_SPACE 4
3865 GtkRequisition indicator_size;
3866 GtkBorder indicator_spacing;
3869 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
3871 indicator_size.width += (indicator_size.width % 2) - 1;
3872 arrow_height = indicator_size.width / 2 + 1;
3874 x += (width - indicator_size.width) / 2;
3875 y += (height - (2 * arrow_height + ARROW_SPACE)) / 2;
3877 if (state_type == GTK_STATE_INSENSITIVE)
3879 draw_arrow (window, &style->white, area,
3880 GTK_ARROW_UP, x + 1, y + 1,
3881 indicator_size.width, arrow_height);
3883 draw_arrow (window, &style->white, area,
3884 GTK_ARROW_DOWN, x + 1, y + arrow_height + ARROW_SPACE + 1,
3885 indicator_size.width, arrow_height);
3888 draw_arrow (window, &style->fg[state_type], area,
3890 indicator_size.width, arrow_height);
3893 draw_arrow (window, &style->fg[state_type], area,
3894 GTK_ARROW_DOWN, x, y + arrow_height + ARROW_SPACE,
3895 indicator_size.width, arrow_height);
3899 gtk_default_draw_shadow_gap (GtkStyle *style,
3901 GtkStateType state_type,
3902 GtkShadowType shadow_type,
3905 const gchar *detail,
3910 GtkPositionType gap_side,
3919 g_return_if_fail (GTK_IS_STYLE (style));
3920 g_return_if_fail (window != NULL);
3922 sanitize_size (window, &width, &height);
3924 switch (shadow_type)
3926 case GTK_SHADOW_NONE:
3929 gc1 = style->dark_gc[state_type];
3930 gc2 = style->black_gc;
3931 gc3 = style->bg_gc[state_type];
3932 gc4 = style->light_gc[state_type];
3934 case GTK_SHADOW_ETCHED_IN:
3935 gc1 = style->dark_gc[state_type];
3936 gc2 = style->light_gc[state_type];
3937 gc3 = style->dark_gc[state_type];
3938 gc4 = style->light_gc[state_type];
3940 case GTK_SHADOW_OUT:
3941 gc1 = style->light_gc[state_type];
3942 gc2 = style->bg_gc[state_type];
3943 gc3 = style->dark_gc[state_type];
3944 gc4 = style->black_gc;
3946 case GTK_SHADOW_ETCHED_OUT:
3947 gc1 = style->light_gc[state_type];
3948 gc2 = style->dark_gc[state_type];
3949 gc3 = style->light_gc[state_type];
3950 gc4 = style->dark_gc[state_type];
3955 gdk_gc_set_clip_rectangle (gc1, area);
3956 gdk_gc_set_clip_rectangle (gc2, area);
3957 gdk_gc_set_clip_rectangle (gc3, area);
3958 gdk_gc_set_clip_rectangle (gc4, area);
3961 switch (shadow_type)
3963 case GTK_SHADOW_NONE:
3965 case GTK_SHADOW_OUT:
3966 case GTK_SHADOW_ETCHED_IN:
3967 case GTK_SHADOW_ETCHED_OUT:
3971 gdk_draw_line (window, gc1,
3972 x, y, x, y + height - 1);
3973 gdk_draw_line (window, gc2,
3974 x + 1, y, x + 1, y + height - 2);
3976 gdk_draw_line (window, gc3,
3977 x + 1, y + height - 2, x + width - 2, y + height - 2);
3978 gdk_draw_line (window, gc3,
3979 x + width - 2, y, x + width - 2, y + height - 2);
3980 gdk_draw_line (window, gc4,
3981 x, y + height - 1, x + width - 1, y + height - 1);
3982 gdk_draw_line (window, gc4,
3983 x + width - 1, y, x + width - 1, y + height - 1);
3986 gdk_draw_line (window, gc1,
3987 x, y, x + gap_x - 1, y);
3988 gdk_draw_line (window, gc2,
3989 x + 1, y + 1, x + gap_x - 1, y + 1);
3990 gdk_draw_line (window, gc2,
3991 x + gap_x, y, x + gap_x, y);
3993 if ((width - (gap_x + gap_width)) > 0)
3995 gdk_draw_line (window, gc1,
3996 x + gap_x + gap_width, y, x + width - 2, y);
3997 gdk_draw_line (window, gc2,
3998 x + gap_x + gap_width, y + 1, x + width - 3, y + 1);
3999 gdk_draw_line (window, gc2,
4000 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
4003 case GTK_POS_BOTTOM:
4004 gdk_draw_line (window, gc1,
4005 x, y, x + width - 1, y);
4006 gdk_draw_line (window, gc1,
4007 x, y, x, y + height - 1);
4008 gdk_draw_line (window, gc2,
4009 x + 1, y + 1, x + width - 2, y + 1);
4010 gdk_draw_line (window, gc2,
4011 x + 1, y + 1, x + 1, y + height - 1);
4013 gdk_draw_line (window, gc3,
4014 x + width - 2, y + 1, x + width - 2, y + height - 1);
4015 gdk_draw_line (window, gc4,
4016 x + width - 1, y, x + width - 1, y + height - 1);
4019 gdk_draw_line (window, gc4,
4020 x, y + height - 1, x + gap_x - 1, y + height - 1);
4021 gdk_draw_line (window, gc3,
4022 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
4023 gdk_draw_line (window, gc3,
4024 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
4026 if ((width - (gap_x + gap_width)) > 0)
4028 gdk_draw_line (window, gc4,
4029 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
4030 gdk_draw_line (window, gc3,
4031 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
4032 gdk_draw_line (window, gc3,
4033 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
4037 gdk_draw_line (window, gc1,
4038 x, y, x + width - 1, y);
4039 gdk_draw_line (window, gc2,
4040 x, y + 1, x + width - 2, y + 1);
4042 gdk_draw_line (window, gc3,
4043 x, y + height - 2, x + width - 2, y + height - 2);
4044 gdk_draw_line (window, gc3,
4045 x + width - 2, y + 1, x + width - 2, y + height - 2);
4046 gdk_draw_line (window, gc4,
4047 x, y + height - 1, x + width - 1, y + height - 1);
4048 gdk_draw_line (window, gc4,
4049 x + width - 1, y, x + width - 1, y + height - 1);
4052 gdk_draw_line (window, gc1,
4053 x, y, x, y + gap_x - 1);
4054 gdk_draw_line (window, gc2,
4055 x + 1, y + 1, x + 1, y + gap_x - 1);
4056 gdk_draw_line (window, gc2,
4057 x, y + gap_x, x, y + gap_x);
4059 if ((width - (gap_x + gap_width)) > 0)
4061 gdk_draw_line (window, gc1,
4062 x, y + gap_x + gap_width, x, y + height - 2);
4063 gdk_draw_line (window, gc2,
4064 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
4065 gdk_draw_line (window, gc2,
4066 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
4070 gdk_draw_line (window, gc1,
4071 x, y, x + width - 1, y);
4072 gdk_draw_line (window, gc1,
4073 x, y, x, y + height - 1);
4074 gdk_draw_line (window, gc2,
4075 x + 1, y + 1, x + width - 1, y + 1);
4076 gdk_draw_line (window, gc2,
4077 x + 1, y + 1, x + 1, y + height - 2);
4079 gdk_draw_line (window, gc3,
4080 x + 1, y + height - 2, x + width - 1, y + height - 2);
4081 gdk_draw_line (window, gc4,
4082 x, y + height - 1, x + width - 1, y + height - 1);
4085 gdk_draw_line (window, gc4,
4086 x + width - 1, y, x + width - 1, y + gap_x - 1);
4087 gdk_draw_line (window, gc3,
4088 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
4089 gdk_draw_line (window, gc3,
4090 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
4092 if ((width - (gap_x + gap_width)) > 0)
4094 gdk_draw_line (window, gc4,
4095 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
4096 gdk_draw_line (window, gc3,
4097 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
4098 gdk_draw_line (window, gc3,
4099 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
4107 gdk_gc_set_clip_rectangle (gc1, NULL);
4108 gdk_gc_set_clip_rectangle (gc2, NULL);
4109 gdk_gc_set_clip_rectangle (gc3, NULL);
4110 gdk_gc_set_clip_rectangle (gc4, NULL);
4115 gtk_default_draw_box_gap (GtkStyle *style,
4117 GtkStateType state_type,
4118 GtkShadowType shadow_type,
4121 const gchar *detail,
4126 GtkPositionType gap_side,
4135 g_return_if_fail (GTK_IS_STYLE (style));
4136 g_return_if_fail (window != NULL);
4138 gtk_style_apply_default_background (style, window,
4139 widget && !GTK_WIDGET_NO_WINDOW (widget),
4140 state_type, area, x, y, width, height);
4142 sanitize_size (window, &width, &height);
4144 switch (shadow_type)
4146 case GTK_SHADOW_NONE:
4149 gc1 = style->dark_gc[state_type];
4150 gc2 = style->black_gc;
4151 gc3 = style->bg_gc[state_type];
4152 gc4 = style->light_gc[state_type];
4154 case GTK_SHADOW_ETCHED_IN:
4155 gc1 = style->dark_gc[state_type];
4156 gc2 = style->light_gc[state_type];
4157 gc3 = style->dark_gc[state_type];
4158 gc4 = style->light_gc[state_type];
4160 case GTK_SHADOW_OUT:
4161 gc1 = style->light_gc[state_type];
4162 gc2 = style->bg_gc[state_type];
4163 gc3 = style->dark_gc[state_type];
4164 gc4 = style->black_gc;
4166 case GTK_SHADOW_ETCHED_OUT:
4167 gc1 = style->light_gc[state_type];
4168 gc2 = style->dark_gc[state_type];
4169 gc3 = style->light_gc[state_type];
4170 gc4 = style->dark_gc[state_type];
4176 gdk_gc_set_clip_rectangle (gc1, area);
4177 gdk_gc_set_clip_rectangle (gc2, area);
4178 gdk_gc_set_clip_rectangle (gc3, area);
4179 gdk_gc_set_clip_rectangle (gc4, area);
4182 switch (shadow_type)
4184 case GTK_SHADOW_NONE:
4186 case GTK_SHADOW_OUT:
4187 case GTK_SHADOW_ETCHED_IN:
4188 case GTK_SHADOW_ETCHED_OUT:
4192 gdk_draw_line (window, gc1,
4193 x, y, x, y + height - 1);
4194 gdk_draw_line (window, gc2,
4195 x + 1, y, x + 1, y + height - 2);
4197 gdk_draw_line (window, gc3,
4198 x + 1, y + height - 2, x + width - 2, y + height - 2);
4199 gdk_draw_line (window, gc3,
4200 x + width - 2, y, x + width - 2, y + height - 2);
4201 gdk_draw_line (window, gc4,
4202 x, y + height - 1, x + width - 1, y + height - 1);
4203 gdk_draw_line (window, gc4,
4204 x + width - 1, y, x + width - 1, y + height - 1);
4207 gdk_draw_line (window, gc1,
4208 x, y, x + gap_x - 1, y);
4209 gdk_draw_line (window, gc2,
4210 x + 1, y + 1, x + gap_x - 1, y + 1);
4211 gdk_draw_line (window, gc2,
4212 x + gap_x, y, x + gap_x, y);
4214 if ((width - (gap_x + gap_width)) > 0)
4216 gdk_draw_line (window, gc1,
4217 x + gap_x + gap_width, y, x + width - 2, y);
4218 gdk_draw_line (window, gc2,
4219 x + gap_x + gap_width, y + 1, x + width - 2, y + 1);
4220 gdk_draw_line (window, gc2,
4221 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
4224 case GTK_POS_BOTTOM:
4225 gdk_draw_line (window, gc1,
4226 x, y, x + width - 1, y);
4227 gdk_draw_line (window, gc1,
4228 x, y, x, y + height - 1);
4229 gdk_draw_line (window, gc2,
4230 x + 1, y + 1, x + width - 2, y + 1);
4231 gdk_draw_line (window, gc2,
4232 x + 1, y + 1, x + 1, y + height - 1);
4234 gdk_draw_line (window, gc3,
4235 x + width - 2, y + 1, x + width - 2, y + height - 1);
4236 gdk_draw_line (window, gc4,
4237 x + width - 1, y, x + width - 1, y + height - 1);
4240 gdk_draw_line (window, gc4,
4241 x, y + height - 1, x + gap_x - 1, y + height - 1);
4242 gdk_draw_line (window, gc3,
4243 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
4244 gdk_draw_line (window, gc3,
4245 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
4247 if ((width - (gap_x + gap_width)) > 0)
4249 gdk_draw_line (window, gc4,
4250 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
4251 gdk_draw_line (window, gc3,
4252 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
4253 gdk_draw_line (window, gc3,
4254 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
4258 gdk_draw_line (window, gc1,
4259 x, y, x + width - 1, y);
4260 gdk_draw_line (window, gc2,
4261 x, y + 1, x + width - 2, y + 1);
4263 gdk_draw_line (window, gc3,
4264 x, y + height - 2, x + width - 2, y + height - 2);
4265 gdk_draw_line (window, gc3,
4266 x + width - 2, y + 1, x + width - 2, y + height - 2);
4267 gdk_draw_line (window, gc4,
4268 x, y + height - 1, x + width - 1, y + height - 1);
4269 gdk_draw_line (window, gc4,
4270 x + width - 1, y, x + width - 1, y + height - 1);
4273 gdk_draw_line (window, gc1,
4274 x, y, x, y + gap_x - 1);
4275 gdk_draw_line (window, gc2,
4276 x + 1, y + 1, x + 1, y + gap_x - 1);
4277 gdk_draw_line (window, gc2,
4278 x, y + gap_x, x, y + gap_x);
4280 if ((width - (gap_x + gap_width)) > 0)
4282 gdk_draw_line (window, gc1,
4283 x, y + gap_x + gap_width, x, y + height - 2);
4284 gdk_draw_line (window, gc2,
4285 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
4286 gdk_draw_line (window, gc2,
4287 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
4291 gdk_draw_line (window, gc1,
4292 x, y, x + width - 1, y);
4293 gdk_draw_line (window, gc1,
4294 x, y, x, y + height - 1);
4295 gdk_draw_line (window, gc2,
4296 x + 1, y + 1, x + width - 1, y + 1);
4297 gdk_draw_line (window, gc2,
4298 x + 1, y + 1, x + 1, y + height - 2);
4300 gdk_draw_line (window, gc3,
4301 x + 1, y + height - 2, x + width - 1, y + height - 2);
4302 gdk_draw_line (window, gc4,
4303 x, y + height - 1, x + width - 1, y + height - 1);
4306 gdk_draw_line (window, gc4,
4307 x + width - 1, y, x + width - 1, y + gap_x - 1);
4308 gdk_draw_line (window, gc3,
4309 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
4310 gdk_draw_line (window, gc3,
4311 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
4313 if ((width - (gap_x + gap_width)) > 0)
4315 gdk_draw_line (window, gc4,
4316 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
4317 gdk_draw_line (window, gc3,
4318 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
4319 gdk_draw_line (window, gc3,
4320 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
4328 gdk_gc_set_clip_rectangle (gc1, NULL);
4329 gdk_gc_set_clip_rectangle (gc2, NULL);
4330 gdk_gc_set_clip_rectangle (gc3, NULL);
4331 gdk_gc_set_clip_rectangle (gc4, NULL);
4336 gtk_default_draw_extension (GtkStyle *style,
4338 GtkStateType state_type,
4339 GtkShadowType shadow_type,
4342 const gchar *detail,
4347 GtkPositionType gap_side)
4354 g_return_if_fail (GTK_IS_STYLE (style));
4355 g_return_if_fail (window != NULL);
4357 gtk_style_apply_default_background (style, window,
4358 widget && !GTK_WIDGET_NO_WINDOW (widget),
4359 GTK_STATE_NORMAL, area, x, y, width, height);
4361 sanitize_size (window, &width, &height);
4363 switch (shadow_type)
4365 case GTK_SHADOW_NONE:
4368 gc1 = style->dark_gc[state_type];
4369 gc2 = style->black_gc;
4370 gc3 = style->bg_gc[state_type];
4371 gc4 = style->light_gc[state_type];
4373 case GTK_SHADOW_ETCHED_IN:
4374 gc1 = style->dark_gc[state_type];
4375 gc2 = style->light_gc[state_type];
4376 gc3 = style->dark_gc[state_type];
4377 gc4 = style->light_gc[state_type];
4379 case GTK_SHADOW_OUT:
4380 gc1 = style->light_gc[state_type];
4381 gc2 = style->bg_gc[state_type];
4382 gc3 = style->dark_gc[state_type];
4383 gc4 = style->black_gc;
4385 case GTK_SHADOW_ETCHED_OUT:
4386 gc1 = style->light_gc[state_type];
4387 gc2 = style->dark_gc[state_type];
4388 gc3 = style->light_gc[state_type];
4389 gc4 = style->dark_gc[state_type];
4395 gdk_gc_set_clip_rectangle (gc1, area);
4396 gdk_gc_set_clip_rectangle (gc2, area);
4397 gdk_gc_set_clip_rectangle (gc3, area);
4398 gdk_gc_set_clip_rectangle (gc4, area);
4401 switch (shadow_type)
4403 case GTK_SHADOW_NONE:
4405 case GTK_SHADOW_OUT:
4406 case GTK_SHADOW_ETCHED_IN:
4407 case GTK_SHADOW_ETCHED_OUT:
4411 gtk_style_apply_default_background (style, window,
4412 widget && !GTK_WIDGET_NO_WINDOW (widget),
4414 x + style->xthickness,
4416 width - (2 * style->xthickness),
4417 height - (style->ythickness));
4418 gdk_draw_line (window, gc1,
4419 x, y, x, y + height - 2);
4420 gdk_draw_line (window, gc2,
4421 x + 1, y, x + 1, y + height - 2);
4423 gdk_draw_line (window, gc3,
4424 x + 2, y + height - 2, x + width - 2, y + height - 2);
4425 gdk_draw_line (window, gc3,
4426 x + width - 2, y, x + width - 2, y + height - 2);
4427 gdk_draw_line (window, gc4,
4428 x + 1, y + height - 1, x + width - 2, y + height - 1);
4429 gdk_draw_line (window, gc4,
4430 x + width - 1, y, x + width - 1, y + height - 2);
4432 case GTK_POS_BOTTOM:
4433 gtk_style_apply_default_background (style, window,
4434 widget && !GTK_WIDGET_NO_WINDOW (widget),
4436 x + style->xthickness,
4437 y + style->ythickness,
4438 width - (2 * style->xthickness),
4439 height - (style->ythickness));
4440 gdk_draw_line (window, gc1,
4441 x + 1, y, x + width - 2, y);
4442 gdk_draw_line (window, gc1,
4443 x, y + 1, x, y + height - 1);
4444 gdk_draw_line (window, gc2,
4445 x + 1, y + 1, x + width - 2, y + 1);
4446 gdk_draw_line (window, gc2,
4447 x + 1, y + 1, x + 1, y + height - 1);
4449 gdk_draw_line (window, gc3,
4450 x + width - 2, y + 2, x + width - 2, y + height - 1);
4451 gdk_draw_line (window, gc4,
4452 x + width - 1, y + 1, x + width - 1, y + height - 1);
4455 gtk_style_apply_default_background (style, window,
4456 widget && !GTK_WIDGET_NO_WINDOW (widget),
4459 y + style->ythickness,
4460 width - (style->xthickness),
4461 height - (2 * style->ythickness));
4462 gdk_draw_line (window, gc1,
4463 x, y, x + width - 2, y);
4464 gdk_draw_line (window, gc2,
4465 x + 1, y + 1, x + width - 2, y + 1);
4467 gdk_draw_line (window, gc3,
4468 x, y + height - 2, x + width - 2, y + height - 2);
4469 gdk_draw_line (window, gc3,
4470 x + width - 2, y + 2, x + width - 2, y + height - 2);
4471 gdk_draw_line (window, gc4,
4472 x, y + height - 1, x + width - 2, y + height - 1);
4473 gdk_draw_line (window, gc4,
4474 x + width - 1, y + 1, x + width - 1, y + height - 2);
4477 gtk_style_apply_default_background (style, window,
4478 widget && !GTK_WIDGET_NO_WINDOW (widget),
4480 x + style->xthickness,
4481 y + style->ythickness,
4482 width - (style->xthickness),
4483 height - (2 * style->ythickness));
4484 gdk_draw_line (window, gc1,
4485 x + 1, y, x + width - 1, y);
4486 gdk_draw_line (window, gc1,
4487 x, y + 1, x, y + height - 2);
4488 gdk_draw_line (window, gc2,
4489 x + 1, y + 1, x + width - 1, y + 1);
4490 gdk_draw_line (window, gc2,
4491 x + 1, y + 1, x + 1, y + height - 2);
4493 gdk_draw_line (window, gc3,
4494 x + 2, y + height - 2, x + width - 1, y + height - 2);
4495 gdk_draw_line (window, gc4,
4496 x + 1, y + height - 1, x + width - 1, y + height - 1);
4503 gdk_gc_set_clip_rectangle (gc1, NULL);
4504 gdk_gc_set_clip_rectangle (gc2, NULL);
4505 gdk_gc_set_clip_rectangle (gc3, NULL);
4506 gdk_gc_set_clip_rectangle (gc4, NULL);
4511 gtk_default_draw_focus (GtkStyle *style,
4513 GtkStateType state_type,
4516 const gchar *detail,
4523 gboolean free_dash_list = FALSE;
4524 gint line_width = 1;
4525 gint8 *dash_list = "\1\1";
4529 gtk_widget_style_get (widget,
4530 "focus-line-width", &line_width,
4531 "focus-line-pattern", (gchar *)&dash_list,
4534 free_dash_list = TRUE;
4537 if (detail && !strcmp (detail, "add-mode"))
4543 free_dash_list = FALSE;
4546 sanitize_size (window, &width, &height);
4548 cr = gdk_cairo_create (window);
4550 if (detail && !strcmp (detail, "colorwheel_light"))
4551 cairo_set_source_rgb (cr, 0., 0., 0.);
4552 else if (detail && !strcmp (detail, "colorwheel_dark"))
4553 cairo_set_source_rgb (cr, 1., 1., 1.);
4555 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
4557 cairo_set_line_width (cr, line_width);
4561 gint n_dashes = strlen (dash_list);
4562 gdouble *dashes = g_new (gdouble, n_dashes);
4563 gdouble total_length = 0;
4564 gdouble dash_offset;
4567 for (i = 0; i < n_dashes; i++)
4569 dashes[i] = dash_list[i];
4570 total_length += dash_list[i];
4573 /* The dash offset here aligns the pattern to integer pixels
4574 * by starting the dash at the right side of the left border
4575 * Negative dash offsets in cairo don't work
4576 * (https://bugs.freedesktop.org/show_bug.cgi?id=2729)
4578 dash_offset = - line_width / 2.;
4579 while (dash_offset < 0)
4580 dash_offset += total_length;
4582 cairo_set_dash (cr, dashes, n_dashes, dash_offset);
4588 gdk_cairo_rectangle (cr, area);
4592 cairo_rectangle (cr,
4593 x + line_width / 2.,
4594 y + line_width / 2.,
4596 height - line_width);
4605 gtk_default_draw_slider (GtkStyle *style,
4607 GtkStateType state_type,
4608 GtkShadowType shadow_type,
4611 const gchar *detail,
4616 GtkOrientation orientation)
4618 g_return_if_fail (GTK_IS_STYLE (style));
4619 g_return_if_fail (window != NULL);
4621 sanitize_size (window, &width, &height);
4623 gtk_paint_box (style, window, state_type, shadow_type,
4624 area, widget, detail, x, y, width, height);
4627 (strcmp ("hscale", detail) == 0 ||
4628 strcmp ("vscale", detail) == 0))
4630 if (orientation == GTK_ORIENTATION_HORIZONTAL)
4631 gtk_paint_vline (style, window, state_type, area, widget, detail,
4632 y + style->ythickness,
4633 y + height - style->ythickness - 1, x + width / 2);
4635 gtk_paint_hline (style, window, state_type, area, widget, detail,
4636 x + style->xthickness,
4637 x + width - style->xthickness - 1, y + height / 2);
4642 draw_dot (GdkWindow *window,
4650 size = CLAMP (size, 2, 3);
4654 gdk_draw_point (window, light_gc, x, y);
4655 gdk_draw_point (window, light_gc, x+1, y+1);
4659 gdk_draw_point (window, light_gc, x, y);
4660 gdk_draw_point (window, light_gc, x+1, y);
4661 gdk_draw_point (window, light_gc, x, y+1);
4662 gdk_draw_point (window, dark_gc, x+1, y+2);
4663 gdk_draw_point (window, dark_gc, x+2, y+1);
4664 gdk_draw_point (window, dark_gc, x+2, y+2);
4669 gtk_default_draw_handle (GtkStyle *style,
4671 GtkStateType state_type,
4672 GtkShadowType shadow_type,
4675 const gchar *detail,
4680 GtkOrientation orientation)
4683 gint xthick, ythick;
4684 GdkGC *light_gc, *dark_gc;
4685 GdkGC *free_me = NULL;
4690 g_return_if_fail (GTK_IS_STYLE (style));
4691 g_return_if_fail (window != NULL);
4693 sanitize_size (window, &width, &height);
4695 gtk_paint_box (style, window, state_type, shadow_type, area, widget,
4696 detail, x, y, width, height);
4699 if (detail && !strcmp (detail, "paned"))
4701 /* we want to ignore the shadow border in paned widgets */
4705 if (state_type == GTK_STATE_SELECTED && widget && !GTK_WIDGET_HAS_FOCUS (widget))
4707 GdkColor unfocused_light;
4709 gtk_style_shade (&style->base[GTK_STATE_ACTIVE], &unfocused_light,
4712 light_gc = free_me = gdk_gc_new (window);
4713 gdk_gc_set_rgb_fg_color (light_gc, &unfocused_light);
4716 light_gc = style->light_gc[state_type];
4718 dark_gc = style->black_gc;
4722 xthick = style->xthickness;
4723 ythick = style->ythickness;
4725 light_gc = style->light_gc[state_type];
4726 dark_gc = style->dark_gc[state_type];
4729 rect.x = x + xthick;
4730 rect.y = y + ythick;
4731 rect.width = width - (xthick * 2);
4732 rect.height = height - (ythick * 2);
4735 intersect = gdk_rectangle_intersect (area, &rect, &dest);
4745 gdk_gc_set_clip_rectangle (light_gc, &dest);
4746 gdk_gc_set_clip_rectangle (dark_gc, &dest);
4748 if (detail && !strcmp (detail, "paned"))
4750 if (orientation == GTK_ORIENTATION_HORIZONTAL)
4751 for (xx = x + width/2 - 15; xx <= x + width/2 + 15; xx += 5)
4752 draw_dot (window, light_gc, dark_gc, xx, y + height/2 - 1, 3);
4754 for (yy = y + height/2 - 15; yy <= y + height/2 + 15; yy += 5)
4755 draw_dot (window, light_gc, dark_gc, x + width/2 - 1, yy, 3);
4759 for (yy = y + ythick; yy < (y + height - ythick); yy += 3)
4760 for (xx = x + xthick; xx < (x + width - xthick); xx += 6)
4762 draw_dot (window, light_gc, dark_gc, xx, yy, 2);
4763 draw_dot (window, light_gc, dark_gc, xx + 3, yy + 1, 2);
4767 gdk_gc_set_clip_rectangle (light_gc, NULL);
4768 gdk_gc_set_clip_rectangle (dark_gc, NULL);
4772 g_object_unref (free_me);
4776 gtk_default_draw_expander (GtkStyle *style,
4778 GtkStateType state_type,
4781 const gchar *detail,
4784 GtkExpanderStyle expander_style)
4786 #define DEFAULT_EXPANDER_SIZE 12
4790 double vertical_overshoot;
4793 double interp; /* interpolation factor for center position */
4794 double x_double_horz, y_double_horz;
4795 double x_double_vert, y_double_vert;
4796 double x_double, y_double;
4799 cairo_t *cr = gdk_cairo_create (window);
4803 gdk_cairo_rectangle (cr, area);
4808 gtk_widget_class_find_style_property (GTK_WIDGET_GET_CLASS (widget),
4811 gtk_widget_style_get (widget,
4812 "expander-size", &expander_size,
4816 expander_size = DEFAULT_EXPANDER_SIZE;
4818 line_width = MAX (1, expander_size/9);
4820 switch (expander_style)
4822 case GTK_EXPANDER_COLLAPSED:
4823 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 180 : 0;
4826 case GTK_EXPANDER_SEMI_COLLAPSED:
4827 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 150 : 30;
4830 case GTK_EXPANDER_SEMI_EXPANDED:
4831 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 120 : 60;
4834 case GTK_EXPANDER_EXPANDED:
4839 g_assert_not_reached ();
4842 /* Compute distance that the stroke extends beyonds the end
4843 * of the triangle we draw.
4845 vertical_overshoot = line_width / 2.0 * (1. / tan (G_PI / 8));
4847 /* For odd line widths, we end the vertical line of the triangle
4848 * at a half pixel, so we round differently.
4850 if (line_width % 2 == 1)
4851 vertical_overshoot = ceil (0.5 + vertical_overshoot) - 0.5;
4853 vertical_overshoot = ceil (vertical_overshoot);
4855 /* Adjust the size of the triangle we draw so that the entire stroke fits
4857 diameter = MAX (3, expander_size - 2 * vertical_overshoot);
4859 /* If the line width is odd, we want the diameter to be even,
4860 * and vice versa, so force the sum to be odd. This relationship
4861 * makes the point of the triangle look right.
4863 diameter -= (1 - (diameter + line_width) % 2);
4865 radius = diameter / 2.;
4867 /* Adjust the center so that the stroke is properly aligned with
4868 * the pixel grid. The center adjustment is different for the
4869 * horizontal and vertical orientations. For intermediate positions
4870 * we interpolate between the two.
4872 x_double_vert = floor (x - (radius + line_width) / 2.) + (radius + line_width) / 2.;
4873 y_double_vert = y - 0.5;
4875 x_double_horz = x - 0.5;
4876 y_double_horz = floor (y - (radius + line_width) / 2.) + (radius + line_width) / 2.;
4878 x_double = x_double_vert * (1 - interp) + x_double_horz * interp;
4879 y_double = y_double_vert * (1 - interp) + y_double_horz * interp;
4881 cairo_translate (cr, x_double, y_double);
4882 cairo_rotate (cr, degrees * G_PI / 180);
4884 cairo_move_to (cr, - radius / 2., - radius);
4885 cairo_line_to (cr, radius / 2., 0);
4886 cairo_line_to (cr, - radius / 2., radius);
4887 cairo_close_path (cr);
4889 cairo_set_line_width (cr, line_width);
4891 if (state_type == GTK_STATE_PRELIGHT)
4892 gdk_cairo_set_source_color (cr,
4893 &style->fg[GTK_STATE_PRELIGHT]);
4894 else if (state_type == GTK_STATE_ACTIVE)
4895 gdk_cairo_set_source_color (cr,
4896 &style->light[GTK_STATE_ACTIVE]);
4898 gdk_cairo_set_source_color (cr,
4899 &style->base[GTK_STATE_NORMAL]);
4901 cairo_fill_preserve (cr);
4903 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
4909 typedef struct _ByteRange ByteRange;
4918 range_new (guint start,
4921 ByteRange *br = g_new (ByteRange, 1);
4930 get_insensitive_layout (GdkDrawable *drawable,
4931 PangoLayout *layout)
4933 GSList *embossed_ranges = NULL;
4934 GSList *stippled_ranges = NULL;
4935 PangoLayoutIter *iter;
4936 GSList *tmp_list = NULL;
4937 PangoLayout *new_layout;
4938 PangoAttrList *attrs;
4939 GdkBitmap *stipple = NULL;
4941 iter = pango_layout_get_iter (layout);
4945 PangoLayoutRun *run;
4946 PangoAttribute *attr;
4947 gboolean need_stipple = FALSE;
4950 run = pango_layout_iter_get_run (iter);
4954 tmp_list = run->item->analysis.extra_attrs;
4956 while (tmp_list != NULL)
4958 attr = tmp_list->data;
4959 switch (attr->klass->type)
4961 case PANGO_ATTR_FOREGROUND:
4962 case PANGO_ATTR_BACKGROUND:
4963 need_stipple = TRUE;
4973 tmp_list = g_slist_next (tmp_list);
4976 br = range_new (run->item->offset, run->item->offset + run->item->length);
4979 stippled_ranges = g_slist_prepend (stippled_ranges, br);
4981 embossed_ranges = g_slist_prepend (embossed_ranges, br);
4984 while (pango_layout_iter_next_run (iter));
4986 pango_layout_iter_free (iter);
4988 new_layout = pango_layout_copy (layout);
4990 attrs = pango_layout_get_attributes (new_layout);
4994 /* Create attr list if there wasn't one */
4995 attrs = pango_attr_list_new ();
4996 pango_layout_set_attributes (new_layout, attrs);
4997 pango_attr_list_unref (attrs);
5000 tmp_list = embossed_ranges;
5001 while (tmp_list != NULL)
5003 PangoAttribute *attr;
5004 ByteRange *br = tmp_list->data;
5006 attr = gdk_pango_attr_embossed_new (TRUE);
5008 attr->start_index = br->start;
5009 attr->end_index = br->end;
5011 pango_attr_list_change (attrs, attr);
5015 tmp_list = g_slist_next (tmp_list);
5018 g_slist_free (embossed_ranges);
5020 tmp_list = stippled_ranges;
5021 while (tmp_list != NULL)
5023 PangoAttribute *attr;
5024 ByteRange *br = tmp_list->data;
5026 if (stipple == NULL)
5028 #define gray50_width 2
5029 #define gray50_height 2
5030 static const char gray50_bits[] = {
5034 stipple = gdk_bitmap_create_from_data (drawable,
5035 gray50_bits, gray50_width,
5039 attr = gdk_pango_attr_stipple_new (stipple);
5041 attr->start_index = br->start;
5042 attr->end_index = br->end;
5044 pango_attr_list_change (attrs, attr);
5048 tmp_list = g_slist_next (tmp_list);
5051 g_slist_free (stippled_ranges);
5054 g_object_unref (stipple);
5060 gtk_default_draw_layout (GtkStyle *style,
5062 GtkStateType state_type,
5066 const gchar *detail,
5069 PangoLayout *layout)
5073 g_return_if_fail (GTK_IS_STYLE (style));
5074 g_return_if_fail (window != NULL);
5076 gc = use_text ? style->text_gc[state_type] : style->fg_gc[state_type];
5079 gdk_gc_set_clip_rectangle (gc, area);
5081 if (state_type == GTK_STATE_INSENSITIVE)
5085 ins = get_insensitive_layout (window, layout);
5087 gdk_draw_layout (window, gc, x, y, ins);
5089 g_object_unref (ins);
5093 gdk_draw_layout (window, gc, x, y, layout);
5097 gdk_gc_set_clip_rectangle (gc, NULL);
5101 gtk_default_draw_resize_grip (GtkStyle *style,
5103 GtkStateType state_type,
5106 const gchar *detail,
5116 g_return_if_fail (GTK_IS_STYLE (style));
5117 g_return_if_fail (window != NULL);
5121 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
5122 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
5123 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
5129 case GDK_WINDOW_EDGE_NORTH_WEST:
5130 /* make it square */
5133 else if (height < width)
5137 case GDK_WINDOW_EDGE_NORTH:
5141 case GDK_WINDOW_EDGE_NORTH_EAST:
5142 /* make it square, aligning to top right */
5145 else if (height < width)
5147 x += (width - height);
5152 case GDK_WINDOW_EDGE_WEST:
5156 case GDK_WINDOW_EDGE_EAST:
5157 /* aligning to right */
5160 x += (width - height);
5164 case GDK_WINDOW_EDGE_SOUTH_WEST:
5165 /* make it square, aligning to bottom left */
5168 y += (height - width);
5171 else if (height < width)
5175 case GDK_WINDOW_EDGE_SOUTH:
5176 /* align to bottom */
5179 y += (height - width);
5183 case GDK_WINDOW_EDGE_SOUTH_EAST:
5184 /* make it square, aligning to bottom right */
5187 y += (height - width);
5190 else if (height < width)
5192 x += (width - height);
5198 g_assert_not_reached ();
5200 /* Clear background */
5202 for (i = 0; i < 4; i++)
5206 points[j].x = (i == 0 || i == 3) ? x : x + width;
5207 points[j].y = (i < 2) ? y : y + height;
5212 gdk_draw_polygon (window, style->bg_gc[state_type], TRUE,
5213 points, skip < 0 ? 4 : 3);
5217 case GDK_WINDOW_EDGE_WEST:
5218 case GDK_WINDOW_EDGE_EAST:
5224 while (xi < x + width)
5226 gdk_draw_line (window,
5227 style->light_gc[state_type],
5232 gdk_draw_line (window,
5233 style->dark_gc[state_type],
5241 case GDK_WINDOW_EDGE_NORTH:
5242 case GDK_WINDOW_EDGE_SOUTH:
5248 while (yi < y + height)
5250 gdk_draw_line (window,
5251 style->light_gc[state_type],
5256 gdk_draw_line (window,
5257 style->dark_gc[state_type],
5265 case GDK_WINDOW_EDGE_NORTH_WEST:
5274 gdk_draw_line (window,
5275 style->dark_gc[state_type],
5282 gdk_draw_line (window,
5283 style->dark_gc[state_type],
5290 gdk_draw_line (window,
5291 style->light_gc[state_type],
5301 case GDK_WINDOW_EDGE_NORTH_EAST:
5308 while (xi < (x + width - 3))
5310 gdk_draw_line (window,
5311 style->light_gc[state_type],
5318 gdk_draw_line (window,
5319 style->dark_gc[state_type],
5326 gdk_draw_line (window,
5327 style->dark_gc[state_type],
5336 case GDK_WINDOW_EDGE_SOUTH_WEST:
5345 gdk_draw_line (window,
5346 style->dark_gc[state_type],
5353 gdk_draw_line (window,
5354 style->dark_gc[state_type],
5361 gdk_draw_line (window,
5362 style->light_gc[state_type],
5372 case GDK_WINDOW_EDGE_SOUTH_EAST:
5379 while (xi < (x + width - 3))
5381 gdk_draw_line (window,
5382 style->light_gc[state_type],
5389 gdk_draw_line (window,
5390 style->dark_gc[state_type],
5397 gdk_draw_line (window,
5398 style->dark_gc[state_type],
5408 g_assert_not_reached ();
5414 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
5415 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
5416 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
5421 gtk_style_shade (GdkColor *a,
5429 red = (gdouble) a->red / 65535.0;
5430 green = (gdouble) a->green / 65535.0;
5431 blue = (gdouble) a->blue / 65535.0;
5433 rgb_to_hls (&red, &green, &blue);
5438 else if (green < 0.0)
5444 else if (blue < 0.0)
5447 hls_to_rgb (&red, &green, &blue);
5449 b->red = red * 65535.0;
5450 b->green = green * 65535.0;
5451 b->blue = blue * 65535.0;
5455 rgb_to_hls (gdouble *r,
5496 l = (max + min) / 2;
5503 s = (max - min) / (max + min);
5505 s = (max - min) / (2 - max - min);
5509 h = (green - blue) / delta;
5510 else if (green == max)
5511 h = 2 + (blue - red) / delta;
5512 else if (blue == max)
5513 h = 4 + (red - green) / delta;
5526 hls_to_rgb (gdouble *h,
5539 if (lightness <= 0.5)
5540 m2 = lightness * (1 + saturation);
5542 m2 = lightness + saturation - lightness * saturation;
5543 m1 = 2 * lightness - m2;
5545 if (saturation == 0)
5560 r = m1 + (m2 - m1) * hue / 60;
5564 r = m1 + (m2 - m1) * (240 - hue) / 60;
5575 g = m1 + (m2 - m1) * hue / 60;
5579 g = m1 + (m2 - m1) * (240 - hue) / 60;
5590 b = m1 + (m2 - m1) * hue / 60;
5594 b = m1 + (m2 - m1) * (240 - hue) / 60;
5607 * @style: a #GtkStyle
5608 * @window: a #GdkWindow
5609 * @state_type: a state
5610 * @area: rectangle to which the output is clipped, or %NULL if the
5611 * output should not be clipped
5612 * @widget: the widget (may be %NULL)
5613 * @detail: a style detail (may be %NULL)
5614 * @x1: the starting x coordinate
5615 * @x2: the ending x coordinate
5616 * @y: the y coordinate
5618 * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @window
5619 * using the given style and state.
5622 gtk_paint_hline (GtkStyle *style,
5624 GtkStateType state_type,
5627 const gchar *detail,
5632 g_return_if_fail (GTK_IS_STYLE (style));
5633 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
5634 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5636 GTK_STYLE_GET_CLASS (style)->draw_hline (style, window, state_type, area, widget, detail, x1, x2, y);
5641 * @style: a #GtkStyle
5642 * @window: a #GdkWindow
5643 * @state_type: a state
5644 * @area: rectangle to which the output is clipped, or %NULL if the
5645 * output should not be clipped
5646 * @widget: the widget (may be %NULL)
5647 * @detail: a style detail (may be %NULL)
5648 * @y1_: the starting y coordinate
5649 * @y2_: the ending y coordinate
5650 * @x: the x coordinate
5652 * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @window
5653 * using the given style and state.
5656 gtk_paint_vline (GtkStyle *style,
5658 GtkStateType state_type,
5661 const gchar *detail,
5666 g_return_if_fail (GTK_IS_STYLE (style));
5667 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
5668 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5670 GTK_STYLE_GET_CLASS (style)->draw_vline (style, window, state_type, area, widget, detail, y1_, y2_, x);
5675 * @style: a #GtkStyle
5676 * @window: a #GdkWindow
5677 * @state_type: a state
5678 * @shadow_type: type of shadow to draw
5679 * @area: clip rectangle or %NULL if the
5680 * output should not be clipped
5681 * @widget: the widget (may be %NULL)
5682 * @detail: a style detail (may be %NULL)
5683 * @x: x origin of the rectangle
5684 * @y: y origin of the rectangle
5685 * @width: width of the rectangle
5686 * @height: width of the rectangle
5688 * Draws a shadow around the given rectangle in @window
5689 * using the given style and state and shadow type.
5692 gtk_paint_shadow (GtkStyle *style,
5694 GtkStateType state_type,
5695 GtkShadowType shadow_type,
5698 const gchar *detail,
5704 g_return_if_fail (GTK_IS_STYLE (style));
5705 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
5706 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5708 GTK_STYLE_GET_CLASS (style)->draw_shadow (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
5712 * gtk_paint_polygon:
5713 * @style: a #GtkStyle
5714 * @window: a #GdkWindow
5715 * @state_type: a state
5716 * @shadow_type: type of shadow to draw
5717 * @area: clip rectangle, or %NULL if the
5718 * output should not be clipped
5719 * @widget: the widget (may be %NULL)
5720 * @detail: a style detail (may be %NULL)
5721 * @points: an array of #GdkPoint<!-- -->s
5722 * @npoints: length of @points
5723 * @fill: %TRUE if the polygon should be filled
5725 * Draws a polygon on @window with the given parameters.
5728 gtk_paint_polygon (GtkStyle *style,
5730 GtkStateType state_type,
5731 GtkShadowType shadow_type,
5734 const gchar *detail,
5739 g_return_if_fail (GTK_IS_STYLE (style));
5740 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_polygon != NULL);
5741 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5743 GTK_STYLE_GET_CLASS (style)->draw_polygon (style, window, state_type, shadow_type, area, widget, detail, points, npoints, fill);
5748 * @style: a #GtkStyle
5749 * @window: a #GdkWindow
5750 * @state_type: a state
5751 * @shadow_type: the type of shadow to draw
5752 * @area: clip rectangle, or %NULL if the
5753 * output should not be clipped
5754 * @widget: the widget (may be %NULL)
5755 * @detail: a style detail (may be %NULL)
5756 * @arrow_type: the type of arrow to draw
5757 * @fill: %TRUE if the arrow tip should be filled
5758 * @x: x origin of the rectangle to draw the arrow in
5759 * @y: y origin of the rectangle to draw the arrow in
5760 * @width: width of the rectangle to draw the arrow in
5761 * @height: height of the rectangle to draw the arrow in
5763 * Draws an arrow in the given rectangle on @window using the given
5764 * parameters. @arrow_type determines the direction of the arrow.
5767 gtk_paint_arrow (GtkStyle *style,
5769 GtkStateType state_type,
5770 GtkShadowType shadow_type,
5773 const gchar *detail,
5774 GtkArrowType arrow_type,
5781 g_return_if_fail (GTK_IS_STYLE (style));
5782 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
5783 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5785 GTK_STYLE_GET_CLASS (style)->draw_arrow (style, window, state_type, shadow_type, area, widget, detail, arrow_type, fill, x, y, width, height);
5789 * gtk_paint_diamond:
5790 * @style: a #GtkStyle
5791 * @window: a #GdkWindow
5792 * @state_type: a state
5793 * @shadow_type: the type of shadow to draw
5794 * @area: clip rectangle, or %NULL if the
5795 * output should not be clipped
5796 * @widget: the widget (may be %NULL)
5797 * @detail: a style detail (may be %NULL)
5798 * @x: x origin of the rectangle to draw the diamond in
5799 * @y: y origin of the rectangle to draw the diamond in
5800 * @width: width of the rectangle to draw the diamond in
5801 * @height: height of the rectangle to draw the diamond in
5803 * Draws a diamond in the given rectangle on @window using the given
5807 gtk_paint_diamond (GtkStyle *style,
5809 GtkStateType state_type,
5810 GtkShadowType shadow_type,
5813 const gchar *detail,
5819 g_return_if_fail (GTK_IS_STYLE (style));
5820 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
5821 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5823 GTK_STYLE_GET_CLASS (style)->draw_diamond (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
5828 * @style: a #GtkStyle
5829 * @window: a #GdkWindow
5830 * @state_type: a state
5831 * @area: clip rectangle, or %NULL if the
5832 * output should not be clipped
5833 * @widget: the widget (may be %NULL)
5834 * @detail: a style detail (may be %NULL)
5837 * @string: the string to draw
5839 * Draws a text string on @window with the given parameters.
5841 * Deprecated: Use gtk_paint_layout() instead.
5844 gtk_paint_string (GtkStyle *style,
5846 GtkStateType state_type,
5849 const gchar *detail,
5852 const gchar *string)
5854 g_return_if_fail (GTK_IS_STYLE (style));
5855 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_string != NULL);
5856 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5858 GTK_STYLE_GET_CLASS (style)->draw_string (style, window, state_type, area, widget, detail, x, y, string);
5863 * @style: a #GtkStyle
5864 * @window: a #GdkWindow
5865 * @state_type: a state
5866 * @shadow_type: the type of shadow to draw
5867 * @area: clip rectangle, or %NULL if the
5868 * output should not be clipped
5869 * @widget: the widget (may be %NULL)
5870 * @detail: a style detail (may be %NULL)
5871 * @x: x origin of the box
5872 * @y: y origin of the box
5873 * @width: the width of the box
5874 * @height: the height of the box
5876 * Draws a box on @window with the given parameters.
5879 gtk_paint_box (GtkStyle *style,
5881 GtkStateType state_type,
5882 GtkShadowType shadow_type,
5885 const gchar *detail,
5891 g_return_if_fail (GTK_IS_STYLE (style));
5892 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
5893 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5895 GTK_STYLE_GET_CLASS (style)->draw_box (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
5899 * gtk_paint_flat_box:
5900 * @style: a #GtkStyle
5901 * @window: a #GdkWindow
5902 * @state_type: a state
5903 * @shadow_type: the type of shadow to draw
5904 * @area: clip rectangle, or %NULL if the
5905 * output should not be clipped
5906 * @widget: the widget (may be %NULL)
5907 * @detail: a style detail (may be %NULL)
5908 * @x: x origin of the box
5909 * @y: y origin of the box
5910 * @width: the width of the box
5911 * @height: the height of the box
5913 * Draws a flat box on @window with the given parameters.
5916 gtk_paint_flat_box (GtkStyle *style,
5918 GtkStateType state_type,
5919 GtkShadowType shadow_type,
5922 const gchar *detail,
5928 g_return_if_fail (GTK_IS_STYLE (style));
5929 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
5930 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5932 GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
5937 * @style: a #GtkStyle
5938 * @window: a #GdkWindow
5939 * @state_type: a state
5940 * @shadow_type: the type of shadow to draw
5941 * @area: clip rectangle, or %NULL if the
5942 * output should not be clipped
5943 * @widget: the widget (may be %NULL)
5944 * @detail: a style detail (may be %NULL)
5945 * @x: x origin of the rectangle to draw the check in
5946 * @y: y origin of the rectangle to draw the check in
5947 * @width: the width of the rectangle to draw the check in
5948 * @height: the height of the rectangle to draw the check in
5950 * Draws a check button indicator in the given rectangle on @window with
5951 * the given parameters.
5954 gtk_paint_check (GtkStyle *style,
5956 GtkStateType state_type,
5957 GtkShadowType shadow_type,
5960 const gchar *detail,
5966 g_return_if_fail (GTK_IS_STYLE (style));
5967 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
5968 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5970 GTK_STYLE_GET_CLASS (style)->draw_check (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
5975 * @style: a #GtkStyle
5976 * @window: a #GdkWindow
5977 * @state_type: a state
5978 * @shadow_type: the type of shadow to draw
5979 * @area: clip rectangle, or %NULL if the
5980 * output should not be clipped
5981 * @widget: the widget (may be %NULL)
5982 * @detail: a style detail (may be %NULL)
5983 * @x: x origin of the rectangle to draw the option in
5984 * @y: y origin of the rectangle to draw the option in
5985 * @width: the width of the rectangle to draw the option in
5986 * @height: the height of the rectangle to draw the option in
5988 * Draws a radio button indicator in the given rectangle on @window with
5989 * the given parameters.
5992 gtk_paint_option (GtkStyle *style,
5994 GtkStateType state_type,
5995 GtkShadowType shadow_type,
5998 const gchar *detail,
6004 g_return_if_fail (GTK_IS_STYLE (style));
6005 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
6006 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6008 GTK_STYLE_GET_CLASS (style)->draw_option (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
6013 * @style: a #GtkStyle
6014 * @window: a #GdkWindow
6015 * @state_type: a state
6016 * @shadow_type: the type of shadow to draw
6017 * @area: clip rectangle, or %NULL if the
6018 * output should not be clipped
6019 * @widget: the widget (may be %NULL)
6020 * @detail: a style detail (may be %NULL)
6021 * @x: x origin of the rectangle to draw the tab in
6022 * @y: y origin of the rectangle to draw the tab in
6023 * @width: the width of the rectangle to draw the tab in
6024 * @height: the height of the rectangle to draw the tab in
6026 * Draws an option menu tab (i.e. the up and down pointing arrows)
6027 * in the given rectangle on @window using the given parameters.
6030 gtk_paint_tab (GtkStyle *style,
6032 GtkStateType state_type,
6033 GtkShadowType shadow_type,
6036 const gchar *detail,
6042 g_return_if_fail (GTK_IS_STYLE (style));
6043 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
6044 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6046 GTK_STYLE_GET_CLASS (style)->draw_tab (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
6050 * gtk_paint_shadow_gap:
6051 * @style: a #GtkStyle
6052 * @window: a #GdkWindow
6053 * @state_type: a state
6054 * @shadow_type: type of shadow to draw
6055 * @area: clip rectangle, or %NULL if the
6056 * output should not be clipped
6057 * @widget: the widget (may be %NULL)
6058 * @detail: a style detail (may be %NULL)
6059 * @x: x origin of the rectangle
6060 * @y: y origin of the rectangle
6061 * @width: width of the rectangle
6062 * @height: width of the rectangle
6063 * @gap_side: side in which to leave the gap
6064 * @gap_x: starting position of the gap
6065 * @gap_width: width of the gap
6067 * Draws a shadow around the given rectangle in @window
6068 * using the given style and state and shadow type, leaving a
6072 gtk_paint_shadow_gap (GtkStyle *style,
6074 GtkStateType state_type,
6075 GtkShadowType shadow_type,
6083 GtkPositionType gap_side,
6087 g_return_if_fail (GTK_IS_STYLE (style));
6088 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
6089 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6091 GTK_STYLE_GET_CLASS (style)->draw_shadow_gap (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, gap_side, gap_x, gap_width);
6096 * gtk_paint_box_gap:
6097 * @style: a #GtkStyle
6098 * @window: a #GdkWindow
6099 * @state_type: a state
6100 * @shadow_type: type of shadow to draw
6101 * @area: clip rectangle, or %NULL if the
6102 * output should not be clipped
6103 * @widget: the widget (may be %NULL)
6104 * @detail: a style detail (may be %NULL)
6105 * @x: x origin of the rectangle
6106 * @y: y origin of the rectangle
6107 * @width: width of the rectangle
6108 * @height: width of the rectangle
6109 * @gap_side: side in which to leave the gap
6110 * @gap_x: starting position of the gap
6111 * @gap_width: width of the gap
6113 * Draws a box in @window using the given style and state and shadow type,
6114 * leaving a gap in one side.
6117 gtk_paint_box_gap (GtkStyle *style,
6119 GtkStateType state_type,
6120 GtkShadowType shadow_type,
6128 GtkPositionType gap_side,
6132 g_return_if_fail (GTK_IS_STYLE (style));
6133 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
6134 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6136 GTK_STYLE_GET_CLASS (style)->draw_box_gap (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, gap_side, gap_x, gap_width);
6140 * gtk_paint_extension:
6141 * @style: a #GtkStyle
6142 * @window: a #GdkWindow
6143 * @state_type: a state
6144 * @shadow_type: type of shadow to draw
6145 * @area: clip rectangle, or %NULL if the
6146 * output should not be clipped
6147 * @widget: the widget (may be %NULL)
6148 * @detail: a style detail (may be %NULL)
6149 * @x: x origin of the extension
6150 * @y: y origin of the extension
6151 * @width: width of the extension
6152 * @height: width of the extension
6153 * @gap_side: the side on to which the extension is attached
6155 * Draws an extension, i.e. a notebook tab.
6158 gtk_paint_extension (GtkStyle *style,
6160 GtkStateType state_type,
6161 GtkShadowType shadow_type,
6169 GtkPositionType gap_side)
6171 g_return_if_fail (GTK_IS_STYLE (style));
6172 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
6173 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6175 GTK_STYLE_GET_CLASS (style)->draw_extension (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, gap_side);
6180 * @style: a #GtkStyle
6181 * @window: a #GdkWindow
6182 * @state_type: a state
6183 * @area: clip rectangle, or %NULL if the
6184 * output should not be clipped
6185 * @widget: the widget (may be %NULL)
6186 * @detail: a style detail (may be %NULL)
6187 * @x: the x origin of the rectangle around which to draw a focus indicator
6188 * @y: the y origin of the rectangle around which to draw a focus indicator
6189 * @width: the width of the rectangle around which to draw a focus indicator
6190 * @height: the height of the rectangle around which to draw a focus indicator
6192 * Draws a focus indicator around the given rectangle on @window using the
6196 gtk_paint_focus (GtkStyle *style,
6198 GtkStateType state_type,
6201 const gchar *detail,
6207 g_return_if_fail (GTK_IS_STYLE (style));
6208 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
6209 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6211 GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, state_type, area, widget, detail, x, y, width, height);
6215 gtk_paint_slider (GtkStyle *style,
6217 GtkStateType state_type,
6218 GtkShadowType shadow_type,
6221 const gchar *detail,
6226 GtkOrientation orientation)
6228 g_return_if_fail (GTK_IS_STYLE (style));
6229 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
6230 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6232 GTK_STYLE_GET_CLASS (style)->draw_slider (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, orientation);
6237 * @style: a #GtkStyle
6238 * @window: a #GdkWindow
6239 * @state_type: a state
6240 * @shadow_type: type of shadow to draw
6241 * @area: clip rectangle, or %NULL if the
6242 * output should not be clipped
6243 * @widget: the widget (may be %NULL)
6244 * @detail: a style detail (may be %NULL)
6245 * @x: x origin of the handle
6246 * @y: y origin of the handle
6247 * @width: with of the handle
6248 * @height: height of the handle
6249 * @orientation: the orientation of the handle
6251 * Draws a handle as used in #GtkHandleBox and #GtkPaned.
6254 gtk_paint_handle (GtkStyle *style,
6256 GtkStateType state_type,
6257 GtkShadowType shadow_type,
6260 const gchar *detail,
6265 GtkOrientation orientation)
6267 g_return_if_fail (GTK_IS_STYLE (style));
6268 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
6269 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6271 GTK_STYLE_GET_CLASS (style)->draw_handle (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, orientation);
6275 * gtk_paint_expander:
6276 * @style: a #GtkStyle
6277 * @window: a #GdkWindow
6278 * @state_type: a state
6279 * @area: clip rectangle, or %NULL if the
6280 * output should not be clipped
6281 * @widget: the widget (may be %NULL)
6282 * @detail: a style detail (may be %NULL)
6283 * @x: the x position to draw the expander at
6284 * @y: the y position to draw the expander at
6285 * @expander_style: the style to draw the expander in; determines
6286 * whether the expander is collapsed, expanded, or in an
6287 * intermediate state.
6289 * Draws an expander as used in #GtkTreeView. @x and @y specify the
6290 * center the expander. The size of the expander is determined by the
6291 * "expander-size" style property of @widget. (If widget is not
6292 * specified or doesn't have an "expander-size" property, an
6293 * unspecified default size will be used, since the caller doesn't
6294 * have sufficient information to position the expander, this is
6295 * likely not useful.) The expander is expander_size pixels tall
6296 * in the collapsed position and expander_size pixels wide in the
6297 * expanded position.
6300 gtk_paint_expander (GtkStyle *style,
6302 GtkStateType state_type,
6305 const gchar *detail,
6308 GtkExpanderStyle expander_style)
6310 g_return_if_fail (GTK_IS_STYLE (style));
6311 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
6312 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6314 GTK_STYLE_GET_CLASS (style)->draw_expander (style, window, state_type, area,
6315 widget, detail, x, y, expander_style);
6319 gtk_paint_layout (GtkStyle *style,
6321 GtkStateType state_type,
6325 const gchar *detail,
6328 PangoLayout *layout)
6330 g_return_if_fail (GTK_IS_STYLE (style));
6331 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
6332 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6334 GTK_STYLE_GET_CLASS (style)->draw_layout (style, window, state_type, use_text, area,
6335 widget, detail, x, y, layout);
6339 * gtk_paint_resize_grip:
6340 * @style: a #GtkStyle
6341 * @window: a #GdkWindow
6342 * @state_type: a state
6343 * @area: clip rectangle, or %NULL if the
6344 * output should not be clipped
6345 * @widget: the widget (may be %NULL)
6346 * @detail: a style detail (may be %NULL)
6347 * @edge: the edge in which to draw the resize grip
6348 * @x: the x origin of the rectangle in which to draw the resize grip
6349 * @y: the y origin of the rectangle in which to draw the resize grip
6350 * @width: the width of the rectangle in which to draw the resize grip
6351 * @height: the height of the rectangle in which to draw the resize grip
6353 * Draws a resize grip in the given rectangle on @window using the given
6357 gtk_paint_resize_grip (GtkStyle *style,
6359 GtkStateType state_type,
6362 const gchar *detail,
6370 g_return_if_fail (GTK_IS_STYLE (style));
6371 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
6372 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6374 GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, window, state_type,
6375 area, widget, detail,
6376 edge, x, y, width, height);
6381 * @border_: a #GtkBorder.
6382 * @returns: a copy of @border_.
6384 * Copies a #GtkBorder structure.
6387 gtk_border_copy (const GtkBorder *border)
6389 return (GtkBorder *)g_memdup (border, sizeof (GtkBorder));
6394 * @border_: a #GtkBorder.
6396 * Frees a #GtkBorder structure.
6399 gtk_border_free (GtkBorder *border)
6405 gtk_border_get_type (void)
6407 static GType our_type = 0;
6410 our_type = g_boxed_type_register_static (I_("GtkBorder"),
6411 (GBoxedCopyFunc) gtk_border_copy,
6412 (GBoxedFreeFunc) gtk_border_free);
6418 gtk_style_get_font_internal (GtkStyle *style)
6420 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
6422 if (style->private_font && style->private_font_desc)
6424 if (!style->font_desc ||
6425 !pango_font_description_equal (style->private_font_desc, style->font_desc))
6427 gdk_font_unref (style->private_font);
6428 style->private_font = NULL;
6430 if (style->private_font_desc)
6432 pango_font_description_free (style->private_font_desc);
6433 style->private_font_desc = NULL;
6438 if (!style->private_font)
6440 GdkDisplay *display;
6442 if (style->colormap)
6444 display = gdk_screen_get_display (gdk_colormap_get_screen (style->colormap));
6448 display = gdk_display_get_default ();
6449 GTK_NOTE (MULTIHEAD,
6450 g_warning ("gtk_style_get_font() should not be called on an unattached style"));
6453 if (style->font_desc)
6455 style->private_font = gdk_font_from_description_for_display (display, style->font_desc);
6456 style->private_font_desc = pango_font_description_copy (style->font_desc);
6459 if (!style->private_font)
6460 style->private_font = gdk_font_load_for_display (display, "fixed");
6462 if (!style->private_font)
6463 g_error ("Unable to load \"fixed\" font");
6466 return style->private_font;
6470 * gtk_style_get_font:
6471 * @style: a #GtkStyle
6473 * Gets the #GdkFont to use for the given style. This is
6474 * meant only as a replacement for direct access to @style->font
6475 * and should not be used in new code. New code should
6476 * use @style->font_desc instead.
6478 * Return value: the #GdkFont for the style. This font is owned
6479 * by the style; if you want to keep around a copy, you must
6480 * call gdk_font_ref().
6483 gtk_style_get_font (GtkStyle *style)
6485 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
6487 return gtk_style_get_font_internal (style);
6491 * gtk_style_set_font:
6492 * @style: a #GtkStyle.
6493 * @font: a #GdkFont, or %NULL to use the #GdkFont corresponding
6494 * to style->font_desc.
6496 * Sets the #GdkFont to use for a given style. This is
6497 * meant only as a replacement for direct access to style->font
6498 * and should not be used in new code. New code should
6499 * use style->font_desc instead.
6502 gtk_style_set_font (GtkStyle *style,
6507 g_return_if_fail (GTK_IS_STYLE (style));
6509 old_font = style->private_font;
6511 style->private_font = font;
6513 gdk_font_ref (font);
6516 gdk_font_unref (old_font);
6518 if (style->private_font_desc)
6520 pango_font_description_free (style->private_font_desc);
6521 style->private_font_desc = NULL;
6525 typedef struct _CursorInfo CursorInfo;
6531 GdkGC *secondary_gc;
6535 style_unrealize_cursor_gcs (GtkStyle *style)
6539 cursor_info = g_object_get_data (G_OBJECT (style), "gtk-style-cursor-info");
6542 if (cursor_info->primary_gc)
6543 gtk_gc_release (cursor_info->primary_gc);
6545 if (cursor_info->secondary_gc)
6546 gtk_gc_release (cursor_info->secondary_gc);
6548 g_free (cursor_info);
6549 g_object_set_data (G_OBJECT (style), I_("gtk-style-cursor-info"), NULL);
6554 make_cursor_gc (GtkWidget *widget,
6555 const gchar *property_name,
6556 const GdkColor *fallback)
6558 GdkGCValues gc_values;
6559 GdkGCValuesMask gc_values_mask;
6560 GdkColor *cursor_color;
6562 gtk_widget_style_get (widget, property_name, &cursor_color, NULL);
6564 gc_values_mask = GDK_GC_FOREGROUND;
6567 gc_values.foreground = *cursor_color;
6568 gdk_color_free (cursor_color);
6571 gc_values.foreground = *fallback;
6573 gdk_rgb_find_color (widget->style->colormap, &gc_values.foreground);
6574 return gtk_gc_get (widget->style->depth, widget->style->colormap, &gc_values, gc_values_mask);
6578 get_insertion_cursor_gc (GtkWidget *widget,
6579 gboolean is_primary)
6581 CursorInfo *cursor_info;
6583 cursor_info = g_object_get_data (G_OBJECT (widget->style), "gtk-style-cursor-info");
6586 cursor_info = g_new (CursorInfo, 1);
6587 g_object_set_data (G_OBJECT (widget->style), I_("gtk-style-cursor-info"), cursor_info);
6588 cursor_info->primary_gc = NULL;
6589 cursor_info->secondary_gc = NULL;
6590 cursor_info->for_type = G_TYPE_INVALID;
6593 /* We have to keep track of the type because gtk_widget_style_get()
6594 * can return different results when called on the same property and
6595 * same style but for different widgets. :-(. That is,
6596 * GtkEntry::cursor-color = "red" in a style will modify the cursor
6597 * color for entries but not for text view.
6599 if (cursor_info->for_type != G_OBJECT_TYPE (widget))
6601 cursor_info->for_type = G_OBJECT_TYPE (widget);
6602 if (cursor_info->primary_gc)
6604 gtk_gc_release (cursor_info->primary_gc);
6605 cursor_info->primary_gc = NULL;
6607 if (cursor_info->secondary_gc)
6609 gtk_gc_release (cursor_info->secondary_gc);
6610 cursor_info->secondary_gc = NULL;
6616 if (!cursor_info->primary_gc)
6617 cursor_info->primary_gc = make_cursor_gc (widget,
6619 &widget->style->black);
6621 return cursor_info->primary_gc;
6625 static const GdkColor gray = { 0, 0x8888, 0x8888, 0x8888 };
6627 if (!cursor_info->secondary_gc)
6628 cursor_info->secondary_gc = make_cursor_gc (widget,
6629 "secondary-cursor-color",
6632 return cursor_info->secondary_gc;
6637 draw_insertion_cursor (GtkWidget *widget,
6638 GdkDrawable *drawable,
6640 GdkRectangle *location,
6641 GtkTextDirection direction,
6642 gboolean draw_arrow)
6648 gfloat cursor_aspect_ratio;
6651 g_return_if_fail (direction != GTK_TEXT_DIR_NONE);
6653 /* When changing the shape or size of the cursor here,
6654 * propagate the changes to gtktextview.c:text_window_invalidate_cursors().
6657 gtk_widget_style_get (widget, "cursor-aspect-ratio", &cursor_aspect_ratio, NULL);
6659 stem_width = location->height * cursor_aspect_ratio + 1;
6660 arrow_width = stem_width + 1;
6662 /* put (stem_width % 2) on the proper side of the cursor */
6663 if (direction == GTK_TEXT_DIR_LTR)
6664 offset = stem_width / 2;
6666 offset = stem_width - stem_width / 2;
6668 for (i = 0; i < stem_width; i++)
6669 gdk_draw_line (drawable, gc,
6670 location->x + i - offset, location->y,
6671 location->x + i - offset, location->y + location->height - 1);
6675 if (direction == GTK_TEXT_DIR_RTL)
6677 x = location->x - offset - 1;
6678 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
6680 for (i = 0; i < arrow_width; i++)
6682 gdk_draw_line (drawable, gc,
6684 x, y + 2 * arrow_width - i - 1);
6688 else if (direction == GTK_TEXT_DIR_LTR)
6690 x = location->x + stem_width - offset;
6691 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
6693 for (i = 0; i < arrow_width; i++)
6695 gdk_draw_line (drawable, gc,
6697 x, y + 2 * arrow_width - i - 1);
6705 * gtk_draw_insertion_cursor:
6706 * @widget: a #GtkWidget
6707 * @drawable: a #GdkDrawable
6708 * @area: rectangle to which the output is clipped, or %NULL if the
6709 * output should not be clipped
6710 * @location: location where to draw the cursor (@location->width is ignored)
6711 * @is_primary: if the cursor should be the primary cursor color.
6712 * @direction: whether the cursor is left-to-right or
6713 * right-to-left. Should never be #GTK_TEXT_DIR_NONE
6714 * @draw_arrow: %TRUE to draw a directional arrow on the
6715 * cursor. Should be %FALSE unless the cursor is split.
6717 * Draws a text caret on @drawable at @location. This is not a style function
6718 * but merely a convenience function for drawing the standard cursor shape.
6723 gtk_draw_insertion_cursor (GtkWidget *widget,
6724 GdkDrawable *drawable,
6726 GdkRectangle *location,
6727 gboolean is_primary,
6728 GtkTextDirection direction,
6729 gboolean draw_arrow)
6733 g_return_if_fail (GTK_IS_WIDGET (widget));
6734 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
6735 g_return_if_fail (location != NULL);
6736 g_return_if_fail (direction != GTK_TEXT_DIR_NONE);
6738 gc = get_insertion_cursor_gc (widget, is_primary);
6740 gdk_gc_set_clip_rectangle (gc, area);
6742 draw_insertion_cursor (widget, drawable, gc,
6743 location, direction, draw_arrow);
6746 gdk_gc_set_clip_rectangle (gc, NULL);
6749 #define __GTK_STYLE_C__
6750 #include "gtkaliasdef.c"