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() */
41 #define LIGHTNESS_MULT 1.3
42 #define DARKNESS_MULT 0.7
44 /* --- typedefs & structures --- */
51 /* --- prototypes --- */
52 static void gtk_style_init (GtkStyle *style);
53 static void gtk_style_class_init (GtkStyleClass *klass);
54 static void gtk_style_finalize (GObject *object);
55 static void gtk_style_realize (GtkStyle *style,
56 GdkColormap *colormap);
57 static void gtk_style_real_realize (GtkStyle *style);
58 static void gtk_style_real_unrealize (GtkStyle *style);
59 static void gtk_style_real_copy (GtkStyle *style,
61 static void gtk_style_real_set_background (GtkStyle *style,
63 GtkStateType state_type);
64 static GtkStyle *gtk_style_real_clone (GtkStyle *style);
65 static void gtk_style_real_init_from_rc (GtkStyle *style,
66 GtkRcStyle *rc_style);
67 static GdkPixbuf *gtk_default_render_icon (GtkStyle *style,
68 const GtkIconSource *source,
69 GtkTextDirection direction,
74 static void gtk_default_draw_hline (GtkStyle *style,
76 GtkStateType state_type,
83 static void gtk_default_draw_vline (GtkStyle *style,
85 GtkStateType state_type,
92 static void gtk_default_draw_shadow (GtkStyle *style,
94 GtkStateType state_type,
95 GtkShadowType shadow_type,
103 static void gtk_default_draw_polygon (GtkStyle *style,
105 GtkStateType state_type,
106 GtkShadowType shadow_type,
113 static void gtk_default_draw_arrow (GtkStyle *style,
115 GtkStateType state_type,
116 GtkShadowType shadow_type,
120 GtkArrowType arrow_type,
126 static void gtk_default_draw_diamond (GtkStyle *style,
128 GtkStateType state_type,
129 GtkShadowType shadow_type,
137 static void gtk_default_draw_string (GtkStyle *style,
139 GtkStateType state_type,
145 const gchar *string);
146 static void gtk_default_draw_box (GtkStyle *style,
148 GtkStateType state_type,
149 GtkShadowType shadow_type,
157 static void gtk_default_draw_flat_box (GtkStyle *style,
159 GtkStateType state_type,
160 GtkShadowType shadow_type,
168 static void gtk_default_draw_check (GtkStyle *style,
170 GtkStateType state_type,
171 GtkShadowType shadow_type,
179 static void gtk_default_draw_option (GtkStyle *style,
181 GtkStateType state_type,
182 GtkShadowType shadow_type,
190 static void gtk_default_draw_tab (GtkStyle *style,
192 GtkStateType state_type,
193 GtkShadowType shadow_type,
201 static void gtk_default_draw_shadow_gap (GtkStyle *style,
203 GtkStateType state_type,
204 GtkShadowType shadow_type,
212 GtkPositionType gap_side,
215 static void gtk_default_draw_box_gap (GtkStyle *style,
217 GtkStateType state_type,
218 GtkShadowType shadow_type,
226 GtkPositionType gap_side,
229 static void gtk_default_draw_extension (GtkStyle *style,
231 GtkStateType state_type,
232 GtkShadowType shadow_type,
240 GtkPositionType gap_side);
241 static void gtk_default_draw_focus (GtkStyle *style,
243 GtkStateType state_type,
251 static void gtk_default_draw_slider (GtkStyle *style,
253 GtkStateType state_type,
254 GtkShadowType shadow_type,
262 GtkOrientation orientation);
263 static void gtk_default_draw_handle (GtkStyle *style,
265 GtkStateType state_type,
266 GtkShadowType shadow_type,
274 GtkOrientation orientation);
275 static void gtk_default_draw_expander (GtkStyle *style,
277 GtkStateType state_type,
283 GtkExpanderStyle expander_style);
284 static void gtk_default_draw_layout (GtkStyle *style,
286 GtkStateType state_type,
293 PangoLayout *layout);
294 static void gtk_default_draw_resize_grip (GtkStyle *style,
296 GtkStateType state_type,
306 static void gtk_style_shade (GdkColor *a,
309 static void rgb_to_hls (gdouble *r,
312 static void hls_to_rgb (gdouble *h,
316 static void style_unrealize_cursor_gcs (GtkStyle *style);
318 static GdkFont *gtk_style_get_font_internal (GtkStyle *style);
321 * Data for default check and radio buttons
324 static const GtkRequisition default_option_indicator_size = { 7, 13 };
325 static const GtkBorder default_option_indicator_spacing = { 7, 5, 2, 2 };
327 #define INDICATOR_PART_SIZE 13
337 CHECK_INCONSISTENT_TEXT,
344 RADIO_INCONSISTENT_AA,
345 RADIO_INCONSISTENT_TEXT
349 * Extracted from check-13.png, width=13, height=13
351 static const guchar check_black_bits[] = {
352 0x00,0x00,0xfe,0x0f,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,
353 0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00};
354 static const guchar check_dark_bits[] = {
355 0xff,0x1f,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,
356 0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00};
357 static const guchar check_mid_bits[] = {
358 0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,
359 0x08,0x00,0x08,0x00,0x08,0x00,0x08,0xfc,0x0f,0x00,0x00,0x00,0x00};
360 static const guchar check_light_bits[] = {
361 0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,
362 0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0xfe,0x1f,0x00,0x00};
363 static const guchar check_text_bits[] = {
364 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x03,0x80,0x01,0x80,0x00,0x58,
365 0x00,0x60,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
366 static const guchar check_aa_bits[] = {
367 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x58,0x00,0xa0,
368 0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
369 static const guchar check_base_bits[] = {
370 0x00,0x00,0x00,0x00,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc,
371 0x07,0xfc,0x07,0xfc,0x07,0xfc,0x07,0x00,0x00,0x00,0x00,0x00,0x00};
374 * Extracted from check-13-inconsistent.png, width=13, height=13
376 static const guchar check_inconsistent_text_bits[] = {
377 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x03,0xf8,
378 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
381 * check_inconsistent_aa_bits is currently not used, since it is all zeros.
383 static const guchar check_inconsistent_aa_bits[] = {
384 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
385 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
389 * Extracted from radio-13.png, width=13, height=13
391 static const guchar radio_black_bits[] = {
392 0x00,0x00,0xf0,0x01,0x0c,0x02,0x04,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,
393 0x00,0x02,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x08};
394 static const guchar radio_dark_bits[] = {
395 0xf0,0x00,0x0c,0x02,0x02,0x04,0x02,0x04,0x01,0x08,0x01,0x08,0x01,0x08,0x01,
396 0x08,0x00,0x08,0x02,0x04,0x0c,0x06,0xf0,0x01,0x00,0x00,0x00,0x00};
397 static const guchar radio_mid_bits[] = {
398 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
399 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
400 static const guchar radio_light_bits[] = {
401 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,
402 0x10,0x00,0x10,0x00,0x08,0x00,0x08,0x00,0x06,0xe0,0x01,0x00,0x00};
403 static const guchar radio_text_bits[] = {
404 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0xf0,0x01,0xf0,0x01,0xf0,
405 0x01,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
408 * radio_aa_bits is currently not used, since it is all zeros.
410 static const guchar radio_aa_bits[] = {
411 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
412 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
414 static const guchar radio_base_bits[] = {
415 0x00,0x00,0x00,0x00,0xf0,0x01,0xf8,0x03,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc,
416 0x07,0xfc,0x07,0xf8,0x03,0xf0,0x01,0x00,0x00,0x00,0x00,0x00,0x00};
419 * Extracted from radio-13.png, width=13, height=13
421 static const guchar radio_inconsistent_text_bits[] = {
422 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x03,0x00,
423 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
424 static const guchar radio_inconsistent_aa_bits[] = {
425 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x03,0x00,0x00,0xf8,
426 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
430 GList *bmap_list; /* list of GdkBitmap */
431 } indicator_parts[] = {
432 { check_aa_bits, NULL },
433 { check_base_bits, NULL },
434 { check_black_bits, NULL },
435 { check_dark_bits, NULL },
436 { check_light_bits, NULL },
437 { check_mid_bits, NULL },
438 { check_text_bits, NULL },
439 { check_inconsistent_text_bits, NULL },
440 { radio_base_bits, NULL },
441 { radio_black_bits, NULL },
442 { radio_dark_bits, NULL },
443 { radio_light_bits, NULL },
444 { radio_mid_bits, NULL },
445 { radio_text_bits, NULL },
446 { radio_inconsistent_aa_bits, NULL },
447 { radio_inconsistent_text_bits, NULL },
450 /* --- variables --- */
451 static const GdkColor gtk_default_normal_fg = { 0, 0, 0, 0 };
452 static const GdkColor gtk_default_active_fg = { 0, 0, 0, 0 };
453 static const GdkColor gtk_default_prelight_fg = { 0, 0, 0, 0 };
454 static const GdkColor gtk_default_selected_fg = { 0, 0xffff, 0xffff, 0xffff };
455 static const GdkColor gtk_default_insensitive_fg = { 0, 0x7530, 0x7530, 0x7530 };
457 static const GdkColor gtk_default_normal_bg = { 0, 0xdcdc, 0xdada, 0xd5d5 };
458 static const GdkColor gtk_default_active_bg = { 0, 0xbaba, 0xb5b5, 0xabab };
459 static const GdkColor gtk_default_prelight_bg = { 0, 0xeeee, 0xebeb, 0xe7e7 };
460 static const GdkColor gtk_default_selected_bg = { 0, 0x4b4b, 0x6969, 0x8383 };
461 static const GdkColor gtk_default_insensitive_bg = { 0, 0xdcdc, 0xdada, 0xd5d5 };
462 static const GdkColor gtk_default_selected_base = { 0, 0x4b4b, 0x6969, 0x8383 };
463 static const GdkColor gtk_default_active_base = { 0, 0x8080, 0x7d7d, 0x7474 };
465 static gpointer parent_class = NULL;
467 /* --- signals --- */
468 static guint realize_signal = 0;
469 static guint unrealize_signal = 0;
471 /* --- functions --- */
473 gtk_style_get_type (void)
475 static GType style_type = 0;
479 static const GTypeInfo style_info =
481 sizeof (GtkStyleClass),
482 (GBaseInitFunc) NULL,
483 (GBaseFinalizeFunc) NULL,
484 (GClassInitFunc) gtk_style_class_init,
485 NULL, /* class_finalize */
486 NULL, /* class_data */
489 (GInstanceInitFunc) gtk_style_init,
492 style_type = g_type_register_static (G_TYPE_OBJECT, "GtkStyle",
500 * _gtk_style_init_for_settings:
501 * @style: a #GtkStyle
502 * @settings: a #GtkSettings
504 * Initializes the font description in @style according to the default
505 * font name of @settings. This is called for gtk_style_new() with
506 * the settings for the default screen (if any); if we are creating
507 * a style for a particular screen, we then call it again in a
508 * location where we know the correct settings.
509 * The reason for this is that gtk_rc_style_create_style() doesn't
510 * take the screen for an argument.
513 _gtk_style_init_for_settings (GtkStyle *style,
514 GtkSettings *settings)
516 const gchar *font_name = _gtk_rc_context_get_default_font_name (settings);
518 if (style->font_desc)
519 pango_font_description_free (style->font_desc);
521 style->font_desc = pango_font_description_from_string (font_name);
523 if (!pango_font_description_get_family (style->font_desc))
525 g_warning ("Default font does not have a family set");
526 pango_font_description_set_family (style->font_desc, "Sans");
528 if (pango_font_description_get_size (style->font_desc) <= 0)
530 g_warning ("Default font does not have a positive size");
531 pango_font_description_set_size (style->font_desc, 10 * PANGO_SCALE);
536 gtk_style_init (GtkStyle *style)
540 GtkSettings *settings = gtk_settings_get_default ();
543 _gtk_style_init_for_settings (style, settings);
545 style->font_desc = pango_font_description_from_string ("Sans 10");
547 style->attach_count = 0;
548 style->colormap = NULL;
551 style->black.red = 0;
552 style->black.green = 0;
553 style->black.blue = 0;
555 style->white.red = 65535;
556 style->white.green = 65535;
557 style->white.blue = 65535;
559 style->black_gc = NULL;
560 style->white_gc = NULL;
562 style->fg[GTK_STATE_NORMAL] = gtk_default_normal_fg;
563 style->fg[GTK_STATE_ACTIVE] = gtk_default_active_fg;
564 style->fg[GTK_STATE_PRELIGHT] = gtk_default_prelight_fg;
565 style->fg[GTK_STATE_SELECTED] = gtk_default_selected_fg;
566 style->fg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
568 style->bg[GTK_STATE_NORMAL] = gtk_default_normal_bg;
569 style->bg[GTK_STATE_ACTIVE] = gtk_default_active_bg;
570 style->bg[GTK_STATE_PRELIGHT] = gtk_default_prelight_bg;
571 style->bg[GTK_STATE_SELECTED] = gtk_default_selected_bg;
572 style->bg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_bg;
574 for (i = 0; i < 4; i++)
576 style->text[i] = style->fg[i];
577 style->base[i] = style->white;
580 style->base[GTK_STATE_SELECTED] = gtk_default_selected_base;
581 style->text[GTK_STATE_SELECTED] = style->white;
582 style->base[GTK_STATE_ACTIVE] = gtk_default_active_base;
583 style->text[GTK_STATE_ACTIVE] = style->white;
584 style->base[GTK_STATE_INSENSITIVE] = gtk_default_prelight_bg;
585 style->text[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
587 for (i = 0; i < 5; i++)
588 style->bg_pixmap[i] = NULL;
590 style->rc_style = NULL;
592 for (i = 0; i < 5; i++)
594 style->fg_gc[i] = NULL;
595 style->bg_gc[i] = NULL;
596 style->light_gc[i] = NULL;
597 style->dark_gc[i] = NULL;
598 style->mid_gc[i] = NULL;
599 style->text_gc[i] = NULL;
600 style->base_gc[i] = NULL;
601 style->text_aa_gc[i] = NULL;
604 style->xthickness = 2;
605 style->ythickness = 2;
607 style->property_cache = NULL;
611 gtk_style_class_init (GtkStyleClass *klass)
613 GObjectClass *object_class = G_OBJECT_CLASS (klass);
615 parent_class = g_type_class_peek_parent (klass);
617 object_class->finalize = gtk_style_finalize;
619 klass->clone = gtk_style_real_clone;
620 klass->copy = gtk_style_real_copy;
621 klass->init_from_rc = gtk_style_real_init_from_rc;
622 klass->realize = gtk_style_real_realize;
623 klass->unrealize = gtk_style_real_unrealize;
624 klass->set_background = gtk_style_real_set_background;
625 klass->render_icon = gtk_default_render_icon;
627 klass->draw_hline = gtk_default_draw_hline;
628 klass->draw_vline = gtk_default_draw_vline;
629 klass->draw_shadow = gtk_default_draw_shadow;
630 klass->draw_polygon = gtk_default_draw_polygon;
631 klass->draw_arrow = gtk_default_draw_arrow;
632 klass->draw_diamond = gtk_default_draw_diamond;
633 klass->draw_string = gtk_default_draw_string;
634 klass->draw_box = gtk_default_draw_box;
635 klass->draw_flat_box = gtk_default_draw_flat_box;
636 klass->draw_check = gtk_default_draw_check;
637 klass->draw_option = gtk_default_draw_option;
638 klass->draw_tab = gtk_default_draw_tab;
639 klass->draw_shadow_gap = gtk_default_draw_shadow_gap;
640 klass->draw_box_gap = gtk_default_draw_box_gap;
641 klass->draw_extension = gtk_default_draw_extension;
642 klass->draw_focus = gtk_default_draw_focus;
643 klass->draw_slider = gtk_default_draw_slider;
644 klass->draw_handle = gtk_default_draw_handle;
645 klass->draw_expander = gtk_default_draw_expander;
646 klass->draw_layout = gtk_default_draw_layout;
647 klass->draw_resize_grip = gtk_default_draw_resize_grip;
652 * @style: the object which received the signal
654 * Emitted when the style has been initialized for a particular
655 * colormap and depth. Connecting to this signal is probably seldom
656 * useful since most of the time applications and widgets only
657 * deal with styles that have been already realized.
661 realize_signal = g_signal_new ("realize",
662 G_TYPE_FROM_CLASS (object_class),
664 G_STRUCT_OFFSET (GtkStyleClass, realize),
666 _gtk_marshal_VOID__VOID,
669 * GtkStyle::unrealize:
670 * @style: the object which received the signal
672 * Emitted when the aspects of the style specific to a particular colormap
673 * and depth are being cleaned up. A connection to this signal can be useful
674 * if a widget wants to cache objects like a #GdkGC as object data on #GtkStyle.
675 * This signal provides a convenient place to free such cached objects.
679 unrealize_signal = g_signal_new ("unrealize",
680 G_TYPE_FROM_CLASS (object_class),
682 G_STRUCT_OFFSET (GtkStyleClass, unrealize),
684 _gtk_marshal_VOID__VOID,
689 clear_property_cache (GtkStyle *style)
691 if (style->property_cache)
695 for (i = 0; i < style->property_cache->len; i++)
697 PropertyValue *node = &g_array_index (style->property_cache, PropertyValue, i);
699 g_param_spec_unref (node->pspec);
700 g_value_unset (&node->value);
702 g_array_free (style->property_cache, TRUE);
703 style->property_cache = NULL;
708 gtk_style_finalize (GObject *object)
710 GtkStyle *style = GTK_STYLE (object);
712 g_return_if_fail (style->attach_count == 0);
714 clear_property_cache (style);
718 if (style->styles->data != style)
719 g_slist_remove (style->styles, style);
722 GSList *tmp_list = style->styles->next;
726 GTK_STYLE (tmp_list->data)->styles = style->styles->next;
727 tmp_list = tmp_list->next;
729 g_slist_free_1 (style->styles);
733 if (style->icon_factories)
735 GSList *tmp_list = style->icon_factories;
739 g_object_unref (tmp_list->data);
740 tmp_list = tmp_list->next;
743 g_slist_free (style->icon_factories);
746 pango_font_description_free (style->font_desc);
748 if (style->private_font)
749 gdk_font_unref (style->private_font);
751 if (style->private_font_desc)
752 pango_font_description_free (style->private_font_desc);
755 gtk_rc_style_unref (style->rc_style);
757 G_OBJECT_CLASS (parent_class)->finalize (object);
762 gtk_style_copy (GtkStyle *style)
766 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
768 new_style = GTK_STYLE_GET_CLASS (style)->clone (style);
769 GTK_STYLE_GET_CLASS (style)->copy (new_style, style);
775 gtk_style_duplicate (GtkStyle *style)
779 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
781 new_style = gtk_style_copy (style);
783 style->styles = g_slist_append (style->styles, new_style);
784 new_style->styles = style->styles;
791 * @returns: a new #GtkStyle.
793 * Creates a new #GtkStyle.
800 style = g_object_new (GTK_TYPE_STYLE, NULL);
807 * @style: a #GtkStyle.
808 * @window: a #GdkWindow.
809 * @returns: Either @style, or a newly-created #GtkStyle.
810 * If the style is newly created, the style parameter
811 * will be dereferenced, and the new style will have
812 * a reference count belonging to the caller.
814 * Attaches a style to a window; this process allocates the
815 * colors and creates the GC's for the style - it specializes
816 * it to a particular visual and colormap. The process may
817 * involve the creation of a new style if the style has already
818 * been attached to a window with a different style and colormap.
821 * FIXME: The sequence -
822 * create a style => s1
823 * attach s1 to v1, c1 => s1
824 * attach s1 to v2, c2 => s2
825 * detach s1 from v1, c1
826 * attach s1 to v2, c2 => s3
827 * results in two separate, unlinked styles s2 and s3 which
828 * are identical and could be shared. To fix this, we would
829 * want to never remove a style from the list of linked
830 * styles as long as as it has a reference count. However, the
831 * disadvantage of doing it this way means that we would need two
832 * passes through the linked list when attaching (one to check for
833 * matching styles, one to look for empty unattached styles - but
834 * it will almost never be longer than 2 elements.
837 gtk_style_attach (GtkStyle *style,
841 GtkStyle *new_style = NULL;
842 GdkColormap *colormap;
844 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
845 g_return_val_if_fail (window != NULL, NULL);
847 colormap = gdk_drawable_get_colormap (window);
850 style->styles = g_slist_append (NULL, style);
852 styles = style->styles;
855 new_style = styles->data;
857 if (new_style->attach_count == 0)
859 gtk_style_realize (new_style, colormap);
862 else if (new_style->colormap == colormap)
866 styles = styles->next;
871 new_style = gtk_style_duplicate (style);
872 if (gdk_colormap_get_screen (style->colormap) != gdk_colormap_get_screen (colormap) &&
873 new_style->private_font)
875 gdk_font_unref (new_style->private_font);
876 new_style->private_font = NULL;
878 gtk_style_realize (new_style, colormap);
881 /* A style gets a refcount from being attached */
882 if (new_style->attach_count == 0)
883 g_object_ref (new_style);
885 /* Another refcount belongs to the parent */
886 if (style != new_style)
888 g_object_unref (style);
889 g_object_ref (new_style);
892 new_style->attach_count++;
898 gtk_style_detach (GtkStyle *style)
900 g_return_if_fail (GTK_IS_STYLE (style));
902 style->attach_count -= 1;
903 if (style->attach_count == 0)
905 g_signal_emit (style, unrealize_signal, 0);
907 g_object_unref (style->colormap);
908 style->colormap = NULL;
910 if (style->private_font_desc)
912 if (style->private_font)
914 gdk_font_unref (style->private_font);
915 style->private_font = NULL;
918 pango_font_description_free (style->private_font_desc);
919 style->private_font_desc = NULL;
922 g_object_unref (style);
928 * @style: a #GtkStyle.
931 * Deprecated equivalent of g_object_ref().
934 gtk_style_ref (GtkStyle *style)
936 return (GtkStyle *) g_object_ref (style);
941 * @style: a #GtkStyle.
943 * Deprecated equivalent of g_object_unref().
946 gtk_style_unref (GtkStyle *style)
948 g_object_unref (style);
952 gtk_style_realize (GtkStyle *style,
953 GdkColormap *colormap)
955 g_return_if_fail (GTK_IS_STYLE (style));
956 g_return_if_fail (GDK_IS_COLORMAP (colormap));
958 style->colormap = g_object_ref (colormap);
959 style->depth = gdk_colormap_get_visual (colormap)->depth;
961 g_signal_emit (style, realize_signal, 0);
965 gtk_style_lookup_icon_set (GtkStyle *style,
966 const char *stock_id)
970 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
971 g_return_val_if_fail (stock_id != NULL, NULL);
973 iter = style->icon_factories;
976 GtkIconSet *icon_set = gtk_icon_factory_lookup (GTK_ICON_FACTORY (iter->data),
981 iter = g_slist_next (iter);
984 return gtk_icon_factory_lookup_default (stock_id);
989 * @style: a #GtkStyle
990 * @window: a #GdkWindow
991 * @state_type: a state
992 * @x1: the starting x coordinate
993 * @x2: the ending x coordinate
994 * @y: the y coordinate
996 * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @window
997 * using the given style and state.
999 * Deprecated: Use gtk_paint_hline() instead.
1002 gtk_draw_hline (GtkStyle *style,
1004 GtkStateType state_type,
1009 g_return_if_fail (GTK_IS_STYLE (style));
1010 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
1012 GTK_STYLE_GET_CLASS (style)->draw_hline (style, window, state_type, NULL, NULL, NULL, x1, x2, y);
1018 * @style: a #GtkStyle
1019 * @window: a #GdkWindow
1020 * @state_type: a state
1021 * @y1_: the starting y coordinate
1022 * @y2_: the ending y coordinate
1023 * @x: the x coordinate
1025 * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @window
1026 * using the given style and state.
1028 * Deprecated: Use gtk_paint_vline() instead.
1031 gtk_draw_vline (GtkStyle *style,
1033 GtkStateType state_type,
1038 g_return_if_fail (GTK_IS_STYLE (style));
1039 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
1041 GTK_STYLE_GET_CLASS (style)->draw_vline (style, window, state_type, NULL, NULL, NULL, y1_, y2_, x);
1046 * @style: a #GtkStyle
1047 * @window: a #GdkWindow
1048 * @state_type: a state
1049 * @shadow_type: type of shadow to draw
1050 * @x: x origin of the rectangle
1051 * @y: y origin of the rectangle
1052 * @width: width of the rectangle
1053 * @height: width of the rectangle
1055 * Draws a shadow around the given rectangle in @window
1056 * using the given style and state and shadow type.
1058 * Deprecated: Use gtk_paint_shadow() instead.
1061 gtk_draw_shadow (GtkStyle *style,
1063 GtkStateType state_type,
1064 GtkShadowType shadow_type,
1070 g_return_if_fail (GTK_IS_STYLE (style));
1071 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
1073 GTK_STYLE_GET_CLASS (style)->draw_shadow (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1078 * @style: a #GtkStyle
1079 * @window: a #GdkWindow
1080 * @state_type: a state
1081 * @shadow_type: type of shadow to draw
1082 * @points: an array of #GdkPoint<!-- -->s
1083 * @npoints: length of @points
1084 * @fill: %TRUE if the polygon should be filled
1086 * Draws a polygon on @window with the given parameters.
1088 * Deprecated: Use gtk_paint_polygon() instead.
1091 gtk_draw_polygon (GtkStyle *style,
1093 GtkStateType state_type,
1094 GtkShadowType shadow_type,
1099 g_return_if_fail (GTK_IS_STYLE (style));
1100 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_polygon != NULL);
1102 GTK_STYLE_GET_CLASS (style)->draw_polygon (style, window, state_type, shadow_type, NULL, NULL, NULL, points, npoints, fill);
1107 * @style: a #GtkStyle
1108 * @window: a #GdkWindow
1109 * @state_type: a state
1110 * @shadow_type: the type of shadow to draw
1111 * @arrow_type: the type of arrow to draw
1112 * @fill: %TRUE if the arrow tip should be filled
1113 * @x: x origin of the rectangle to draw the arrow in
1114 * @y: y origin of the rectangle to draw the arrow in
1115 * @width: width of the rectangle to draw the arrow in
1116 * @height: height of the rectangle to draw the arrow in
1118 * Draws an arrow in the given rectangle on @window using the given
1119 * parameters. @arrow_type determines the direction of the arrow.
1121 * Deprecated: Use gtk_paint_arrow() instead.
1124 gtk_draw_arrow (GtkStyle *style,
1126 GtkStateType state_type,
1127 GtkShadowType shadow_type,
1128 GtkArrowType arrow_type,
1135 g_return_if_fail (GTK_IS_STYLE (style));
1136 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
1138 GTK_STYLE_GET_CLASS (style)->draw_arrow (style, window, state_type, shadow_type, NULL, NULL, NULL, arrow_type, fill, x, y, width, height);
1143 * @style: a #GtkStyle
1144 * @window: a #GdkWindow
1145 * @state_type: a state
1146 * @shadow_type: the type of shadow to draw
1147 * @x: x origin of the rectangle to draw the diamond in
1148 * @y: y origin of the rectangle to draw the diamond in
1149 * @width: width of the rectangle to draw the diamond in
1150 * @height: height of the rectangle to draw the diamond in
1152 * Draws a diamond in the given rectangle on @window using the given
1155 * Deprecated: Use gtk_paint_diamond() instead.
1158 gtk_draw_diamond (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_diamond != NULL);
1170 GTK_STYLE_GET_CLASS (style)->draw_diamond (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
1180 * @string: the string to draw
1182 * Draws a text string on @window with the given parameters.
1184 * Deprecated: Use gtk_paint_layout() instead.
1187 gtk_draw_string (GtkStyle *style,
1189 GtkStateType state_type,
1192 const gchar *string)
1194 g_return_if_fail (GTK_IS_STYLE (style));
1195 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_string != NULL);
1197 GTK_STYLE_GET_CLASS (style)->draw_string (style, window, state_type, NULL, NULL, NULL, x, y, string);
1202 * @style: a #GtkStyle
1203 * @window: a #GdkWindow
1204 * @state_type: a state
1205 * @shadow_type: the type of shadow to draw
1206 * @x: x origin of the box
1207 * @y: y origin of the box
1208 * @width: the width of the box
1209 * @height: the height of the box
1211 * Draws a box on @window with the given parameters.
1213 * Deprecated: Use gtk_paint_box() instead.
1216 gtk_draw_box (GtkStyle *style,
1218 GtkStateType state_type,
1219 GtkShadowType shadow_type,
1225 g_return_if_fail (GTK_IS_STYLE (style));
1226 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
1228 GTK_STYLE_GET_CLASS (style)->draw_box (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1232 * gtk_draw_flat_box:
1233 * @style: a #GtkStyle
1234 * @window: a #GdkWindow
1235 * @state_type: a state
1236 * @shadow_type: the type of shadow to draw
1237 * @x: x origin of the box
1238 * @y: y origin of the box
1239 * @width: the width of the box
1240 * @height: the height of the box
1242 * Draws a flat box on @window with the given parameters.
1244 * Deprecated: Use gtk_paint_flat_box() instead.
1247 gtk_draw_flat_box (GtkStyle *style,
1249 GtkStateType state_type,
1250 GtkShadowType shadow_type,
1256 g_return_if_fail (GTK_IS_STYLE (style));
1257 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
1259 GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1264 * @style: a #GtkStyle
1265 * @window: a #GdkWindow
1266 * @state_type: a state
1267 * @shadow_type: the type of shadow to draw
1268 * @x: x origin of the rectangle to draw the check in
1269 * @y: y origin of the rectangle to draw the check in
1270 * @width: the width of the rectangle to draw the check in
1271 * @height: the height of the rectangle to draw the check in
1273 * Draws a check button indicator in the given rectangle on @window with
1274 * the given parameters.
1276 * Deprecated: Use gtk_paint_check() instead.
1279 gtk_draw_check (GtkStyle *style,
1281 GtkStateType state_type,
1282 GtkShadowType shadow_type,
1288 g_return_if_fail (GTK_IS_STYLE (style));
1289 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
1291 GTK_STYLE_GET_CLASS (style)->draw_check (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1296 * @style: a #GtkStyle
1297 * @window: a #GdkWindow
1298 * @state_type: a state
1299 * @shadow_type: the type of shadow to draw
1300 * @x: x origin of the rectangle to draw the option in
1301 * @y: y origin of the rectangle to draw the option in
1302 * @width: the width of the rectangle to draw the option in
1303 * @height: the height of the rectangle to draw the option in
1305 * Draws a radio button indicator in the given rectangle on @window with
1306 * the given parameters.
1308 * Deprecated: Use gtk_paint_option() instead.
1311 gtk_draw_option (GtkStyle *style,
1313 GtkStateType state_type,
1314 GtkShadowType shadow_type,
1320 g_return_if_fail (GTK_IS_STYLE (style));
1321 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
1323 GTK_STYLE_GET_CLASS (style)->draw_option (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1328 * @style: a #GtkStyle
1329 * @window: a #GdkWindow
1330 * @state_type: a state
1331 * @shadow_type: the type of shadow to draw
1332 * @x: x origin of the rectangle to draw the tab in
1333 * @y: y origin of the rectangle to draw the tab in
1334 * @width: the width of the rectangle to draw the tab in
1335 * @height: the height of the rectangle to draw the tab in
1337 * Draws an option menu tab (i.e. the up and down pointing arrows)
1338 * in the given rectangle on @window using the given parameters.
1340 * Deprecated: Use gtk_paint_tab() instead.
1343 gtk_draw_tab (GtkStyle *style,
1345 GtkStateType state_type,
1346 GtkShadowType shadow_type,
1352 g_return_if_fail (GTK_IS_STYLE (style));
1353 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
1355 GTK_STYLE_GET_CLASS (style)->draw_tab (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1359 * gtk_draw_shadow_gap:
1360 * @style: a #GtkStyle
1361 * @window: a #GdkWindow
1362 * @state_type: a state
1363 * @shadow_type: type of shadow to draw
1364 * @x: x origin of the rectangle
1365 * @y: y origin of the rectangle
1366 * @width: width of the rectangle
1367 * @height: width of the rectangle
1368 * @gap_side: side in which to leave the gap
1369 * @gap_x: starting position of the gap
1370 * @gap_width: width of the gap
1372 * Draws a shadow around the given rectangle in @window
1373 * using the given style and state and shadow type, leaving a
1376 * Deprecated: Use gtk_paint_shadow_gap() instead.
1379 gtk_draw_shadow_gap (GtkStyle *style,
1381 GtkStateType state_type,
1382 GtkShadowType shadow_type,
1387 GtkPositionType gap_side,
1391 g_return_if_fail (GTK_IS_STYLE (style));
1392 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
1394 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);
1399 * @style: a #GtkStyle
1400 * @window: a #GdkWindow
1401 * @state_type: a state
1402 * @shadow_type: type of shadow to draw
1403 * @x: x origin of the rectangle
1404 * @y: y origin of the rectangle
1405 * @width: width of the rectangle
1406 * @height: width of the rectangle
1407 * @gap_side: side in which to leave the gap
1408 * @gap_x: starting position of the gap
1409 * @gap_width: width of the gap
1411 * Draws a box in @window using the given style and state and shadow type,
1412 * leaving a gap in one side.
1414 * Deprecated: Use gtk_paint_box_gap() instead.
1417 gtk_draw_box_gap (GtkStyle *style,
1419 GtkStateType state_type,
1420 GtkShadowType shadow_type,
1425 GtkPositionType gap_side,
1429 g_return_if_fail (GTK_IS_STYLE (style));
1430 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
1432 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);
1436 * gtk_draw_extension:
1437 * @style: a #GtkStyle
1438 * @window: a #GdkWindow
1439 * @state_type: a state
1440 * @shadow_type: type of shadow to draw
1441 * @x: x origin of the extension
1442 * @y: y origin of the extension
1443 * @width: width of the extension
1444 * @height: width of the extension
1445 * @gap_side: the side on to which the extension is attached
1447 * Draws an extension, i.e. a notebook tab.
1449 * Deprecated: Use gtk_paint_extension() instead.
1452 gtk_draw_extension (GtkStyle *style,
1454 GtkStateType state_type,
1455 GtkShadowType shadow_type,
1460 GtkPositionType gap_side)
1462 g_return_if_fail (GTK_IS_STYLE (style));
1463 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
1465 GTK_STYLE_GET_CLASS (style)->draw_extension (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, gap_side);
1470 * @style: a #GtkStyle
1471 * @window: a #GdkWindow
1472 * @x: the x origin of the rectangle around which to draw a focus indicator
1473 * @y: the y origin of the rectangle around which to draw a focus indicator
1474 * @width: the width of the rectangle around which to draw a focus indicator
1475 * @height: the height of the rectangle around which to draw a focus indicator
1477 * Draws a focus indicator around the given rectangle on @window using the
1480 * Deprecated: Use gtk_paint_focus() instead.
1483 gtk_draw_focus (GtkStyle *style,
1490 g_return_if_fail (GTK_IS_STYLE (style));
1491 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
1493 GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, GTK_STATE_NORMAL, NULL, NULL, NULL, x, y, width, height);
1497 gtk_draw_slider (GtkStyle *style,
1499 GtkStateType state_type,
1500 GtkShadowType shadow_type,
1505 GtkOrientation orientation)
1507 g_return_if_fail (GTK_IS_STYLE (style));
1508 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
1510 GTK_STYLE_GET_CLASS (style)->draw_slider (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, orientation);
1515 * @style: a #GtkStyle
1516 * @window: a #GdkWindow
1517 * @state_type: a state
1518 * @shadow_type: type of shadow to draw
1519 * @x: x origin of the handle
1520 * @y: y origin of the handle
1521 * @width: with of the handle
1522 * @height: height of the handle
1523 * @orientation: the orientation of the handle
1525 * Draws a handle as used in #GtkHandleBox and #GtkPaned.
1527 * Deprecated: Use gtk_paint_handle() instead.
1530 gtk_draw_handle (GtkStyle *style,
1532 GtkStateType state_type,
1533 GtkShadowType shadow_type,
1538 GtkOrientation orientation)
1540 g_return_if_fail (GTK_IS_STYLE (style));
1541 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
1543 GTK_STYLE_GET_CLASS (style)->draw_handle (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, orientation);
1547 * gtk_draw_expander:
1548 * @style: a #GtkStyle
1549 * @window: a #GdkWindow
1550 * @state_type: a state
1551 * @x: the x position to draw the expander at
1552 * @y: the y position to draw the expander at
1553 * @expander_style: the style to draw the expander in
1555 * Draws an expander as used in #GtkTreeView.
1557 * Deprecated: Use gtk_paint_expander() instead.
1560 gtk_draw_expander (GtkStyle *style,
1562 GtkStateType state_type,
1565 GtkExpanderStyle expander_style)
1567 g_return_if_fail (GTK_IS_STYLE (style));
1568 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
1570 GTK_STYLE_GET_CLASS (style)->draw_expander (style, window, state_type,
1572 x, y, expander_style);
1576 gtk_draw_layout (GtkStyle *style,
1578 GtkStateType state_type,
1582 PangoLayout *layout)
1584 g_return_if_fail (GTK_IS_STYLE (style));
1585 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
1587 GTK_STYLE_GET_CLASS (style)->draw_layout (style, window, state_type, use_text,
1593 * gtk_draw_resize_grip:
1594 * @style: a #GtkStyle
1595 * @window: a #GdkWindow
1596 * @state_type: a state
1597 * @edge: the edge in which to draw the resize grip
1598 * @x: the x origin of the rectangle in which to draw the resize grip
1599 * @y: the y origin of the rectangle in which to draw the resize grip
1600 * @width: the width of the rectangle in which to draw the resize grip
1601 * @height: the height of the rectangle in which to draw the resize grip
1603 * Draws a resize grip in the given rectangle on @window using the given
1606 * Deprecated: Use gtk_paint_resize_grip() instead.
1609 gtk_draw_resize_grip (GtkStyle *style,
1611 GtkStateType state_type,
1618 g_return_if_fail (GTK_IS_STYLE (style));
1619 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
1621 GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, window, state_type,
1624 x, y, width, height);
1629 * gtk_style_set_background:
1630 * @style: a #GtkStyle
1631 * @window: a #GdkWindow
1632 * @state_type: a state
1634 * Sets the background of @window to the background color or pixmap
1635 * specified by @style for the given state.
1638 gtk_style_set_background (GtkStyle *style,
1640 GtkStateType state_type)
1642 g_return_if_fail (GTK_IS_STYLE (style));
1643 g_return_if_fail (window != NULL);
1645 GTK_STYLE_GET_CLASS (style)->set_background (style, window, state_type);
1648 /* Default functions */
1650 gtk_style_real_clone (GtkStyle *style)
1652 return GTK_STYLE (g_object_new (G_OBJECT_TYPE (style), NULL));
1656 gtk_style_real_copy (GtkStyle *style,
1661 for (i = 0; i < 5; i++)
1663 style->fg[i] = src->fg[i];
1664 style->bg[i] = src->bg[i];
1665 style->text[i] = src->text[i];
1666 style->base[i] = src->base[i];
1668 style->bg_pixmap[i] = src->bg_pixmap[i];
1671 if (style->private_font)
1672 gdk_font_unref (style->private_font);
1673 style->private_font = src->private_font;
1674 if (style->private_font)
1675 gdk_font_ref (style->private_font);
1677 if (style->font_desc)
1678 pango_font_description_free (style->font_desc);
1680 style->font_desc = pango_font_description_copy (src->font_desc);
1682 style->font_desc = NULL;
1684 style->xthickness = src->xthickness;
1685 style->ythickness = src->ythickness;
1687 if (style->rc_style)
1688 gtk_rc_style_unref (style->rc_style);
1689 style->rc_style = src->rc_style;
1691 gtk_rc_style_ref (src->rc_style);
1693 /* don't copy, just clear cache */
1694 clear_property_cache (style);
1698 gtk_style_real_init_from_rc (GtkStyle *style,
1699 GtkRcStyle *rc_style)
1703 /* cache _should_ be still empty */
1704 clear_property_cache (style);
1706 if (rc_style->font_desc)
1707 pango_font_description_merge (style->font_desc, rc_style->font_desc, TRUE);
1709 for (i = 0; i < 5; i++)
1711 if (rc_style->color_flags[i] & GTK_RC_FG)
1712 style->fg[i] = rc_style->fg[i];
1713 if (rc_style->color_flags[i] & GTK_RC_BG)
1714 style->bg[i] = rc_style->bg[i];
1715 if (rc_style->color_flags[i] & GTK_RC_TEXT)
1716 style->text[i] = rc_style->text[i];
1717 if (rc_style->color_flags[i] & GTK_RC_BASE)
1718 style->base[i] = rc_style->base[i];
1721 if (rc_style->xthickness >= 0)
1722 style->xthickness = rc_style->xthickness;
1723 if (rc_style->ythickness >= 0)
1724 style->ythickness = rc_style->ythickness;
1726 if (rc_style->icon_factories)
1730 style->icon_factories = g_slist_copy (rc_style->icon_factories);
1732 iter = style->icon_factories;
1733 while (iter != NULL)
1735 g_object_ref (iter->data);
1736 iter = g_slist_next (iter);
1742 style_property_values_cmp (gconstpointer bsearch_node1,
1743 gconstpointer bsearch_node2)
1745 const PropertyValue *val1 = bsearch_node1;
1746 const PropertyValue *val2 = bsearch_node2;
1748 if (val1->widget_type == val2->widget_type)
1749 return val1->pspec < val2->pspec ? -1 : val1->pspec == val2->pspec ? 0 : 1;
1751 return val1->widget_type < val2->widget_type ? -1 : 1;
1755 _gtk_style_peek_property_value (GtkStyle *style,
1758 GtkRcPropertyParser parser)
1760 PropertyValue *pcache, key = { 0, NULL, { 0, } };
1761 const GtkRcProperty *rcprop = NULL;
1764 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1765 g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL);
1766 g_return_val_if_fail (g_type_is_a (pspec->owner_type, GTK_TYPE_WIDGET), NULL);
1767 g_return_val_if_fail (g_type_is_a (widget_type, pspec->owner_type), NULL);
1769 key.widget_type = widget_type;
1772 /* need value cache array */
1773 if (!style->property_cache)
1774 style->property_cache = g_array_new (FALSE, FALSE, sizeof (PropertyValue));
1777 pcache = bsearch (&key,
1778 style->property_cache->data, style->property_cache->len,
1779 sizeof (PropertyValue), style_property_values_cmp);
1781 return &pcache->value;
1785 while (i < style->property_cache->len &&
1786 style_property_values_cmp (&key, &g_array_index (style->property_cache, PropertyValue, i)) >= 0)
1789 g_array_insert_val (style->property_cache, i, key);
1790 pcache = &g_array_index (style->property_cache, PropertyValue, i);
1792 /* cache miss, initialize value type, then set contents */
1793 g_param_spec_ref (pcache->pspec);
1794 g_value_init (&pcache->value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1796 /* value provided by rc style? */
1797 if (style->rc_style)
1799 GQuark prop_quark = g_quark_from_string (pspec->name);
1803 rcprop = _gtk_rc_style_lookup_rc_property (style->rc_style,
1804 g_type_qname (widget_type),
1808 widget_type = g_type_parent (widget_type);
1810 while (g_type_is_a (widget_type, pspec->owner_type));
1813 /* when supplied by rc style, we need to convert */
1814 if (rcprop && !_gtk_settings_parse_convert (parser, &rcprop->value,
1815 pspec, &pcache->value))
1817 gchar *contents = g_strdup_value_contents (&rcprop->value);
1819 g_message ("%s: failed to retrieve property `%s::%s' of type `%s' from rc file value \"%s\" of type `%s'",
1821 g_type_name (pspec->owner_type), pspec->name,
1822 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1824 G_VALUE_TYPE_NAME (&rcprop->value));
1826 rcprop = NULL; /* needs default */
1829 /* not supplied by rc style (or conversion failed), revert to default */
1831 g_param_value_set_default (pspec, &pcache->value);
1833 return &pcache->value;
1837 load_bg_image (GdkColormap *colormap,
1839 const gchar *filename)
1841 if (strcmp (filename, "<parent>") == 0)
1842 return (GdkPixmap*) GDK_PARENT_RELATIVE;
1845 return gdk_pixmap_colormap_create_from_xpm (NULL, colormap, NULL,
1852 gtk_style_real_realize (GtkStyle *style)
1854 GdkGCValues gc_values;
1855 GdkGCValuesMask gc_values_mask;
1859 for (i = 0; i < 5; i++)
1861 gtk_style_shade (&style->bg[i], &style->light[i], LIGHTNESS_MULT);
1862 gtk_style_shade (&style->bg[i], &style->dark[i], DARKNESS_MULT);
1864 style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
1865 style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
1866 style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
1868 style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
1869 style->text_aa[i].green = (style->text[i].green + style->base[i].green) / 2;
1870 style->text_aa[i].blue = (style->text[i].blue + style->base[i].blue) / 2;
1873 style->black.red = 0x0000;
1874 style->black.green = 0x0000;
1875 style->black.blue = 0x0000;
1876 gdk_colormap_alloc_color (style->colormap, &style->black, FALSE, TRUE);
1878 style->white.red = 0xffff;
1879 style->white.green = 0xffff;
1880 style->white.blue = 0xffff;
1881 gdk_colormap_alloc_color (style->colormap, &style->white, FALSE, TRUE);
1883 gc_values_mask = GDK_GC_FOREGROUND | GDK_GC_BACKGROUND;
1885 gc_values.foreground = style->black;
1886 gc_values.background = style->white;
1887 style->black_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1889 gc_values.foreground = style->white;
1890 gc_values.background = style->black;
1891 style->white_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1893 gc_values_mask = GDK_GC_FOREGROUND;
1895 for (i = 0; i < 5; i++)
1897 if (style->rc_style && style->rc_style->bg_pixmap_name[i])
1898 style->bg_pixmap[i] = load_bg_image (style->colormap,
1900 style->rc_style->bg_pixmap_name[i]);
1902 if (!gdk_colormap_alloc_color (style->colormap, &style->fg[i], FALSE, TRUE))
1903 g_warning ("unable to allocate color: ( %d %d %d )",
1904 style->fg[i].red, style->fg[i].green, style->fg[i].blue);
1905 if (!gdk_colormap_alloc_color (style->colormap, &style->bg[i], FALSE, TRUE))
1906 g_warning ("unable to allocate color: ( %d %d %d )",
1907 style->bg[i].red, style->bg[i].green, style->bg[i].blue);
1908 if (!gdk_colormap_alloc_color (style->colormap, &style->light[i], FALSE, TRUE))
1909 g_warning ("unable to allocate color: ( %d %d %d )",
1910 style->light[i].red, style->light[i].green, style->light[i].blue);
1911 if (!gdk_colormap_alloc_color (style->colormap, &style->dark[i], FALSE, TRUE))
1912 g_warning ("unable to allocate color: ( %d %d %d )",
1913 style->dark[i].red, style->dark[i].green, style->dark[i].blue);
1914 if (!gdk_colormap_alloc_color (style->colormap, &style->mid[i], FALSE, TRUE))
1915 g_warning ("unable to allocate color: ( %d %d %d )",
1916 style->mid[i].red, style->mid[i].green, style->mid[i].blue);
1917 if (!gdk_colormap_alloc_color (style->colormap, &style->text[i], FALSE, TRUE))
1918 g_warning ("unable to allocate color: ( %d %d %d )",
1919 style->text[i].red, style->text[i].green, style->text[i].blue);
1920 if (!gdk_colormap_alloc_color (style->colormap, &style->base[i], FALSE, TRUE))
1921 g_warning ("unable to allocate color: ( %d %d %d )",
1922 style->base[i].red, style->base[i].green, style->base[i].blue);
1923 if (!gdk_colormap_alloc_color (style->colormap, &style->text_aa[i], FALSE, TRUE))
1924 g_warning ("unable to allocate color: ( %d %d %d )",
1925 style->text_aa[i].red, style->text_aa[i].green, style->text_aa[i].blue);
1927 gc_values.foreground = style->fg[i];
1928 style->fg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1930 gc_values.foreground = style->bg[i];
1931 style->bg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1933 gc_values.foreground = style->light[i];
1934 style->light_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1936 gc_values.foreground = style->dark[i];
1937 style->dark_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1939 gc_values.foreground = style->mid[i];
1940 style->mid_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1942 gc_values.foreground = style->text[i];
1943 style->text_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1945 gc_values.foreground = style->base[i];
1946 style->base_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1948 gc_values.foreground = style->text_aa[i];
1949 style->text_aa_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1954 gtk_style_real_unrealize (GtkStyle *style)
1958 gtk_gc_release (style->black_gc);
1959 gtk_gc_release (style->white_gc);
1961 for (i = 0; i < 5; i++)
1963 gtk_gc_release (style->fg_gc[i]);
1964 gtk_gc_release (style->bg_gc[i]);
1965 gtk_gc_release (style->light_gc[i]);
1966 gtk_gc_release (style->dark_gc[i]);
1967 gtk_gc_release (style->mid_gc[i]);
1968 gtk_gc_release (style->text_gc[i]);
1969 gtk_gc_release (style->base_gc[i]);
1970 gtk_gc_release (style->text_aa_gc[i]);
1972 if (style->bg_pixmap[i] && style->bg_pixmap[i] != (GdkPixmap*) GDK_PARENT_RELATIVE)
1973 g_object_unref (style->bg_pixmap[i]);
1976 gdk_colormap_free_colors (style->colormap, style->fg, 5);
1977 gdk_colormap_free_colors (style->colormap, style->bg, 5);
1978 gdk_colormap_free_colors (style->colormap, style->light, 5);
1979 gdk_colormap_free_colors (style->colormap, style->dark, 5);
1980 gdk_colormap_free_colors (style->colormap, style->mid, 5);
1981 gdk_colormap_free_colors (style->colormap, style->text, 5);
1982 gdk_colormap_free_colors (style->colormap, style->base, 5);
1983 gdk_colormap_free_colors (style->colormap, style->text_aa, 5);
1985 style_unrealize_cursor_gcs (style);
1989 gtk_style_real_set_background (GtkStyle *style,
1991 GtkStateType state_type)
1994 gint parent_relative;
1996 if (style->bg_pixmap[state_type])
1998 if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
2001 parent_relative = TRUE;
2005 pixmap = style->bg_pixmap[state_type];
2006 parent_relative = FALSE;
2009 gdk_window_set_back_pixmap (window, pixmap, parent_relative);
2012 gdk_window_set_background (window, &style->bg[state_type]);
2016 * gtk_style_render_icon:
2017 * @style: a #GtkStyle
2018 * @source: the #GtkIconSource specifying the icon to render
2019 * @direction: a text direction
2021 * @size: the size to render the icon at. A size of (GtkIconSize)-1
2022 * means render at the size of the source and don't scale.
2023 * @widget: the widget
2024 * @detail: a style detail
2025 * @returns: a newly-created #GdkPixbuf containing the rendered icon
2027 * Renders the icon specified by @source at the given @size
2028 * according to the given parameters and returns the result in a
2032 gtk_style_render_icon (GtkStyle *style,
2033 const GtkIconSource *source,
2034 GtkTextDirection direction,
2038 const gchar *detail)
2042 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
2043 g_return_val_if_fail (GTK_STYLE_GET_CLASS (style)->render_icon != NULL, NULL);
2045 pixbuf = GTK_STYLE_GET_CLASS (style)->render_icon (style, source, direction, state,
2046 size, widget, detail);
2048 g_return_val_if_fail (pixbuf != NULL, NULL);
2053 /* Default functions */
2055 gtk_style_apply_default_background (GtkStyle *style,
2058 GtkStateType state_type,
2065 GdkRectangle new_rect, old_rect;
2071 old_rect.width = width;
2072 old_rect.height = height;
2074 if (!gdk_rectangle_intersect (area, &old_rect, &new_rect))
2081 new_rect.width = width;
2082 new_rect.height = height;
2085 if (!style->bg_pixmap[state_type] ||
2086 GDK_IS_PIXMAP (window) ||
2087 (!set_bg && style->bg_pixmap[state_type] != (GdkPixmap*) GDK_PARENT_RELATIVE))
2089 GdkGC *gc = style->bg_gc[state_type];
2091 if (style->bg_pixmap[state_type])
2093 gdk_gc_set_fill (gc, GDK_TILED);
2094 gdk_gc_set_tile (gc, style->bg_pixmap[state_type]);
2097 gdk_draw_rectangle (window, gc, TRUE,
2098 new_rect.x, new_rect.y, new_rect.width, new_rect.height);
2099 if (style->bg_pixmap[state_type])
2100 gdk_gc_set_fill (gc, GDK_SOLID);
2106 if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
2107 gdk_window_set_back_pixmap (window, NULL, TRUE);
2109 gdk_window_set_back_pixmap (window, style->bg_pixmap[state_type], FALSE);
2112 gdk_window_clear_area (window,
2113 new_rect.x, new_rect.y,
2114 new_rect.width, new_rect.height);
2119 scale_or_ref (GdkPixbuf *src,
2123 if (width == gdk_pixbuf_get_width (src) &&
2124 height == gdk_pixbuf_get_height (src))
2126 return g_object_ref (src);
2130 return gdk_pixbuf_scale_simple (src,
2132 GDK_INTERP_BILINEAR);
2137 gtk_default_render_icon (GtkStyle *style,
2138 const GtkIconSource *source,
2139 GtkTextDirection direction,
2143 const gchar *detail)
2149 GdkPixbuf *base_pixbuf;
2151 GtkSettings *settings;
2153 /* Oddly, style can be NULL in this function, because
2154 * GtkIconSet can be used without a style and if so
2155 * it uses this function.
2158 base_pixbuf = gtk_icon_source_get_pixbuf (source);
2160 g_return_val_if_fail (base_pixbuf != NULL, NULL);
2162 if (widget && gtk_widget_has_screen (widget))
2164 screen = gtk_widget_get_screen (widget);
2165 settings = gtk_settings_get_for_screen (screen);
2167 else if (style && style->colormap)
2169 screen = gdk_colormap_get_screen (style->colormap);
2170 settings = gtk_settings_get_for_screen (screen);
2174 settings = gtk_settings_get_default ();
2175 GTK_NOTE (MULTIHEAD,
2176 g_warning ("Using the default screen for gtk_default_render_icon()"));
2180 if (size != (GtkIconSize) -1 && !gtk_icon_size_lookup_for_settings (settings, size, &width, &height))
2182 g_warning (G_STRLOC ": invalid icon size '%d'", size);
2186 /* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
2189 if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source))
2190 scaled = scale_or_ref (base_pixbuf, width, height);
2192 scaled = g_object_ref (base_pixbuf);
2194 /* If the state was wildcarded, then generate a state. */
2195 if (gtk_icon_source_get_state_wildcarded (source))
2197 if (state == GTK_STATE_INSENSITIVE)
2199 stated = gdk_pixbuf_copy (scaled);
2201 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
2204 g_object_unref (scaled);
2206 else if (state == GTK_STATE_PRELIGHT)
2208 stated = gdk_pixbuf_copy (scaled);
2210 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
2213 g_object_unref (scaled);
2227 sanitize_size (GdkWindow *window,
2231 if ((*width == -1) && (*height == -1))
2232 gdk_drawable_get_size (window, width, height);
2233 else if (*width == -1)
2234 gdk_drawable_get_size (window, width, NULL);
2235 else if (*height == -1)
2236 gdk_drawable_get_size (window, NULL, height);
2240 get_indicator_for_screen (GdkDrawable *drawable,
2244 GdkScreen *screen = gdk_drawable_get_screen (drawable);
2248 tmp_list = indicator_parts[part].bmap_list;
2251 bitmap = tmp_list->data;
2253 if (gdk_drawable_get_screen (bitmap) == screen)
2256 tmp_list = tmp_list->next;
2259 bitmap = gdk_bitmap_create_from_data (drawable,
2260 (gchar *)indicator_parts[part].bits,
2261 INDICATOR_PART_SIZE, INDICATOR_PART_SIZE);
2262 indicator_parts[part].bmap_list = g_list_prepend (indicator_parts[part].bmap_list, bitmap);
2268 draw_part (GdkDrawable *drawable,
2276 gdk_gc_set_clip_rectangle (gc, area);
2278 gdk_gc_set_ts_origin (gc, x, y);
2279 gdk_gc_set_stipple (gc, get_indicator_for_screen (drawable, part));
2280 gdk_gc_set_fill (gc, GDK_STIPPLED);
2282 gdk_draw_rectangle (drawable, gc, TRUE, x, y, INDICATOR_PART_SIZE, INDICATOR_PART_SIZE);
2284 gdk_gc_set_fill (gc, GDK_SOLID);
2287 gdk_gc_set_clip_rectangle (gc, NULL);
2291 gtk_default_draw_hline (GtkStyle *style,
2293 GtkStateType state_type,
2296 const gchar *detail,
2301 gint thickness_light;
2302 gint thickness_dark;
2305 g_return_if_fail (GTK_IS_STYLE (style));
2306 g_return_if_fail (window != NULL);
2308 thickness_light = style->ythickness / 2;
2309 thickness_dark = style->ythickness - thickness_light;
2313 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2314 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2317 if (detail && !strcmp (detail, "label"))
2319 if (state_type == GTK_STATE_INSENSITIVE)
2320 gdk_draw_line (window, style->white_gc, x1 + 1, y + 1, x2 + 1, y + 1);
2321 gdk_draw_line (window, style->fg_gc[state_type], x1, y, x2, y);
2325 for (i = 0; i < thickness_dark; i++)
2327 gdk_draw_line (window, style->dark_gc[state_type], x1, y + i, x2 - i - 1, y + i);
2328 gdk_draw_line (window, style->light_gc[state_type], x2 - i, y + i, x2, y + i);
2331 y += thickness_dark;
2332 for (i = 0; i < thickness_light; i++)
2334 gdk_draw_line (window, style->dark_gc[state_type], x1, y + i, x1 + thickness_light - i - 1, y + i);
2335 gdk_draw_line (window, style->light_gc[state_type], x1 + thickness_light - i, y + i, x2, y + i);
2341 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2342 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2348 gtk_default_draw_vline (GtkStyle *style,
2350 GtkStateType state_type,
2353 const gchar *detail,
2358 gint thickness_light;
2359 gint thickness_dark;
2362 g_return_if_fail (GTK_IS_STYLE (style));
2363 g_return_if_fail (window != NULL);
2365 thickness_light = style->xthickness / 2;
2366 thickness_dark = style->xthickness - thickness_light;
2370 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2371 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2373 for (i = 0; i < thickness_dark; i++)
2375 gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i, y2 - i - 1);
2376 gdk_draw_line (window, style->light_gc[state_type], x + i, y2 - i, x + i, y2);
2379 x += thickness_dark;
2380 for (i = 0; i < thickness_light; i++)
2382 gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i, y1 + thickness_light - i - 1);
2383 gdk_draw_line (window, style->light_gc[state_type], x + i, y1 + thickness_light - i, x + i, y2);
2387 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2388 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2393 draw_thin_shadow (GtkStyle *style,
2404 sanitize_size (window, &width, &height);
2406 gc1 = style->light_gc[state];
2407 gc2 = style->dark_gc[state];
2411 gdk_gc_set_clip_rectangle (gc1, area);
2412 gdk_gc_set_clip_rectangle (gc2, area);
2415 gdk_draw_line (window, gc1,
2416 x, y + height - 1, x + width - 1, y + height - 1);
2417 gdk_draw_line (window, gc1,
2418 x + width - 1, y, x + width - 1, y + height - 1);
2420 gdk_draw_line (window, gc2,
2421 x, y, x + width - 2, y);
2422 gdk_draw_line (window, gc2,
2423 x, y, x, y + height - 2);
2427 gdk_gc_set_clip_rectangle (gc1, NULL);
2428 gdk_gc_set_clip_rectangle (gc2, NULL);
2433 draw_spinbutton_shadow (GtkStyle *style,
2436 GtkTextDirection direction,
2443 sanitize_size (window, &width, &height);
2447 gdk_gc_set_clip_rectangle (style->black_gc, area);
2448 gdk_gc_set_clip_rectangle (style->bg_gc[state], area);
2449 gdk_gc_set_clip_rectangle (style->dark_gc[state], area);
2450 gdk_gc_set_clip_rectangle (style->light_gc[state], area);
2453 if (direction == GTK_TEXT_DIR_LTR)
2455 gdk_draw_line (window, style->dark_gc[state],
2456 x, y, x + width - 1, y);
2457 gdk_draw_line (window, style->black_gc,
2458 x, y + 1, x + width - 2, y + 1);
2459 gdk_draw_line (window, style->black_gc,
2460 x + width - 2, y + 2, x + width - 2, y + height - 3);
2461 gdk_draw_line (window, style->light_gc[state],
2462 x + width - 1, y + 1, x + width - 1, y + height - 2);
2463 gdk_draw_line (window, style->light_gc[state],
2464 x, y + height - 1, x + width - 1, y + height - 1);
2465 gdk_draw_line (window, style->bg_gc[state],
2466 x, y + height - 2, x + width - 2, y + height - 2);
2467 gdk_draw_line (window, style->black_gc,
2468 x, y + 2, x, y + height - 3);
2472 gdk_draw_line (window, style->dark_gc[state],
2473 x, y, x + width - 1, y);
2474 gdk_draw_line (window, style->dark_gc[state],
2475 x, y + 1, x, y + height - 1);
2476 gdk_draw_line (window, style->black_gc,
2477 x + 1, y + 1, x + width - 1, y + 1);
2478 gdk_draw_line (window, style->black_gc,
2479 x + 1, y + 2, x + 1, y + height - 2);
2480 gdk_draw_line (window, style->black_gc,
2481 x + width - 1, y + 2, x + width - 1, y + height - 3);
2482 gdk_draw_line (window, style->light_gc[state],
2483 x + 1, y + height - 1, x + width - 1, y + height - 1);
2484 gdk_draw_line (window, style->bg_gc[state],
2485 x + 2, y + height - 2, x + width - 1, y + height - 2);
2490 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
2491 gdk_gc_set_clip_rectangle (style->bg_gc[state], NULL);
2492 gdk_gc_set_clip_rectangle (style->dark_gc[state], NULL);
2493 gdk_gc_set_clip_rectangle (style->light_gc[state], NULL);
2498 draw_menu_shadow (GtkStyle *style,
2507 if (style->ythickness > 0)
2509 if (style->ythickness > 1)
2511 gdk_draw_line (window, style->dark_gc[state],
2512 x + 1, y + height - 2, x + width - 2, y + height - 2);
2513 gdk_draw_line (window, style->black_gc,
2514 x, y + height - 1, x + width - 1, y + height - 1);
2518 gdk_draw_line (window, style->dark_gc[state],
2519 x + 1, y + height - 1, x + width - 1, y + height - 1);
2523 if (style->xthickness > 0)
2525 if (style->xthickness > 1)
2527 gdk_draw_line (window, style->dark_gc[state],
2528 x + width - 2, y + 1, x + width - 2, y + height - 2);
2530 gdk_draw_line (window, style->black_gc,
2531 x + width - 1, y, x + width - 1, y + height - 1);
2535 gdk_draw_line (window, style->dark_gc[state],
2536 x + width - 1, y + 1, x + width - 1, y + height - 1);
2540 /* Light around top and left */
2542 if (style->ythickness > 0)
2543 gdk_draw_line (window, style->black_gc,
2544 x, y, x + width - 2, y);
2545 if (style->xthickness > 0)
2546 gdk_draw_line (window, style->black_gc,
2547 x, y, x, y + height - 2);
2549 if (style->ythickness > 1)
2550 gdk_draw_line (window, style->light_gc[state],
2551 x + 1, y + 1, x + width - 3, y + 1);
2552 if (style->xthickness > 1)
2553 gdk_draw_line (window, style->light_gc[state],
2554 x + 1, y + 1, x + 1, y + height - 3);
2558 gtk_default_draw_shadow (GtkStyle *style,
2560 GtkStateType state_type,
2561 GtkShadowType shadow_type,
2564 const gchar *detail,
2572 gint thickness_light;
2573 gint thickness_dark;
2576 g_return_if_fail (GTK_IS_STYLE (style));
2577 g_return_if_fail (window != NULL);
2579 if (shadow_type == GTK_SHADOW_IN)
2581 if (detail && (strcmp (detail, "buttondefault") == 0))
2583 sanitize_size (window, &width, &height);
2585 gdk_draw_rectangle (window, style->black_gc, FALSE,
2586 x, y, width - 1, height - 1);
2590 if (detail && strcmp (detail, "trough") == 0)
2592 draw_thin_shadow (style, window, state_type, area,
2593 x, y, width, height);
2596 if (widget && GTK_IS_SPIN_BUTTON (widget) &&
2597 detail && strcmp (detail, "spinbutton") == 0)
2599 draw_spinbutton_shadow (style, window, state_type,
2600 gtk_widget_get_direction (widget), area, x, y, width, height);
2606 if (shadow_type == GTK_SHADOW_OUT && detail && strcmp (detail, "menu") == 0)
2608 draw_menu_shadow (style, window, state_type, area, x, y, width, height);
2612 sanitize_size (window, &width, &height);
2614 switch (shadow_type)
2616 case GTK_SHADOW_NONE:
2619 case GTK_SHADOW_ETCHED_IN:
2620 gc1 = style->light_gc[state_type];
2621 gc2 = style->dark_gc[state_type];
2623 case GTK_SHADOW_OUT:
2624 case GTK_SHADOW_ETCHED_OUT:
2625 gc1 = style->dark_gc[state_type];
2626 gc2 = style->light_gc[state_type];
2632 gdk_gc_set_clip_rectangle (gc1, area);
2633 gdk_gc_set_clip_rectangle (gc2, area);
2634 if (shadow_type == GTK_SHADOW_IN ||
2635 shadow_type == GTK_SHADOW_OUT)
2637 gdk_gc_set_clip_rectangle (style->black_gc, area);
2638 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
2642 switch (shadow_type)
2644 case GTK_SHADOW_NONE:
2648 /* Light around right and bottom edge */
2650 if (style->ythickness > 0)
2651 gdk_draw_line (window, gc1,
2652 x, y + height - 1, x + width - 1, y + height - 1);
2653 if (style->xthickness > 0)
2654 gdk_draw_line (window, gc1,
2655 x + width - 1, y, x + width - 1, y + height - 1);
2657 if (style->ythickness > 1)
2658 gdk_draw_line (window, style->bg_gc[state_type],
2659 x + 1, y + height - 2, x + width - 2, y + height - 2);
2660 if (style->xthickness > 1)
2661 gdk_draw_line (window, style->bg_gc[state_type],
2662 x + width - 2, y + 1, x + width - 2, y + height - 2);
2664 /* Dark around left and top */
2666 if (style->ythickness > 1)
2667 gdk_draw_line (window, style->black_gc,
2668 x + 1, y + 1, x + width - 2, y + 1);
2669 if (style->xthickness > 1)
2670 gdk_draw_line (window, style->black_gc,
2671 x + 1, y + 1, x + 1, y + height - 2);
2673 if (style->ythickness > 0)
2674 gdk_draw_line (window, gc2,
2675 x, y, x + width - 1, y);
2676 if (style->xthickness > 0)
2677 gdk_draw_line (window, gc2,
2678 x, y, x, y + height - 1);
2681 case GTK_SHADOW_OUT:
2682 /* Dark around right and bottom edge */
2684 if (style->ythickness > 0)
2686 if (style->ythickness > 1)
2688 gdk_draw_line (window, gc1,
2689 x + 1, y + height - 2, x + width - 2, y + height - 2);
2690 gdk_draw_line (window, style->black_gc,
2691 x, y + height - 1, x + width - 1, y + height - 1);
2695 gdk_draw_line (window, gc1,
2696 x + 1, y + height - 1, x + width - 1, y + height - 1);
2700 if (style->xthickness > 0)
2702 if (style->xthickness > 1)
2704 gdk_draw_line (window, gc1,
2705 x + width - 2, y + 1, x + width - 2, y + height - 2);
2707 gdk_draw_line (window, style->black_gc,
2708 x + width - 1, y, x + width - 1, y + height - 1);
2712 gdk_draw_line (window, gc1,
2713 x + width - 1, y + 1, x + width - 1, y + height - 1);
2717 /* Light around top and left */
2719 if (style->ythickness > 0)
2720 gdk_draw_line (window, gc2,
2721 x, y, x + width - 2, y);
2722 if (style->xthickness > 0)
2723 gdk_draw_line (window, gc2,
2724 x, y, x, y + height - 2);
2726 if (style->ythickness > 1)
2727 gdk_draw_line (window, style->bg_gc[state_type],
2728 x + 1, y + 1, x + width - 3, y + 1);
2729 if (style->xthickness > 1)
2730 gdk_draw_line (window, style->bg_gc[state_type],
2731 x + 1, y + 1, x + 1, y + height - 3);
2734 case GTK_SHADOW_ETCHED_IN:
2735 case GTK_SHADOW_ETCHED_OUT:
2736 if (style->xthickness > 0)
2738 if (style->xthickness > 1)
2740 thickness_light = 1;
2743 for (i = 0; i < thickness_dark; i++)
2745 gdk_draw_line (window, gc1,
2749 y + height - i - 1);
2750 gdk_draw_line (window, gc2,
2754 y + height - i - 2);
2757 for (i = 0; i < thickness_light; i++)
2759 gdk_draw_line (window, gc1,
2760 x + thickness_dark + i,
2761 y + thickness_dark + i,
2762 x + thickness_dark + i,
2763 y + height - thickness_dark - i - 1);
2764 gdk_draw_line (window, gc2,
2765 x + width - thickness_light - i - 1,
2766 y + thickness_dark + i,
2767 x + width - thickness_light - i - 1,
2768 y + height - thickness_light - 1);
2773 gdk_draw_line (window,
2774 style->dark_gc[state_type],
2775 x, y, x, y + height);
2776 gdk_draw_line (window,
2777 style->dark_gc[state_type],
2778 x + width, y, x + width, y + height);
2782 if (style->ythickness > 0)
2784 if (style->ythickness > 1)
2786 thickness_light = 1;
2789 for (i = 0; i < thickness_dark; i++)
2791 gdk_draw_line (window, gc1,
2795 y + height - i - 1);
2797 gdk_draw_line (window, gc2,
2804 for (i = 0; i < thickness_light; i++)
2806 gdk_draw_line (window, gc1,
2807 x + thickness_dark + i,
2808 y + thickness_dark + i,
2809 x + width - thickness_dark - i - 2,
2810 y + thickness_dark + i);
2812 gdk_draw_line (window, gc2,
2813 x + thickness_dark + i,
2814 y + height - thickness_light - i - 1,
2815 x + width - thickness_light - 1,
2816 y + height - thickness_light - i - 1);
2821 gdk_draw_line (window,
2822 style->dark_gc[state_type],
2823 x, y, x + width, y);
2824 gdk_draw_line (window,
2825 style->dark_gc[state_type],
2826 x, y + height, x + width, y + height);
2833 if (shadow_type == GTK_SHADOW_IN &&
2834 widget && GTK_IS_SPIN_BUTTON (widget) &&
2835 detail && strcmp (detail, "entry") == 0)
2837 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
2839 gdk_draw_line (window,
2840 style->base_gc[state_type],
2841 x + width - 1, y + 2,
2842 x + width - 1, y + height - 3);
2843 gdk_draw_line (window,
2844 style->base_gc[state_type],
2845 x + width - 2, y + 2,
2846 x + width - 2, y + height - 3);
2847 gdk_draw_point (window,
2849 x + width - 1, y + 1);
2850 gdk_draw_point (window,
2851 style->bg_gc[state_type],
2852 x + width - 1, y + height - 2);
2856 gdk_draw_line (window,
2857 style->base_gc[state_type],
2860 gdk_draw_line (window,
2861 style->base_gc[state_type],
2863 x + 1, y + height - 3);
2864 gdk_draw_point (window,
2867 gdk_draw_line (window,
2868 style->bg_gc[state_type],
2870 x + 1, y + height - 2);
2871 gdk_draw_point (window,
2872 style->light_gc[state_type],
2880 gdk_gc_set_clip_rectangle (gc1, NULL);
2881 gdk_gc_set_clip_rectangle (gc2, NULL);
2882 if (shadow_type == GTK_SHADOW_IN ||
2883 shadow_type == GTK_SHADOW_OUT)
2885 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
2886 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
2892 gtk_default_draw_polygon (GtkStyle *style,
2894 GtkStateType state_type,
2895 GtkShadowType shadow_type,
2898 const gchar *detail,
2903 static const gdouble pi_over_4 = G_PI_4;
2904 static const gdouble pi_3_over_4 = G_PI_4 * 3;
2914 g_return_if_fail (GTK_IS_STYLE (style));
2915 g_return_if_fail (window != NULL);
2916 g_return_if_fail (points != NULL);
2918 switch (shadow_type)
2921 gc1 = style->bg_gc[state_type];
2922 gc2 = style->dark_gc[state_type];
2923 gc3 = style->light_gc[state_type];
2924 gc4 = style->black_gc;
2926 case GTK_SHADOW_ETCHED_IN:
2927 gc1 = style->light_gc[state_type];
2928 gc2 = style->dark_gc[state_type];
2929 gc3 = style->dark_gc[state_type];
2930 gc4 = style->light_gc[state_type];
2932 case GTK_SHADOW_OUT:
2933 gc1 = style->dark_gc[state_type];
2934 gc2 = style->light_gc[state_type];
2935 gc3 = style->black_gc;
2936 gc4 = style->bg_gc[state_type];
2938 case GTK_SHADOW_ETCHED_OUT:
2939 gc1 = style->dark_gc[state_type];
2940 gc2 = style->light_gc[state_type];
2941 gc3 = style->light_gc[state_type];
2942 gc4 = style->dark_gc[state_type];
2950 gdk_gc_set_clip_rectangle (gc1, area);
2951 gdk_gc_set_clip_rectangle (gc2, area);
2952 gdk_gc_set_clip_rectangle (gc3, area);
2953 gdk_gc_set_clip_rectangle (gc4, area);
2957 gdk_draw_polygon (window, style->bg_gc[state_type], TRUE, points, npoints);
2961 for (i = 0; i < npoints; i++)
2963 if ((points[i].x == points[i+1].x) &&
2964 (points[i].y == points[i+1].y))
2970 angle = atan2 (points[i+1].y - points[i].y,
2971 points[i+1].x - points[i].x);
2974 if ((angle > -pi_3_over_4) && (angle < pi_over_4))
2976 if (angle > -pi_over_4)
2987 gdk_draw_line (window, gc1,
2988 points[i].x-xadjust, points[i].y-yadjust,
2989 points[i+1].x-xadjust, points[i+1].y-yadjust);
2990 gdk_draw_line (window, gc3,
2991 points[i].x, points[i].y,
2992 points[i+1].x, points[i+1].y);
2996 if ((angle < -pi_3_over_4) || (angle > pi_3_over_4))
3007 gdk_draw_line (window, gc4,
3008 points[i].x+xadjust, points[i].y+yadjust,
3009 points[i+1].x+xadjust, points[i+1].y+yadjust);
3010 gdk_draw_line (window, gc2,
3011 points[i].x, points[i].y,
3012 points[i+1].x, points[i+1].y);
3018 gdk_gc_set_clip_rectangle (gc1, NULL);
3019 gdk_gc_set_clip_rectangle (gc2, NULL);
3020 gdk_gc_set_clip_rectangle (gc3, NULL);
3021 gdk_gc_set_clip_rectangle (gc4, NULL);
3026 draw_arrow (GdkWindow *window,
3029 GtkArrowType arrow_type,
3038 gdk_gc_set_clip_rectangle (gc, area);
3040 if (arrow_type == GTK_ARROW_DOWN)
3042 for (i = 0, j = 0; i < height; i++, j++)
3043 gdk_draw_line (window, gc, x + j, y + i, x + width - j - 1, y + i);
3045 else if (arrow_type == GTK_ARROW_UP)
3047 for (i = height - 1, j = 0; i >= 0; i--, j++)
3048 gdk_draw_line (window, gc, x + j, y + i, x + width - j - 1, y + i);
3050 else if (arrow_type == GTK_ARROW_LEFT)
3052 for (i = width - 1, j = 0; i >= 0; i--, j++)
3053 gdk_draw_line (window, gc, x + i, y + j, x + i, y + height - j - 1);
3055 else if (arrow_type == GTK_ARROW_RIGHT)
3057 for (i = 0, j = 0; i < width; i++, j++)
3058 gdk_draw_line (window, gc, x + i, y + j, x + i, y + height - j - 1);
3062 gdk_gc_set_clip_rectangle (gc, NULL);
3066 calculate_arrow_geometry (GtkArrowType arrow_type,
3078 case GTK_ARROW_DOWN:
3088 if (arrow_type == GTK_ARROW_DOWN)
3090 if (*height % 2 == 1 || h % 2 == 0)
3095 if (*height % 2 == 0 || h % 2 == 0)
3100 case GTK_ARROW_RIGHT:
3101 case GTK_ARROW_LEFT:
3111 if (arrow_type == GTK_ARROW_RIGHT)
3113 if (*width % 2 == 1 || w % 2 == 0)
3118 if (*width % 2 == 0 || w % 2 == 0)
3124 /* should not be reached */
3128 *x += (*width - w) / 2;
3129 *y += (*height - h) / 2;
3135 gtk_default_draw_arrow (GtkStyle *style,
3138 GtkShadowType shadow,
3141 const gchar *detail,
3142 GtkArrowType arrow_type,
3149 gint original_width, original_x;
3151 sanitize_size (window, &width, &height);
3153 original_width = width;
3156 calculate_arrow_geometry (arrow_type, &x, &y, &width, &height);
3158 if (detail && strcmp (detail, "menu_scroll_arrow_up") == 0)
3161 if (state == GTK_STATE_INSENSITIVE)
3162 draw_arrow (window, style->white_gc, area, arrow_type,
3163 x + 1, y + 1, width, height);
3164 draw_arrow (window, style->fg_gc[state], area, arrow_type,
3165 x, y, width, height);
3169 gtk_default_draw_diamond (GtkStyle *style,
3171 GtkStateType state_type,
3172 GtkShadowType shadow_type,
3175 const gchar *detail,
3183 GdkGC *outer_nw = NULL;
3184 GdkGC *outer_ne = NULL;
3185 GdkGC *outer_sw = NULL;
3186 GdkGC *outer_se = NULL;
3187 GdkGC *middle_nw = NULL;
3188 GdkGC *middle_ne = NULL;
3189 GdkGC *middle_sw = NULL;
3190 GdkGC *middle_se = NULL;
3191 GdkGC *inner_nw = NULL;
3192 GdkGC *inner_ne = NULL;
3193 GdkGC *inner_sw = NULL;
3194 GdkGC *inner_se = NULL;
3196 g_return_if_fail (GTK_IS_STYLE (style));
3197 g_return_if_fail (window != NULL);
3199 sanitize_size (window, &width, &height);
3201 half_width = width / 2;
3202 half_height = height / 2;
3206 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
3207 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
3208 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
3209 gdk_gc_set_clip_rectangle (style->black_gc, area);
3212 switch (shadow_type)
3215 inner_sw = inner_se = style->bg_gc[state_type];
3216 middle_sw = middle_se = style->light_gc[state_type];
3217 outer_sw = outer_se = style->light_gc[state_type];
3218 inner_nw = inner_ne = style->black_gc;
3219 middle_nw = middle_ne = style->dark_gc[state_type];
3220 outer_nw = outer_ne = style->dark_gc[state_type];
3223 case GTK_SHADOW_OUT:
3224 inner_sw = inner_se = style->dark_gc[state_type];
3225 middle_sw = middle_se = style->dark_gc[state_type];
3226 outer_sw = outer_se = style->black_gc;
3227 inner_nw = inner_ne = style->bg_gc[state_type];
3228 middle_nw = middle_ne = style->light_gc[state_type];
3229 outer_nw = outer_ne = style->light_gc[state_type];
3232 case GTK_SHADOW_ETCHED_IN:
3233 inner_sw = inner_se = style->bg_gc[state_type];
3234 middle_sw = middle_se = style->dark_gc[state_type];
3235 outer_sw = outer_se = style->light_gc[state_type];
3236 inner_nw = inner_ne = style->bg_gc[state_type];
3237 middle_nw = middle_ne = style->light_gc[state_type];
3238 outer_nw = outer_ne = style->dark_gc[state_type];
3241 case GTK_SHADOW_ETCHED_OUT:
3242 inner_sw = inner_se = style->bg_gc[state_type];
3243 middle_sw = middle_se = style->light_gc[state_type];
3244 outer_sw = outer_se = style->dark_gc[state_type];
3245 inner_nw = inner_ne = style->bg_gc[state_type];
3246 middle_nw = middle_ne = style->dark_gc[state_type];
3247 outer_nw = outer_ne = style->light_gc[state_type];
3257 gdk_draw_line (window, inner_sw,
3258 x + 2, y + half_height,
3259 x + half_width, y + height - 2);
3260 gdk_draw_line (window, inner_se,
3261 x + half_width, y + height - 2,
3262 x + width - 2, y + half_height);
3263 gdk_draw_line (window, middle_sw,
3264 x + 1, y + half_height,
3265 x + half_width, y + height - 1);
3266 gdk_draw_line (window, middle_se,
3267 x + half_width, y + height - 1,
3268 x + width - 1, y + half_height);
3269 gdk_draw_line (window, outer_sw,
3271 x + half_width, y + height);
3272 gdk_draw_line (window, outer_se,
3273 x + half_width, y + height,
3274 x + width, y + half_height);
3276 gdk_draw_line (window, inner_nw,
3277 x + 2, y + half_height,
3278 x + half_width, y + 2);
3279 gdk_draw_line (window, inner_ne,
3280 x + half_width, y + 2,
3281 x + width - 2, y + half_height);
3282 gdk_draw_line (window, middle_nw,
3283 x + 1, y + half_height,
3284 x + half_width, y + 1);
3285 gdk_draw_line (window, middle_ne,
3286 x + half_width, y + 1,
3287 x + width - 1, y + half_height);
3288 gdk_draw_line (window, outer_nw,
3291 gdk_draw_line (window, outer_ne,
3293 x + width, y + half_height);
3298 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
3299 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
3300 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
3301 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
3306 gtk_default_draw_string (GtkStyle *style,
3308 GtkStateType state_type,
3311 const gchar *detail,
3314 const gchar *string)
3316 GdkDisplay *display;
3318 g_return_if_fail (GTK_IS_STYLE (style));
3319 g_return_if_fail (window != NULL);
3321 display = gdk_drawable_get_display (window);
3325 gdk_gc_set_clip_rectangle (style->white_gc, area);
3326 gdk_gc_set_clip_rectangle (style->fg_gc[state_type], area);
3329 if (state_type == GTK_STATE_INSENSITIVE)
3330 gdk_draw_string (window,
3331 gtk_style_get_font_internal (style),
3332 style->white_gc, x + 1, y + 1, string);
3334 gdk_draw_string (window,
3335 gtk_style_get_font_internal (style),
3336 style->fg_gc[state_type], x, y, string);
3340 gdk_gc_set_clip_rectangle (style->white_gc, NULL);
3341 gdk_gc_set_clip_rectangle (style->fg_gc[state_type], NULL);
3346 option_menu_get_props (GtkWidget *widget,
3347 GtkRequisition *indicator_size,
3348 GtkBorder *indicator_spacing)
3350 GtkRequisition *tmp_size = NULL;
3351 GtkBorder *tmp_spacing = NULL;
3354 gtk_widget_style_get (widget,
3355 "indicator_size", &tmp_size,
3356 "indicator_spacing", &tmp_spacing,
3361 *indicator_size = *tmp_size;
3365 *indicator_size = default_option_indicator_size;
3369 *indicator_spacing = *tmp_spacing;
3370 g_free (tmp_spacing);
3373 *indicator_spacing = default_option_indicator_spacing;
3377 gtk_default_draw_box (GtkStyle *style,
3379 GtkStateType state_type,
3380 GtkShadowType shadow_type,
3383 const gchar *detail,
3389 gboolean is_spinbutton_box = FALSE;
3391 g_return_if_fail (GTK_IS_STYLE (style));
3392 g_return_if_fail (window != NULL);
3394 sanitize_size (window, &width, &height);
3396 if (widget && GTK_IS_SPIN_BUTTON (widget) && detail)
3398 if (strcmp (detail, "spinbutton_up") == 0)
3404 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
3409 is_spinbutton_box = TRUE;
3411 else if (strcmp (detail, "spinbutton_down") == 0)
3416 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
3421 is_spinbutton_box = TRUE;
3425 if (!style->bg_pixmap[state_type] ||
3426 GDK_IS_PIXMAP (window))
3428 GdkGC *gc = style->bg_gc[state_type];
3430 if (state_type == GTK_STATE_SELECTED && strcmp (detail, "paned") == 0)
3432 if (!GTK_WIDGET_HAS_FOCUS (widget))
3433 gc = style->base_gc[GTK_STATE_ACTIVE];
3437 gdk_gc_set_clip_rectangle (gc, area);
3439 gdk_draw_rectangle (window, gc, TRUE,
3440 x, y, width, height);
3442 gdk_gc_set_clip_rectangle (gc, NULL);
3445 gtk_style_apply_default_background (style, window,
3446 widget && !GTK_WIDGET_NO_WINDOW (widget),
3447 state_type, area, x, y, width, height);
3449 if (is_spinbutton_box)
3454 lower_gc = style->dark_gc[state_type];
3455 if (shadow_type == GTK_SHADOW_OUT)
3456 upper_gc = style->light_gc[state_type];
3458 upper_gc = style->dark_gc[state_type];
3462 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
3463 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
3466 gdk_draw_line (window, upper_gc, x, y, x + width - 1, y);
3467 gdk_draw_line (window, lower_gc, x, y + height - 1, x + width - 1, y + height - 1);
3471 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
3472 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
3477 gtk_paint_shadow (style, window, state_type, shadow_type, area, widget, detail,
3478 x, y, width, height);
3480 if (detail && strcmp (detail, "optionmenu") == 0)
3482 GtkRequisition indicator_size;
3483 GtkBorder indicator_spacing;
3486 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
3488 sanitize_size (window, &width, &height);
3490 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
3491 vline_x = x + indicator_size.width + indicator_spacing.left + indicator_spacing.right;
3493 vline_x = x + width - (indicator_size.width + indicator_spacing.left + indicator_spacing.right) - style->xthickness;
3495 gtk_paint_vline (style, window, state_type, area, widget,
3497 y + style->ythickness + 1,
3498 y + height - style->ythickness - 3,
3504 get_darkened_gc (GdkWindow *window,
3508 GdkColor src = *color;
3509 GdkColor shaded = *color;
3512 gc = gdk_gc_new (window);
3514 while (darken_count)
3516 gtk_style_shade (&src, &shaded, 0.93);
3521 gdk_gc_set_rgb_fg_color (gc, &shaded);
3527 gtk_default_draw_flat_box (GtkStyle *style,
3529 GtkStateType state_type,
3530 GtkShadowType shadow_type,
3533 const gchar *detail,
3540 GdkGC *freeme = NULL;
3542 g_return_if_fail (GTK_IS_STYLE (style));
3543 g_return_if_fail (window != NULL);
3545 sanitize_size (window, &width, &height);
3549 if (state_type == GTK_STATE_SELECTED)
3551 if (!strcmp ("text", detail))
3552 gc1 = style->bg_gc[GTK_STATE_SELECTED];
3553 else if (!strncmp ("cell_even", detail, strlen ("cell_even")) ||
3554 !strncmp ("cell_odd", detail, strlen ("cell_odd")))
3556 /* This has to be really broken; alex made me do it. -jrb */
3557 if (GTK_WIDGET_HAS_FOCUS (widget))
3558 gc1 = style->base_gc[state_type];
3560 gc1 = style->base_gc[GTK_STATE_ACTIVE];
3564 gc1 = style->bg_gc[state_type];
3569 if (!strcmp ("viewportbin", detail))
3570 gc1 = style->bg_gc[GTK_STATE_NORMAL];
3571 else if (!strcmp ("entry_bg", detail))
3572 gc1 = style->base_gc[state_type];
3574 /* For trees: even rows are base color, odd rows are a shade of
3575 * the base color, the sort column is a shade of the original color
3579 else if (!strcmp ("cell_even", detail) ||
3580 !strcmp ("cell_odd", detail) ||
3581 !strcmp ("cell_even_ruled", detail))
3583 GdkColor *color = NULL;
3585 gtk_widget_style_get (widget,
3586 "even_row_color", &color,
3591 freeme = get_darkened_gc (window, color, 0);
3594 gdk_color_free (color);
3597 gc1 = style->base_gc[state_type];
3599 else if (!strcmp ("cell_odd_ruled", detail))
3603 gtk_widget_style_get (widget,
3604 "odd_row_color", &color,
3609 freeme = get_darkened_gc (window, color, 0);
3612 gdk_color_free (color);
3616 gtk_widget_style_get (widget,
3617 "even_row_color", &color,
3622 freeme = get_darkened_gc (window, color, 1);
3623 gdk_color_free (color);
3626 freeme = get_darkened_gc (window, &style->base[state_type], 1);
3630 else if (!strcmp ("cell_even_sorted", detail) ||
3631 !strcmp ("cell_odd_sorted", detail) ||
3632 !strcmp ("cell_even_ruled_sorted", detail))
3634 GdkColor *color = NULL;
3636 if (!strcmp ("cell_odd_sorted", detail))
3637 gtk_widget_style_get (widget,
3638 "odd_row_color", &color,
3641 gtk_widget_style_get (widget,
3642 "even_row_color", &color,
3647 freeme = get_darkened_gc (window, color, 1);
3650 gdk_color_free (color);
3654 freeme = get_darkened_gc (window, &style->base[state_type], 1);
3658 else if (!strcmp ("cell_odd_ruled_sorted", detail))
3660 GdkColor *color = NULL;
3662 gtk_widget_style_get (widget,
3663 "odd_row_color", &color,
3668 freeme = get_darkened_gc (window, color, 1);
3671 gdk_color_free (color);
3675 gtk_widget_style_get (widget,
3676 "even_row_color", &color,
3681 freeme = get_darkened_gc (window, color, 2);
3682 gdk_color_free (color);
3685 freeme = get_darkened_gc (window, &style->base[state_type], 2);
3690 gc1 = style->bg_gc[state_type];
3694 gc1 = style->bg_gc[state_type];
3696 if (!style->bg_pixmap[state_type] || gc1 != style->bg_gc[state_type] ||
3697 GDK_IS_PIXMAP (window))
3700 gdk_gc_set_clip_rectangle (gc1, area);
3702 gdk_draw_rectangle (window, gc1, TRUE,
3703 x, y, width, height);
3705 if (detail && !strcmp ("tooltip", detail))
3706 gdk_draw_rectangle (window, style->black_gc, FALSE,
3707 x, y, width - 1, height - 1);
3710 gdk_gc_set_clip_rectangle (gc1, NULL);
3713 gtk_style_apply_default_background (style, window,
3714 widget && !GTK_WIDGET_NO_WINDOW (widget),
3715 state_type, area, x, y, width, height);
3719 g_object_unref (freeme);
3723 create_aa_gc (GdkWindow *window, GtkStyle *style, GtkStateType state_type)
3726 GdkGC *gc = gdk_gc_new (window);
3728 aa_color.red = (style->fg[state_type].red + style->bg[state_type].red) / 2;
3729 aa_color.green = (style->fg[state_type].green + style->bg[state_type].green) / 2;
3730 aa_color.blue = (style->fg[state_type].blue + style->bg[state_type].blue) / 2;
3732 gdk_gc_set_rgb_fg_color (gc, &aa_color);
3738 gtk_default_draw_check (GtkStyle *style,
3740 GtkStateType state_type,
3741 GtkShadowType shadow_type,
3744 const gchar *detail,
3750 if (detail && strcmp (detail, "cellcheck") == 0)
3753 gdk_gc_set_clip_rectangle (widget->style->base_gc[state_type], area);
3754 gdk_draw_rectangle (window,
3755 widget->style->base_gc[state_type],
3761 gdk_gc_set_clip_rectangle (widget->style->base_gc[state_type], NULL);
3762 gdk_gc_set_clip_rectangle (widget->style->text_gc[state_type], area);
3764 gdk_draw_rectangle (window,
3765 widget->style->text_gc[state_type],
3770 gdk_gc_set_clip_rectangle (widget->style->text_gc[state_type], NULL);
3772 x -= (1 + INDICATOR_PART_SIZE - width) / 2;
3773 y -= (((1 + INDICATOR_PART_SIZE - height) / 2) - 1);
3774 if (shadow_type == GTK_SHADOW_IN)
3776 draw_part (window, style->text_gc[state_type], area, x, y, CHECK_TEXT);
3777 draw_part (window, style->text_aa_gc[state_type], area, x, y, CHECK_AA);
3779 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
3781 draw_part (window, style->text_gc[state_type], area, x, y, CHECK_INCONSISTENT_TEXT);
3786 GdkGC *free_me = NULL;
3792 x -= (1 + INDICATOR_PART_SIZE - width) / 2;
3793 y -= (1 + INDICATOR_PART_SIZE - height) / 2;
3795 if (strcmp (detail, "check") == 0) /* Menu item */
3797 text_gc = style->fg_gc[state_type];
3798 base_gc = style->bg_gc[state_type];
3799 aa_gc = free_me = create_aa_gc (window, style, state_type);
3803 if (state_type == GTK_STATE_ACTIVE)
3805 text_gc = style->fg_gc[state_type];
3806 base_gc = style->bg_gc[state_type];
3807 aa_gc = free_me = create_aa_gc (window, style, state_type);
3811 text_gc = style->text_gc[state_type];
3812 base_gc = style->base_gc[state_type];
3813 aa_gc = style->text_aa_gc[state_type];
3816 draw_part (window, base_gc, area, x, y, CHECK_BASE);
3817 draw_part (window, style->black_gc, area, x, y, CHECK_BLACK);
3818 draw_part (window, style->dark_gc[state_type], area, x, y, CHECK_DARK);
3819 draw_part (window, style->mid_gc[state_type], area, x, y, CHECK_MID);
3820 draw_part (window, style->light_gc[state_type], area, x, y, CHECK_LIGHT);
3823 if (shadow_type == GTK_SHADOW_IN)
3825 draw_part (window, text_gc, area, x, y, CHECK_TEXT);
3826 draw_part (window, aa_gc, area, x, y, CHECK_AA);
3828 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
3830 draw_part (window, text_gc, area, x, y, CHECK_INCONSISTENT_TEXT);
3834 g_object_unref (free_me);
3839 gtk_default_draw_option (GtkStyle *style,
3841 GtkStateType state_type,
3842 GtkShadowType shadow_type,
3845 const gchar *detail,
3851 if (detail && strcmp (detail, "cellradio") == 0)
3854 gdk_gc_set_clip_rectangle (widget->style->fg_gc[state_type], area);
3855 gdk_draw_arc (window,
3856 widget->style->fg_gc[state_type],
3863 if (shadow_type == GTK_SHADOW_IN)
3865 gdk_draw_arc (window,
3866 widget->style->fg_gc[state_type],
3874 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
3876 draw_part (window, widget->style->fg_gc[state_type],
3877 area, x, y, CHECK_INCONSISTENT_TEXT);
3880 gdk_gc_set_clip_rectangle (widget->style->fg_gc[state_type], NULL);
3884 GdkGC *free_me = NULL;
3890 x -= (1 + INDICATOR_PART_SIZE - width) / 2;
3891 y -= (1 + INDICATOR_PART_SIZE - height) / 2;
3893 if (strcmp (detail, "option") == 0) /* Menu item */
3895 text_gc = style->fg_gc[state_type];
3896 base_gc = style->bg_gc[state_type];
3897 aa_gc = free_me = create_aa_gc (window, style, state_type);
3901 if (state_type == GTK_STATE_ACTIVE)
3903 text_gc = style->fg_gc[state_type];
3904 base_gc = style->bg_gc[state_type];
3905 aa_gc = free_me = create_aa_gc (window, style, state_type);
3909 text_gc = style->text_gc[state_type];
3910 base_gc = style->base_gc[state_type];
3911 aa_gc = style->text_aa_gc[state_type];
3914 draw_part (window, base_gc, area, x, y, RADIO_BASE);
3915 draw_part (window, style->black_gc, area, x, y, RADIO_BLACK);
3916 draw_part (window, style->dark_gc[state_type], area, x, y, RADIO_DARK);
3917 draw_part (window, style->mid_gc[state_type], area, x, y, RADIO_MID);
3918 draw_part (window, style->light_gc[state_type], area, x, y, RADIO_LIGHT);
3921 if (shadow_type == GTK_SHADOW_IN)
3923 draw_part (window, text_gc, area, x, y, RADIO_TEXT);
3925 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
3927 if (strcmp (detail, "option") == 0) /* Menu item */
3929 draw_part (window, text_gc, area, x, y, CHECK_INCONSISTENT_TEXT);
3933 draw_part (window, text_gc, area, x, y, RADIO_INCONSISTENT_TEXT);
3934 draw_part (window, aa_gc, area, x, y, RADIO_INCONSISTENT_AA);
3939 g_object_unref (free_me);
3944 gtk_default_draw_tab (GtkStyle *style,
3946 GtkStateType state_type,
3947 GtkShadowType shadow_type,
3950 const gchar *detail,
3956 #define ARROW_SPACE 4
3958 GtkRequisition indicator_size;
3959 GtkBorder indicator_spacing;
3962 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
3964 indicator_size.width += (indicator_size.width % 2) - 1;
3965 arrow_height = indicator_size.width / 2 + 1;
3967 x += (width - indicator_size.width) / 2;
3968 y += (height - (2 * arrow_height + ARROW_SPACE)) / 2;
3970 if (state_type == GTK_STATE_INSENSITIVE)
3972 draw_arrow (window, style->white_gc, area,
3973 GTK_ARROW_UP, x + 1, y + 1,
3974 indicator_size.width, arrow_height);
3976 draw_arrow (window, style->white_gc, area,
3977 GTK_ARROW_DOWN, x + 1, y + arrow_height + ARROW_SPACE + 1,
3978 indicator_size.width, arrow_height);
3981 draw_arrow (window, style->fg_gc[state_type], area,
3983 indicator_size.width, arrow_height);
3986 draw_arrow (window, style->fg_gc[state_type], area,
3987 GTK_ARROW_DOWN, x, y + arrow_height + ARROW_SPACE,
3988 indicator_size.width, arrow_height);
3992 gtk_default_draw_shadow_gap (GtkStyle *style,
3994 GtkStateType state_type,
3995 GtkShadowType shadow_type,
3998 const gchar *detail,
4003 GtkPositionType gap_side,
4012 g_return_if_fail (GTK_IS_STYLE (style));
4013 g_return_if_fail (window != NULL);
4015 sanitize_size (window, &width, &height);
4017 switch (shadow_type)
4019 case GTK_SHADOW_NONE:
4022 gc1 = style->dark_gc[state_type];
4023 gc2 = style->black_gc;
4024 gc3 = style->bg_gc[state_type];
4025 gc4 = style->light_gc[state_type];
4027 case GTK_SHADOW_ETCHED_IN:
4028 gc1 = style->dark_gc[state_type];
4029 gc2 = style->light_gc[state_type];
4030 gc3 = style->dark_gc[state_type];
4031 gc4 = style->light_gc[state_type];
4033 case GTK_SHADOW_OUT:
4034 gc1 = style->light_gc[state_type];
4035 gc2 = style->bg_gc[state_type];
4036 gc3 = style->dark_gc[state_type];
4037 gc4 = style->black_gc;
4039 case GTK_SHADOW_ETCHED_OUT:
4040 gc1 = style->light_gc[state_type];
4041 gc2 = style->dark_gc[state_type];
4042 gc3 = style->light_gc[state_type];
4043 gc4 = style->dark_gc[state_type];
4048 gdk_gc_set_clip_rectangle (gc1, area);
4049 gdk_gc_set_clip_rectangle (gc2, area);
4050 gdk_gc_set_clip_rectangle (gc3, area);
4051 gdk_gc_set_clip_rectangle (gc4, area);
4054 switch (shadow_type)
4056 case GTK_SHADOW_NONE:
4058 case GTK_SHADOW_OUT:
4059 case GTK_SHADOW_ETCHED_IN:
4060 case GTK_SHADOW_ETCHED_OUT:
4064 gdk_draw_line (window, gc1,
4065 x, y, x, y + height - 1);
4066 gdk_draw_line (window, gc2,
4067 x + 1, y, x + 1, y + height - 2);
4069 gdk_draw_line (window, gc3,
4070 x + 1, y + height - 2, x + width - 2, y + height - 2);
4071 gdk_draw_line (window, gc3,
4072 x + width - 2, y, x + width - 2, y + height - 2);
4073 gdk_draw_line (window, gc4,
4074 x, y + height - 1, x + width - 1, y + height - 1);
4075 gdk_draw_line (window, gc4,
4076 x + width - 1, y, x + width - 1, y + height - 1);
4079 gdk_draw_line (window, gc1,
4080 x, y, x + gap_x - 1, y);
4081 gdk_draw_line (window, gc2,
4082 x + 1, y + 1, x + gap_x - 1, y + 1);
4083 gdk_draw_line (window, gc2,
4084 x + gap_x, y, x + gap_x, y);
4086 if ((width - (gap_x + gap_width)) > 0)
4088 gdk_draw_line (window, gc1,
4089 x + gap_x + gap_width, y, x + width - 2, y);
4090 gdk_draw_line (window, gc2,
4091 x + gap_x + gap_width, y + 1, x + width - 3, y + 1);
4092 gdk_draw_line (window, gc2,
4093 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
4096 case GTK_POS_BOTTOM:
4097 gdk_draw_line (window, gc1,
4098 x, y, x + width - 1, y);
4099 gdk_draw_line (window, gc1,
4100 x, y, x, y + height - 1);
4101 gdk_draw_line (window, gc2,
4102 x + 1, y + 1, x + width - 2, y + 1);
4103 gdk_draw_line (window, gc2,
4104 x + 1, y + 1, x + 1, y + height - 1);
4106 gdk_draw_line (window, gc3,
4107 x + width - 2, y + 1, x + width - 2, y + height - 1);
4108 gdk_draw_line (window, gc4,
4109 x + width - 1, y, x + width - 1, y + height - 1);
4112 gdk_draw_line (window, gc4,
4113 x, y + height - 1, x + gap_x - 1, y + height - 1);
4114 gdk_draw_line (window, gc3,
4115 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
4116 gdk_draw_line (window, gc3,
4117 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
4119 if ((width - (gap_x + gap_width)) > 0)
4121 gdk_draw_line (window, gc4,
4122 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
4123 gdk_draw_line (window, gc3,
4124 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
4125 gdk_draw_line (window, gc3,
4126 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
4130 gdk_draw_line (window, gc1,
4131 x, y, x + width - 1, y);
4132 gdk_draw_line (window, gc2,
4133 x, y + 1, x + width - 2, y + 1);
4135 gdk_draw_line (window, gc3,
4136 x, y + height - 2, x + width - 2, y + height - 2);
4137 gdk_draw_line (window, gc3,
4138 x + width - 2, y + 1, x + width - 2, y + height - 2);
4139 gdk_draw_line (window, gc4,
4140 x, y + height - 1, x + width - 1, y + height - 1);
4141 gdk_draw_line (window, gc4,
4142 x + width - 1, y, x + width - 1, y + height - 1);
4145 gdk_draw_line (window, gc1,
4146 x, y, x, y + gap_x - 1);
4147 gdk_draw_line (window, gc2,
4148 x + 1, y + 1, x + 1, y + gap_x - 1);
4149 gdk_draw_line (window, gc2,
4150 x, y + gap_x, x, y + gap_x);
4152 if ((width - (gap_x + gap_width)) > 0)
4154 gdk_draw_line (window, gc1,
4155 x, y + gap_x + gap_width, x, y + height - 2);
4156 gdk_draw_line (window, gc2,
4157 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
4158 gdk_draw_line (window, gc2,
4159 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
4163 gdk_draw_line (window, gc1,
4164 x, y, x + width - 1, y);
4165 gdk_draw_line (window, gc1,
4166 x, y, x, y + height - 1);
4167 gdk_draw_line (window, gc2,
4168 x + 1, y + 1, x + width - 1, y + 1);
4169 gdk_draw_line (window, gc2,
4170 x + 1, y + 1, x + 1, y + height - 2);
4172 gdk_draw_line (window, gc3,
4173 x + 1, y + height - 2, x + width - 1, y + height - 2);
4174 gdk_draw_line (window, gc4,
4175 x, y + height - 1, x + width - 1, y + height - 1);
4178 gdk_draw_line (window, gc4,
4179 x + width - 1, y, x + width - 1, y + gap_x - 1);
4180 gdk_draw_line (window, gc3,
4181 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
4182 gdk_draw_line (window, gc3,
4183 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
4185 if ((width - (gap_x + gap_width)) > 0)
4187 gdk_draw_line (window, gc4,
4188 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
4189 gdk_draw_line (window, gc3,
4190 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
4191 gdk_draw_line (window, gc3,
4192 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
4200 gdk_gc_set_clip_rectangle (gc1, NULL);
4201 gdk_gc_set_clip_rectangle (gc2, NULL);
4202 gdk_gc_set_clip_rectangle (gc3, NULL);
4203 gdk_gc_set_clip_rectangle (gc4, NULL);
4208 gtk_default_draw_box_gap (GtkStyle *style,
4210 GtkStateType state_type,
4211 GtkShadowType shadow_type,
4214 const gchar *detail,
4219 GtkPositionType gap_side,
4228 g_return_if_fail (GTK_IS_STYLE (style));
4229 g_return_if_fail (window != NULL);
4231 gtk_style_apply_default_background (style, window,
4232 widget && !GTK_WIDGET_NO_WINDOW (widget),
4233 state_type, area, x, y, width, height);
4235 sanitize_size (window, &width, &height);
4237 switch (shadow_type)
4239 case GTK_SHADOW_NONE:
4242 gc1 = style->dark_gc[state_type];
4243 gc2 = style->black_gc;
4244 gc3 = style->bg_gc[state_type];
4245 gc4 = style->light_gc[state_type];
4247 case GTK_SHADOW_ETCHED_IN:
4248 gc1 = style->dark_gc[state_type];
4249 gc2 = style->light_gc[state_type];
4250 gc3 = style->dark_gc[state_type];
4251 gc4 = style->light_gc[state_type];
4253 case GTK_SHADOW_OUT:
4254 gc1 = style->light_gc[state_type];
4255 gc2 = style->bg_gc[state_type];
4256 gc3 = style->dark_gc[state_type];
4257 gc4 = style->black_gc;
4259 case GTK_SHADOW_ETCHED_OUT:
4260 gc1 = style->light_gc[state_type];
4261 gc2 = style->dark_gc[state_type];
4262 gc3 = style->light_gc[state_type];
4263 gc4 = style->dark_gc[state_type];
4269 gdk_gc_set_clip_rectangle (gc1, area);
4270 gdk_gc_set_clip_rectangle (gc2, area);
4271 gdk_gc_set_clip_rectangle (gc3, area);
4272 gdk_gc_set_clip_rectangle (gc4, area);
4275 switch (shadow_type)
4277 case GTK_SHADOW_NONE:
4279 case GTK_SHADOW_OUT:
4280 case GTK_SHADOW_ETCHED_IN:
4281 case GTK_SHADOW_ETCHED_OUT:
4285 gdk_draw_line (window, gc1,
4286 x, y, x, y + height - 1);
4287 gdk_draw_line (window, gc2,
4288 x + 1, y, x + 1, y + height - 2);
4290 gdk_draw_line (window, gc3,
4291 x + 1, y + height - 2, x + width - 2, y + height - 2);
4292 gdk_draw_line (window, gc3,
4293 x + width - 2, y, x + width - 2, y + height - 2);
4294 gdk_draw_line (window, gc4,
4295 x, y + height - 1, x + width - 1, y + height - 1);
4296 gdk_draw_line (window, gc4,
4297 x + width - 1, y, x + width - 1, y + height - 1);
4300 gdk_draw_line (window, gc1,
4301 x, y, x + gap_x - 1, y);
4302 gdk_draw_line (window, gc2,
4303 x + 1, y + 1, x + gap_x - 1, y + 1);
4304 gdk_draw_line (window, gc2,
4305 x + gap_x, y, x + gap_x, y);
4307 if ((width - (gap_x + gap_width)) > 0)
4309 gdk_draw_line (window, gc1,
4310 x + gap_x + gap_width, y, x + width - 2, y);
4311 gdk_draw_line (window, gc2,
4312 x + gap_x + gap_width, y + 1, x + width - 2, y + 1);
4313 gdk_draw_line (window, gc2,
4314 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
4317 case GTK_POS_BOTTOM:
4318 gdk_draw_line (window, gc1,
4319 x, y, x + width - 1, y);
4320 gdk_draw_line (window, gc1,
4321 x, y, x, y + height - 1);
4322 gdk_draw_line (window, gc2,
4323 x + 1, y + 1, x + width - 2, y + 1);
4324 gdk_draw_line (window, gc2,
4325 x + 1, y + 1, x + 1, y + height - 1);
4327 gdk_draw_line (window, gc3,
4328 x + width - 2, y + 1, x + width - 2, y + height - 1);
4329 gdk_draw_line (window, gc4,
4330 x + width - 1, y, x + width - 1, y + height - 1);
4333 gdk_draw_line (window, gc4,
4334 x, y + height - 1, x + gap_x - 1, y + height - 1);
4335 gdk_draw_line (window, gc3,
4336 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
4337 gdk_draw_line (window, gc3,
4338 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
4340 if ((width - (gap_x + gap_width)) > 0)
4342 gdk_draw_line (window, gc4,
4343 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
4344 gdk_draw_line (window, gc3,
4345 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
4346 gdk_draw_line (window, gc3,
4347 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
4351 gdk_draw_line (window, gc1,
4352 x, y, x + width - 1, y);
4353 gdk_draw_line (window, gc2,
4354 x, y + 1, x + width - 2, y + 1);
4356 gdk_draw_line (window, gc3,
4357 x, y + height - 2, x + width - 2, y + height - 2);
4358 gdk_draw_line (window, gc3,
4359 x + width - 2, y + 1, x + width - 2, y + height - 2);
4360 gdk_draw_line (window, gc4,
4361 x, y + height - 1, x + width - 1, y + height - 1);
4362 gdk_draw_line (window, gc4,
4363 x + width - 1, y, x + width - 1, y + height - 1);
4366 gdk_draw_line (window, gc1,
4367 x, y, x, y + gap_x - 1);
4368 gdk_draw_line (window, gc2,
4369 x + 1, y + 1, x + 1, y + gap_x - 1);
4370 gdk_draw_line (window, gc2,
4371 x, y + gap_x, x, y + gap_x);
4373 if ((width - (gap_x + gap_width)) > 0)
4375 gdk_draw_line (window, gc1,
4376 x, y + gap_x + gap_width, x, y + height - 2);
4377 gdk_draw_line (window, gc2,
4378 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
4379 gdk_draw_line (window, gc2,
4380 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
4384 gdk_draw_line (window, gc1,
4385 x, y, x + width - 1, y);
4386 gdk_draw_line (window, gc1,
4387 x, y, x, y + height - 1);
4388 gdk_draw_line (window, gc2,
4389 x + 1, y + 1, x + width - 1, y + 1);
4390 gdk_draw_line (window, gc2,
4391 x + 1, y + 1, x + 1, y + height - 2);
4393 gdk_draw_line (window, gc3,
4394 x + 1, y + height - 2, x + width - 1, y + height - 2);
4395 gdk_draw_line (window, gc4,
4396 x, y + height - 1, x + width - 1, y + height - 1);
4399 gdk_draw_line (window, gc4,
4400 x + width - 1, y, x + width - 1, y + gap_x - 1);
4401 gdk_draw_line (window, gc3,
4402 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
4403 gdk_draw_line (window, gc3,
4404 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
4406 if ((width - (gap_x + gap_width)) > 0)
4408 gdk_draw_line (window, gc4,
4409 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
4410 gdk_draw_line (window, gc3,
4411 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
4412 gdk_draw_line (window, gc3,
4413 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
4421 gdk_gc_set_clip_rectangle (gc1, NULL);
4422 gdk_gc_set_clip_rectangle (gc2, NULL);
4423 gdk_gc_set_clip_rectangle (gc3, NULL);
4424 gdk_gc_set_clip_rectangle (gc4, NULL);
4429 gtk_default_draw_extension (GtkStyle *style,
4431 GtkStateType state_type,
4432 GtkShadowType shadow_type,
4435 const gchar *detail,
4440 GtkPositionType gap_side)
4447 g_return_if_fail (GTK_IS_STYLE (style));
4448 g_return_if_fail (window != NULL);
4450 gtk_style_apply_default_background (style, window,
4451 widget && !GTK_WIDGET_NO_WINDOW (widget),
4452 GTK_STATE_NORMAL, area, x, y, width, height);
4454 sanitize_size (window, &width, &height);
4456 switch (shadow_type)
4458 case GTK_SHADOW_NONE:
4461 gc1 = style->dark_gc[state_type];
4462 gc2 = style->black_gc;
4463 gc3 = style->bg_gc[state_type];
4464 gc4 = style->light_gc[state_type];
4466 case GTK_SHADOW_ETCHED_IN:
4467 gc1 = style->dark_gc[state_type];
4468 gc2 = style->light_gc[state_type];
4469 gc3 = style->dark_gc[state_type];
4470 gc4 = style->light_gc[state_type];
4472 case GTK_SHADOW_OUT:
4473 gc1 = style->light_gc[state_type];
4474 gc2 = style->bg_gc[state_type];
4475 gc3 = style->dark_gc[state_type];
4476 gc4 = style->black_gc;
4478 case GTK_SHADOW_ETCHED_OUT:
4479 gc1 = style->light_gc[state_type];
4480 gc2 = style->dark_gc[state_type];
4481 gc3 = style->light_gc[state_type];
4482 gc4 = style->dark_gc[state_type];
4488 gdk_gc_set_clip_rectangle (gc1, area);
4489 gdk_gc_set_clip_rectangle (gc2, area);
4490 gdk_gc_set_clip_rectangle (gc3, area);
4491 gdk_gc_set_clip_rectangle (gc4, area);
4494 switch (shadow_type)
4496 case GTK_SHADOW_NONE:
4498 case GTK_SHADOW_OUT:
4499 case GTK_SHADOW_ETCHED_IN:
4500 case GTK_SHADOW_ETCHED_OUT:
4504 gtk_style_apply_default_background (style, window,
4505 widget && !GTK_WIDGET_NO_WINDOW (widget),
4507 x + style->xthickness,
4509 width - (2 * style->xthickness),
4510 height - (style->ythickness));
4511 gdk_draw_line (window, gc1,
4512 x, y, x, y + height - 2);
4513 gdk_draw_line (window, gc2,
4514 x + 1, y, x + 1, y + height - 2);
4516 gdk_draw_line (window, gc3,
4517 x + 2, y + height - 2, x + width - 2, y + height - 2);
4518 gdk_draw_line (window, gc3,
4519 x + width - 2, y, x + width - 2, y + height - 2);
4520 gdk_draw_line (window, gc4,
4521 x + 1, y + height - 1, x + width - 2, y + height - 1);
4522 gdk_draw_line (window, gc4,
4523 x + width - 1, y, x + width - 1, y + height - 2);
4525 case GTK_POS_BOTTOM:
4526 gtk_style_apply_default_background (style, window,
4527 widget && !GTK_WIDGET_NO_WINDOW (widget),
4529 x + style->xthickness,
4530 y + style->ythickness,
4531 width - (2 * style->xthickness),
4532 height - (style->ythickness));
4533 gdk_draw_line (window, gc1,
4534 x + 1, y, x + width - 2, y);
4535 gdk_draw_line (window, gc1,
4536 x, y + 1, x, y + height - 1);
4537 gdk_draw_line (window, gc2,
4538 x + 1, y + 1, x + width - 2, y + 1);
4539 gdk_draw_line (window, gc2,
4540 x + 1, y + 1, x + 1, y + height - 1);
4542 gdk_draw_line (window, gc3,
4543 x + width - 2, y + 2, x + width - 2, y + height - 1);
4544 gdk_draw_line (window, gc4,
4545 x + width - 1, y + 1, x + width - 1, y + height - 1);
4548 gtk_style_apply_default_background (style, window,
4549 widget && !GTK_WIDGET_NO_WINDOW (widget),
4552 y + style->ythickness,
4553 width - (style->xthickness),
4554 height - (2 * style->ythickness));
4555 gdk_draw_line (window, gc1,
4556 x, y, x + width - 2, y);
4557 gdk_draw_line (window, gc2,
4558 x + 1, y + 1, x + width - 2, y + 1);
4560 gdk_draw_line (window, gc3,
4561 x, y + height - 2, x + width - 2, y + height - 2);
4562 gdk_draw_line (window, gc3,
4563 x + width - 2, y + 2, x + width - 2, y + height - 2);
4564 gdk_draw_line (window, gc4,
4565 x, y + height - 1, x + width - 2, y + height - 1);
4566 gdk_draw_line (window, gc4,
4567 x + width - 1, y + 1, x + width - 1, y + height - 2);
4570 gtk_style_apply_default_background (style, window,
4571 widget && !GTK_WIDGET_NO_WINDOW (widget),
4573 x + style->xthickness,
4574 y + style->ythickness,
4575 width - (style->xthickness),
4576 height - (2 * style->ythickness));
4577 gdk_draw_line (window, gc1,
4578 x + 1, y, x + width - 1, y);
4579 gdk_draw_line (window, gc1,
4580 x, y + 1, x, y + height - 2);
4581 gdk_draw_line (window, gc2,
4582 x + 1, y + 1, x + width - 1, y + 1);
4583 gdk_draw_line (window, gc2,
4584 x + 1, y + 1, x + 1, y + height - 2);
4586 gdk_draw_line (window, gc3,
4587 x + 2, y + height - 2, x + width - 1, y + height - 2);
4588 gdk_draw_line (window, gc4,
4589 x + 1, y + height - 1, x + width - 1, y + height - 1);
4596 gdk_gc_set_clip_rectangle (gc1, NULL);
4597 gdk_gc_set_clip_rectangle (gc2, NULL);
4598 gdk_gc_set_clip_rectangle (gc3, NULL);
4599 gdk_gc_set_clip_rectangle (gc4, NULL);
4604 gtk_default_draw_focus (GtkStyle *style,
4606 GtkStateType state_type,
4609 const gchar *detail,
4617 gboolean free_dash_list = FALSE;
4618 gint line_width = 1;
4619 gint8 *dash_list = "\1\1";
4624 gtk_widget_style_get (widget,
4625 "focus-line-width", &line_width,
4626 "focus-line-pattern", (gchar *)&dash_list,
4629 free_dash_list = TRUE;
4632 sanitize_size (window, &width, &height);
4634 if (detail && !strcmp (detail, "colorwheel_light"))
4635 gc = style->black_gc;
4636 else if (detail && !strcmp (detail, "colorwheel_dark"))
4637 gc = style->white_gc;
4639 gc = style->fg_gc[state_type];
4641 gdk_gc_set_line_attributes (gc, line_width,
4642 dash_list[0] ? GDK_LINE_ON_OFF_DASH : GDK_LINE_SOLID,
4643 GDK_CAP_BUTT, GDK_JOIN_MITER);
4646 gdk_gc_set_clip_rectangle (gc, area);
4648 if (detail && !strcmp (detail, "add-mode"))
4654 free_dash_list = FALSE;
4657 points[0].x = x + line_width / 2;
4658 points[0].y = y + line_width / 2;
4659 points[1].x = x + width - line_width + line_width / 2;
4660 points[1].y = y + line_width / 2;
4661 points[2].x = x + width - line_width + line_width / 2;
4662 points[2].y = y + height - line_width + line_width / 2;
4663 points[3].x = x + line_width / 2;
4664 points[3].y = y + height - line_width + line_width / 2;
4665 points[4] = points[0];
4669 gdk_draw_lines (window, gc, points, 5);
4673 /* We go through all the pain below because the X rasterization
4674 * rules don't really work right for dashed lines if you
4675 * want continuity in segments that go between top/right
4676 * and left/bottom. For instance, a top left corner
4677 * with a 1-1 dash is drawn as:
4684 * This is because pixels on the top and left boundaries
4685 * of polygons are drawn, but not on the bottom and right.
4686 * So, if you have a line going up that turns the corner
4687 * and goes right, there is a one pixel shift in the pattern.
4689 * So, to fix this, we drawn the top and right in one call,
4690 * then the left and bottom in another call, fixing up
4691 * the dash offset for the second call ourselves to get
4692 * continuity at the upper left.
4694 * It's not perfect since we really should have a join at
4695 * the upper left and lower right instead of two intersecting
4696 * lines but that's only really apparent for no-dashes,
4697 * which (for this reason) are done as one polygon and
4698 * don't to through this code path.
4701 dash_len = strlen (dash_list);
4704 gdk_gc_set_dashes (gc, 0, dash_list, dash_len);
4706 gdk_draw_lines (window, gc, points, 3);
4708 /* We draw this line one farther over than it is "supposed" to
4709 * because of another rasterization problem ... if two 1 pixel
4710 * unjoined lines meet at the lower right, there will be a missing
4717 gint dash_pixels = 0;
4720 /* Adjust the dash offset for the bottom and left so we
4721 * match up at the upper left.
4723 for (i = 0; i < dash_len; i++)
4724 dash_pixels += dash_list[i];
4726 if (dash_len % 2 == 1)
4729 gdk_gc_set_dashes (gc, dash_pixels - (width + height - 2 * line_width) % dash_pixels, dash_list, dash_len);
4732 gdk_draw_lines (window, gc, points + 2, 3);
4735 gdk_gc_set_line_attributes (gc, 0, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
4738 gdk_gc_set_clip_rectangle (gc, NULL);
4745 gtk_default_draw_slider (GtkStyle *style,
4747 GtkStateType state_type,
4748 GtkShadowType shadow_type,
4751 const gchar *detail,
4756 GtkOrientation orientation)
4758 g_return_if_fail (GTK_IS_STYLE (style));
4759 g_return_if_fail (window != NULL);
4761 sanitize_size (window, &width, &height);
4763 gtk_paint_box (style, window, state_type, shadow_type,
4764 area, widget, detail, x, y, width, height);
4767 (strcmp ("hscale", detail) == 0 ||
4768 strcmp ("vscale", detail) == 0))
4770 if (orientation == GTK_ORIENTATION_HORIZONTAL)
4771 gtk_paint_vline (style, window, state_type, area, widget, detail,
4772 y + style->ythickness,
4773 y + height - style->ythickness - 1, x + width / 2);
4775 gtk_paint_hline (style, window, state_type, area, widget, detail,
4776 x + style->xthickness,
4777 x + width - style->xthickness - 1, y + height / 2);
4782 draw_dot (GdkWindow *window,
4790 size = CLAMP (size, 2, 3);
4794 gdk_draw_point (window, light_gc, x, y);
4795 gdk_draw_point (window, light_gc, x+1, y+1);
4799 gdk_draw_point (window, light_gc, x, y);
4800 gdk_draw_point (window, light_gc, x+1, y);
4801 gdk_draw_point (window, light_gc, x, y+1);
4802 gdk_draw_point (window, dark_gc, x+1, y+2);
4803 gdk_draw_point (window, dark_gc, x+2, y+1);
4804 gdk_draw_point (window, dark_gc, x+2, y+2);
4809 gtk_default_draw_handle (GtkStyle *style,
4811 GtkStateType state_type,
4812 GtkShadowType shadow_type,
4815 const gchar *detail,
4820 GtkOrientation orientation)
4823 gint xthick, ythick;
4824 GdkGC *light_gc, *dark_gc;
4825 GdkGC *free_me = NULL;
4830 g_return_if_fail (GTK_IS_STYLE (style));
4831 g_return_if_fail (window != NULL);
4833 sanitize_size (window, &width, &height);
4835 gtk_paint_box (style, window, state_type, shadow_type, area, widget,
4836 detail, x, y, width, height);
4839 if (!strcmp (detail, "paned"))
4841 /* we want to ignore the shadow border in paned widgets */
4845 if (state_type == GTK_STATE_SELECTED && !GTK_WIDGET_HAS_FOCUS (widget))
4847 GdkColor unfocused_light;
4849 gtk_style_shade (&style->base[GTK_STATE_ACTIVE], &unfocused_light,
4852 light_gc = free_me = gdk_gc_new (window);
4853 gdk_gc_set_rgb_fg_color (light_gc, &unfocused_light);
4856 light_gc = style->light_gc[state_type];
4858 dark_gc = style->black_gc;
4862 xthick = style->xthickness;
4863 ythick = style->ythickness;
4865 light_gc = style->light_gc[state_type];
4866 dark_gc = style->dark_gc[state_type];
4869 rect.x = x + xthick;
4870 rect.y = y + ythick;
4871 rect.width = width - (xthick * 2);
4872 rect.height = height - (ythick * 2);
4875 intersect = gdk_rectangle_intersect (area, &rect, &dest);
4885 gdk_gc_set_clip_rectangle (light_gc, &dest);
4886 gdk_gc_set_clip_rectangle (dark_gc, &dest);
4888 if (!strcmp (detail, "paned"))
4890 if (orientation == GTK_ORIENTATION_HORIZONTAL)
4891 for (xx = x + width/2 - 15; xx <= x + width/2 + 15; xx += 5)
4892 draw_dot (window, light_gc, dark_gc, xx, y + height/2 - 1, 3);
4894 for (yy = y + height/2 - 15; yy <= y + height/2 + 15; yy += 5)
4895 draw_dot (window, light_gc, dark_gc, x + width/2 - 1, yy, 3);
4899 for (yy = y + ythick; yy < (y + height - ythick); yy += 3)
4900 for (xx = x + xthick; xx < (x + width - xthick); xx += 6)
4902 draw_dot (window, light_gc, dark_gc, xx, yy, 2);
4903 draw_dot (window, light_gc, dark_gc, xx + 3, yy + 1, 2);
4907 gdk_gc_set_clip_rectangle (light_gc, NULL);
4908 gdk_gc_set_clip_rectangle (dark_gc, NULL);
4912 g_object_unref (G_OBJECT (free_me));
4916 create_expander_affine (gdouble affine[6],
4926 width = expander_size / 4.0;
4927 height = expander_size / 2.0;
4929 s = sin (degrees * G_PI / 180.0);
4930 c = cos (degrees * G_PI / 180.0);
4936 affine[4] = -width * c - height * -s + x;
4937 affine[5] = -width * s - height * c + y;
4941 apply_affine_on_point (double affine[6], GdkPoint *point)
4945 x = point->x * affine[0] + point->y * affine[2] + affine[4];
4946 y = point->x * affine[1] + point->y * affine[3] + affine[5];
4948 point->x = floor (x);
4949 point->y = floor (y);
4953 gtk_style_draw_polygon_with_gc (GdkWindow *window, GdkGC *gc, gint line_width,
4954 gboolean do_fill, GdkPoint *points, gint n_points)
4956 gdk_gc_set_line_attributes (gc, line_width,
4958 GDK_CAP_BUTT, GDK_JOIN_MITER);
4960 gdk_draw_polygon (window, gc, do_fill, points, n_points);
4961 gdk_gc_set_line_attributes (gc, 0, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
4965 gtk_default_draw_expander (GtkStyle *style,
4967 GtkStateType state_type,
4970 const gchar *detail,
4973 GtkExpanderStyle expander_style)
4982 gtk_widget_style_get (widget,
4983 "expander_size", &expander_size,
4985 line_width = MAX (1, expander_size/7);
4989 gdk_gc_set_clip_rectangle (style->fg_gc[GTK_STATE_NORMAL], area);
4990 gdk_gc_set_clip_rectangle (style->base_gc[GTK_STATE_NORMAL], area);
4993 expander_size -= (line_width * 2 - 2);
4994 points[0].x = line_width / 2;
4995 points[0].y = line_width / 2;
4996 points[1].x = expander_size / 2 + line_width / 2;
4997 points[1].y = expander_size / 2 + line_width / 2;
4998 points[2].x = line_width / 2;
4999 points[2].y = expander_size + line_width / 2;
5001 switch (expander_style)
5003 case GTK_EXPANDER_COLLAPSED:
5004 degrees = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ? 180 : 0;
5006 case GTK_EXPANDER_SEMI_COLLAPSED:
5007 degrees = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ? 150 : 30;
5009 case GTK_EXPANDER_SEMI_EXPANDED:
5010 degrees = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ? 120 : 60;
5012 case GTK_EXPANDER_EXPANDED:
5016 g_assert_not_reached ();
5019 create_expander_affine (affine, degrees, expander_size, x, y);
5021 for (i = 0; i < 3; i++)
5022 apply_affine_on_point (affine, &points[i]);
5024 if (state_type == GTK_STATE_PRELIGHT)
5026 gtk_style_draw_polygon_with_gc (window, style->fg_gc[GTK_STATE_PRELIGHT],
5027 1, TRUE, points, 3);
5029 else if (state_type == GTK_STATE_ACTIVE)
5031 gtk_style_draw_polygon_with_gc (window, style->light_gc[GTK_STATE_ACTIVE],
5032 1, TRUE, points, 3);
5033 gtk_style_draw_polygon_with_gc (window, style->fg_gc[GTK_STATE_NORMAL],
5034 line_width, FALSE, points, 3);
5038 gtk_style_draw_polygon_with_gc (window, style->base_gc[GTK_STATE_NORMAL],
5039 1, TRUE, points, 3);
5040 gtk_style_draw_polygon_with_gc (window, style->fg_gc[GTK_STATE_NORMAL],
5041 line_width, FALSE, points, 3);
5045 gdk_gc_set_clip_rectangle (style->fg_gc[GTK_STATE_NORMAL], NULL);
5046 gdk_gc_set_clip_rectangle (style->base_gc[GTK_STATE_NORMAL], NULL);
5050 typedef struct _ByteRange ByteRange;
5059 range_new (guint start,
5062 ByteRange *br = g_new (ByteRange, 1);
5071 get_insensitive_layout (GdkDrawable *drawable,
5072 PangoLayout *layout)
5074 GSList *embossed_ranges = NULL;
5075 GSList *stippled_ranges = NULL;
5076 PangoLayoutIter *iter;
5077 GSList *tmp_list = NULL;
5078 PangoLayout *new_layout;
5079 PangoAttrList *attrs;
5080 GdkBitmap *stipple = NULL;
5082 iter = pango_layout_get_iter (layout);
5086 PangoLayoutRun *run;
5087 PangoAttribute *attr;
5088 gboolean need_stipple = FALSE;
5091 run = pango_layout_iter_get_run (iter);
5095 tmp_list = run->item->analysis.extra_attrs;
5097 while (tmp_list != NULL)
5099 attr = tmp_list->data;
5100 switch (attr->klass->type)
5102 case PANGO_ATTR_FOREGROUND:
5103 case PANGO_ATTR_BACKGROUND:
5104 need_stipple = TRUE;
5114 tmp_list = g_slist_next (tmp_list);
5117 br = range_new (run->item->offset, run->item->offset + run->item->length);
5120 stippled_ranges = g_slist_prepend (stippled_ranges, br);
5122 embossed_ranges = g_slist_prepend (embossed_ranges, br);
5125 while (pango_layout_iter_next_run (iter));
5127 pango_layout_iter_free (iter);
5129 new_layout = pango_layout_copy (layout);
5131 attrs = pango_layout_get_attributes (new_layout);
5135 /* Create attr list if there wasn't one */
5136 attrs = pango_attr_list_new ();
5137 pango_layout_set_attributes (new_layout, attrs);
5138 pango_attr_list_unref (attrs);
5141 tmp_list = embossed_ranges;
5142 while (tmp_list != NULL)
5144 PangoAttribute *attr;
5145 ByteRange *br = tmp_list->data;
5147 attr = gdk_pango_attr_embossed_new (TRUE);
5149 attr->start_index = br->start;
5150 attr->end_index = br->end;
5152 pango_attr_list_change (attrs, attr);
5156 tmp_list = g_slist_next (tmp_list);
5159 g_slist_free (embossed_ranges);
5161 tmp_list = stippled_ranges;
5162 while (tmp_list != NULL)
5164 PangoAttribute *attr;
5165 ByteRange *br = tmp_list->data;
5167 if (stipple == NULL)
5169 #define gray50_width 2
5170 #define gray50_height 2
5171 static const char gray50_bits[] = {
5175 stipple = gdk_bitmap_create_from_data (drawable,
5176 gray50_bits, gray50_width,
5180 attr = gdk_pango_attr_stipple_new (stipple);
5182 attr->start_index = br->start;
5183 attr->end_index = br->end;
5185 pango_attr_list_change (attrs, attr);
5189 tmp_list = g_slist_next (tmp_list);
5192 g_slist_free (stippled_ranges);
5195 g_object_unref (stipple);
5201 gtk_default_draw_layout (GtkStyle *style,
5203 GtkStateType state_type,
5207 const gchar *detail,
5210 PangoLayout *layout)
5214 g_return_if_fail (GTK_IS_STYLE (style));
5215 g_return_if_fail (window != NULL);
5217 gc = use_text ? style->text_gc[state_type] : style->fg_gc[state_type];
5220 gdk_gc_set_clip_rectangle (gc, area);
5222 if (state_type == GTK_STATE_INSENSITIVE)
5226 ins = get_insensitive_layout (window, layout);
5228 gdk_draw_layout (window, gc, x, y, ins);
5230 g_object_unref (ins);
5234 gdk_draw_layout (window, gc, x, y, layout);
5238 gdk_gc_set_clip_rectangle (gc, NULL);
5242 gtk_default_draw_resize_grip (GtkStyle *style,
5244 GtkStateType state_type,
5247 const gchar *detail,
5254 g_return_if_fail (GTK_IS_STYLE (style));
5255 g_return_if_fail (window != NULL);
5259 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
5260 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
5261 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
5266 case GDK_WINDOW_EDGE_NORTH_WEST:
5267 /* make it square */
5272 else if (height < width)
5277 case GDK_WINDOW_EDGE_NORTH:
5283 case GDK_WINDOW_EDGE_NORTH_EAST:
5284 /* make it square, aligning to top right */
5289 else if (height < width)
5291 x += (width - height);
5295 case GDK_WINDOW_EDGE_WEST:
5301 case GDK_WINDOW_EDGE_EAST:
5302 /* aligning to right */
5305 x += (width - height);
5309 case GDK_WINDOW_EDGE_SOUTH_WEST:
5310 /* make it square, aligning to bottom left */
5313 y += (height - width);
5316 else if (height < width)
5321 case GDK_WINDOW_EDGE_SOUTH:
5322 /* align to bottom */
5325 y += (height - width);
5329 case GDK_WINDOW_EDGE_SOUTH_EAST:
5330 /* make it square, aligning to bottom right */
5333 y += (height - width);
5336 else if (height < width)
5338 x += (width - height);
5343 g_assert_not_reached ();
5345 /* Clear background */
5346 gtk_style_apply_default_background (style, window, FALSE,
5348 x, y, width, height);
5352 case GDK_WINDOW_EDGE_WEST:
5353 case GDK_WINDOW_EDGE_EAST:
5359 while (xi < x + width)
5361 gdk_draw_line (window,
5362 style->light_gc[state_type],
5367 gdk_draw_line (window,
5368 style->dark_gc[state_type],
5376 case GDK_WINDOW_EDGE_NORTH:
5377 case GDK_WINDOW_EDGE_SOUTH:
5383 while (yi < y + height)
5385 gdk_draw_line (window,
5386 style->light_gc[state_type],
5391 gdk_draw_line (window,
5392 style->dark_gc[state_type],
5400 case GDK_WINDOW_EDGE_NORTH_WEST:
5409 gdk_draw_line (window,
5410 style->dark_gc[state_type],
5417 gdk_draw_line (window,
5418 style->dark_gc[state_type],
5425 gdk_draw_line (window,
5426 style->light_gc[state_type],
5436 case GDK_WINDOW_EDGE_NORTH_EAST:
5443 while (xi < (x + width - 3))
5445 gdk_draw_line (window,
5446 style->light_gc[state_type],
5453 gdk_draw_line (window,
5454 style->dark_gc[state_type],
5461 gdk_draw_line (window,
5462 style->dark_gc[state_type],
5471 case GDK_WINDOW_EDGE_SOUTH_WEST:
5480 gdk_draw_line (window,
5481 style->dark_gc[state_type],
5488 gdk_draw_line (window,
5489 style->dark_gc[state_type],
5496 gdk_draw_line (window,
5497 style->light_gc[state_type],
5507 case GDK_WINDOW_EDGE_SOUTH_EAST:
5514 while (xi < (x + width - 3))
5516 gdk_draw_line (window,
5517 style->light_gc[state_type],
5524 gdk_draw_line (window,
5525 style->dark_gc[state_type],
5532 gdk_draw_line (window,
5533 style->dark_gc[state_type],
5543 g_assert_not_reached ();
5549 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
5550 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
5551 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
5556 gtk_style_shade (GdkColor *a,
5564 red = (gdouble) a->red / 65535.0;
5565 green = (gdouble) a->green / 65535.0;
5566 blue = (gdouble) a->blue / 65535.0;
5568 rgb_to_hls (&red, &green, &blue);
5573 else if (green < 0.0)
5579 else if (blue < 0.0)
5582 hls_to_rgb (&red, &green, &blue);
5584 b->red = red * 65535.0;
5585 b->green = green * 65535.0;
5586 b->blue = blue * 65535.0;
5590 rgb_to_hls (gdouble *r,
5631 l = (max + min) / 2;
5638 s = (max - min) / (max + min);
5640 s = (max - min) / (2 - max - min);
5644 h = (green - blue) / delta;
5645 else if (green == max)
5646 h = 2 + (blue - red) / delta;
5647 else if (blue == max)
5648 h = 4 + (red - green) / delta;
5661 hls_to_rgb (gdouble *h,
5674 if (lightness <= 0.5)
5675 m2 = lightness * (1 + saturation);
5677 m2 = lightness + saturation - lightness * saturation;
5678 m1 = 2 * lightness - m2;
5680 if (saturation == 0)
5695 r = m1 + (m2 - m1) * hue / 60;
5699 r = m1 + (m2 - m1) * (240 - hue) / 60;
5710 g = m1 + (m2 - m1) * hue / 60;
5714 g = m1 + (m2 - m1) * (240 - hue) / 60;
5725 b = m1 + (m2 - m1) * hue / 60;
5729 b = m1 + (m2 - m1) * (240 - hue) / 60;
5742 * @style: a #GtkStyle
5743 * @window: a #GdkWindow
5744 * @state_type: a state
5745 * @area: rectangle to which the output is clipped
5746 * @widget: the widget
5747 * @detail: a style detail
5748 * @x1: the starting x coordinate
5749 * @x2: the ending x coordinate
5750 * @y: the y coordinate
5752 * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @window
5753 * using the given style and state.
5756 gtk_paint_hline (GtkStyle *style,
5758 GtkStateType state_type,
5761 const gchar *detail,
5766 g_return_if_fail (GTK_IS_STYLE (style));
5767 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
5769 GTK_STYLE_GET_CLASS (style)->draw_hline (style, window, state_type, area, widget, detail, x1, x2, y);
5774 * @style: a #GtkStyle
5775 * @window: a #GdkWindow
5776 * @state_type: a state
5777 * @area: rectangle to which the output is clipped
5778 * @widget: the widget
5779 * @detail: a style detail
5780 * @y1_: the starting y coordinate
5781 * @y2_: the ending y coordinate
5782 * @x: the x coordinate
5784 * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @window
5785 * using the given style and state.
5788 gtk_paint_vline (GtkStyle *style,
5790 GtkStateType state_type,
5793 const gchar *detail,
5798 g_return_if_fail (GTK_IS_STYLE (style));
5799 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
5801 GTK_STYLE_GET_CLASS (style)->draw_vline (style, window, state_type, area, widget, detail, y1_, y2_, x);
5806 * @style: a #GtkStyle
5807 * @window: a #GdkWindow
5808 * @state_type: a state
5809 * @shadow_type: type of shadow to draw
5810 * @area: clip rectangle
5811 * @widget: the widget
5812 * @detail: a style detail
5813 * @x: x origin of the rectangle
5814 * @y: y origin of the rectangle
5815 * @width: width of the rectangle
5816 * @height: width of the rectangle
5818 * Draws a shadow around the given rectangle in @window
5819 * using the given style and state and shadow type.
5822 gtk_paint_shadow (GtkStyle *style,
5824 GtkStateType state_type,
5825 GtkShadowType shadow_type,
5828 const gchar *detail,
5834 g_return_if_fail (GTK_IS_STYLE (style));
5835 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
5837 GTK_STYLE_GET_CLASS (style)->draw_shadow (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
5841 * gtk_paint_polygon:
5842 * @style: a #GtkStyle
5843 * @window: a #GdkWindow
5844 * @state_type: a state
5845 * @shadow_type: type of shadow to draw
5846 * @area: clip rectangle
5847 * @widget: the widget
5848 * @detail: a style detail
5849 * @points: an array of #GdkPoint<!-- -->s
5850 * @npoints: length of @points
5851 * @fill: %TRUE if the polygon should be filled
5853 * Draws a polygon on @window with the given parameters.
5856 gtk_paint_polygon (GtkStyle *style,
5858 GtkStateType state_type,
5859 GtkShadowType shadow_type,
5862 const gchar *detail,
5867 g_return_if_fail (GTK_IS_STYLE (style));
5868 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_polygon != NULL);
5870 GTK_STYLE_GET_CLASS (style)->draw_polygon (style, window, state_type, shadow_type, area, widget, detail, points, npoints, fill);
5875 * @style: a #GtkStyle
5876 * @window: a #GdkWindow
5877 * @state_type: a state
5878 * @shadow_type: the type of shadow to draw
5879 * @area: clip rectangle
5880 * @widget: the widget
5881 * @detail: a style detail
5882 * @arrow_type: the type of arrow to draw
5883 * @fill: %TRUE if the arrow tip should be filled
5884 * @x: x origin of the rectangle to draw the arrow in
5885 * @y: y origin of the rectangle to draw the arrow in
5886 * @width: width of the rectangle to draw the arrow in
5887 * @height: height of the rectangle to draw the arrow in
5889 * Draws an arrow in the given rectangle on @window using the given
5890 * parameters. @arrow_type determines the direction of the arrow.
5893 gtk_paint_arrow (GtkStyle *style,
5895 GtkStateType state_type,
5896 GtkShadowType shadow_type,
5899 const gchar *detail,
5900 GtkArrowType arrow_type,
5907 g_return_if_fail (GTK_IS_STYLE (style));
5908 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
5910 GTK_STYLE_GET_CLASS (style)->draw_arrow (style, window, state_type, shadow_type, area, widget, detail, arrow_type, fill, x, y, width, height);
5914 * gtk_paint_diamond:
5915 * @style: a #GtkStyle
5916 * @window: a #GdkWindow
5917 * @state_type: a state
5918 * @shadow_type: the type of shadow to draw
5919 * @area: clip rectangle
5920 * @widget: the widget
5921 * @detail: a style detail
5922 * @x: x origin of the rectangle to draw the diamond in
5923 * @y: y origin of the rectangle to draw the diamond in
5924 * @width: width of the rectangle to draw the diamond in
5925 * @height: height of the rectangle to draw the diamond in
5927 * Draws a diamond in the given rectangle on @window using the given
5931 gtk_paint_diamond (GtkStyle *style,
5933 GtkStateType state_type,
5934 GtkShadowType shadow_type,
5937 const gchar *detail,
5943 g_return_if_fail (GTK_IS_STYLE (style));
5944 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
5946 GTK_STYLE_GET_CLASS (style)->draw_diamond (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
5951 * @style: a #GtkStyle
5952 * @window: a #GdkWindow
5953 * @state_type: a state
5954 * @area: clip rectangle
5955 * @widget: the widget
5956 * @detail: a style detail
5959 * @string: the string to draw
5961 * Draws a text string on @window with the given parameters.
5963 * Deprecated: Use gtk_paint_layout() instead.
5966 gtk_paint_string (GtkStyle *style,
5968 GtkStateType state_type,
5971 const gchar *detail,
5974 const gchar *string)
5976 g_return_if_fail (GTK_IS_STYLE (style));
5977 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_string != NULL);
5979 GTK_STYLE_GET_CLASS (style)->draw_string (style, window, state_type, area, widget, detail, x, y, string);
5984 * @style: a #GtkStyle
5985 * @window: a #GdkWindow
5986 * @state_type: a state
5987 * @shadow_type: the type of shadow to draw
5988 * @area: clip rectangle
5989 * @widget: the widget
5990 * @detail: a style detail
5991 * @x: x origin of the box
5992 * @y: y origin of the box
5993 * @width: the width of the box
5994 * @height: the height of the box
5996 * Draws a box on @window with the given parameters.
5999 gtk_paint_box (GtkStyle *style,
6001 GtkStateType state_type,
6002 GtkShadowType shadow_type,
6005 const gchar *detail,
6011 g_return_if_fail (GTK_IS_STYLE (style));
6012 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
6014 GTK_STYLE_GET_CLASS (style)->draw_box (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
6018 * gtk_paint_flat_box:
6019 * @style: a #GtkStyle
6020 * @window: a #GdkWindow
6021 * @state_type: a state
6022 * @shadow_type: the type of shadow to draw
6023 * @area: clip rectangle
6024 * @widget: the widget
6025 * @detail: a style detail
6026 * @x: x origin of the box
6027 * @y: y origin of the box
6028 * @width: the width of the box
6029 * @height: the height of the box
6031 * Draws a flat box on @window with the given parameters.
6034 gtk_paint_flat_box (GtkStyle *style,
6036 GtkStateType state_type,
6037 GtkShadowType shadow_type,
6040 const gchar *detail,
6046 g_return_if_fail (GTK_IS_STYLE (style));
6047 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
6049 GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
6054 * @style: a #GtkStyle
6055 * @window: a #GdkWindow
6056 * @state_type: a state
6057 * @shadow_type: the type of shadow to draw
6058 * @area: clip rectangle
6059 * @widget: the widget
6060 * @detail: a style detail
6061 * @x: x origin of the rectangle to draw the check in
6062 * @y: y origin of the rectangle to draw the check in
6063 * @width: the width of the rectangle to draw the check in
6064 * @height: the height of the rectangle to draw the check in
6066 * Draws a check button indicator in the given rectangle on @window with
6067 * the given parameters.
6070 gtk_paint_check (GtkStyle *style,
6072 GtkStateType state_type,
6073 GtkShadowType shadow_type,
6076 const gchar *detail,
6082 g_return_if_fail (GTK_IS_STYLE (style));
6083 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
6085 GTK_STYLE_GET_CLASS (style)->draw_check (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
6090 * @style: a #GtkStyle
6091 * @window: a #GdkWindow
6092 * @state_type: a state
6093 * @shadow_type: the type of shadow to draw
6094 * @area: clip rectangle
6095 * @widget: the widget
6096 * @detail: a style detail
6097 * @x: x origin of the rectangle to draw the option in
6098 * @y: y origin of the rectangle to draw the option in
6099 * @width: the width of the rectangle to draw the option in
6100 * @height: the height of the rectangle to draw the option in
6102 * Draws a radio button indicator in the given rectangle on @window with
6103 * the given parameters.
6106 gtk_paint_option (GtkStyle *style,
6108 GtkStateType state_type,
6109 GtkShadowType shadow_type,
6112 const gchar *detail,
6118 g_return_if_fail (GTK_IS_STYLE (style));
6119 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
6121 GTK_STYLE_GET_CLASS (style)->draw_option (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
6126 * @style: a #GtkStyle
6127 * @window: a #GdkWindow
6128 * @state_type: a state
6129 * @shadow_type: the type of shadow to draw
6130 * @area: clip rectangle
6131 * @widget: the widget
6132 * @detail: a style detail
6133 * @x: x origin of the rectangle to draw the tab in
6134 * @y: y origin of the rectangle to draw the tab in
6135 * @width: the width of the rectangle to draw the tab in
6136 * @height: the height of the rectangle to draw the tab in
6138 * Draws an option menu tab (i.e. the up and down pointing arrows)
6139 * in the given rectangle on @window using the given parameters.
6142 gtk_paint_tab (GtkStyle *style,
6144 GtkStateType state_type,
6145 GtkShadowType shadow_type,
6148 const gchar *detail,
6154 g_return_if_fail (GTK_IS_STYLE (style));
6155 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
6157 GTK_STYLE_GET_CLASS (style)->draw_tab (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
6161 * gtk_paint_shadow_gap:
6162 * @style: a #GtkStyle
6163 * @window: a #GdkWindow
6164 * @state_type: a state
6165 * @shadow_type: type of shadow to draw
6166 * @area: clip rectangle
6167 * @widget: the widget
6168 * @detail: a style detail
6169 * @x: x origin of the rectangle
6170 * @y: y origin of the rectangle
6171 * @width: width of the rectangle
6172 * @height: width of the rectangle
6173 * @gap_side: side in which to leave the gap
6174 * @gap_x: starting position of the gap
6175 * @gap_width: width of the gap
6177 * Draws a shadow around the given rectangle in @window
6178 * using the given style and state and shadow type, leaving a
6182 gtk_paint_shadow_gap (GtkStyle *style,
6184 GtkStateType state_type,
6185 GtkShadowType shadow_type,
6193 GtkPositionType gap_side,
6197 g_return_if_fail (GTK_IS_STYLE (style));
6198 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
6200 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);
6205 * gtk_paint_box_gap:
6206 * @style: a #GtkStyle
6207 * @window: a #GdkWindow
6208 * @state_type: a state
6209 * @shadow_type: type of shadow to draw
6210 * @area: clip rectangle
6211 * @widget: the widget
6212 * @detail: a style detail
6213 * @x: x origin of the rectangle
6214 * @y: y origin of the rectangle
6215 * @width: width of the rectangle
6216 * @height: width of the rectangle
6217 * @gap_side: side in which to leave the gap
6218 * @gap_x: starting position of the gap
6219 * @gap_width: width of the gap
6221 * Draws a box in @window using the given style and state and shadow type,
6222 * leaving a gap in one side.
6225 gtk_paint_box_gap (GtkStyle *style,
6227 GtkStateType state_type,
6228 GtkShadowType shadow_type,
6236 GtkPositionType gap_side,
6240 g_return_if_fail (GTK_IS_STYLE (style));
6241 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
6243 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);
6247 * gtk_paint_extension:
6248 * @style: a #GtkStyle
6249 * @window: a #GdkWindow
6250 * @state_type: a state
6251 * @shadow_type: type of shadow to draw
6252 * @area: clip rectangle
6253 * @widget: the widget
6254 * @detail: a style detail
6255 * @x: x origin of the extension
6256 * @y: y origin of the extension
6257 * @width: width of the extension
6258 * @height: width of the extension
6259 * @gap_side: the side on to which the extension is attached
6261 * Draws an extension, i.e. a notebook tab.
6264 gtk_paint_extension (GtkStyle *style,
6266 GtkStateType state_type,
6267 GtkShadowType shadow_type,
6275 GtkPositionType gap_side)
6277 g_return_if_fail (GTK_IS_STYLE (style));
6278 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
6280 GTK_STYLE_GET_CLASS (style)->draw_extension (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, gap_side);
6285 * @style: a #GtkStyle
6286 * @window: a #GdkWindow
6287 * @state_type: a state
6288 * @area: clip rectangle
6289 * @widget: the widget
6290 * @detail: a style detail
6291 * @x: the x origin of the rectangle around which to draw a focus indicator
6292 * @y: the y origin of the rectangle around which to draw a focus indicator
6293 * @width: the width of the rectangle around which to draw a focus indicator
6294 * @height: the height of the rectangle around which to draw a focus indicator
6296 * Draws a focus indicator around the given rectangle on @window using the
6300 gtk_paint_focus (GtkStyle *style,
6302 GtkStateType state_type,
6305 const gchar *detail,
6311 g_return_if_fail (GTK_IS_STYLE (style));
6312 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
6314 GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, state_type, area, widget, detail, x, y, width, height);
6318 gtk_paint_slider (GtkStyle *style,
6320 GtkStateType state_type,
6321 GtkShadowType shadow_type,
6324 const gchar *detail,
6329 GtkOrientation orientation)
6331 g_return_if_fail (GTK_IS_STYLE (style));
6332 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
6334 GTK_STYLE_GET_CLASS (style)->draw_slider (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, orientation);
6339 * @style: a #GtkStyle
6340 * @window: a #GdkWindow
6341 * @state_type: a state
6342 * @shadow_type: type of shadow to draw
6343 * @area: clip rectangle
6344 * @widget: the widget
6345 * @detail: a style detail
6346 * @x: x origin of the handle
6347 * @y: y origin of the handle
6348 * @width: with of the handle
6349 * @height: height of the handle
6350 * @orientation: the orientation of the handle
6352 * Draws a handle as used in #GtkHandleBox and #GtkPaned.
6355 gtk_paint_handle (GtkStyle *style,
6357 GtkStateType state_type,
6358 GtkShadowType shadow_type,
6361 const gchar *detail,
6366 GtkOrientation orientation)
6368 g_return_if_fail (GTK_IS_STYLE (style));
6369 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
6371 GTK_STYLE_GET_CLASS (style)->draw_handle (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, orientation);
6375 * gtk_paint_expander:
6376 * @style: a #GtkStyle
6377 * @window: a #GdkWindow
6378 * @state_type: a state
6379 * @area: clip rectangle
6380 * @widget: the widget
6381 * @detail: a style detail
6382 * @x: the x position to draw the expander at
6383 * @y: the y position to draw the expander at
6384 * @expander_style: the style to draw the expander in
6386 * Draws an expander as used in #GtkTreeView.
6389 gtk_paint_expander (GtkStyle *style,
6391 GtkStateType state_type,
6394 const gchar *detail,
6397 GtkExpanderStyle expander_style)
6399 g_return_if_fail (GTK_IS_STYLE (style));
6400 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
6402 GTK_STYLE_GET_CLASS (style)->draw_expander (style, window, state_type, area,
6403 widget, detail, x, y, expander_style);
6407 gtk_paint_layout (GtkStyle *style,
6409 GtkStateType state_type,
6413 const gchar *detail,
6416 PangoLayout *layout)
6418 g_return_if_fail (GTK_IS_STYLE (style));
6419 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
6421 GTK_STYLE_GET_CLASS (style)->draw_layout (style, window, state_type, use_text, area,
6422 widget, detail, x, y, layout);
6426 * gtk_paint_resize_grip:
6427 * @style: a #GtkStyle
6428 * @window: a #GdkWindow
6429 * @state_type: a state
6430 * @area: clip rectangle
6431 * @widget: the widget
6432 * @detail: a style detail
6433 * @edge: the edge in which to draw the resize grip
6434 * @x: the x origin of the rectangle in which to draw the resize grip
6435 * @y: the y origin of the rectangle in which to draw the resize grip
6436 * @width: the width of the rectangle in which to draw the resize grip
6437 * @height: the height of the rectangle in which to draw the resize grip
6439 * Draws a resize grip in the given rectangle on @window using the given
6443 gtk_paint_resize_grip (GtkStyle *style,
6445 GtkStateType state_type,
6448 const gchar *detail,
6456 g_return_if_fail (GTK_IS_STYLE (style));
6457 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
6459 GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, window, state_type,
6460 area, widget, detail,
6461 edge, x, y, width, height);
6466 * @border_: a #GtkBorder.
6467 * @returns: a copy of @border_.
6469 * Copies a #GtkBorder structure.
6472 gtk_border_copy (const GtkBorder *border)
6474 return (GtkBorder *)g_memdup (border, sizeof (GtkBorder));
6479 * @border_: a #GtkBorder.
6481 * Frees a #GtkBorder structure.
6484 gtk_border_free (GtkBorder *border)
6490 gtk_border_get_type (void)
6492 static GType our_type = 0;
6495 our_type = g_boxed_type_register_static ("GtkBorder",
6496 (GBoxedCopyFunc) gtk_border_copy,
6497 (GBoxedFreeFunc) gtk_border_free);
6503 gtk_style_get_font_internal (GtkStyle *style)
6505 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
6507 if (style->private_font && style->private_font_desc)
6509 if (!style->font_desc ||
6510 !pango_font_description_equal (style->private_font_desc, style->font_desc))
6512 gdk_font_unref (style->private_font);
6513 style->private_font = NULL;
6515 if (style->private_font_desc)
6517 pango_font_description_free (style->private_font_desc);
6518 style->private_font_desc = NULL;
6523 if (!style->private_font)
6525 GdkDisplay *display;
6527 if (style->colormap)
6529 display = gdk_screen_get_display (gdk_colormap_get_screen (style->colormap));
6533 display = gdk_display_get_default ();
6534 GTK_NOTE (MULTIHEAD,
6535 g_warning ("gtk_style_get_font() should not be called on an unattached style"));
6538 if (style->font_desc)
6540 style->private_font = gdk_font_from_description_for_display (display, style->font_desc);
6541 style->private_font_desc = pango_font_description_copy (style->font_desc);
6544 if (!style->private_font)
6545 style->private_font = gdk_font_load_for_display (display, "fixed");
6547 if (!style->private_font)
6548 g_error ("Unable to load \"fixed\" font");
6551 return style->private_font;
6555 * gtk_style_get_font:
6556 * @style: a #GtkStyle
6558 * Gets the #GdkFont to use for the given style. This is
6559 * meant only as a replacement for direct access to @style->font
6560 * and should not be used in new code. New code should
6561 * use @style->font_desc instead.
6563 * Return value: the #GdkFont for the style. This font is owned
6564 * by the style; if you want to keep around a copy, you must
6565 * call gdk_font_ref().
6568 gtk_style_get_font (GtkStyle *style)
6570 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
6572 return gtk_style_get_font_internal (style);
6576 * gtk_style_set_font:
6577 * @style: a #GtkStyle.
6578 * @font: a #GdkFont, or %NULL to use the #GdkFont corresponding
6579 * to style->font_desc.
6581 * Sets the #GdkFont to use for a given style. This is
6582 * meant only as a replacement for direct access to style->font
6583 * and should not be used in new code. New code should
6584 * use style->font_desc instead.
6587 gtk_style_set_font (GtkStyle *style,
6592 g_return_if_fail (GTK_IS_STYLE (style));
6594 old_font = style->private_font;
6596 style->private_font = font;
6598 gdk_font_ref (font);
6601 gdk_font_unref (old_font);
6603 if (style->private_font_desc)
6605 pango_font_description_free (style->private_font_desc);
6606 style->private_font_desc = NULL;
6610 typedef struct _CursorInfo CursorInfo;
6616 GdkGC *secondary_gc;
6620 style_unrealize_cursor_gcs (GtkStyle *style)
6624 cursor_info = g_object_get_data (G_OBJECT (style), "gtk-style-cursor-info");
6627 if (cursor_info->primary_gc)
6628 gtk_gc_release (cursor_info->primary_gc);
6630 if (cursor_info->secondary_gc)
6631 gtk_gc_release (cursor_info->secondary_gc);
6633 g_free (cursor_info);
6634 g_object_set_data (G_OBJECT (style), "gtk-style-cursor-info", NULL);
6639 make_cursor_gc (GtkWidget *widget,
6640 const gchar *property_name,
6641 const GdkColor *fallback)
6643 GdkGCValues gc_values;
6644 GdkGCValuesMask gc_values_mask;
6645 GdkColor *cursor_color;
6647 gtk_widget_style_get (widget, property_name, &cursor_color, NULL);
6649 gc_values_mask = GDK_GC_FOREGROUND;
6652 gc_values.foreground = *cursor_color;
6653 gdk_color_free (cursor_color);
6656 gc_values.foreground = *fallback;
6658 gdk_rgb_find_color (widget->style->colormap, &gc_values.foreground);
6659 return gtk_gc_get (widget->style->depth, widget->style->colormap, &gc_values, gc_values_mask);
6663 get_insertion_cursor_gc (GtkWidget *widget,
6664 gboolean is_primary)
6666 CursorInfo *cursor_info;
6668 cursor_info = g_object_get_data (G_OBJECT (widget->style), "gtk-style-cursor-info");
6671 cursor_info = g_new (CursorInfo, 1);
6672 g_object_set_data (G_OBJECT (widget->style), "gtk-style-cursor-info", cursor_info);
6673 cursor_info->primary_gc = NULL;
6674 cursor_info->secondary_gc = NULL;
6675 cursor_info->for_type = G_TYPE_INVALID;
6678 /* We have to keep track of the type because gtk_widget_style_get()
6679 * can return different results when called on the same property and
6680 * same style but for different widgets. :-(. That is,
6681 * GtkEntry::cursor-color = "red" in a style will modify the cursor
6682 * color for entries but not for text view.
6684 if (cursor_info->for_type != G_OBJECT_TYPE (widget))
6686 cursor_info->for_type = G_OBJECT_TYPE (widget);
6687 if (cursor_info->primary_gc)
6689 gtk_gc_release (cursor_info->primary_gc);
6690 cursor_info->primary_gc = NULL;
6692 if (cursor_info->secondary_gc)
6694 gtk_gc_release (cursor_info->secondary_gc);
6695 cursor_info->secondary_gc = NULL;
6701 if (!cursor_info->primary_gc)
6702 cursor_info->primary_gc = make_cursor_gc (widget,
6704 &widget->style->black);
6706 return cursor_info->primary_gc;
6710 static const GdkColor gray = { 0, 0x8888, 0x8888, 0x8888 };
6712 if (!cursor_info->secondary_gc)
6713 cursor_info->secondary_gc = make_cursor_gc (widget,
6714 "secondary-cursor-color",
6717 return cursor_info->secondary_gc;
6722 draw_insertion_cursor (GtkWidget *widget,
6723 GdkDrawable *drawable,
6725 GdkRectangle *location,
6726 GtkTextDirection direction,
6727 gboolean draw_arrow)
6733 gfloat cursor_aspect_ratio;
6736 g_return_if_fail (direction != GTK_TEXT_DIR_NONE);
6738 gtk_widget_style_get (widget, "cursor-aspect-ratio", &cursor_aspect_ratio, NULL);
6740 stem_width = location->height * cursor_aspect_ratio + 1;
6741 arrow_width = stem_width + 1;
6743 /* put (stem_width % 2) on the proper side of the cursor */
6744 if (direction == GTK_TEXT_DIR_LTR)
6745 offset = stem_width / 2;
6747 offset = stem_width - stem_width / 2;
6749 for (i = 0; i < stem_width; i++)
6750 gdk_draw_line (drawable, gc,
6751 location->x + i - offset, location->y,
6752 location->x + i - offset, location->y + location->height - 1);
6756 if (direction == GTK_TEXT_DIR_RTL)
6758 x = location->x - offset - 1;
6759 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
6761 for (i = 0; i < arrow_width; i++)
6763 gdk_draw_line (drawable, gc,
6765 x, y + 2 * arrow_width - i - 1);
6769 else if (direction == GTK_TEXT_DIR_LTR)
6771 x = location->x + stem_width - offset;
6772 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
6774 for (i = 0; i < arrow_width; i++)
6776 gdk_draw_line (drawable, gc,
6778 x, y + 2 * arrow_width - i - 1);
6786 * gtk_draw_insertion_cursor:
6787 * @widget: a #GtkWidget
6788 * @drawable: a #GdkDrawable
6789 * @area: rectangle to which the output is clipped, or %NULL if the
6790 * output should not be clipped
6791 * @location: location where to draw the cursor (@location->width is ignored)
6792 * @is_primary: if the cursor should be the primary cursor color.
6793 * @direction: whether the cursor is left-to-right or
6794 * right-to-left. Should never be #GTK_TEXT_DIR_NONE
6795 * @draw_arrow: %TRUE to draw a directional arrow on the
6796 * cursor. Should be %FALSE unless the cursor is split.
6798 * Draws a text caret on @drawable at @location. This is not a style function
6799 * but merely a convenience function for drawing the standard cursor shape.
6804 gtk_draw_insertion_cursor (GtkWidget *widget,
6805 GdkDrawable *drawable,
6807 GdkRectangle *location,
6808 gboolean is_primary,
6809 GtkTextDirection direction,
6810 gboolean draw_arrow)
6814 g_return_if_fail (GTK_IS_WIDGET (widget));
6815 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
6816 g_return_if_fail (location != NULL);
6817 g_return_if_fail (direction != GTK_TEXT_DIR_NONE);
6819 gc = get_insertion_cursor_gc (widget, is_primary);
6821 gdk_gc_set_clip_rectangle (gc, area);
6823 draw_insertion_cursor (widget, drawable, gc,
6824 location, direction, draw_arrow);
6827 gdk_gc_set_clip_rectangle (gc, NULL);