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 "gtkspinbutton.h"
34 #include "gtkwidget.h"
35 #include "gtkthemes.h"
36 #include "gtkiconfactory.h"
37 #include "gtksettings.h" /* _gtk_settings_parse_convert() */
39 #define LIGHTNESS_MULT 1.3
40 #define DARKNESS_MULT 0.7
42 /* --- typedefs & structures --- */
49 /* --- prototypes --- */
50 static void gtk_style_init (GtkStyle *style);
51 static void gtk_style_class_init (GtkStyleClass *klass);
52 static void gtk_style_finalize (GObject *object);
53 static void gtk_style_realize (GtkStyle *style,
54 GdkColormap *colormap);
55 static void gtk_style_real_realize (GtkStyle *style);
56 static void gtk_style_real_unrealize (GtkStyle *style);
57 static void gtk_style_real_copy (GtkStyle *style,
59 static void gtk_style_real_set_background (GtkStyle *style,
61 GtkStateType state_type);
62 static GtkStyle *gtk_style_real_clone (GtkStyle *style);
63 static void gtk_style_real_init_from_rc (GtkStyle *style,
64 GtkRcStyle *rc_style);
65 static GdkPixbuf *gtk_default_render_icon (GtkStyle *style,
66 const GtkIconSource *source,
67 GtkTextDirection direction,
72 static void gtk_default_draw_hline (GtkStyle *style,
74 GtkStateType state_type,
81 static void gtk_default_draw_vline (GtkStyle *style,
83 GtkStateType state_type,
90 static void gtk_default_draw_shadow (GtkStyle *style,
92 GtkStateType state_type,
93 GtkShadowType shadow_type,
101 static void gtk_default_draw_polygon (GtkStyle *style,
103 GtkStateType state_type,
104 GtkShadowType shadow_type,
111 static void gtk_default_draw_arrow (GtkStyle *style,
113 GtkStateType state_type,
114 GtkShadowType shadow_type,
118 GtkArrowType arrow_type,
124 static void gtk_default_draw_diamond (GtkStyle *style,
126 GtkStateType state_type,
127 GtkShadowType shadow_type,
135 static void gtk_default_draw_string (GtkStyle *style,
137 GtkStateType state_type,
143 const gchar *string);
144 static void gtk_default_draw_box (GtkStyle *style,
146 GtkStateType state_type,
147 GtkShadowType shadow_type,
155 static void gtk_default_draw_flat_box (GtkStyle *style,
157 GtkStateType state_type,
158 GtkShadowType shadow_type,
166 static void gtk_default_draw_check (GtkStyle *style,
168 GtkStateType state_type,
169 GtkShadowType shadow_type,
177 static void gtk_default_draw_option (GtkStyle *style,
179 GtkStateType state_type,
180 GtkShadowType shadow_type,
188 static void gtk_default_draw_tab (GtkStyle *style,
190 GtkStateType state_type,
191 GtkShadowType shadow_type,
199 static void gtk_default_draw_shadow_gap (GtkStyle *style,
201 GtkStateType state_type,
202 GtkShadowType shadow_type,
210 GtkPositionType gap_side,
213 static void gtk_default_draw_box_gap (GtkStyle *style,
215 GtkStateType state_type,
216 GtkShadowType shadow_type,
224 GtkPositionType gap_side,
227 static void gtk_default_draw_extension (GtkStyle *style,
229 GtkStateType state_type,
230 GtkShadowType shadow_type,
238 GtkPositionType gap_side);
239 static void gtk_default_draw_focus (GtkStyle *style,
241 GtkStateType state_type,
249 static void gtk_default_draw_slider (GtkStyle *style,
251 GtkStateType state_type,
252 GtkShadowType shadow_type,
260 GtkOrientation orientation);
261 static void gtk_default_draw_handle (GtkStyle *style,
263 GtkStateType state_type,
264 GtkShadowType shadow_type,
272 GtkOrientation orientation);
273 static void gtk_default_draw_expander (GtkStyle *style,
275 GtkStateType state_type,
281 GtkExpanderStyle expander_style);
282 static void gtk_default_draw_layout (GtkStyle *style,
284 GtkStateType state_type,
291 PangoLayout *layout);
292 static void gtk_default_draw_resize_grip (GtkStyle *style,
294 GtkStateType state_type,
304 static void gtk_style_shade (GdkColor *a,
307 static void rgb_to_hls (gdouble *r,
310 static void hls_to_rgb (gdouble *h,
314 static void style_unrealize_cursor_gcs (GtkStyle *style);
316 static GdkFont *gtk_style_get_font_internal (GtkStyle *style);
319 * Data for default check and radio buttons
322 static const GtkRequisition default_option_indicator_size = { 7, 13 };
323 static const GtkBorder default_option_indicator_spacing = { 7, 5, 2, 2 };
325 #define INDICATOR_PART_SIZE 13
335 CHECK_INCONSISTENT_TEXT,
342 RADIO_INCONSISTENT_AA,
343 RADIO_INCONSISTENT_TEXT
347 * Extracted from check-13.png, width=13, height=13
349 static const guchar check_black_bits[] = {
350 0x00,0x00,0xfe,0x0f,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,
351 0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00};
352 static const guchar check_dark_bits[] = {
353 0xff,0x1f,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,
354 0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00};
355 static const guchar check_mid_bits[] = {
356 0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,
357 0x08,0x00,0x08,0x00,0x08,0x00,0x08,0xfc,0x0f,0x00,0x00,0x00,0x00};
358 static const guchar check_light_bits[] = {
359 0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,
360 0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0xfe,0x1f,0x00,0x00};
361 static const guchar check_text_bits[] = {
362 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x03,0x80,0x01,0x80,0x00,0x58,
363 0x00,0x60,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
364 static const guchar check_aa_bits[] = {
365 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x58,0x00,0xa0,
366 0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
367 static const guchar check_base_bits[] = {
368 0x00,0x00,0x00,0x00,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc,
369 0x07,0xfc,0x07,0xfc,0x07,0xfc,0x07,0x00,0x00,0x00,0x00,0x00,0x00};
372 * Extracted from check-13-inconsistent.png, width=13, height=13
374 static const guchar check_inconsistent_text_bits[] = {
375 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x03,0xf8,
376 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
379 * check_inconsistent_aa_bits is currently not used, since it is all zeros.
381 static const guchar check_inconsistent_aa_bits[] = {
382 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
383 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
387 * Extracted from radio-13.png, width=13, height=13
389 static const guchar radio_black_bits[] = {
390 0x00,0x00,0xf0,0x01,0x0c,0x02,0x04,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,
391 0x00,0x02,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x08};
392 static const guchar radio_dark_bits[] = {
393 0xf0,0x00,0x0c,0x02,0x02,0x04,0x02,0x04,0x01,0x08,0x01,0x08,0x01,0x08,0x01,
394 0x08,0x00,0x08,0x02,0x04,0x0c,0x06,0xf0,0x01,0x00,0x00,0x00,0x00};
395 static const guchar radio_mid_bits[] = {
396 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
397 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
398 static const guchar radio_light_bits[] = {
399 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,
400 0x10,0x00,0x10,0x00,0x08,0x00,0x08,0x00,0x06,0xe0,0x01,0x00,0x00};
401 static const guchar radio_text_bits[] = {
402 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0xf0,0x01,0xf0,0x01,0xf0,
403 0x01,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
406 * radio_aa_bits is currently not used, since it is all zeros.
408 static const guchar radio_aa_bits[] = {
409 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
410 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
412 static const guchar radio_base_bits[] = {
413 0x00,0x00,0x00,0x00,0xf0,0x01,0xf8,0x03,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc,
414 0x07,0xfc,0x07,0xf8,0x03,0xf0,0x01,0x00,0x00,0x00,0x00,0x00,0x00};
417 * Extracted from radio-13.png, width=13, height=13
419 static const guchar radio_inconsistent_text_bits[] = {
420 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x03,0x00,
421 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
422 static const guchar radio_inconsistent_aa_bits[] = {
423 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x03,0x00,0x00,0xf8,
424 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
428 GList *bmap_list; /* list of GdkBitmap */
429 } indicator_parts[] = {
430 { check_aa_bits, NULL },
431 { check_base_bits, NULL },
432 { check_black_bits, NULL },
433 { check_dark_bits, NULL },
434 { check_light_bits, NULL },
435 { check_mid_bits, NULL },
436 { check_text_bits, NULL },
437 { check_inconsistent_text_bits, NULL },
438 { radio_base_bits, NULL },
439 { radio_black_bits, NULL },
440 { radio_dark_bits, NULL },
441 { radio_light_bits, NULL },
442 { radio_mid_bits, NULL },
443 { radio_text_bits, NULL },
444 { radio_inconsistent_aa_bits, NULL },
445 { radio_inconsistent_text_bits, NULL },
448 /* --- variables --- */
449 static const GdkColor gtk_default_normal_fg = { 0, 0, 0, 0 };
450 static const GdkColor gtk_default_active_fg = { 0, 0, 0, 0 };
451 static const GdkColor gtk_default_prelight_fg = { 0, 0, 0, 0 };
452 static const GdkColor gtk_default_selected_fg = { 0, 0xffff, 0xffff, 0xffff };
453 static const GdkColor gtk_default_insensitive_fg = { 0, 0x7530, 0x7530, 0x7530 };
455 static const GdkColor gtk_default_normal_bg = { 0, 0xdcdc, 0xdada, 0xd5d5 };
456 static const GdkColor gtk_default_active_bg = { 0, 0xbaba, 0xb5b5, 0xabab };
457 static const GdkColor gtk_default_prelight_bg = { 0, 0xeeee, 0xebeb, 0xe7e7 };
458 static const GdkColor gtk_default_selected_bg = { 0, 0x4b4b, 0x6969, 0x8383 };
459 static const GdkColor gtk_default_insensitive_bg = { 0, 0xdcdc, 0xdada, 0xd5d5 };
460 static const GdkColor gtk_default_selected_base = { 0, 0x4b4b, 0x6969, 0x8383 };
461 static const GdkColor gtk_default_active_base = { 0, 0x8080, 0x7d7d, 0x7474 };
463 static gpointer parent_class = NULL;
466 /* --- functions --- */
468 gtk_style_get_type (void)
470 static GType style_type = 0;
474 static const GTypeInfo style_info =
476 sizeof (GtkStyleClass),
477 (GBaseInitFunc) NULL,
478 (GBaseFinalizeFunc) NULL,
479 (GClassInitFunc) gtk_style_class_init,
480 NULL, /* class_finalize */
481 NULL, /* class_data */
484 (GInstanceInitFunc) gtk_style_init,
487 style_type = g_type_register_static (G_TYPE_OBJECT, "GtkStyle",
495 * _gtk_style_init_for_settings:
496 * @style: a #GtkStyle
497 * @settings: a #GtkSettings
499 * Initializes the font description in @style accoridng to the default
500 * font name of @settings. This is called for gtk_style_new() with
501 * the settings for the default screen (if any); if we are creating
502 * a style for a particular screen, we then call it again in a
503 * location where we know the correct settings.
504 * The reason for this is that gtk_rc_style_create_style() doesn't
505 * take the screen for an argument.
508 _gtk_style_init_for_settings (GtkStyle *style,
509 GtkSettings *settings)
511 const gchar *font_name = _gtk_rc_context_get_default_font_name (settings);
513 if (style->font_desc)
514 pango_font_description_free (style->font_desc);
516 style->font_desc = pango_font_description_from_string (font_name);
518 if (!pango_font_description_get_family (style->font_desc))
520 g_warning ("Default font does not have a family set");
521 pango_font_description_set_family (style->font_desc, "Sans");
523 if (pango_font_description_get_size (style->font_desc) <= 0)
525 g_warning ("Default font does not have a positive size");
526 pango_font_description_set_size (style->font_desc, 10 * PANGO_SCALE);
531 gtk_style_init (GtkStyle *style)
535 GtkSettings *settings = gtk_settings_get_default ();
538 _gtk_style_init_for_settings (style, settings);
540 style->font_desc = pango_font_description_from_string ("Sans 10");
542 style->attach_count = 0;
543 style->colormap = NULL;
546 style->black.red = 0;
547 style->black.green = 0;
548 style->black.blue = 0;
550 style->white.red = 65535;
551 style->white.green = 65535;
552 style->white.blue = 65535;
554 style->black_gc = NULL;
555 style->white_gc = NULL;
557 style->fg[GTK_STATE_NORMAL] = gtk_default_normal_fg;
558 style->fg[GTK_STATE_ACTIVE] = gtk_default_active_fg;
559 style->fg[GTK_STATE_PRELIGHT] = gtk_default_prelight_fg;
560 style->fg[GTK_STATE_SELECTED] = gtk_default_selected_fg;
561 style->fg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
563 style->bg[GTK_STATE_NORMAL] = gtk_default_normal_bg;
564 style->bg[GTK_STATE_ACTIVE] = gtk_default_active_bg;
565 style->bg[GTK_STATE_PRELIGHT] = gtk_default_prelight_bg;
566 style->bg[GTK_STATE_SELECTED] = gtk_default_selected_bg;
567 style->bg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_bg;
569 for (i = 0; i < 4; i++)
571 style->text[i] = style->fg[i];
572 style->base[i] = style->white;
575 style->base[GTK_STATE_SELECTED] = gtk_default_selected_base;
576 style->text[GTK_STATE_SELECTED] = style->white;
577 style->base[GTK_STATE_ACTIVE] = gtk_default_active_base;
578 style->text[GTK_STATE_ACTIVE] = style->white;
579 style->base[GTK_STATE_INSENSITIVE] = gtk_default_prelight_bg;
580 style->text[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
582 for (i = 0; i < 5; i++)
583 style->bg_pixmap[i] = NULL;
585 style->rc_style = NULL;
587 for (i = 0; i < 5; i++)
589 style->fg_gc[i] = NULL;
590 style->bg_gc[i] = NULL;
591 style->light_gc[i] = NULL;
592 style->dark_gc[i] = NULL;
593 style->mid_gc[i] = NULL;
594 style->text_gc[i] = NULL;
595 style->base_gc[i] = NULL;
596 style->text_aa_gc[i] = NULL;
599 style->xthickness = 2;
600 style->ythickness = 2;
602 style->property_cache = NULL;
606 gtk_style_class_init (GtkStyleClass *klass)
608 GObjectClass *object_class = G_OBJECT_CLASS (klass);
610 parent_class = g_type_class_peek_parent (klass);
612 object_class->finalize = gtk_style_finalize;
614 klass->clone = gtk_style_real_clone;
615 klass->copy = gtk_style_real_copy;
616 klass->init_from_rc = gtk_style_real_init_from_rc;
617 klass->realize = gtk_style_real_realize;
618 klass->unrealize = gtk_style_real_unrealize;
619 klass->set_background = gtk_style_real_set_background;
620 klass->render_icon = gtk_default_render_icon;
622 klass->draw_hline = gtk_default_draw_hline;
623 klass->draw_vline = gtk_default_draw_vline;
624 klass->draw_shadow = gtk_default_draw_shadow;
625 klass->draw_polygon = gtk_default_draw_polygon;
626 klass->draw_arrow = gtk_default_draw_arrow;
627 klass->draw_diamond = gtk_default_draw_diamond;
628 klass->draw_string = gtk_default_draw_string;
629 klass->draw_box = gtk_default_draw_box;
630 klass->draw_flat_box = gtk_default_draw_flat_box;
631 klass->draw_check = gtk_default_draw_check;
632 klass->draw_option = gtk_default_draw_option;
633 klass->draw_tab = gtk_default_draw_tab;
634 klass->draw_shadow_gap = gtk_default_draw_shadow_gap;
635 klass->draw_box_gap = gtk_default_draw_box_gap;
636 klass->draw_extension = gtk_default_draw_extension;
637 klass->draw_focus = gtk_default_draw_focus;
638 klass->draw_slider = gtk_default_draw_slider;
639 klass->draw_handle = gtk_default_draw_handle;
640 klass->draw_expander = gtk_default_draw_expander;
641 klass->draw_layout = gtk_default_draw_layout;
642 klass->draw_resize_grip = gtk_default_draw_resize_grip;
646 clear_property_cache (GtkStyle *style)
648 if (style->property_cache)
652 for (i = 0; i < style->property_cache->len; i++)
654 PropertyValue *node = &g_array_index (style->property_cache, PropertyValue, i);
656 g_param_spec_unref (node->pspec);
657 g_value_unset (&node->value);
659 g_array_free (style->property_cache, TRUE);
660 style->property_cache = NULL;
665 gtk_style_finalize (GObject *object)
667 GtkStyle *style = GTK_STYLE (object);
669 g_return_if_fail (style->attach_count == 0);
671 clear_property_cache (style);
675 if (style->styles->data != style)
676 g_slist_remove (style->styles, style);
679 GSList *tmp_list = style->styles->next;
683 GTK_STYLE (tmp_list->data)->styles = style->styles->next;
684 tmp_list = tmp_list->next;
686 g_slist_free_1 (style->styles);
690 pango_font_description_free (style->font_desc);
692 if (style->private_font)
693 gdk_font_unref (style->private_font);
695 if (style->private_font_desc)
696 pango_font_description_free (style->private_font_desc);
699 gtk_rc_style_unref (style->rc_style);
701 G_OBJECT_CLASS (parent_class)->finalize (object);
706 gtk_style_copy (GtkStyle *style)
710 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
712 new_style = GTK_STYLE_GET_CLASS (style)->clone (style);
713 GTK_STYLE_GET_CLASS (style)->copy (new_style, style);
719 gtk_style_duplicate (GtkStyle *style)
723 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
725 new_style = gtk_style_copy (style);
727 style->styles = g_slist_append (style->styles, new_style);
728 new_style->styles = style->styles;
735 * @returns: a new #GtkStyle.
737 * Creates a new #GtkStyle.
744 style = g_object_new (GTK_TYPE_STYLE, NULL);
751 * @style: a #GtkStyle.
752 * @window: a #GdkWindow.
753 * @returns: Either @style, or a newly-created #GtkStyle.
754 * If the style is newly created, the style parameter
755 * will be dereferenced, and the new style will have
756 * a reference count belonging to the caller.
758 * Attaches a style to a window; this process allocates the
759 * colors and creates the GC's for the style - it specializes
760 * it to a particular visual and colormap. The process may
761 * involve the creation of a new style if the style has already
762 * been attached to a window with a different style and colormap.
765 * FIXME: The sequence -
766 * create a style => s1
767 * attach s1 to v1, c1 => s1
768 * attach s1 to v2, c2 => s2
769 * detach s1 from v1, c1
770 * attach s1 to v2, c2 => s3
771 * results in two separate, unlinked styles s2 and s3 which
772 * are identical and could be shared. To fix this, we would
773 * want to never remove a style from the list of linked
774 * styles as long as as it has a reference count. However, the
775 * disadvantage of doing it this way means that we would need two
776 * passes through the linked list when attaching (one to check for
777 * matching styles, one to look for empty unattached styles - but
778 * it will almost never be longer than 2 elements.
781 gtk_style_attach (GtkStyle *style,
785 GtkStyle *new_style = NULL;
786 GdkColormap *colormap;
788 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
789 g_return_val_if_fail (window != NULL, NULL);
791 colormap = gdk_drawable_get_colormap (window);
794 style->styles = g_slist_append (NULL, style);
796 styles = style->styles;
799 new_style = styles->data;
801 if (new_style->attach_count == 0)
803 gtk_style_realize (new_style, colormap);
806 else if (new_style->colormap == colormap)
810 styles = styles->next;
815 new_style = gtk_style_duplicate (style);
816 if (gdk_colormap_get_screen (style->colormap) != gdk_colormap_get_screen (colormap) &&
817 new_style->private_font)
819 gdk_font_unref (new_style->private_font);
820 new_style->private_font = NULL;
822 gtk_style_realize (new_style, colormap);
825 /* A style gets a refcount from being attached */
826 if (new_style->attach_count == 0)
827 g_object_ref (new_style);
829 /* Another refcount belongs to the parent */
830 if (style != new_style)
832 g_object_unref (style);
833 g_object_ref (new_style);
836 new_style->attach_count++;
842 gtk_style_detach (GtkStyle *style)
844 g_return_if_fail (GTK_IS_STYLE (style));
846 style->attach_count -= 1;
847 if (style->attach_count == 0)
849 GTK_STYLE_GET_CLASS (style)->unrealize (style);
851 g_object_unref (style->colormap);
852 style->colormap = NULL;
854 if (style->private_font_desc)
856 if (style->private_font)
858 gdk_font_unref (style->private_font);
859 style->private_font = NULL;
862 pango_font_description_free (style->private_font_desc);
863 style->private_font_desc = NULL;
866 g_object_unref (style);
872 * @style: a #GtkStyle.
875 * Deprecated equivalent of g_object_ref().
878 gtk_style_ref (GtkStyle *style)
880 return (GtkStyle *) g_object_ref (style);
885 * @style: a #GtkStyle.
887 * Deprecated equivalent of g_object_unref().
890 gtk_style_unref (GtkStyle *style)
892 g_object_unref (style);
896 gtk_style_realize (GtkStyle *style,
897 GdkColormap *colormap)
899 g_return_if_fail (GTK_IS_STYLE (style));
900 g_return_if_fail (GDK_IS_COLORMAP (colormap));
902 style->colormap = g_object_ref (colormap);
903 style->depth = gdk_colormap_get_visual (colormap)->depth;
905 GTK_STYLE_GET_CLASS (style)->realize (style);
909 gtk_style_lookup_icon_set (GtkStyle *style,
910 const char *stock_id)
914 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
915 g_return_val_if_fail (stock_id != NULL, NULL);
917 iter = style->icon_factories;
920 GtkIconSet *icon_set = gtk_icon_factory_lookup (GTK_ICON_FACTORY (iter->data),
925 iter = g_slist_next (iter);
928 return gtk_icon_factory_lookup_default (stock_id);
933 * @style: a #GtkStyle
934 * @window: a #GdkWindow
935 * @state_type: a state
936 * @x1: the starting x coordinate
937 * @x2: the ending x coordinate
938 * @y: the y coordinate
940 * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @window
941 * using the given style and state.
943 * Deprecated: Use gtk_paint_hline() instead.
946 gtk_draw_hline (GtkStyle *style,
948 GtkStateType state_type,
953 g_return_if_fail (GTK_IS_STYLE (style));
954 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
956 GTK_STYLE_GET_CLASS (style)->draw_hline (style, window, state_type, NULL, NULL, NULL, x1, x2, y);
962 * @style: a #GtkStyle
963 * @window: a #GdkWindow
964 * @state_type: a state
965 * @y1_: the starting y coordinate
966 * @y2_: the ending y coordinate
967 * @x: the x coordinate
969 * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @window
970 * using the given style and state.
972 * Deprecated: Use gtk_paint_vline() instead.
975 gtk_draw_vline (GtkStyle *style,
977 GtkStateType state_type,
982 g_return_if_fail (GTK_IS_STYLE (style));
983 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
985 GTK_STYLE_GET_CLASS (style)->draw_vline (style, window, state_type, NULL, NULL, NULL, y1_, y2_, x);
990 * @style: a #GtkStyle
991 * @window: a #GdkWindow
992 * @state_type: a state
993 * @shadow_type: type of shadow to draw
994 * @x: x origin of the rectangle
995 * @y: y origin of the rectangle
996 * @width: width of the rectangle
997 * @height: width of the rectangle
999 * Draws a shadow around the given rectangle in @window
1000 * using the given style and state and shadow type.
1002 * Deprecated: Use gtk_paint_shadow() instead.
1005 gtk_draw_shadow (GtkStyle *style,
1007 GtkStateType state_type,
1008 GtkShadowType shadow_type,
1014 g_return_if_fail (GTK_IS_STYLE (style));
1015 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
1017 GTK_STYLE_GET_CLASS (style)->draw_shadow (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1022 * @style: a #GtkStyle
1023 * @window: a #GdkWindow
1024 * @state_type: a state
1025 * @shadow_type: type of shadow to draw
1026 * @points: an array of #GdkPoint<!-- -->s
1027 * @npoints: length of @points
1028 * @fill: %TRUE if the polygon should be filled
1030 * Draws a polygon on @window with the given parameters.
1032 * Deprecated: Use gtk_paint_polygon() instead.
1035 gtk_draw_polygon (GtkStyle *style,
1037 GtkStateType state_type,
1038 GtkShadowType shadow_type,
1043 g_return_if_fail (GTK_IS_STYLE (style));
1044 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_polygon != NULL);
1046 GTK_STYLE_GET_CLASS (style)->draw_polygon (style, window, state_type, shadow_type, NULL, NULL, NULL, points, npoints, fill);
1051 * @style: a #GtkStyle
1052 * @window: a #GdkWindow
1053 * @state_type: a state
1054 * @shadow_type: the type of shadow to draw
1055 * @arrow_type: the type of arrow to draw
1056 * @fill: %TRUE if the arrow tip should be filled
1057 * @x: x origin of the rectangle to draw the arrow in
1058 * @y: y origin of the rectangle to draw the arrow in
1059 * @width: width of the rectangle to draw the arrow in
1060 * @height: height of the rectangle to draw the arrow in
1062 * Draws an arrow in the given rectangle on @window using the given
1063 * parameters. @arrow_type determines the direction of the arrow.
1065 * Deprecated: Use gtk_paint_arrow() instead.
1068 gtk_draw_arrow (GtkStyle *style,
1070 GtkStateType state_type,
1071 GtkShadowType shadow_type,
1072 GtkArrowType arrow_type,
1079 g_return_if_fail (GTK_IS_STYLE (style));
1080 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
1082 GTK_STYLE_GET_CLASS (style)->draw_arrow (style, window, state_type, shadow_type, NULL, NULL, NULL, arrow_type, fill, x, y, width, height);
1087 * @style: a #GtkStyle
1088 * @window: a #GdkWindow
1089 * @state_type: a state
1090 * @shadow_type: the type of shadow to draw
1091 * @x: x origin of the rectangle to draw the diamond in
1092 * @y: y origin of the rectangle to draw the diamond in
1093 * @width: width of the rectangle to draw the diamond in
1094 * @height: height of the rectangle to draw the diamond in
1096 * Draws a diamond in the given rectangle on @window using the given
1099 * Deprecated: Use gtk_paint_diamond() instead.
1102 gtk_draw_diamond (GtkStyle *style,
1104 GtkStateType state_type,
1105 GtkShadowType shadow_type,
1111 g_return_if_fail (GTK_IS_STYLE (style));
1112 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
1114 GTK_STYLE_GET_CLASS (style)->draw_diamond (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1119 * @style: a #GtkStyle
1120 * @window: a #GdkWindow
1121 * @state_type: a state
1124 * @string: the string to draw
1126 * Draws a text string on @window with the given parameters.
1128 * Deprecated: Use gtk_paint_layout() instead.
1131 gtk_draw_string (GtkStyle *style,
1133 GtkStateType state_type,
1136 const gchar *string)
1138 g_return_if_fail (GTK_IS_STYLE (style));
1139 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_string != NULL);
1141 GTK_STYLE_GET_CLASS (style)->draw_string (style, window, state_type, NULL, NULL, NULL, x, y, string);
1146 * @style: a #GtkStyle
1147 * @window: a #GdkWindow
1148 * @state_type: a state
1149 * @shadow_type: the type of shadow to draw
1150 * @x: x origin of the box
1151 * @y: y origin of the box
1152 * @width: the width of the box
1153 * @height: the height of the box
1155 * Draws a box on @window with the given parameters.
1157 * Deprecated: Use gtk_paint_box() instead.
1160 gtk_draw_box (GtkStyle *style,
1162 GtkStateType state_type,
1163 GtkShadowType shadow_type,
1169 g_return_if_fail (GTK_IS_STYLE (style));
1170 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
1172 GTK_STYLE_GET_CLASS (style)->draw_box (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1176 * gtk_draw_flat_box:
1177 * @style: a #GtkStyle
1178 * @window: a #GdkWindow
1179 * @state_type: a state
1180 * @shadow_type: the type of shadow to draw
1181 * @x: x origin of the box
1182 * @y: y origin of the box
1183 * @width: the width of the box
1184 * @height: the height of the box
1186 * Draws a flat box on @window with the given parameters.
1188 * Deprecated: Use gtk_paint_flat_box() instead.
1191 gtk_draw_flat_box (GtkStyle *style,
1193 GtkStateType state_type,
1194 GtkShadowType shadow_type,
1200 g_return_if_fail (GTK_IS_STYLE (style));
1201 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
1203 GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1208 * @style: a #GtkStyle
1209 * @window: a #GdkWindow
1210 * @state_type: a state
1211 * @shadow_type: the type of shadow to draw
1212 * @x: x origin of the rectangle to draw the check in
1213 * @y: y origin of the rectangle to draw the check in
1214 * @width: the width of the rectangle to draw the check in
1215 * @height: the height of the rectangle to draw the check in
1217 * Draws a check button indicator in the given rectangle on @window with
1218 * the given parameters.
1220 * Deprecated: Use gtk_paint_check() instead.
1223 gtk_draw_check (GtkStyle *style,
1225 GtkStateType state_type,
1226 GtkShadowType shadow_type,
1232 g_return_if_fail (GTK_IS_STYLE (style));
1233 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
1235 GTK_STYLE_GET_CLASS (style)->draw_check (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1240 * @style: a #GtkStyle
1241 * @window: a #GdkWindow
1242 * @state_type: a state
1243 * @shadow_type: the type of shadow to draw
1244 * @x: x origin of the rectangle to draw the option in
1245 * @y: y origin of the rectangle to draw the option in
1246 * @width: the width of the rectangle to draw the option in
1247 * @height: the height of the rectangle to draw the option in
1249 * Draws a radio button indicator in the given rectangle on @window with
1250 * the given parameters.
1252 * Deprecated: Use gtk_paint_option() instead.
1255 gtk_draw_option (GtkStyle *style,
1257 GtkStateType state_type,
1258 GtkShadowType shadow_type,
1264 g_return_if_fail (GTK_IS_STYLE (style));
1265 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
1267 GTK_STYLE_GET_CLASS (style)->draw_option (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1272 * @style: a #GtkStyle
1273 * @window: a #GdkWindow
1274 * @state_type: a state
1275 * @shadow_type: the type of shadow to draw
1276 * @x: x origin of the rectangle to draw the tab in
1277 * @y: y origin of the rectangle to draw the tab in
1278 * @width: the width of the rectangle to draw the tab in
1279 * @height: the height of the rectangle to draw the tab in
1281 * Draws an option menu tab (i.e. the up and down pointing arrows)
1282 * in the given rectangle on @window using the given parameters.
1284 * Deprecated: Use gtk_paint_tab() instead.
1287 gtk_draw_tab (GtkStyle *style,
1289 GtkStateType state_type,
1290 GtkShadowType shadow_type,
1296 g_return_if_fail (GTK_IS_STYLE (style));
1297 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
1299 GTK_STYLE_GET_CLASS (style)->draw_tab (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1303 * gtk_draw_shadow_gap:
1304 * @style: a #GtkStyle
1305 * @window: a #GdkWindow
1306 * @state_type: a state
1307 * @shadow_type: type of shadow to draw
1308 * @x: x origin of the rectangle
1309 * @y: y origin of the rectangle
1310 * @width: width of the rectangle
1311 * @height: width of the rectangle
1312 * @gap_side: side in which to leave the gap
1313 * @gap_x: starting position of the gap
1314 * @gap_width: width of the gap
1316 * Draws a shadow around the given rectangle in @window
1317 * using the given style and state and shadow type, leaving a
1320 * Deprecated: Use gtk_paint_shadow_gap() instead.
1323 gtk_draw_shadow_gap (GtkStyle *style,
1325 GtkStateType state_type,
1326 GtkShadowType shadow_type,
1331 GtkPositionType gap_side,
1335 g_return_if_fail (GTK_IS_STYLE (style));
1336 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
1338 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);
1343 * @style: a #GtkStyle
1344 * @window: a #GdkWindow
1345 * @state_type: a state
1346 * @shadow_type: type of shadow to draw
1347 * @x: x origin of the rectangle
1348 * @y: y origin of the rectangle
1349 * @width: width of the rectangle
1350 * @height: width of the rectangle
1351 * @gap_side: side in which to leave the gap
1352 * @gap_x: starting position of the gap
1353 * @gap_width: width of the gap
1355 * Draws a box in @window using the given style and state and shadow type,
1356 * leaving a gap in one side.
1358 * Deprecated: Use gtk_paint_box_gap() instead.
1361 gtk_draw_box_gap (GtkStyle *style,
1363 GtkStateType state_type,
1364 GtkShadowType shadow_type,
1369 GtkPositionType gap_side,
1373 g_return_if_fail (GTK_IS_STYLE (style));
1374 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
1376 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);
1380 * gtk_draw_extension:
1381 * @style: a #GtkStyle
1382 * @window: a #GdkWindow
1383 * @state_type: a state
1384 * @shadow_type: type of shadow to draw
1385 * @x: x origin of the extension
1386 * @y: y origin of the extension
1387 * @width: width of the extension
1388 * @height: width of the extension
1389 * @gap_side: the side on to which the extension is attached
1391 * Draws an extension, i.e. a notebook tab.
1393 * Deprecated: Use gtk_paint_extension() instead.
1396 gtk_draw_extension (GtkStyle *style,
1398 GtkStateType state_type,
1399 GtkShadowType shadow_type,
1404 GtkPositionType gap_side)
1406 g_return_if_fail (GTK_IS_STYLE (style));
1407 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
1409 GTK_STYLE_GET_CLASS (style)->draw_extension (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, gap_side);
1414 * @style: a #GtkStyle
1415 * @window: a #GdkWindow
1416 * @x: the x origin of the rectangle around which to draw a focus indicator
1417 * @y: the y origin of the rectangle around which to draw a focus indicator
1418 * @width: the width of the rectangle around which to draw a focus indicator
1419 * @height: the height of the rectangle around which to draw a focus indicator
1421 * Draws a focus indicator around the given rectangle on @window using the
1424 * Deprecated: Use gtk_paint_focus() instead.
1427 gtk_draw_focus (GtkStyle *style,
1434 g_return_if_fail (GTK_IS_STYLE (style));
1435 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
1437 GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, GTK_STATE_NORMAL, NULL, NULL, NULL, x, y, width, height);
1441 gtk_draw_slider (GtkStyle *style,
1443 GtkStateType state_type,
1444 GtkShadowType shadow_type,
1449 GtkOrientation orientation)
1451 g_return_if_fail (GTK_IS_STYLE (style));
1452 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
1454 GTK_STYLE_GET_CLASS (style)->draw_slider (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, orientation);
1459 * @style: a #GtkStyle
1460 * @window: a #GdkWindow
1461 * @state_type: a state
1462 * @shadow_type: type of shadow to draw
1463 * @x: x origin of the handle
1464 * @y: y origin of the handle
1465 * @width: with of the handle
1466 * @height: height of the handle
1467 * @orientation: the orientation of the handle
1469 * Draws a handle as used in #GtkHandleBox and #GtkPaned.
1471 * Deprecated: Use gtk_paint_handle() instead.
1474 gtk_draw_handle (GtkStyle *style,
1476 GtkStateType state_type,
1477 GtkShadowType shadow_type,
1482 GtkOrientation orientation)
1484 g_return_if_fail (GTK_IS_STYLE (style));
1485 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
1487 GTK_STYLE_GET_CLASS (style)->draw_handle (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, orientation);
1491 * gtk_draw_expander:
1492 * @style: a #GtkStyle
1493 * @window: a #GdkWindow
1494 * @state_type: a state
1495 * @x: the x position to draw the expander at
1496 * @y: the y position to draw the expander at
1497 * @expander_style: the style to draw the expander in
1499 * Draws an expander as used in #GtkTreeView.
1501 * Deprecated: Use gtk_paint_expander() instead.
1504 gtk_draw_expander (GtkStyle *style,
1506 GtkStateType state_type,
1509 GtkExpanderStyle expander_style)
1511 g_return_if_fail (GTK_IS_STYLE (style));
1512 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
1514 GTK_STYLE_GET_CLASS (style)->draw_expander (style, window, state_type,
1516 x, y, expander_style);
1520 gtk_draw_layout (GtkStyle *style,
1522 GtkStateType state_type,
1526 PangoLayout *layout)
1528 g_return_if_fail (GTK_IS_STYLE (style));
1529 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
1531 GTK_STYLE_GET_CLASS (style)->draw_layout (style, window, state_type, use_text,
1537 * gtk_draw_resize_grip:
1538 * @style: a #GtkStyle
1539 * @window: a #GdkWindow
1540 * @state_type: a state
1541 * @edge: the edge in which to draw the resize grip
1542 * @x: the x origin of the rectangle in which to draw the resize grip
1543 * @y: the y origin of the rectangle in which to draw the resize grip
1544 * @width: the width of the rectangle in which to draw the resize grip
1545 * @height: the height of the rectangle in which to draw the resize grip
1547 * Draws a resize grip in the given rectangle on @window using the given
1550 * Deprecated: Use gtk_paint_resize_grip() instead.
1553 gtk_draw_resize_grip (GtkStyle *style,
1555 GtkStateType state_type,
1562 g_return_if_fail (GTK_IS_STYLE (style));
1563 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
1565 GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, window, state_type,
1568 x, y, width, height);
1573 * gtk_style_set_background:
1574 * @style: a #GtkStyle
1575 * @window: a #GdkWindow
1576 * @state_type: a state
1578 * Sets the background of @window to the background color or pixmap
1579 * specified by @style for the given state.
1582 gtk_style_set_background (GtkStyle *style,
1584 GtkStateType state_type)
1586 g_return_if_fail (GTK_IS_STYLE (style));
1587 g_return_if_fail (window != NULL);
1589 GTK_STYLE_GET_CLASS (style)->set_background (style, window, state_type);
1592 /* Default functions */
1594 gtk_style_real_clone (GtkStyle *style)
1596 return GTK_STYLE (g_object_new (G_OBJECT_TYPE (style), NULL));
1600 gtk_style_real_copy (GtkStyle *style,
1605 for (i = 0; i < 5; i++)
1607 style->fg[i] = src->fg[i];
1608 style->bg[i] = src->bg[i];
1609 style->text[i] = src->text[i];
1610 style->base[i] = src->base[i];
1612 style->bg_pixmap[i] = src->bg_pixmap[i];
1615 if (style->private_font)
1616 gdk_font_unref (style->private_font);
1617 style->private_font = src->private_font;
1618 if (style->private_font)
1619 gdk_font_ref (style->private_font);
1621 if (style->font_desc)
1622 pango_font_description_free (style->font_desc);
1624 style->font_desc = pango_font_description_copy (src->font_desc);
1626 style->font_desc = NULL;
1628 style->xthickness = src->xthickness;
1629 style->ythickness = src->ythickness;
1631 if (style->rc_style)
1632 gtk_rc_style_unref (style->rc_style);
1633 style->rc_style = src->rc_style;
1635 gtk_rc_style_ref (src->rc_style);
1637 /* don't copy, just clear cache */
1638 clear_property_cache (style);
1642 gtk_style_real_init_from_rc (GtkStyle *style,
1643 GtkRcStyle *rc_style)
1647 /* cache _should_ be still empty */
1648 clear_property_cache (style);
1650 if (rc_style->font_desc)
1651 pango_font_description_merge (style->font_desc, rc_style->font_desc, TRUE);
1653 for (i = 0; i < 5; i++)
1655 if (rc_style->color_flags[i] & GTK_RC_FG)
1656 style->fg[i] = rc_style->fg[i];
1657 if (rc_style->color_flags[i] & GTK_RC_BG)
1658 style->bg[i] = rc_style->bg[i];
1659 if (rc_style->color_flags[i] & GTK_RC_TEXT)
1660 style->text[i] = rc_style->text[i];
1661 if (rc_style->color_flags[i] & GTK_RC_BASE)
1662 style->base[i] = rc_style->base[i];
1665 if (rc_style->xthickness >= 0)
1666 style->xthickness = rc_style->xthickness;
1667 if (rc_style->ythickness >= 0)
1668 style->ythickness = rc_style->ythickness;
1670 if (rc_style->icon_factories)
1674 style->icon_factories = g_slist_copy (rc_style->icon_factories);
1676 iter = style->icon_factories;
1677 while (iter != NULL)
1679 g_object_ref (iter->data);
1680 iter = g_slist_next (iter);
1686 style_property_values_cmp (gconstpointer bsearch_node1,
1687 gconstpointer bsearch_node2)
1689 const PropertyValue *val1 = bsearch_node1;
1690 const PropertyValue *val2 = bsearch_node2;
1692 if (val1->widget_type == val2->widget_type)
1693 return val1->pspec < val2->pspec ? -1 : val1->pspec == val2->pspec ? 0 : 1;
1695 return val1->widget_type < val2->widget_type ? -1 : 1;
1699 _gtk_style_peek_property_value (GtkStyle *style,
1702 GtkRcPropertyParser parser)
1704 PropertyValue *pcache, key = { 0, NULL, { 0, } };
1705 const GtkRcProperty *rcprop = NULL;
1708 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1709 g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL);
1710 g_return_val_if_fail (g_type_is_a (pspec->owner_type, GTK_TYPE_WIDGET), NULL);
1711 g_return_val_if_fail (g_type_is_a (widget_type, pspec->owner_type), NULL);
1713 key.widget_type = widget_type;
1716 /* need value cache array */
1717 if (!style->property_cache)
1718 style->property_cache = g_array_new (FALSE, FALSE, sizeof (PropertyValue));
1721 pcache = bsearch (&key,
1722 style->property_cache->data, style->property_cache->len,
1723 sizeof (PropertyValue), style_property_values_cmp);
1725 return &pcache->value;
1729 while (i < style->property_cache->len &&
1730 style_property_values_cmp (&key, &g_array_index (style->property_cache, PropertyValue, i)) >= 0)
1733 g_array_insert_val (style->property_cache, i, key);
1734 pcache = &g_array_index (style->property_cache, PropertyValue, i);
1736 /* cache miss, initialize value type, then set contents */
1737 g_param_spec_ref (pcache->pspec);
1738 g_value_init (&pcache->value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1740 /* value provided by rc style? */
1741 if (style->rc_style)
1743 GQuark prop_quark = g_quark_from_string (pspec->name);
1747 rcprop = _gtk_rc_style_lookup_rc_property (style->rc_style,
1748 g_type_qname (widget_type),
1752 widget_type = g_type_parent (widget_type);
1754 while (g_type_is_a (widget_type, pspec->owner_type));
1757 /* when supplied by rc style, we need to convert */
1758 if (rcprop && !_gtk_settings_parse_convert (parser, &rcprop->value,
1759 pspec, &pcache->value))
1761 gchar *contents = g_strdup_value_contents (&rcprop->value);
1763 g_message ("%s: failed to retrieve property `%s::%s' of type `%s' from rc file value \"%s\" of type `%s'",
1765 g_type_name (pspec->owner_type), pspec->name,
1766 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1768 G_VALUE_TYPE_NAME (&rcprop->value));
1770 rcprop = NULL; /* needs default */
1773 /* not supplied by rc style (or conversion failed), revert to default */
1775 g_param_value_set_default (pspec, &pcache->value);
1777 return &pcache->value;
1781 load_bg_image (GdkColormap *colormap,
1783 const gchar *filename)
1785 if (strcmp (filename, "<parent>") == 0)
1786 return (GdkPixmap*) GDK_PARENT_RELATIVE;
1789 return gdk_pixmap_colormap_create_from_xpm (NULL, colormap, NULL,
1796 gtk_style_real_realize (GtkStyle *style)
1798 GdkGCValues gc_values;
1799 GdkGCValuesMask gc_values_mask;
1803 for (i = 0; i < 5; i++)
1805 gtk_style_shade (&style->bg[i], &style->light[i], LIGHTNESS_MULT);
1806 gtk_style_shade (&style->bg[i], &style->dark[i], DARKNESS_MULT);
1808 style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
1809 style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
1810 style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
1812 style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
1813 style->text_aa[i].green = (style->text[i].green + style->base[i].green) / 2;
1814 style->text_aa[i].blue = (style->text[i].blue + style->base[i].blue) / 2;
1817 style->black.red = 0x0000;
1818 style->black.green = 0x0000;
1819 style->black.blue = 0x0000;
1820 gdk_colormap_alloc_color (style->colormap, &style->black, FALSE, TRUE);
1822 style->white.red = 0xffff;
1823 style->white.green = 0xffff;
1824 style->white.blue = 0xffff;
1825 gdk_colormap_alloc_color (style->colormap, &style->white, FALSE, TRUE);
1827 gc_values_mask = GDK_GC_FOREGROUND;
1829 gc_values.foreground = style->black;
1830 style->black_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1832 gc_values.foreground = style->white;
1833 style->white_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1835 for (i = 0; i < 5; i++)
1837 if (style->rc_style && style->rc_style->bg_pixmap_name[i])
1838 style->bg_pixmap[i] = load_bg_image (style->colormap,
1840 style->rc_style->bg_pixmap_name[i]);
1842 if (!gdk_colormap_alloc_color (style->colormap, &style->fg[i], FALSE, TRUE))
1843 g_warning ("unable to allocate color: ( %d %d %d )",
1844 style->fg[i].red, style->fg[i].green, style->fg[i].blue);
1845 if (!gdk_colormap_alloc_color (style->colormap, &style->bg[i], FALSE, TRUE))
1846 g_warning ("unable to allocate color: ( %d %d %d )",
1847 style->bg[i].red, style->bg[i].green, style->bg[i].blue);
1848 if (!gdk_colormap_alloc_color (style->colormap, &style->light[i], FALSE, TRUE))
1849 g_warning ("unable to allocate color: ( %d %d %d )",
1850 style->light[i].red, style->light[i].green, style->light[i].blue);
1851 if (!gdk_colormap_alloc_color (style->colormap, &style->dark[i], FALSE, TRUE))
1852 g_warning ("unable to allocate color: ( %d %d %d )",
1853 style->dark[i].red, style->dark[i].green, style->dark[i].blue);
1854 if (!gdk_colormap_alloc_color (style->colormap, &style->mid[i], FALSE, TRUE))
1855 g_warning ("unable to allocate color: ( %d %d %d )",
1856 style->mid[i].red, style->mid[i].green, style->mid[i].blue);
1857 if (!gdk_colormap_alloc_color (style->colormap, &style->text[i], FALSE, TRUE))
1858 g_warning ("unable to allocate color: ( %d %d %d )",
1859 style->text[i].red, style->text[i].green, style->text[i].blue);
1860 if (!gdk_colormap_alloc_color (style->colormap, &style->base[i], FALSE, TRUE))
1861 g_warning ("unable to allocate color: ( %d %d %d )",
1862 style->base[i].red, style->base[i].green, style->base[i].blue);
1863 if (!gdk_colormap_alloc_color (style->colormap, &style->text_aa[i], FALSE, TRUE))
1864 g_warning ("unable to allocate color: ( %d %d %d )",
1865 style->text_aa[i].red, style->text_aa[i].green, style->text_aa[i].blue);
1867 gc_values.foreground = style->fg[i];
1868 style->fg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1870 gc_values.foreground = style->bg[i];
1871 style->bg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1873 gc_values.foreground = style->light[i];
1874 style->light_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1876 gc_values.foreground = style->dark[i];
1877 style->dark_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1879 gc_values.foreground = style->mid[i];
1880 style->mid_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1882 gc_values.foreground = style->text[i];
1883 style->text_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1885 gc_values.foreground = style->base[i];
1886 style->base_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1888 gc_values.foreground = style->text_aa[i];
1889 style->text_aa_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1894 gtk_style_real_unrealize (GtkStyle *style)
1898 gtk_gc_release (style->black_gc);
1899 gtk_gc_release (style->white_gc);
1901 for (i = 0; i < 5; i++)
1903 gtk_gc_release (style->fg_gc[i]);
1904 gtk_gc_release (style->bg_gc[i]);
1905 gtk_gc_release (style->light_gc[i]);
1906 gtk_gc_release (style->dark_gc[i]);
1907 gtk_gc_release (style->mid_gc[i]);
1908 gtk_gc_release (style->text_gc[i]);
1909 gtk_gc_release (style->base_gc[i]);
1910 gtk_gc_release (style->text_aa_gc[i]);
1912 if (style->bg_pixmap[i] && style->bg_pixmap[i] != (GdkPixmap*) GDK_PARENT_RELATIVE)
1913 g_object_unref (style->bg_pixmap[i]);
1916 gdk_colormap_free_colors (style->colormap, style->fg, 5);
1917 gdk_colormap_free_colors (style->colormap, style->bg, 5);
1918 gdk_colormap_free_colors (style->colormap, style->light, 5);
1919 gdk_colormap_free_colors (style->colormap, style->dark, 5);
1920 gdk_colormap_free_colors (style->colormap, style->mid, 5);
1921 gdk_colormap_free_colors (style->colormap, style->text, 5);
1922 gdk_colormap_free_colors (style->colormap, style->base, 5);
1923 gdk_colormap_free_colors (style->colormap, style->text_aa, 5);
1925 style_unrealize_cursor_gcs (style);
1929 gtk_style_real_set_background (GtkStyle *style,
1931 GtkStateType state_type)
1934 gint parent_relative;
1936 if (style->bg_pixmap[state_type])
1938 if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
1941 parent_relative = TRUE;
1945 pixmap = style->bg_pixmap[state_type];
1946 parent_relative = FALSE;
1949 gdk_window_set_back_pixmap (window, pixmap, parent_relative);
1952 gdk_window_set_background (window, &style->bg[state_type]);
1956 * gtk_style_render_icon:
1957 * @style: a #GtkStyle
1958 * @source: the #GtkIconSource specifying the icon to render
1959 * @direction: a text direction
1961 * @size: the size to render the icon at. A size of (GtkIconSize)-1
1962 * means render at the size of the source and don't scale.
1963 * @widget: the widget
1964 * @detail: a style detail
1965 * @returns: a newly-created #GdkPixbuf containing the rendered icon
1967 * Renders the icon specified by @source at the given @size
1968 * according to the given parameters and returns the result in a
1972 gtk_style_render_icon (GtkStyle *style,
1973 const GtkIconSource *source,
1974 GtkTextDirection direction,
1978 const gchar *detail)
1982 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1983 g_return_val_if_fail (GTK_STYLE_GET_CLASS (style)->render_icon != NULL, NULL);
1985 pixbuf = GTK_STYLE_GET_CLASS (style)->render_icon (style, source, direction, state,
1986 size, widget, detail);
1988 g_return_val_if_fail (pixbuf != NULL, NULL);
1993 /* Default functions */
1995 gtk_style_apply_default_background (GtkStyle *style,
1998 GtkStateType state_type,
2005 GdkRectangle new_rect, old_rect;
2011 old_rect.width = width;
2012 old_rect.height = height;
2014 if (!gdk_rectangle_intersect (area, &old_rect, &new_rect))
2021 new_rect.width = width;
2022 new_rect.height = height;
2025 if (!style->bg_pixmap[state_type] ||
2026 GDK_IS_PIXMAP (window) ||
2027 (!set_bg && style->bg_pixmap[state_type] != (GdkPixmap*) GDK_PARENT_RELATIVE))
2029 GdkGC *gc = style->bg_gc[state_type];
2031 if (style->bg_pixmap[state_type])
2033 gdk_gc_set_fill (gc, GDK_TILED);
2034 gdk_gc_set_tile (gc, style->bg_pixmap[state_type]);
2037 gdk_draw_rectangle (window, gc, TRUE,
2038 new_rect.x, new_rect.y, new_rect.width, new_rect.height);
2039 if (style->bg_pixmap[state_type])
2040 gdk_gc_set_fill (gc, GDK_SOLID);
2046 if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
2047 gdk_window_set_back_pixmap (window, NULL, TRUE);
2049 gdk_window_set_back_pixmap (window, style->bg_pixmap[state_type], FALSE);
2052 gdk_window_clear_area (window,
2053 new_rect.x, new_rect.y,
2054 new_rect.width, new_rect.height);
2059 scale_or_ref (GdkPixbuf *src,
2063 if (width == gdk_pixbuf_get_width (src) &&
2064 height == gdk_pixbuf_get_height (src))
2066 return g_object_ref (src);
2070 return gdk_pixbuf_scale_simple (src,
2072 GDK_INTERP_BILINEAR);
2077 gtk_default_render_icon (GtkStyle *style,
2078 const GtkIconSource *source,
2079 GtkTextDirection direction,
2083 const gchar *detail)
2089 GdkPixbuf *base_pixbuf;
2091 GtkSettings *settings;
2093 /* Oddly, style can be NULL in this function, because
2094 * GtkIconSet can be used without a style and if so
2095 * it uses this function.
2098 base_pixbuf = gtk_icon_source_get_pixbuf (source);
2100 g_return_val_if_fail (base_pixbuf != NULL, NULL);
2102 if (widget && gtk_widget_has_screen (widget))
2104 screen = gtk_widget_get_screen (widget);
2105 settings = gtk_settings_get_for_screen (screen);
2107 else if (style->colormap)
2109 screen = gdk_colormap_get_screen (style->colormap);
2110 settings = gtk_settings_get_for_screen (screen);
2114 settings = gtk_settings_get_default ();
2115 GTK_NOTE (MULTIHEAD,
2116 g_warning ("Using the default screen for gtk_default_render_icon()"));
2120 if (size != (GtkIconSize) -1 && !gtk_icon_size_lookup_for_settings (settings, size, &width, &height))
2122 g_warning (G_STRLOC ": invalid icon size '%d'", size);
2126 /* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
2129 if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source))
2130 scaled = scale_or_ref (base_pixbuf, width, height);
2132 scaled = g_object_ref (base_pixbuf);
2134 /* If the state was wildcarded, then generate a state. */
2135 if (gtk_icon_source_get_state_wildcarded (source))
2137 if (state == GTK_STATE_INSENSITIVE)
2139 stated = gdk_pixbuf_copy (scaled);
2141 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
2144 g_object_unref (scaled);
2146 else if (state == GTK_STATE_PRELIGHT)
2148 stated = gdk_pixbuf_copy (scaled);
2150 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
2153 g_object_unref (scaled);
2167 sanitize_size (GdkWindow *window,
2171 if ((*width == -1) && (*height == -1))
2172 gdk_drawable_get_size (window, width, height);
2173 else if (*width == -1)
2174 gdk_drawable_get_size (window, width, NULL);
2175 else if (*height == -1)
2176 gdk_drawable_get_size (window, NULL, height);
2180 get_indicator_for_screen (GdkDrawable *drawable,
2184 GdkScreen *screen = gdk_drawable_get_screen (drawable);
2188 tmp_list = indicator_parts[part].bmap_list;
2191 bitmap = tmp_list->data;
2193 if (gdk_drawable_get_screen (bitmap) == screen)
2196 tmp_list = tmp_list->next;
2199 bitmap = gdk_bitmap_create_from_data (drawable,
2200 (gchar *)indicator_parts[part].bits,
2201 INDICATOR_PART_SIZE, INDICATOR_PART_SIZE);
2202 indicator_parts[part].bmap_list = g_list_prepend (indicator_parts[part].bmap_list, bitmap);
2208 draw_part (GdkDrawable *drawable,
2216 gdk_gc_set_clip_rectangle (gc, area);
2218 gdk_gc_set_ts_origin (gc, x, y);
2219 gdk_gc_set_stipple (gc, get_indicator_for_screen (drawable, part));
2220 gdk_gc_set_fill (gc, GDK_STIPPLED);
2222 gdk_draw_rectangle (drawable, gc, TRUE, x, y, INDICATOR_PART_SIZE, INDICATOR_PART_SIZE);
2224 gdk_gc_set_fill (gc, GDK_SOLID);
2227 gdk_gc_set_clip_rectangle (gc, NULL);
2231 gtk_default_draw_hline (GtkStyle *style,
2233 GtkStateType state_type,
2236 const gchar *detail,
2241 gint thickness_light;
2242 gint thickness_dark;
2245 g_return_if_fail (GTK_IS_STYLE (style));
2246 g_return_if_fail (window != NULL);
2248 thickness_light = style->ythickness / 2;
2249 thickness_dark = style->ythickness - thickness_light;
2253 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2254 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2257 if (detail && !strcmp (detail, "label"))
2259 if (state_type == GTK_STATE_INSENSITIVE)
2260 gdk_draw_line (window, style->white_gc, x1 + 1, y + 1, x2 + 1, y + 1);
2261 gdk_draw_line (window, style->fg_gc[state_type], x1, y, x2, y);
2265 for (i = 0; i < thickness_dark; i++)
2267 gdk_draw_line (window, style->dark_gc[state_type], x1, y + i, x2 - i - 1, y + i);
2268 gdk_draw_line (window, style->light_gc[state_type], x2 - i, y + i, x2, y + i);
2271 y += thickness_dark;
2272 for (i = 0; i < thickness_light; i++)
2274 gdk_draw_line (window, style->dark_gc[state_type], x1, y + i, x1 + thickness_light - i - 1, y + i);
2275 gdk_draw_line (window, style->light_gc[state_type], x1 + thickness_light - i, y + i, x2, y + i);
2281 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2282 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2288 gtk_default_draw_vline (GtkStyle *style,
2290 GtkStateType state_type,
2293 const gchar *detail,
2298 gint thickness_light;
2299 gint thickness_dark;
2302 g_return_if_fail (GTK_IS_STYLE (style));
2303 g_return_if_fail (window != NULL);
2305 thickness_light = style->xthickness / 2;
2306 thickness_dark = style->xthickness - thickness_light;
2310 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2311 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2313 for (i = 0; i < thickness_dark; i++)
2315 gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i, y2 - i - 1);
2316 gdk_draw_line (window, style->light_gc[state_type], x + i, y2 - i, x + i, y2);
2319 x += thickness_dark;
2320 for (i = 0; i < thickness_light; i++)
2322 gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i, y1 + thickness_light - i - 1);
2323 gdk_draw_line (window, style->light_gc[state_type], x + i, y1 + thickness_light - i, x + i, y2);
2327 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2328 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2333 draw_thin_shadow (GtkStyle *style,
2344 sanitize_size (window, &width, &height);
2346 gc1 = style->light_gc[state];
2347 gc2 = style->dark_gc[state];
2351 gdk_gc_set_clip_rectangle (gc1, area);
2352 gdk_gc_set_clip_rectangle (gc2, area);
2355 gdk_draw_line (window, gc1,
2356 x, y + height - 1, x + width - 1, y + height - 1);
2357 gdk_draw_line (window, gc1,
2358 x + width - 1, y, x + width - 1, y + height - 1);
2360 gdk_draw_line (window, gc2,
2361 x, y, x + width - 2, y);
2362 gdk_draw_line (window, gc2,
2363 x, y, x, y + height - 2);
2367 gdk_gc_set_clip_rectangle (gc1, NULL);
2368 gdk_gc_set_clip_rectangle (gc2, NULL);
2373 draw_spinbutton_shadow (GtkStyle *style,
2376 GtkTextDirection direction,
2383 sanitize_size (window, &width, &height);
2387 gdk_gc_set_clip_rectangle (style->black_gc, area);
2388 gdk_gc_set_clip_rectangle (style->bg_gc[state], area);
2389 gdk_gc_set_clip_rectangle (style->dark_gc[state], area);
2390 gdk_gc_set_clip_rectangle (style->light_gc[state], area);
2393 if (direction == GTK_TEXT_DIR_LTR)
2395 gdk_draw_line (window, style->dark_gc[state],
2396 x, y, x + width - 1, y);
2397 gdk_draw_line (window, style->black_gc,
2398 x, y + 1, x + width - 2, y + 1);
2399 gdk_draw_line (window, style->black_gc,
2400 x + width - 2, y + 2, x + width - 2, y + height - 3);
2401 gdk_draw_line (window, style->light_gc[state],
2402 x + width - 1, y + 1, x + width - 1, y + height - 2);
2403 gdk_draw_line (window, style->light_gc[state],
2404 x, y + height - 1, x + width - 1, y + height - 1);
2405 gdk_draw_line (window, style->bg_gc[state],
2406 x, y + height - 2, x + width - 2, y + height - 2);
2407 gdk_draw_line (window, style->black_gc,
2408 x, y + 2, x, y + height - 3);
2412 gdk_draw_line (window, style->dark_gc[state],
2413 x, y, x + width - 1, y);
2414 gdk_draw_line (window, style->dark_gc[state],
2415 x, y + 1, x, y + height - 1);
2416 gdk_draw_line (window, style->black_gc,
2417 x + 1, y + 1, x + width - 1, y + 1);
2418 gdk_draw_line (window, style->black_gc,
2419 x + 1, y + 2, x + 1, y + height - 2);
2420 gdk_draw_line (window, style->black_gc,
2421 x + width - 1, y + 2, x + width - 1, y + height - 3);
2422 gdk_draw_line (window, style->light_gc[state],
2423 x + 1, y + height - 1, x + width - 1, y + height - 1);
2424 gdk_draw_line (window, style->bg_gc[state],
2425 x + 2, y + height - 2, x + width - 1, y + height - 2);
2430 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
2431 gdk_gc_set_clip_rectangle (style->bg_gc[state], NULL);
2432 gdk_gc_set_clip_rectangle (style->dark_gc[state], NULL);
2433 gdk_gc_set_clip_rectangle (style->light_gc[state], NULL);
2438 draw_menu_shadow (GtkStyle *style,
2447 if (style->ythickness > 0)
2449 if (style->ythickness > 1)
2451 gdk_draw_line (window, style->dark_gc[state],
2452 x + 1, y + height - 2, x + width - 2, y + height - 2);
2453 gdk_draw_line (window, style->black_gc,
2454 x, y + height - 1, x + width - 1, y + height - 1);
2458 gdk_draw_line (window, style->dark_gc[state],
2459 x + 1, y + height - 1, x + width - 1, y + height - 1);
2463 if (style->xthickness > 0)
2465 if (style->xthickness > 1)
2467 gdk_draw_line (window, style->dark_gc[state],
2468 x + width - 2, y + 1, x + width - 2, y + height - 2);
2470 gdk_draw_line (window, style->black_gc,
2471 x + width - 1, y, x + width - 1, y + height - 1);
2475 gdk_draw_line (window, style->dark_gc[state],
2476 x + width - 1, y + 1, x + width - 1, y + height - 1);
2480 /* Light around top and left */
2482 if (style->ythickness > 0)
2483 gdk_draw_line (window, style->black_gc,
2484 x, y, x + width - 2, y);
2485 if (style->xthickness > 0)
2486 gdk_draw_line (window, style->black_gc,
2487 x, y, x, y + height - 2);
2489 if (style->ythickness > 1)
2490 gdk_draw_line (window, style->light_gc[state],
2491 x + 1, y + 1, x + width - 3, y + 1);
2492 if (style->xthickness > 1)
2493 gdk_draw_line (window, style->light_gc[state],
2494 x + 1, y + 1, x + 1, y + height - 3);
2498 gtk_default_draw_shadow (GtkStyle *style,
2500 GtkStateType state_type,
2501 GtkShadowType shadow_type,
2504 const gchar *detail,
2512 gint thickness_light;
2513 gint thickness_dark;
2516 g_return_if_fail (GTK_IS_STYLE (style));
2517 g_return_if_fail (window != NULL);
2519 if (shadow_type == GTK_SHADOW_IN)
2521 if (detail && (strcmp (detail, "buttondefault") == 0))
2523 sanitize_size (window, &width, &height);
2525 gdk_draw_rectangle (window, style->black_gc, FALSE,
2526 x, y, width - 1, height - 1);
2530 if (detail && strcmp (detail, "trough") == 0)
2532 draw_thin_shadow (style, window, state_type, area,
2533 x, y, width, height);
2536 if (widget && GTK_IS_SPIN_BUTTON (widget) &&
2537 detail && strcmp (detail, "spinbutton") == 0)
2539 draw_spinbutton_shadow (style, window, state_type,
2540 gtk_widget_get_direction (widget), area, x, y, width, height);
2546 if (shadow_type == GTK_SHADOW_OUT && detail && strcmp (detail, "menu") == 0)
2548 draw_menu_shadow (style, window, state_type, area, x, y, width, height);
2552 sanitize_size (window, &width, &height);
2554 switch (shadow_type)
2556 case GTK_SHADOW_NONE:
2559 case GTK_SHADOW_ETCHED_IN:
2560 gc1 = style->light_gc[state_type];
2561 gc2 = style->dark_gc[state_type];
2563 case GTK_SHADOW_OUT:
2564 case GTK_SHADOW_ETCHED_OUT:
2565 gc1 = style->dark_gc[state_type];
2566 gc2 = style->light_gc[state_type];
2572 gdk_gc_set_clip_rectangle (gc1, area);
2573 gdk_gc_set_clip_rectangle (gc2, area);
2574 if (shadow_type == GTK_SHADOW_IN ||
2575 shadow_type == GTK_SHADOW_OUT)
2577 gdk_gc_set_clip_rectangle (style->black_gc, area);
2578 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
2582 switch (shadow_type)
2584 case GTK_SHADOW_NONE:
2588 /* Light around right and bottom edge */
2590 if (style->ythickness > 0)
2591 gdk_draw_line (window, gc1,
2592 x, y + height - 1, x + width - 1, y + height - 1);
2593 if (style->xthickness > 0)
2594 gdk_draw_line (window, gc1,
2595 x + width - 1, y, x + width - 1, y + height - 1);
2597 if (style->ythickness > 1)
2598 gdk_draw_line (window, style->bg_gc[state_type],
2599 x + 1, y + height - 2, x + width - 2, y + height - 2);
2600 if (style->xthickness > 1)
2601 gdk_draw_line (window, style->bg_gc[state_type],
2602 x + width - 2, y + 1, x + width - 2, y + height - 2);
2604 /* Dark around left and top */
2606 if (style->ythickness > 1)
2607 gdk_draw_line (window, style->black_gc,
2608 x + 1, y + 1, x + width - 2, y + 1);
2609 if (style->xthickness > 1)
2610 gdk_draw_line (window, style->black_gc,
2611 x + 1, y + 1, x + 1, y + height - 2);
2613 if (style->ythickness > 0)
2614 gdk_draw_line (window, gc2,
2615 x, y, x + width - 1, y);
2616 if (style->xthickness > 0)
2617 gdk_draw_line (window, gc2,
2618 x, y, x, y + height - 1);
2621 case GTK_SHADOW_OUT:
2622 /* Dark around right and bottom edge */
2624 if (style->ythickness > 0)
2626 if (style->ythickness > 1)
2628 gdk_draw_line (window, gc1,
2629 x + 1, y + height - 2, x + width - 2, y + height - 2);
2630 gdk_draw_line (window, style->black_gc,
2631 x, y + height - 1, x + width - 1, y + height - 1);
2635 gdk_draw_line (window, gc1,
2636 x + 1, y + height - 1, x + width - 1, y + height - 1);
2640 if (style->xthickness > 0)
2642 if (style->xthickness > 1)
2644 gdk_draw_line (window, gc1,
2645 x + width - 2, y + 1, x + width - 2, y + height - 2);
2647 gdk_draw_line (window, style->black_gc,
2648 x + width - 1, y, x + width - 1, y + height - 1);
2652 gdk_draw_line (window, gc1,
2653 x + width - 1, y + 1, x + width - 1, y + height - 1);
2657 /* Light around top and left */
2659 if (style->ythickness > 0)
2660 gdk_draw_line (window, gc2,
2661 x, y, x + width - 2, y);
2662 if (style->xthickness > 0)
2663 gdk_draw_line (window, gc2,
2664 x, y, x, y + height - 2);
2666 if (style->ythickness > 1)
2667 gdk_draw_line (window, style->bg_gc[state_type],
2668 x + 1, y + 1, x + width - 3, y + 1);
2669 if (style->xthickness > 1)
2670 gdk_draw_line (window, style->bg_gc[state_type],
2671 x + 1, y + 1, x + 1, y + height - 3);
2674 case GTK_SHADOW_ETCHED_IN:
2675 case GTK_SHADOW_ETCHED_OUT:
2676 if (style->xthickness > 0)
2678 if (style->xthickness > 1)
2680 thickness_light = 1;
2683 for (i = 0; i < thickness_dark; i++)
2685 gdk_draw_line (window, gc1,
2689 y + height - i - 1);
2690 gdk_draw_line (window, gc2,
2694 y + height - i - 2);
2697 for (i = 0; i < thickness_light; i++)
2699 gdk_draw_line (window, gc1,
2700 x + thickness_dark + i,
2701 y + thickness_dark + i,
2702 x + thickness_dark + i,
2703 y + height - thickness_dark - i - 1);
2704 gdk_draw_line (window, gc2,
2705 x + width - thickness_light - i - 1,
2706 y + thickness_dark + i,
2707 x + width - thickness_light - i - 1,
2708 y + height - thickness_light - 1);
2713 gdk_draw_line (window,
2714 style->dark_gc[state_type],
2715 x, y, x, y + height);
2716 gdk_draw_line (window,
2717 style->dark_gc[state_type],
2718 x + width, y, x + width, y + height);
2722 if (style->ythickness > 0)
2724 if (style->ythickness > 1)
2726 thickness_light = 1;
2729 for (i = 0; i < thickness_dark; i++)
2731 gdk_draw_line (window, gc1,
2735 y + height - i - 1);
2737 gdk_draw_line (window, gc2,
2744 for (i = 0; i < thickness_light; i++)
2746 gdk_draw_line (window, gc1,
2747 x + thickness_dark + i,
2748 y + thickness_dark + i,
2749 x + width - thickness_dark - i - 2,
2750 y + thickness_dark + i);
2752 gdk_draw_line (window, gc2,
2753 x + thickness_dark + i,
2754 y + height - thickness_light - i - 1,
2755 x + width - thickness_light - 1,
2756 y + height - thickness_light - i - 1);
2761 gdk_draw_line (window,
2762 style->dark_gc[state_type],
2763 x, y, x + width, y);
2764 gdk_draw_line (window,
2765 style->dark_gc[state_type],
2766 x, y + height, x + width, y + height);
2773 if (shadow_type == GTK_SHADOW_IN &&
2774 widget && GTK_IS_SPIN_BUTTON (widget) &&
2775 detail && strcmp (detail, "entry") == 0)
2777 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
2779 gdk_draw_line (window,
2780 style->base_gc[state_type],
2781 x + width - 1, y + 2,
2782 x + width - 1, y + height - 3);
2783 gdk_draw_line (window,
2784 style->base_gc[state_type],
2785 x + width - 2, y + 2,
2786 x + width - 2, y + height - 3);
2787 gdk_draw_point (window,
2789 x + width - 1, y + 1);
2790 gdk_draw_point (window,
2791 style->bg_gc[state_type],
2792 x + width - 1, y + height - 2);
2796 gdk_draw_line (window,
2797 style->base_gc[state_type],
2800 gdk_draw_line (window,
2801 style->base_gc[state_type],
2803 x + 1, y + height - 3);
2804 gdk_draw_point (window,
2807 gdk_draw_line (window,
2808 style->bg_gc[state_type],
2810 x + 1, y + height - 2);
2811 gdk_draw_point (window,
2812 style->light_gc[state_type],
2820 gdk_gc_set_clip_rectangle (gc1, NULL);
2821 gdk_gc_set_clip_rectangle (gc2, NULL);
2822 if (shadow_type == GTK_SHADOW_IN ||
2823 shadow_type == GTK_SHADOW_OUT)
2825 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
2826 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
2832 gtk_default_draw_polygon (GtkStyle *style,
2834 GtkStateType state_type,
2835 GtkShadowType shadow_type,
2838 const gchar *detail,
2843 static const gdouble pi_over_4 = G_PI_4;
2844 static const gdouble pi_3_over_4 = G_PI_4 * 3;
2854 g_return_if_fail (GTK_IS_STYLE (style));
2855 g_return_if_fail (window != NULL);
2856 g_return_if_fail (points != NULL);
2858 switch (shadow_type)
2861 gc1 = style->bg_gc[state_type];
2862 gc2 = style->dark_gc[state_type];
2863 gc3 = style->light_gc[state_type];
2864 gc4 = style->black_gc;
2866 case GTK_SHADOW_ETCHED_IN:
2867 gc1 = style->light_gc[state_type];
2868 gc2 = style->dark_gc[state_type];
2869 gc3 = style->dark_gc[state_type];
2870 gc4 = style->light_gc[state_type];
2872 case GTK_SHADOW_OUT:
2873 gc1 = style->dark_gc[state_type];
2874 gc2 = style->light_gc[state_type];
2875 gc3 = style->black_gc;
2876 gc4 = style->bg_gc[state_type];
2878 case GTK_SHADOW_ETCHED_OUT:
2879 gc1 = style->dark_gc[state_type];
2880 gc2 = style->light_gc[state_type];
2881 gc3 = style->light_gc[state_type];
2882 gc4 = style->dark_gc[state_type];
2890 gdk_gc_set_clip_rectangle (gc1, area);
2891 gdk_gc_set_clip_rectangle (gc2, area);
2892 gdk_gc_set_clip_rectangle (gc3, area);
2893 gdk_gc_set_clip_rectangle (gc4, area);
2897 gdk_draw_polygon (window, style->bg_gc[state_type], TRUE, points, npoints);
2901 for (i = 0; i < npoints; i++)
2903 if ((points[i].x == points[i+1].x) &&
2904 (points[i].y == points[i+1].y))
2910 angle = atan2 (points[i+1].y - points[i].y,
2911 points[i+1].x - points[i].x);
2914 if ((angle > -pi_3_over_4) && (angle < pi_over_4))
2916 if (angle > -pi_over_4)
2927 gdk_draw_line (window, gc1,
2928 points[i].x-xadjust, points[i].y-yadjust,
2929 points[i+1].x-xadjust, points[i+1].y-yadjust);
2930 gdk_draw_line (window, gc3,
2931 points[i].x, points[i].y,
2932 points[i+1].x, points[i+1].y);
2936 if ((angle < -pi_3_over_4) || (angle > pi_3_over_4))
2947 gdk_draw_line (window, gc4,
2948 points[i].x+xadjust, points[i].y+yadjust,
2949 points[i+1].x+xadjust, points[i+1].y+yadjust);
2950 gdk_draw_line (window, gc2,
2951 points[i].x, points[i].y,
2952 points[i+1].x, points[i+1].y);
2958 gdk_gc_set_clip_rectangle (gc1, NULL);
2959 gdk_gc_set_clip_rectangle (gc2, NULL);
2960 gdk_gc_set_clip_rectangle (gc3, NULL);
2961 gdk_gc_set_clip_rectangle (gc4, NULL);
2966 draw_arrow (GdkWindow *window,
2969 GtkArrowType arrow_type,
2978 gdk_gc_set_clip_rectangle (gc, area);
2980 if (arrow_type == GTK_ARROW_DOWN)
2982 for (i = 0, j = 0; i < height; i++, j++)
2983 gdk_draw_line (window, gc, x + j, y + i, x + width - j - 1, y + i);
2985 else if (arrow_type == GTK_ARROW_UP)
2987 for (i = height - 1, j = 0; i >= 0; i--, j++)
2988 gdk_draw_line (window, gc, x + j, y + i, x + width - j - 1, y + i);
2990 else if (arrow_type == GTK_ARROW_LEFT)
2992 for (i = width - 1, j = 0; i >= 0; i--, j++)
2993 gdk_draw_line (window, gc, x + i, y + j, x + i, y + height - j - 1);
2995 else if (arrow_type == GTK_ARROW_RIGHT)
2997 for (i = 0, j = 0; i < width; i++, j++)
2998 gdk_draw_line (window, gc, x + i, y + j, x + i, y + height - j - 1);
3002 gdk_gc_set_clip_rectangle (gc, NULL);
3006 calculate_arrow_geometry (GtkArrowType arrow_type,
3018 case GTK_ARROW_DOWN:
3028 if (arrow_type == GTK_ARROW_DOWN)
3030 if (*height % 2 == 1 || h % 2 == 0)
3035 if (*height % 2 == 0 || h % 2 == 0)
3040 case GTK_ARROW_RIGHT:
3041 case GTK_ARROW_LEFT:
3051 if (arrow_type == GTK_ARROW_RIGHT)
3053 if (*width % 2 == 1 || w % 2 == 0)
3058 if (*width % 2 == 0 || w % 2 == 0)
3064 /* should not be reached */
3068 *x += (*width - w) / 2;
3069 *y += (*height - h) / 2;
3075 gtk_default_draw_arrow (GtkStyle *style,
3078 GtkShadowType shadow,
3081 const gchar *detail,
3082 GtkArrowType arrow_type,
3089 gint original_width, original_x;
3091 sanitize_size (window, &width, &height);
3093 original_width = width;
3096 calculate_arrow_geometry (arrow_type, &x, &y, &width, &height);
3098 if (detail && strcmp (detail, "menu_scroll_arrow_up") == 0)
3101 if (state == GTK_STATE_INSENSITIVE)
3102 draw_arrow (window, style->white_gc, area, arrow_type,
3103 x + 1, y + 1, width, height);
3104 draw_arrow (window, style->fg_gc[state], area, arrow_type,
3105 x, y, width, height);
3109 gtk_default_draw_diamond (GtkStyle *style,
3111 GtkStateType state_type,
3112 GtkShadowType shadow_type,
3115 const gchar *detail,
3123 GdkGC *outer_nw = NULL;
3124 GdkGC *outer_ne = NULL;
3125 GdkGC *outer_sw = NULL;
3126 GdkGC *outer_se = NULL;
3127 GdkGC *middle_nw = NULL;
3128 GdkGC *middle_ne = NULL;
3129 GdkGC *middle_sw = NULL;
3130 GdkGC *middle_se = NULL;
3131 GdkGC *inner_nw = NULL;
3132 GdkGC *inner_ne = NULL;
3133 GdkGC *inner_sw = NULL;
3134 GdkGC *inner_se = NULL;
3136 g_return_if_fail (GTK_IS_STYLE (style));
3137 g_return_if_fail (window != NULL);
3139 sanitize_size (window, &width, &height);
3141 half_width = width / 2;
3142 half_height = height / 2;
3146 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
3147 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
3148 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
3149 gdk_gc_set_clip_rectangle (style->black_gc, area);
3152 switch (shadow_type)
3155 inner_sw = inner_se = style->bg_gc[state_type];
3156 middle_sw = middle_se = style->light_gc[state_type];
3157 outer_sw = outer_se = style->light_gc[state_type];
3158 inner_nw = inner_ne = style->black_gc;
3159 middle_nw = middle_ne = style->dark_gc[state_type];
3160 outer_nw = outer_ne = style->dark_gc[state_type];
3163 case GTK_SHADOW_OUT:
3164 inner_sw = inner_se = style->dark_gc[state_type];
3165 middle_sw = middle_se = style->dark_gc[state_type];
3166 outer_sw = outer_se = style->black_gc;
3167 inner_nw = inner_ne = style->bg_gc[state_type];
3168 middle_nw = middle_ne = style->light_gc[state_type];
3169 outer_nw = outer_ne = style->light_gc[state_type];
3172 case GTK_SHADOW_ETCHED_IN:
3173 inner_sw = inner_se = style->bg_gc[state_type];
3174 middle_sw = middle_se = style->dark_gc[state_type];
3175 outer_sw = outer_se = style->light_gc[state_type];
3176 inner_nw = inner_ne = style->bg_gc[state_type];
3177 middle_nw = middle_ne = style->light_gc[state_type];
3178 outer_nw = outer_ne = style->dark_gc[state_type];
3181 case GTK_SHADOW_ETCHED_OUT:
3182 inner_sw = inner_se = style->bg_gc[state_type];
3183 middle_sw = middle_se = style->light_gc[state_type];
3184 outer_sw = outer_se = style->dark_gc[state_type];
3185 inner_nw = inner_ne = style->bg_gc[state_type];
3186 middle_nw = middle_ne = style->dark_gc[state_type];
3187 outer_nw = outer_ne = style->light_gc[state_type];
3197 gdk_draw_line (window, inner_sw,
3198 x + 2, y + half_height,
3199 x + half_width, y + height - 2);
3200 gdk_draw_line (window, inner_se,
3201 x + half_width, y + height - 2,
3202 x + width - 2, y + half_height);
3203 gdk_draw_line (window, middle_sw,
3204 x + 1, y + half_height,
3205 x + half_width, y + height - 1);
3206 gdk_draw_line (window, middle_se,
3207 x + half_width, y + height - 1,
3208 x + width - 1, y + half_height);
3209 gdk_draw_line (window, outer_sw,
3211 x + half_width, y + height);
3212 gdk_draw_line (window, outer_se,
3213 x + half_width, y + height,
3214 x + width, y + half_height);
3216 gdk_draw_line (window, inner_nw,
3217 x + 2, y + half_height,
3218 x + half_width, y + 2);
3219 gdk_draw_line (window, inner_ne,
3220 x + half_width, y + 2,
3221 x + width - 2, y + half_height);
3222 gdk_draw_line (window, middle_nw,
3223 x + 1, y + half_height,
3224 x + half_width, y + 1);
3225 gdk_draw_line (window, middle_ne,
3226 x + half_width, y + 1,
3227 x + width - 1, y + half_height);
3228 gdk_draw_line (window, outer_nw,
3231 gdk_draw_line (window, outer_ne,
3233 x + width, y + half_height);
3238 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
3239 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
3240 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
3241 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
3246 gtk_default_draw_string (GtkStyle *style,
3248 GtkStateType state_type,
3251 const gchar *detail,
3254 const gchar *string)
3256 GdkDisplay *display;
3258 g_return_if_fail (GTK_IS_STYLE (style));
3259 g_return_if_fail (window != NULL);
3261 display = gdk_drawable_get_display (window);
3265 gdk_gc_set_clip_rectangle (style->white_gc, area);
3266 gdk_gc_set_clip_rectangle (style->fg_gc[state_type], area);
3269 if (state_type == GTK_STATE_INSENSITIVE)
3270 gdk_draw_string (window,
3271 gtk_style_get_font_internal (style),
3272 style->white_gc, x + 1, y + 1, string);
3274 gdk_draw_string (window,
3275 gtk_style_get_font_internal (style),
3276 style->fg_gc[state_type], x, y, string);
3280 gdk_gc_set_clip_rectangle (style->white_gc, NULL);
3281 gdk_gc_set_clip_rectangle (style->fg_gc[state_type], NULL);
3286 option_menu_get_props (GtkWidget *widget,
3287 GtkRequisition *indicator_size,
3288 GtkBorder *indicator_spacing)
3290 GtkRequisition *tmp_size = NULL;
3291 GtkBorder *tmp_spacing = NULL;
3294 gtk_widget_style_get (widget,
3295 "indicator_size", &tmp_size,
3296 "indicator_spacing", &tmp_spacing,
3301 *indicator_size = *tmp_size;
3305 *indicator_size = default_option_indicator_size;
3309 *indicator_spacing = *tmp_spacing;
3310 g_free (tmp_spacing);
3313 *indicator_spacing = default_option_indicator_spacing;
3317 gtk_default_draw_box (GtkStyle *style,
3319 GtkStateType state_type,
3320 GtkShadowType shadow_type,
3323 const gchar *detail,
3329 gboolean is_spinbutton_box = FALSE;
3331 g_return_if_fail (GTK_IS_STYLE (style));
3332 g_return_if_fail (window != NULL);
3334 sanitize_size (window, &width, &height);
3336 if (widget && GTK_IS_SPIN_BUTTON (widget) && detail)
3338 if (strcmp (detail, "spinbutton_up") == 0)
3344 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
3349 is_spinbutton_box = TRUE;
3351 else if (strcmp (detail, "spinbutton_down") == 0)
3356 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
3361 is_spinbutton_box = TRUE;
3365 if (!style->bg_pixmap[state_type] ||
3366 GDK_IS_PIXMAP (window))
3368 GdkGC *gc = style->bg_gc[state_type];
3370 if (state_type == GTK_STATE_SELECTED && strcmp (detail, "paned") == 0)
3372 if (!GTK_WIDGET_HAS_FOCUS (widget))
3373 gc = style->base_gc[GTK_STATE_ACTIVE];
3377 gdk_gc_set_clip_rectangle (gc, area);
3379 gdk_draw_rectangle (window, gc, TRUE,
3380 x, y, width, height);
3382 gdk_gc_set_clip_rectangle (gc, NULL);
3385 gtk_style_apply_default_background (style, window,
3386 widget && !GTK_WIDGET_NO_WINDOW (widget),
3387 state_type, area, x, y, width, height);
3389 if (is_spinbutton_box)
3394 lower_gc = style->dark_gc[state_type];
3395 if (shadow_type == GTK_SHADOW_OUT)
3396 upper_gc = style->light_gc[state_type];
3398 upper_gc = style->dark_gc[state_type];
3402 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
3403 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
3406 gdk_draw_line (window, upper_gc, x, y, x + width - 1, y);
3407 gdk_draw_line (window, lower_gc, x, y + height - 1, x + width - 1, y + height - 1);
3411 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
3412 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
3417 gtk_paint_shadow (style, window, state_type, shadow_type, area, widget, detail,
3418 x, y, width, height);
3420 if (detail && strcmp (detail, "optionmenu") == 0)
3422 GtkRequisition indicator_size;
3423 GtkBorder indicator_spacing;
3426 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
3428 sanitize_size (window, &width, &height);
3430 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
3431 vline_x = x + indicator_size.width + indicator_spacing.left + indicator_spacing.right;
3433 vline_x = x + width - (indicator_size.width + indicator_spacing.left + indicator_spacing.right) - style->xthickness;
3435 gtk_paint_vline (style, window, state_type, area, widget,
3437 y + style->ythickness + 1,
3438 y + height - style->ythickness - 3,
3444 get_darkened_gc (GdkWindow *window,
3448 GdkColor src = *color;
3449 GdkColor shaded = *color;
3452 gc = gdk_gc_new (window);
3454 while (darken_count)
3456 gtk_style_shade (&src, &shaded, 0.93);
3461 gdk_gc_set_rgb_fg_color (gc, &shaded);
3467 gtk_default_draw_flat_box (GtkStyle *style,
3469 GtkStateType state_type,
3470 GtkShadowType shadow_type,
3473 const gchar *detail,
3480 GdkGC *freeme = NULL;
3482 g_return_if_fail (GTK_IS_STYLE (style));
3483 g_return_if_fail (window != NULL);
3485 sanitize_size (window, &width, &height);
3489 if (state_type == GTK_STATE_SELECTED)
3491 if (!strcmp ("text", detail))
3492 gc1 = style->bg_gc[GTK_STATE_SELECTED];
3493 else if (!strncmp ("cell_even", detail, strlen ("cell_even")) ||
3494 !strncmp ("cell_odd", detail, strlen ("cell_odd")))
3496 /* This has to be really broken; alex made me do it. -jrb */
3497 if (GTK_WIDGET_HAS_FOCUS (widget))
3498 gc1 = style->base_gc[state_type];
3500 gc1 = style->base_gc[GTK_STATE_ACTIVE];
3504 gc1 = style->bg_gc[state_type];
3509 if (!strcmp ("viewportbin", detail))
3510 gc1 = style->bg_gc[GTK_STATE_NORMAL];
3511 else if (!strcmp ("entry_bg", detail))
3512 gc1 = style->base_gc[state_type];
3514 /* For trees: even rows are base color, odd rows are a shade of
3515 * the base color, the sort column is a shade of the original color
3519 else if (!strcmp ("cell_even", detail) ||
3520 !strcmp ("cell_odd", detail) ||
3521 !strcmp ("cell_even_ruled", detail))
3523 GdkColor *color = NULL;
3525 gtk_widget_style_get (widget,
3526 "even_row_color", &color,
3531 freeme = get_darkened_gc (window, color, 0);
3534 gdk_color_free (color);
3537 gc1 = style->base_gc[state_type];
3539 else if (!strcmp ("cell_odd_ruled", detail))
3543 gtk_widget_style_get (widget,
3544 "odd_row_color", &color,
3549 freeme = get_darkened_gc (window, color, 0);
3552 gdk_color_free (color);
3556 gtk_widget_style_get (widget,
3557 "even_row_color", &color,
3562 freeme = get_darkened_gc (window, color, 1);
3563 gdk_color_free (color);
3566 freeme = get_darkened_gc (window, &style->base[state_type], 1);
3570 else if (!strcmp ("cell_even_sorted", detail) ||
3571 !strcmp ("cell_odd_sorted", detail) ||
3572 !strcmp ("cell_even_ruled_sorted", detail))
3574 GdkColor *color = NULL;
3576 if (!strcmp ("cell_odd_sorted", detail))
3577 gtk_widget_style_get (widget,
3578 "odd_row_color", &color,
3581 gtk_widget_style_get (widget,
3582 "even_row_color", &color,
3587 freeme = get_darkened_gc (window, color, 1);
3590 gdk_color_free (color);
3594 freeme = get_darkened_gc (window, &style->base[state_type], 1);
3598 else if (!strcmp ("cell_odd_ruled_sorted", detail))
3600 GdkColor *color = NULL;
3602 gtk_widget_style_get (widget,
3603 "odd_row_color", &color,
3608 freeme = get_darkened_gc (window, color, 1);
3611 gdk_color_free (color);
3615 gtk_widget_style_get (widget,
3616 "even_row_color", &color,
3621 freeme = get_darkened_gc (window, color, 2);
3622 gdk_color_free (color);
3625 freeme = get_darkened_gc (window, &style->base[state_type], 2);
3630 gc1 = style->bg_gc[state_type];
3634 gc1 = style->bg_gc[state_type];
3636 if (!style->bg_pixmap[state_type] || gc1 != style->bg_gc[state_type] ||
3637 GDK_IS_PIXMAP (window))
3640 gdk_gc_set_clip_rectangle (gc1, area);
3642 gdk_draw_rectangle (window, gc1, TRUE,
3643 x, y, width, height);
3645 if (detail && !strcmp ("tooltip", detail))
3646 gdk_draw_rectangle (window, style->black_gc, FALSE,
3647 x, y, width - 1, height - 1);
3650 gdk_gc_set_clip_rectangle (gc1, NULL);
3653 gtk_style_apply_default_background (style, window,
3654 widget && !GTK_WIDGET_NO_WINDOW (widget),
3655 state_type, area, x, y, width, height);
3659 g_object_unref (freeme);
3663 create_aa_gc (GdkWindow *window, GtkStyle *style, GtkStateType state_type)
3666 GdkGC *gc = gdk_gc_new (window);
3668 aa_color.red = (style->fg[state_type].red + style->bg[state_type].red) / 2;
3669 aa_color.green = (style->fg[state_type].green + style->bg[state_type].green) / 2;
3670 aa_color.blue = (style->fg[state_type].blue + style->bg[state_type].blue) / 2;
3672 gdk_gc_set_rgb_fg_color (gc, &aa_color);
3678 gtk_default_draw_check (GtkStyle *style,
3680 GtkStateType state_type,
3681 GtkShadowType shadow_type,
3684 const gchar *detail,
3690 if (detail && strcmp (detail, "cellcheck") == 0)
3693 gdk_gc_set_clip_rectangle (widget->style->base_gc[state_type], area);
3694 gdk_draw_rectangle (window,
3695 widget->style->base_gc[state_type],
3701 gdk_gc_set_clip_rectangle (widget->style->base_gc[state_type], NULL);
3702 gdk_gc_set_clip_rectangle (widget->style->text_gc[state_type], area);
3704 gdk_draw_rectangle (window,
3705 widget->style->text_gc[state_type],
3710 gdk_gc_set_clip_rectangle (widget->style->text_gc[state_type], NULL);
3712 x -= (1 + INDICATOR_PART_SIZE - width) / 2;
3713 y -= (((1 + INDICATOR_PART_SIZE - height) / 2) - 1);
3714 if (shadow_type == GTK_SHADOW_IN)
3716 draw_part (window, style->text_gc[state_type], area, x, y, CHECK_TEXT);
3717 draw_part (window, style->text_aa_gc[state_type], area, x, y, CHECK_AA);
3719 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
3721 draw_part (window, style->text_gc[state_type], area, x, y, CHECK_INCONSISTENT_TEXT);
3726 GdkGC *free_me = NULL;
3732 x -= (1 + INDICATOR_PART_SIZE - width) / 2;
3733 y -= (1 + INDICATOR_PART_SIZE - height) / 2;
3735 if (strcmp (detail, "check") == 0) /* Menu item */
3737 text_gc = style->fg_gc[state_type];
3738 base_gc = style->bg_gc[state_type];
3739 aa_gc = free_me = create_aa_gc (window, style, state_type);
3743 if (state_type == GTK_STATE_ACTIVE)
3745 text_gc = style->fg_gc[state_type];
3746 base_gc = style->bg_gc[state_type];
3747 aa_gc = free_me = create_aa_gc (window, style, state_type);
3751 text_gc = style->text_gc[state_type];
3752 base_gc = style->base_gc[state_type];
3753 aa_gc = style->text_aa_gc[state_type];
3756 draw_part (window, base_gc, area, x, y, CHECK_BASE);
3757 draw_part (window, style->black_gc, area, x, y, CHECK_BLACK);
3758 draw_part (window, style->dark_gc[state_type], area, x, y, CHECK_DARK);
3759 draw_part (window, style->mid_gc[state_type], area, x, y, CHECK_MID);
3760 draw_part (window, style->light_gc[state_type], area, x, y, CHECK_LIGHT);
3763 if (shadow_type == GTK_SHADOW_IN)
3765 draw_part (window, text_gc, area, x, y, CHECK_TEXT);
3766 draw_part (window, aa_gc, area, x, y, CHECK_AA);
3768 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
3770 draw_part (window, text_gc, area, x, y, CHECK_INCONSISTENT_TEXT);
3774 g_object_unref (free_me);
3779 gtk_default_draw_option (GtkStyle *style,
3781 GtkStateType state_type,
3782 GtkShadowType shadow_type,
3785 const gchar *detail,
3791 if (detail && strcmp (detail, "cellradio") == 0)
3794 gdk_gc_set_clip_rectangle (widget->style->fg_gc[state_type], area);
3795 gdk_draw_arc (window,
3796 widget->style->fg_gc[state_type],
3803 if (shadow_type == GTK_SHADOW_IN)
3805 gdk_draw_arc (window,
3806 widget->style->fg_gc[state_type],
3814 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
3816 draw_part (window, widget->style->fg_gc[state_type],
3817 area, x, y, CHECK_INCONSISTENT_TEXT);
3820 gdk_gc_set_clip_rectangle (widget->style->fg_gc[state_type], NULL);
3824 GdkGC *free_me = NULL;
3830 x -= (1 + INDICATOR_PART_SIZE - width) / 2;
3831 y -= (1 + INDICATOR_PART_SIZE - height) / 2;
3833 if (strcmp (detail, "option") == 0) /* Menu item */
3835 text_gc = style->fg_gc[state_type];
3836 base_gc = style->bg_gc[state_type];
3837 aa_gc = free_me = create_aa_gc (window, style, state_type);
3841 if (state_type == GTK_STATE_ACTIVE)
3843 text_gc = style->fg_gc[state_type];
3844 base_gc = style->bg_gc[state_type];
3845 aa_gc = free_me = create_aa_gc (window, style, state_type);
3849 text_gc = style->text_gc[state_type];
3850 base_gc = style->base_gc[state_type];
3851 aa_gc = style->text_aa_gc[state_type];
3854 draw_part (window, base_gc, area, x, y, RADIO_BASE);
3855 draw_part (window, style->black_gc, area, x, y, RADIO_BLACK);
3856 draw_part (window, style->dark_gc[state_type], area, x, y, RADIO_DARK);
3857 draw_part (window, style->mid_gc[state_type], area, x, y, RADIO_MID);
3858 draw_part (window, style->light_gc[state_type], area, x, y, RADIO_LIGHT);
3861 if (shadow_type == GTK_SHADOW_IN)
3863 draw_part (window, text_gc, area, x, y, RADIO_TEXT);
3865 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
3867 if (strcmp (detail, "option") == 0) /* Menu item */
3869 draw_part (window, text_gc, area, x, y, CHECK_INCONSISTENT_TEXT);
3873 draw_part (window, text_gc, area, x, y, RADIO_INCONSISTENT_TEXT);
3874 draw_part (window, aa_gc, area, x, y, RADIO_INCONSISTENT_AA);
3879 g_object_unref (free_me);
3884 gtk_default_draw_tab (GtkStyle *style,
3886 GtkStateType state_type,
3887 GtkShadowType shadow_type,
3890 const gchar *detail,
3896 #define ARROW_SPACE 4
3898 GtkRequisition indicator_size;
3899 GtkBorder indicator_spacing;
3902 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
3904 indicator_size.width += (indicator_size.width % 2) - 1;
3905 arrow_height = indicator_size.width / 2 + 1;
3907 x += (width - indicator_size.width) / 2;
3908 y += (height - (2 * arrow_height + ARROW_SPACE)) / 2;
3910 if (state_type == GTK_STATE_INSENSITIVE)
3912 draw_arrow (window, style->white_gc, area,
3913 GTK_ARROW_UP, x + 1, y + 1,
3914 indicator_size.width, arrow_height);
3916 draw_arrow (window, style->white_gc, area,
3917 GTK_ARROW_DOWN, x + 1, y + arrow_height + ARROW_SPACE + 1,
3918 indicator_size.width, arrow_height);
3921 draw_arrow (window, style->fg_gc[state_type], area,
3923 indicator_size.width, arrow_height);
3926 draw_arrow (window, style->fg_gc[state_type], area,
3927 GTK_ARROW_DOWN, x, y + arrow_height + ARROW_SPACE,
3928 indicator_size.width, arrow_height);
3932 gtk_default_draw_shadow_gap (GtkStyle *style,
3934 GtkStateType state_type,
3935 GtkShadowType shadow_type,
3938 const gchar *detail,
3943 GtkPositionType gap_side,
3952 g_return_if_fail (GTK_IS_STYLE (style));
3953 g_return_if_fail (window != NULL);
3955 sanitize_size (window, &width, &height);
3957 switch (shadow_type)
3959 case GTK_SHADOW_NONE:
3962 gc1 = style->dark_gc[state_type];
3963 gc2 = style->black_gc;
3964 gc3 = style->bg_gc[state_type];
3965 gc4 = style->light_gc[state_type];
3967 case GTK_SHADOW_ETCHED_IN:
3968 gc1 = style->dark_gc[state_type];
3969 gc2 = style->light_gc[state_type];
3970 gc3 = style->dark_gc[state_type];
3971 gc4 = style->light_gc[state_type];
3973 case GTK_SHADOW_OUT:
3974 gc1 = style->light_gc[state_type];
3975 gc2 = style->bg_gc[state_type];
3976 gc3 = style->dark_gc[state_type];
3977 gc4 = style->black_gc;
3979 case GTK_SHADOW_ETCHED_OUT:
3980 gc1 = style->light_gc[state_type];
3981 gc2 = style->dark_gc[state_type];
3982 gc3 = style->light_gc[state_type];
3983 gc4 = style->dark_gc[state_type];
3988 gdk_gc_set_clip_rectangle (gc1, area);
3989 gdk_gc_set_clip_rectangle (gc2, area);
3990 gdk_gc_set_clip_rectangle (gc3, area);
3991 gdk_gc_set_clip_rectangle (gc4, area);
3994 switch (shadow_type)
3996 case GTK_SHADOW_NONE:
3998 case GTK_SHADOW_OUT:
3999 case GTK_SHADOW_ETCHED_IN:
4000 case GTK_SHADOW_ETCHED_OUT:
4004 gdk_draw_line (window, gc1,
4005 x, y, x, y + height - 1);
4006 gdk_draw_line (window, gc2,
4007 x + 1, y, x + 1, y + height - 2);
4009 gdk_draw_line (window, gc3,
4010 x + 1, y + height - 2, x + width - 2, y + height - 2);
4011 gdk_draw_line (window, gc3,
4012 x + width - 2, y, x + width - 2, y + height - 2);
4013 gdk_draw_line (window, gc4,
4014 x, y + height - 1, x + width - 1, y + height - 1);
4015 gdk_draw_line (window, gc4,
4016 x + width - 1, y, x + width - 1, y + height - 1);
4019 gdk_draw_line (window, gc1,
4020 x, y, x + gap_x - 1, y);
4021 gdk_draw_line (window, gc2,
4022 x + 1, y + 1, x + gap_x - 1, y + 1);
4023 gdk_draw_line (window, gc2,
4024 x + gap_x, y, x + gap_x, y);
4026 if ((width - (gap_x + gap_width)) > 0)
4028 gdk_draw_line (window, gc1,
4029 x + gap_x + gap_width, y, x + width - 2, y);
4030 gdk_draw_line (window, gc2,
4031 x + gap_x + gap_width, y + 1, x + width - 3, y + 1);
4032 gdk_draw_line (window, gc2,
4033 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
4036 case GTK_POS_BOTTOM:
4037 gdk_draw_line (window, gc1,
4038 x, y, x + width - 1, y);
4039 gdk_draw_line (window, gc1,
4040 x, y, x, y + height - 1);
4041 gdk_draw_line (window, gc2,
4042 x + 1, y + 1, x + width - 2, y + 1);
4043 gdk_draw_line (window, gc2,
4044 x + 1, y + 1, x + 1, y + height - 1);
4046 gdk_draw_line (window, gc3,
4047 x + width - 2, y + 1, x + width - 2, y + height - 1);
4048 gdk_draw_line (window, gc4,
4049 x + width - 1, y, x + width - 1, y + height - 1);
4052 gdk_draw_line (window, gc4,
4053 x, y + height - 1, x + gap_x - 1, y + height - 1);
4054 gdk_draw_line (window, gc3,
4055 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
4056 gdk_draw_line (window, gc3,
4057 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
4059 if ((width - (gap_x + gap_width)) > 0)
4061 gdk_draw_line (window, gc4,
4062 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
4063 gdk_draw_line (window, gc3,
4064 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
4065 gdk_draw_line (window, gc3,
4066 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
4070 gdk_draw_line (window, gc1,
4071 x, y, x + width - 1, y);
4072 gdk_draw_line (window, gc2,
4073 x, y + 1, x + width - 2, y + 1);
4075 gdk_draw_line (window, gc3,
4076 x, y + height - 2, x + width - 2, y + height - 2);
4077 gdk_draw_line (window, gc3,
4078 x + width - 2, y + 1, x + width - 2, y + height - 2);
4079 gdk_draw_line (window, gc4,
4080 x, y + height - 1, x + width - 1, y + height - 1);
4081 gdk_draw_line (window, gc4,
4082 x + width - 1, y, x + width - 1, y + height - 1);
4085 gdk_draw_line (window, gc1,
4086 x, y, x, y + gap_x - 1);
4087 gdk_draw_line (window, gc2,
4088 x + 1, y + 1, x + 1, y + gap_x - 1);
4089 gdk_draw_line (window, gc2,
4090 x, y + gap_x, x, y + gap_x);
4092 if ((width - (gap_x + gap_width)) > 0)
4094 gdk_draw_line (window, gc1,
4095 x, y + gap_x + gap_width, x, y + height - 2);
4096 gdk_draw_line (window, gc2,
4097 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
4098 gdk_draw_line (window, gc2,
4099 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
4103 gdk_draw_line (window, gc1,
4104 x, y, x + width - 1, y);
4105 gdk_draw_line (window, gc1,
4106 x, y, x, y + height - 1);
4107 gdk_draw_line (window, gc2,
4108 x + 1, y + 1, x + width - 1, y + 1);
4109 gdk_draw_line (window, gc2,
4110 x + 1, y + 1, x + 1, y + height - 2);
4112 gdk_draw_line (window, gc3,
4113 x + 1, y + height - 2, x + width - 1, y + height - 2);
4114 gdk_draw_line (window, gc4,
4115 x, y + height - 1, x + width - 1, y + height - 1);
4118 gdk_draw_line (window, gc4,
4119 x + width - 1, y, x + width - 1, y + gap_x - 1);
4120 gdk_draw_line (window, gc3,
4121 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
4122 gdk_draw_line (window, gc3,
4123 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
4125 if ((width - (gap_x + gap_width)) > 0)
4127 gdk_draw_line (window, gc4,
4128 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
4129 gdk_draw_line (window, gc3,
4130 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
4131 gdk_draw_line (window, gc3,
4132 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
4140 gdk_gc_set_clip_rectangle (gc1, NULL);
4141 gdk_gc_set_clip_rectangle (gc2, NULL);
4142 gdk_gc_set_clip_rectangle (gc3, NULL);
4143 gdk_gc_set_clip_rectangle (gc4, NULL);
4148 gtk_default_draw_box_gap (GtkStyle *style,
4150 GtkStateType state_type,
4151 GtkShadowType shadow_type,
4154 const gchar *detail,
4159 GtkPositionType gap_side,
4168 g_return_if_fail (GTK_IS_STYLE (style));
4169 g_return_if_fail (window != NULL);
4171 gtk_style_apply_default_background (style, window,
4172 widget && !GTK_WIDGET_NO_WINDOW (widget),
4173 state_type, area, x, y, width, height);
4175 sanitize_size (window, &width, &height);
4177 switch (shadow_type)
4179 case GTK_SHADOW_NONE:
4182 gc1 = style->dark_gc[state_type];
4183 gc2 = style->black_gc;
4184 gc3 = style->bg_gc[state_type];
4185 gc4 = style->light_gc[state_type];
4187 case GTK_SHADOW_ETCHED_IN:
4188 gc1 = style->dark_gc[state_type];
4189 gc2 = style->light_gc[state_type];
4190 gc3 = style->dark_gc[state_type];
4191 gc4 = style->light_gc[state_type];
4193 case GTK_SHADOW_OUT:
4194 gc1 = style->light_gc[state_type];
4195 gc2 = style->bg_gc[state_type];
4196 gc3 = style->dark_gc[state_type];
4197 gc4 = style->black_gc;
4199 case GTK_SHADOW_ETCHED_OUT:
4200 gc1 = style->light_gc[state_type];
4201 gc2 = style->dark_gc[state_type];
4202 gc3 = style->light_gc[state_type];
4203 gc4 = style->dark_gc[state_type];
4209 gdk_gc_set_clip_rectangle (gc1, area);
4210 gdk_gc_set_clip_rectangle (gc2, area);
4211 gdk_gc_set_clip_rectangle (gc3, area);
4212 gdk_gc_set_clip_rectangle (gc4, area);
4215 switch (shadow_type)
4217 case GTK_SHADOW_NONE:
4219 case GTK_SHADOW_OUT:
4220 case GTK_SHADOW_ETCHED_IN:
4221 case GTK_SHADOW_ETCHED_OUT:
4225 gdk_draw_line (window, gc1,
4226 x, y, x, y + height - 1);
4227 gdk_draw_line (window, gc2,
4228 x + 1, y, x + 1, y + height - 2);
4230 gdk_draw_line (window, gc3,
4231 x + 1, y + height - 2, x + width - 2, y + height - 2);
4232 gdk_draw_line (window, gc3,
4233 x + width - 2, y, x + width - 2, y + height - 2);
4234 gdk_draw_line (window, gc4,
4235 x, y + height - 1, x + width - 1, y + height - 1);
4236 gdk_draw_line (window, gc4,
4237 x + width - 1, y, x + width - 1, y + height - 1);
4240 gdk_draw_line (window, gc1,
4241 x, y, x + gap_x - 1, y);
4242 gdk_draw_line (window, gc2,
4243 x + 1, y + 1, x + gap_x - 1, y + 1);
4244 gdk_draw_line (window, gc2,
4245 x + gap_x, y, x + gap_x, y);
4247 if ((width - (gap_x + gap_width)) > 0)
4249 gdk_draw_line (window, gc1,
4250 x + gap_x + gap_width, y, x + width - 2, y);
4251 gdk_draw_line (window, gc2,
4252 x + gap_x + gap_width, y + 1, x + width - 2, y + 1);
4253 gdk_draw_line (window, gc2,
4254 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
4257 case GTK_POS_BOTTOM:
4258 gdk_draw_line (window, gc1,
4259 x, y, x + width - 1, y);
4260 gdk_draw_line (window, gc1,
4261 x, y, x, y + height - 1);
4262 gdk_draw_line (window, gc2,
4263 x + 1, y + 1, x + width - 2, y + 1);
4264 gdk_draw_line (window, gc2,
4265 x + 1, y + 1, x + 1, y + height - 1);
4267 gdk_draw_line (window, gc3,
4268 x + width - 2, y + 1, x + width - 2, y + height - 1);
4269 gdk_draw_line (window, gc4,
4270 x + width - 1, y, x + width - 1, y + height - 1);
4273 gdk_draw_line (window, gc4,
4274 x, y + height - 1, x + gap_x - 1, y + height - 1);
4275 gdk_draw_line (window, gc3,
4276 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
4277 gdk_draw_line (window, gc3,
4278 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
4280 if ((width - (gap_x + gap_width)) > 0)
4282 gdk_draw_line (window, gc4,
4283 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
4284 gdk_draw_line (window, gc3,
4285 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
4286 gdk_draw_line (window, gc3,
4287 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
4291 gdk_draw_line (window, gc1,
4292 x, y, x + width - 1, y);
4293 gdk_draw_line (window, gc2,
4294 x, y + 1, x + width - 2, y + 1);
4296 gdk_draw_line (window, gc3,
4297 x, y + height - 2, x + width - 2, y + height - 2);
4298 gdk_draw_line (window, gc3,
4299 x + width - 2, y + 1, x + width - 2, y + height - 2);
4300 gdk_draw_line (window, gc4,
4301 x, y + height - 1, x + width - 1, y + height - 1);
4302 gdk_draw_line (window, gc4,
4303 x + width - 1, y, x + width - 1, y + height - 1);
4306 gdk_draw_line (window, gc1,
4307 x, y, x, y + gap_x - 1);
4308 gdk_draw_line (window, gc2,
4309 x + 1, y + 1, x + 1, y + gap_x - 1);
4310 gdk_draw_line (window, gc2,
4311 x, y + gap_x, x, y + gap_x);
4313 if ((width - (gap_x + gap_width)) > 0)
4315 gdk_draw_line (window, gc1,
4316 x, y + gap_x + gap_width, x, y + height - 2);
4317 gdk_draw_line (window, gc2,
4318 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
4319 gdk_draw_line (window, gc2,
4320 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
4324 gdk_draw_line (window, gc1,
4325 x, y, x + width - 1, y);
4326 gdk_draw_line (window, gc1,
4327 x, y, x, y + height - 1);
4328 gdk_draw_line (window, gc2,
4329 x + 1, y + 1, x + width - 1, y + 1);
4330 gdk_draw_line (window, gc2,
4331 x + 1, y + 1, x + 1, y + height - 2);
4333 gdk_draw_line (window, gc3,
4334 x + 1, y + height - 2, x + width - 1, y + height - 2);
4335 gdk_draw_line (window, gc4,
4336 x, y + height - 1, x + width - 1, y + height - 1);
4339 gdk_draw_line (window, gc4,
4340 x + width - 1, y, x + width - 1, y + gap_x - 1);
4341 gdk_draw_line (window, gc3,
4342 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
4343 gdk_draw_line (window, gc3,
4344 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
4346 if ((width - (gap_x + gap_width)) > 0)
4348 gdk_draw_line (window, gc4,
4349 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
4350 gdk_draw_line (window, gc3,
4351 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
4352 gdk_draw_line (window, gc3,
4353 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
4361 gdk_gc_set_clip_rectangle (gc1, NULL);
4362 gdk_gc_set_clip_rectangle (gc2, NULL);
4363 gdk_gc_set_clip_rectangle (gc3, NULL);
4364 gdk_gc_set_clip_rectangle (gc4, NULL);
4369 gtk_default_draw_extension (GtkStyle *style,
4371 GtkStateType state_type,
4372 GtkShadowType shadow_type,
4375 const gchar *detail,
4380 GtkPositionType gap_side)
4387 g_return_if_fail (GTK_IS_STYLE (style));
4388 g_return_if_fail (window != NULL);
4390 gtk_style_apply_default_background (style, window,
4391 widget && !GTK_WIDGET_NO_WINDOW (widget),
4392 GTK_STATE_NORMAL, area, x, y, width, height);
4394 sanitize_size (window, &width, &height);
4396 switch (shadow_type)
4398 case GTK_SHADOW_NONE:
4401 gc1 = style->dark_gc[state_type];
4402 gc2 = style->black_gc;
4403 gc3 = style->bg_gc[state_type];
4404 gc4 = style->light_gc[state_type];
4406 case GTK_SHADOW_ETCHED_IN:
4407 gc1 = style->dark_gc[state_type];
4408 gc2 = style->light_gc[state_type];
4409 gc3 = style->dark_gc[state_type];
4410 gc4 = style->light_gc[state_type];
4412 case GTK_SHADOW_OUT:
4413 gc1 = style->light_gc[state_type];
4414 gc2 = style->bg_gc[state_type];
4415 gc3 = style->dark_gc[state_type];
4416 gc4 = style->black_gc;
4418 case GTK_SHADOW_ETCHED_OUT:
4419 gc1 = style->light_gc[state_type];
4420 gc2 = style->dark_gc[state_type];
4421 gc3 = style->light_gc[state_type];
4422 gc4 = style->dark_gc[state_type];
4428 gdk_gc_set_clip_rectangle (gc1, area);
4429 gdk_gc_set_clip_rectangle (gc2, area);
4430 gdk_gc_set_clip_rectangle (gc3, area);
4431 gdk_gc_set_clip_rectangle (gc4, area);
4434 switch (shadow_type)
4436 case GTK_SHADOW_NONE:
4438 case GTK_SHADOW_OUT:
4439 case GTK_SHADOW_ETCHED_IN:
4440 case GTK_SHADOW_ETCHED_OUT:
4444 gtk_style_apply_default_background (style, window,
4445 widget && !GTK_WIDGET_NO_WINDOW (widget),
4447 x + style->xthickness,
4449 width - (2 * style->xthickness),
4450 height - (style->ythickness));
4451 gdk_draw_line (window, gc1,
4452 x, y, x, y + height - 2);
4453 gdk_draw_line (window, gc2,
4454 x + 1, y, x + 1, y + height - 2);
4456 gdk_draw_line (window, gc3,
4457 x + 2, y + height - 2, x + width - 2, y + height - 2);
4458 gdk_draw_line (window, gc3,
4459 x + width - 2, y, x + width - 2, y + height - 2);
4460 gdk_draw_line (window, gc4,
4461 x + 1, y + height - 1, x + width - 2, y + height - 1);
4462 gdk_draw_line (window, gc4,
4463 x + width - 1, y, x + width - 1, y + height - 2);
4465 case GTK_POS_BOTTOM:
4466 gtk_style_apply_default_background (style, window,
4467 widget && !GTK_WIDGET_NO_WINDOW (widget),
4469 x + style->xthickness,
4470 y + style->ythickness,
4471 width - (2 * style->xthickness),
4472 height - (style->ythickness));
4473 gdk_draw_line (window, gc1,
4474 x + 1, y, x + width - 2, y);
4475 gdk_draw_line (window, gc1,
4476 x, y + 1, x, y + height - 1);
4477 gdk_draw_line (window, gc2,
4478 x + 1, y + 1, x + width - 2, y + 1);
4479 gdk_draw_line (window, gc2,
4480 x + 1, y + 1, x + 1, y + height - 1);
4482 gdk_draw_line (window, gc3,
4483 x + width - 2, y + 2, x + width - 2, y + height - 1);
4484 gdk_draw_line (window, gc4,
4485 x + width - 1, y + 1, x + width - 1, y + height - 1);
4488 gtk_style_apply_default_background (style, window,
4489 widget && !GTK_WIDGET_NO_WINDOW (widget),
4492 y + style->ythickness,
4493 width - (style->xthickness),
4494 height - (2 * style->ythickness));
4495 gdk_draw_line (window, gc1,
4496 x, y, x + width - 2, y);
4497 gdk_draw_line (window, gc2,
4498 x + 1, y + 1, x + width - 2, y + 1);
4500 gdk_draw_line (window, gc3,
4501 x, y + height - 2, x + width - 2, y + height - 2);
4502 gdk_draw_line (window, gc3,
4503 x + width - 2, y + 2, x + width - 2, y + height - 2);
4504 gdk_draw_line (window, gc4,
4505 x, y + height - 1, x + width - 2, y + height - 1);
4506 gdk_draw_line (window, gc4,
4507 x + width - 1, y + 1, x + width - 1, y + height - 2);
4510 gtk_style_apply_default_background (style, window,
4511 widget && !GTK_WIDGET_NO_WINDOW (widget),
4513 x + style->xthickness,
4514 y + style->ythickness,
4515 width - (style->xthickness),
4516 height - (2 * style->ythickness));
4517 gdk_draw_line (window, gc1,
4518 x + 1, y, x + width - 1, y);
4519 gdk_draw_line (window, gc1,
4520 x, y + 1, x, y + height - 2);
4521 gdk_draw_line (window, gc2,
4522 x + 1, y + 1, x + width - 1, y + 1);
4523 gdk_draw_line (window, gc2,
4524 x + 1, y + 1, x + 1, y + height - 2);
4526 gdk_draw_line (window, gc3,
4527 x + 2, y + height - 2, x + width - 1, y + height - 2);
4528 gdk_draw_line (window, gc4,
4529 x + 1, y + height - 1, x + width - 1, y + height - 1);
4536 gdk_gc_set_clip_rectangle (gc1, NULL);
4537 gdk_gc_set_clip_rectangle (gc2, NULL);
4538 gdk_gc_set_clip_rectangle (gc3, NULL);
4539 gdk_gc_set_clip_rectangle (gc4, NULL);
4544 gtk_default_draw_focus (GtkStyle *style,
4546 GtkStateType state_type,
4549 const gchar *detail,
4557 gboolean free_dash_list = FALSE;
4558 gint line_width = 1;
4559 gint8 *dash_list = "\1\1";
4562 gc = style->fg_gc[state_type];
4566 gtk_widget_style_get (widget,
4567 "focus-line-width", &line_width,
4568 "focus-line-pattern", (gchar *)&dash_list,
4571 free_dash_list = TRUE;
4574 sanitize_size (window, &width, &height);
4577 gdk_gc_set_clip_rectangle (gc, area);
4579 gdk_gc_set_line_attributes (gc, line_width,
4580 dash_list[0] ? GDK_LINE_ON_OFF_DASH : GDK_LINE_SOLID,
4581 GDK_CAP_BUTT, GDK_JOIN_MITER);
4584 if (detail && !strcmp (detail, "add-mode"))
4590 free_dash_list = FALSE;
4593 points[0].x = x + line_width / 2;
4594 points[0].y = y + line_width / 2;
4595 points[1].x = x + width - line_width + line_width / 2;
4596 points[1].y = y + line_width / 2;
4597 points[2].x = x + width - line_width + line_width / 2;
4598 points[2].y = y + height - line_width + line_width / 2;
4599 points[3].x = x + line_width / 2;
4600 points[3].y = y + height - line_width + line_width / 2;
4601 points[4] = points[0];
4605 gdk_draw_lines (window, gc, points, 5);
4609 /* We go through all the pain below because the X rasterization
4610 * rules don't really work right for dashed lines if you
4611 * want continuity in segments that go between top/right
4612 * and left/bottom. For instance, a top left corner
4613 * with a 1-1 dash is drawn as:
4620 * This is because pixels on the top and left boundaries
4621 * of polygons are drawn, but not on the bottom and right.
4622 * So, if you have a line going up that turns the corner
4623 * and goes right, there is a one pixel shift in the pattern.
4625 * So, to fix this, we drawn the top and right in one call,
4626 * then the left and bottom in another call, fixing up
4627 * the dash offset for the second call ourselves to get
4628 * continuity at the upper left.
4630 * It's not perfect since we really should have a join at
4631 * the upper left and lower right instead of two intersecting
4632 * lines but that's only really apparent for no-dashes,
4633 * which (for this reason) are done as one polygon and
4634 * don't to through this code path.
4637 dash_len = strlen (dash_list);
4640 gdk_gc_set_dashes (gc, 0, dash_list, dash_len);
4642 gdk_draw_lines (window, gc, points, 3);
4644 /* We draw this line one farther over than it is "supposed" to
4645 * because of another rasterization problem ... if two 1 pixel
4646 * unjoined lines meet at the lower right, there will be a missing
4653 gint dash_pixels = 0;
4656 /* Adjust the dash offset for the bottom and left so we
4657 * match up at the upper left.
4659 for (i = 0; i < dash_len; i++)
4660 dash_pixels += dash_list[i];
4662 if (dash_len % 2 == 1)
4665 gdk_gc_set_dashes (gc, dash_pixels - (width + height - 2 * line_width) % dash_pixels, dash_list, dash_len);
4668 gdk_draw_lines (window, gc, points + 2, 3);
4671 gdk_gc_set_line_attributes (gc, 0, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
4674 gdk_gc_set_clip_rectangle (gc, NULL);
4681 gtk_default_draw_slider (GtkStyle *style,
4683 GtkStateType state_type,
4684 GtkShadowType shadow_type,
4687 const gchar *detail,
4692 GtkOrientation orientation)
4694 g_return_if_fail (GTK_IS_STYLE (style));
4695 g_return_if_fail (window != NULL);
4697 sanitize_size (window, &width, &height);
4699 gtk_paint_box (style, window, state_type, shadow_type,
4700 area, widget, detail, x, y, width, height);
4703 (strcmp ("hscale", detail) == 0 ||
4704 strcmp ("vscale", detail) == 0))
4706 if (orientation == GTK_ORIENTATION_HORIZONTAL)
4707 gtk_paint_vline (style, window, state_type, area, widget, detail,
4708 y + style->ythickness,
4709 y + height - style->ythickness - 1, x + width / 2);
4711 gtk_paint_hline (style, window, state_type, area, widget, detail,
4712 x + style->xthickness,
4713 x + width - style->xthickness - 1, y + height / 2);
4718 draw_dot (GdkWindow *window,
4726 size = CLAMP (size, 2, 3);
4730 gdk_draw_point (window, light_gc, x, y);
4731 gdk_draw_point (window, light_gc, x+1, y+1);
4733 else if (size == 3);
4735 gdk_draw_point (window, light_gc, x, y);
4736 gdk_draw_point (window, light_gc, x+1, y);
4737 gdk_draw_point (window, light_gc, x, y+1);
4738 gdk_draw_point (window, dark_gc, x+1, y+2);
4739 gdk_draw_point (window, dark_gc, x+2, y+1);
4740 gdk_draw_point (window, dark_gc, x+2, y+2);
4745 gtk_default_draw_handle (GtkStyle *style,
4747 GtkStateType state_type,
4748 GtkShadowType shadow_type,
4751 const gchar *detail,
4756 GtkOrientation orientation)
4759 gint xthick, ythick;
4760 GdkGC *light_gc, *dark_gc;
4761 GdkGC *free_me = NULL;
4766 g_return_if_fail (GTK_IS_STYLE (style));
4767 g_return_if_fail (window != NULL);
4769 sanitize_size (window, &width, &height);
4771 gtk_paint_box (style, window, state_type, shadow_type, area, widget,
4772 detail, x, y, width, height);
4775 if (!strcmp (detail, "paned"))
4777 /* we want to ignore the shadow border in paned widgets */
4781 if (state_type == GTK_STATE_SELECTED && !GTK_WIDGET_HAS_FOCUS (widget))
4783 GdkColor unfocused_light;
4785 gtk_style_shade (&style->base[GTK_STATE_ACTIVE], &unfocused_light,
4788 light_gc = free_me = gdk_gc_new (window);
4789 gdk_gc_set_rgb_fg_color (light_gc, &unfocused_light);
4792 light_gc = style->light_gc[state_type];
4794 dark_gc = style->black_gc;
4798 xthick = style->xthickness;
4799 ythick = style->ythickness;
4801 light_gc = style->light_gc[state_type];
4802 dark_gc = style->dark_gc[state_type];
4805 rect.x = x + xthick;
4806 rect.y = y + ythick;
4807 rect.width = width - (xthick * 2);
4808 rect.height = height - (ythick * 2);
4811 intersect = gdk_rectangle_intersect (area, &rect, &dest);
4821 gdk_gc_set_clip_rectangle (light_gc, &dest);
4822 gdk_gc_set_clip_rectangle (dark_gc, &dest);
4824 if (!strcmp (detail, "paned"))
4826 if (orientation == GTK_ORIENTATION_HORIZONTAL)
4827 for (xx = x + width/2 - 15; xx <= x + width/2 + 15; xx += 5)
4828 draw_dot (window, light_gc, dark_gc, xx, y + height/2 - 1, 3);
4830 for (yy = y + height/2 - 15; yy <= y + height/2 + 15; yy += 5)
4831 draw_dot (window, light_gc, dark_gc, x + width/2 - 1, yy, 3);
4835 for (yy = y + ythick; yy < (y + height - ythick); yy += 3)
4836 for (xx = x + xthick; xx < (x + width - xthick); xx += 6)
4838 draw_dot (window, light_gc, dark_gc, xx, yy, 2);
4839 draw_dot (window, light_gc, dark_gc, xx + 3, yy + 1, 2);
4843 gdk_gc_set_clip_rectangle (light_gc, NULL);
4844 gdk_gc_set_clip_rectangle (dark_gc, NULL);
4848 g_object_unref (G_OBJECT (free_me));
4852 create_expander_affine (gdouble affine[6],
4862 width = expander_size / 4.0;
4863 height = expander_size / 2.0;
4865 s = sin (degrees * G_PI / 180.0);
4866 c = cos (degrees * G_PI / 180.0);
4872 affine[4] = -width * c - height * -s + x;
4873 affine[5] = -width * s - height * c + y;
4877 apply_affine_on_point (double affine[6], GdkPoint *point)
4881 x = point->x * affine[0] + point->y * affine[2] + affine[4];
4882 y = point->x * affine[1] + point->y * affine[3] + affine[5];
4884 point->x = floor (x);
4885 point->y = floor (y);
4889 gtk_style_draw_polygon_with_gc (GdkWindow *window, GdkGC *gc, gint line_width,
4890 gboolean do_fill, GdkPoint *points, gint n_points)
4892 gdk_gc_set_line_attributes (gc, line_width,
4894 GDK_CAP_BUTT, GDK_JOIN_MITER);
4896 gdk_draw_polygon (window, gc, do_fill, points, n_points);
4897 gdk_gc_set_line_attributes (gc, 0, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
4901 gtk_default_draw_expander (GtkStyle *style,
4903 GtkStateType state_type,
4906 const gchar *detail,
4909 GtkExpanderStyle expander_style)
4918 gtk_widget_style_get (widget,
4919 "expander_size", &expander_size,
4921 line_width = MAX (1, expander_size/7);
4925 gdk_gc_set_clip_rectangle (style->fg_gc[GTK_STATE_NORMAL], area);
4926 gdk_gc_set_clip_rectangle (style->base_gc[GTK_STATE_NORMAL], area);
4929 expander_size -= (line_width * 2 - 2);
4930 points[0].x = line_width / 2;
4931 points[0].y = line_width / 2;
4932 points[1].x = expander_size / 2 + line_width / 2;
4933 points[1].y = expander_size / 2 + line_width / 2;
4934 points[2].x = line_width / 2;
4935 points[2].y = expander_size + line_width / 2;
4937 switch (expander_style)
4939 case GTK_EXPANDER_COLLAPSED:
4940 degrees = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ? 180 : 0;
4942 case GTK_EXPANDER_SEMI_COLLAPSED:
4943 degrees = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ? 150 : 30;
4945 case GTK_EXPANDER_SEMI_EXPANDED:
4946 degrees = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ? 120 : 60;
4948 case GTK_EXPANDER_EXPANDED:
4952 g_assert_not_reached ();
4955 create_expander_affine (affine, degrees, expander_size, x, y);
4957 for (i = 0; i < 3; i++)
4958 apply_affine_on_point (affine, &points[i]);
4960 if (state_type == GTK_STATE_PRELIGHT)
4962 gtk_style_draw_polygon_with_gc (window, style->fg_gc[GTK_STATE_NORMAL],
4963 1, TRUE, points, 3);
4965 else if (state_type == GTK_STATE_ACTIVE)
4967 gtk_style_draw_polygon_with_gc (window, style->light_gc[GTK_STATE_ACTIVE],
4968 1, TRUE, points, 3);
4969 gtk_style_draw_polygon_with_gc (window, style->fg_gc[GTK_STATE_NORMAL],
4970 line_width, FALSE, points, 3);
4974 gtk_style_draw_polygon_with_gc (window, style->base_gc[GTK_STATE_NORMAL],
4975 1, TRUE, points, 3);
4976 gtk_style_draw_polygon_with_gc (window, style->fg_gc[GTK_STATE_NORMAL],
4977 line_width, FALSE, points, 3);
4981 gdk_gc_set_clip_rectangle (style->fg_gc[GTK_STATE_NORMAL], NULL);
4982 gdk_gc_set_clip_rectangle (style->base_gc[GTK_STATE_NORMAL], NULL);
4986 typedef struct _ByteRange ByteRange;
4995 range_new (guint start,
4998 ByteRange *br = g_new (ByteRange, 1);
5007 get_insensitive_layout (GdkDrawable *drawable,
5008 PangoLayout *layout)
5010 GSList *embossed_ranges = NULL;
5011 GSList *stippled_ranges = NULL;
5012 PangoLayoutIter *iter;
5013 GSList *tmp_list = NULL;
5014 PangoLayout *new_layout;
5015 PangoAttrList *attrs;
5016 GdkBitmap *stipple = NULL;
5018 iter = pango_layout_get_iter (layout);
5022 PangoLayoutRun *run;
5023 PangoAttribute *attr;
5024 gboolean need_stipple = FALSE;
5027 run = pango_layout_iter_get_run (iter);
5031 tmp_list = run->item->analysis.extra_attrs;
5033 while (tmp_list != NULL)
5035 attr = tmp_list->data;
5036 switch (attr->klass->type)
5038 case PANGO_ATTR_FOREGROUND:
5039 case PANGO_ATTR_BACKGROUND:
5040 need_stipple = TRUE;
5050 tmp_list = g_slist_next (tmp_list);
5053 br = range_new (run->item->offset, run->item->offset + run->item->length);
5056 stippled_ranges = g_slist_prepend (stippled_ranges, br);
5058 embossed_ranges = g_slist_prepend (embossed_ranges, br);
5061 while (pango_layout_iter_next_run (iter));
5063 pango_layout_iter_free (iter);
5065 new_layout = pango_layout_copy (layout);
5067 attrs = pango_layout_get_attributes (new_layout);
5071 /* Create attr list if there wasn't one */
5072 attrs = pango_attr_list_new ();
5073 pango_layout_set_attributes (new_layout, attrs);
5074 pango_attr_list_unref (attrs);
5077 tmp_list = embossed_ranges;
5078 while (tmp_list != NULL)
5080 PangoAttribute *attr;
5081 ByteRange *br = tmp_list->data;
5083 attr = gdk_pango_attr_embossed_new (TRUE);
5085 attr->start_index = br->start;
5086 attr->end_index = br->end;
5088 pango_attr_list_change (attrs, attr);
5092 tmp_list = g_slist_next (tmp_list);
5095 g_slist_free (embossed_ranges);
5097 tmp_list = stippled_ranges;
5098 while (tmp_list != NULL)
5100 PangoAttribute *attr;
5101 ByteRange *br = tmp_list->data;
5103 if (stipple == NULL)
5105 #define gray50_width 2
5106 #define gray50_height 2
5107 static const char gray50_bits[] = {
5111 stipple = gdk_bitmap_create_from_data (drawable,
5112 gray50_bits, gray50_width,
5116 attr = gdk_pango_attr_stipple_new (stipple);
5118 attr->start_index = br->start;
5119 attr->end_index = br->end;
5121 pango_attr_list_change (attrs, attr);
5125 tmp_list = g_slist_next (tmp_list);
5128 g_slist_free (stippled_ranges);
5131 g_object_unref (stipple);
5137 gtk_default_draw_layout (GtkStyle *style,
5139 GtkStateType state_type,
5143 const gchar *detail,
5146 PangoLayout *layout)
5150 g_return_if_fail (GTK_IS_STYLE (style));
5151 g_return_if_fail (window != NULL);
5153 gc = use_text ? style->text_gc[state_type] : style->fg_gc[state_type];
5156 gdk_gc_set_clip_rectangle (gc, area);
5158 if (state_type == GTK_STATE_INSENSITIVE)
5162 ins = get_insensitive_layout (window, layout);
5164 gdk_draw_layout (window, gc, x, y, ins);
5166 g_object_unref (ins);
5170 gdk_draw_layout (window, gc, x, y, layout);
5174 gdk_gc_set_clip_rectangle (gc, NULL);
5178 gtk_default_draw_resize_grip (GtkStyle *style,
5180 GtkStateType state_type,
5183 const gchar *detail,
5190 g_return_if_fail (GTK_IS_STYLE (style));
5191 g_return_if_fail (window != NULL);
5195 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
5196 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
5197 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
5202 case GDK_WINDOW_EDGE_NORTH_WEST:
5203 /* make it square */
5208 else if (height < width)
5213 case GDK_WINDOW_EDGE_NORTH:
5219 case GDK_WINDOW_EDGE_NORTH_EAST:
5220 /* make it square, aligning to top right */
5225 else if (height < width)
5227 x += (width - height);
5231 case GDK_WINDOW_EDGE_WEST:
5237 case GDK_WINDOW_EDGE_EAST:
5238 /* aligning to right */
5241 x += (width - height);
5245 case GDK_WINDOW_EDGE_SOUTH_WEST:
5246 /* make it square, aligning to bottom left */
5249 y += (height - width);
5252 else if (height < width)
5257 case GDK_WINDOW_EDGE_SOUTH:
5258 /* align to bottom */
5261 y += (height - width);
5265 case GDK_WINDOW_EDGE_SOUTH_EAST:
5266 /* make it square, aligning to bottom right */
5269 y += (height - width);
5272 else if (height < width)
5274 x += (width - height);
5279 g_assert_not_reached ();
5281 /* Clear background */
5282 gtk_style_apply_default_background (style, window, FALSE,
5284 x, y, width, height);
5288 case GDK_WINDOW_EDGE_WEST:
5289 case GDK_WINDOW_EDGE_EAST:
5295 while (xi < x + width)
5297 gdk_draw_line (window,
5298 style->light_gc[state_type],
5303 gdk_draw_line (window,
5304 style->dark_gc[state_type],
5312 case GDK_WINDOW_EDGE_NORTH:
5313 case GDK_WINDOW_EDGE_SOUTH:
5319 while (yi < y + height)
5321 gdk_draw_line (window,
5322 style->light_gc[state_type],
5327 gdk_draw_line (window,
5328 style->dark_gc[state_type],
5336 case GDK_WINDOW_EDGE_NORTH_WEST:
5345 gdk_draw_line (window,
5346 style->dark_gc[state_type],
5353 gdk_draw_line (window,
5354 style->dark_gc[state_type],
5361 gdk_draw_line (window,
5362 style->light_gc[state_type],
5372 case GDK_WINDOW_EDGE_NORTH_EAST:
5379 while (xi < (x + width - 3))
5381 gdk_draw_line (window,
5382 style->light_gc[state_type],
5389 gdk_draw_line (window,
5390 style->dark_gc[state_type],
5397 gdk_draw_line (window,
5398 style->dark_gc[state_type],
5407 case GDK_WINDOW_EDGE_SOUTH_WEST:
5416 gdk_draw_line (window,
5417 style->dark_gc[state_type],
5424 gdk_draw_line (window,
5425 style->dark_gc[state_type],
5432 gdk_draw_line (window,
5433 style->light_gc[state_type],
5443 case GDK_WINDOW_EDGE_SOUTH_EAST:
5450 while (xi < (x + width - 3))
5452 gdk_draw_line (window,
5453 style->light_gc[state_type],
5460 gdk_draw_line (window,
5461 style->dark_gc[state_type],
5468 gdk_draw_line (window,
5469 style->dark_gc[state_type],
5479 g_assert_not_reached ();
5485 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
5486 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
5487 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
5492 gtk_style_shade (GdkColor *a,
5500 red = (gdouble) a->red / 65535.0;
5501 green = (gdouble) a->green / 65535.0;
5502 blue = (gdouble) a->blue / 65535.0;
5504 rgb_to_hls (&red, &green, &blue);
5509 else if (green < 0.0)
5515 else if (blue < 0.0)
5518 hls_to_rgb (&red, &green, &blue);
5520 b->red = red * 65535.0;
5521 b->green = green * 65535.0;
5522 b->blue = blue * 65535.0;
5526 rgb_to_hls (gdouble *r,
5567 l = (max + min) / 2;
5574 s = (max - min) / (max + min);
5576 s = (max - min) / (2 - max - min);
5580 h = (green - blue) / delta;
5581 else if (green == max)
5582 h = 2 + (blue - red) / delta;
5583 else if (blue == max)
5584 h = 4 + (red - green) / delta;
5597 hls_to_rgb (gdouble *h,
5610 if (lightness <= 0.5)
5611 m2 = lightness * (1 + saturation);
5613 m2 = lightness + saturation - lightness * saturation;
5614 m1 = 2 * lightness - m2;
5616 if (saturation == 0)
5631 r = m1 + (m2 - m1) * hue / 60;
5635 r = m1 + (m2 - m1) * (240 - hue) / 60;
5646 g = m1 + (m2 - m1) * hue / 60;
5650 g = m1 + (m2 - m1) * (240 - hue) / 60;
5661 b = m1 + (m2 - m1) * hue / 60;
5665 b = m1 + (m2 - m1) * (240 - hue) / 60;
5678 * @style: a #GtkStyle
5679 * @window: a #GdkWindow
5680 * @state_type: a state
5681 * @area: rectangle to which the output is clipped
5682 * @widget: the widget
5683 * @detail: a style detail
5684 * @x1: the starting x coordinate
5685 * @x2: the ending x coordinate
5686 * @y: the y coordinate
5688 * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @window
5689 * using the given style and state.
5692 gtk_paint_hline (GtkStyle *style,
5694 GtkStateType state_type,
5697 const gchar *detail,
5702 g_return_if_fail (GTK_IS_STYLE (style));
5703 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
5705 GTK_STYLE_GET_CLASS (style)->draw_hline (style, window, state_type, area, widget, detail, x1, x2, y);
5710 * @style: a #GtkStyle
5711 * @window: a #GdkWindow
5712 * @state_type: a state
5713 * @area: rectangle to which the output is clipped
5714 * @widget: the widget
5715 * @detail: a style detail
5716 * @y1_: the starting y coordinate
5717 * @y2_: the ending y coordinate
5718 * @x: the x coordinate
5720 * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @window
5721 * using the given style and state.
5724 gtk_paint_vline (GtkStyle *style,
5726 GtkStateType state_type,
5729 const gchar *detail,
5734 g_return_if_fail (GTK_IS_STYLE (style));
5735 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
5737 GTK_STYLE_GET_CLASS (style)->draw_vline (style, window, state_type, area, widget, detail, y1_, y2_, x);
5742 * @style: a #GtkStyle
5743 * @window: a #GdkWindow
5744 * @state_type: a state
5745 * @shadow_type: type of shadow to draw
5746 * @area: clip rectangle
5747 * @widget: the widget
5748 * @detail: a style detail
5749 * @x: x origin of the rectangle
5750 * @y: y origin of the rectangle
5751 * @width: width of the rectangle
5752 * @height: width of the rectangle
5754 * Draws a shadow around the given rectangle in @window
5755 * using the given style and state and shadow type.
5758 gtk_paint_shadow (GtkStyle *style,
5760 GtkStateType state_type,
5761 GtkShadowType shadow_type,
5764 const gchar *detail,
5770 g_return_if_fail (GTK_IS_STYLE (style));
5771 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
5773 GTK_STYLE_GET_CLASS (style)->draw_shadow (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
5777 * gtk_paint_polygon:
5778 * @style: a #GtkStyle
5779 * @window: a #GdkWindow
5780 * @state_type: a state
5781 * @shadow_type: type of shadow to draw
5782 * @area: clip rectangle
5783 * @widget: the widget
5784 * @detail: a style detail
5785 * @points: an array of #GdkPoint<!-- -->s
5786 * @npoints: length of @points
5787 * @fill: %TRUE if the polygon should be filled
5789 * Draws a polygon on @window with the given parameters.
5792 gtk_paint_polygon (GtkStyle *style,
5794 GtkStateType state_type,
5795 GtkShadowType shadow_type,
5798 const gchar *detail,
5803 g_return_if_fail (GTK_IS_STYLE (style));
5804 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
5806 GTK_STYLE_GET_CLASS (style)->draw_polygon (style, window, state_type, shadow_type, area, widget, detail, points, npoints, fill);
5811 * @style: a #GtkStyle
5812 * @window: a #GdkWindow
5813 * @state_type: a state
5814 * @shadow_type: the type of shadow to draw
5815 * @area: clip rectangle
5816 * @widget: the widget
5817 * @detail: a style detail
5818 * @arrow_type: the type of arrow to draw
5819 * @fill: %TRUE if the arrow tip should be filled
5820 * @x: x origin of the rectangle to draw the arrow in
5821 * @y: y origin of the rectangle to draw the arrow in
5822 * @width: width of the rectangle to draw the arrow in
5823 * @height: height of the rectangle to draw the arrow in
5825 * Draws an arrow in the given rectangle on @window using the given
5826 * parameters. @arrow_type determines the direction of the arrow.
5829 gtk_paint_arrow (GtkStyle *style,
5831 GtkStateType state_type,
5832 GtkShadowType shadow_type,
5835 const gchar *detail,
5836 GtkArrowType arrow_type,
5843 g_return_if_fail (GTK_IS_STYLE (style));
5844 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
5846 GTK_STYLE_GET_CLASS (style)->draw_arrow (style, window, state_type, shadow_type, area, widget, detail, arrow_type, fill, x, y, width, height);
5850 * gtk_paint_diamond:
5851 * @style: a #GtkStyle
5852 * @window: a #GdkWindow
5853 * @state_type: a state
5854 * @shadow_type: the type of shadow to draw
5855 * @area: clip rectangle
5856 * @widget: the widget
5857 * @detail: a style detail
5858 * @x: x origin of the rectangle to draw the diamond in
5859 * @y: y origin of the rectangle to draw the diamond in
5860 * @width: width of the rectangle to draw the diamond in
5861 * @height: height of the rectangle to draw the diamond in
5863 * Draws a diamond in the given rectangle on @window using the given
5867 gtk_paint_diamond (GtkStyle *style,
5869 GtkStateType state_type,
5870 GtkShadowType shadow_type,
5873 const gchar *detail,
5879 g_return_if_fail (GTK_IS_STYLE (style));
5880 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
5882 GTK_STYLE_GET_CLASS (style)->draw_diamond (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
5887 * @style: a #GtkStyle
5888 * @window: a #GdkWindow
5889 * @state_type: a state
5890 * @area: clip rectangle
5891 * @widget: the widget
5892 * @detail: a style detail
5895 * @string: the string to draw
5897 * Draws a text string on @window with the given parameters.
5899 * Deprecated: Use gtk_paint_layout() instead.
5902 gtk_paint_string (GtkStyle *style,
5904 GtkStateType state_type,
5907 const gchar *detail,
5910 const gchar *string)
5912 g_return_if_fail (GTK_IS_STYLE (style));
5913 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_string != NULL);
5915 GTK_STYLE_GET_CLASS (style)->draw_string (style, window, state_type, area, widget, detail, x, y, string);
5920 * @style: a #GtkStyle
5921 * @window: a #GdkWindow
5922 * @state_type: a state
5923 * @shadow_type: the type of shadow to draw
5924 * @area: clip rectangle
5925 * @widget: the widget
5926 * @detail: a style detail
5927 * @x: x origin of the box
5928 * @y: y origin of the box
5929 * @width: the width of the box
5930 * @height: the height of the box
5932 * Draws a box on @window with the given parameters.
5935 gtk_paint_box (GtkStyle *style,
5937 GtkStateType state_type,
5938 GtkShadowType shadow_type,
5941 const gchar *detail,
5947 g_return_if_fail (GTK_IS_STYLE (style));
5948 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
5950 GTK_STYLE_GET_CLASS (style)->draw_box (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
5954 * gtk_paint_flat_box:
5955 * @style: a #GtkStyle
5956 * @window: a #GdkWindow
5957 * @state_type: a state
5958 * @shadow_type: the type of shadow to draw
5959 * @area: clip rectangle
5960 * @widget: the widget
5961 * @detail: a style detail
5962 * @x: x origin of the box
5963 * @y: y origin of the box
5964 * @width: the width of the box
5965 * @height: the height of the box
5967 * Draws a flat box on @window with the given parameters.
5970 gtk_paint_flat_box (GtkStyle *style,
5972 GtkStateType state_type,
5973 GtkShadowType shadow_type,
5976 const gchar *detail,
5982 g_return_if_fail (GTK_IS_STYLE (style));
5983 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
5985 GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
5990 * @style: a #GtkStyle
5991 * @window: a #GdkWindow
5992 * @state_type: a state
5993 * @shadow_type: the type of shadow to draw
5994 * @area: clip rectangle
5995 * @widget: the widget
5996 * @detail: a style detail
5997 * @x: x origin of the rectangle to draw the check in
5998 * @y: y origin of the rectangle to draw the check in
5999 * @width: the width of the rectangle to draw the check in
6000 * @height: the height of the rectangle to draw the check in
6002 * Draws a check button indicator in the given rectangle on @window with
6003 * the given parameters.
6006 gtk_paint_check (GtkStyle *style,
6008 GtkStateType state_type,
6009 GtkShadowType shadow_type,
6012 const gchar *detail,
6018 g_return_if_fail (GTK_IS_STYLE (style));
6019 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
6021 GTK_STYLE_GET_CLASS (style)->draw_check (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
6026 * @style: a #GtkStyle
6027 * @window: a #GdkWindow
6028 * @state_type: a state
6029 * @shadow_type: the type of shadow to draw
6030 * @area: clip rectangle
6031 * @widget: the widget
6032 * @detail: a style detail
6033 * @x: x origin of the rectangle to draw the option in
6034 * @y: y origin of the rectangle to draw the option in
6035 * @width: the width of the rectangle to draw the option in
6036 * @height: the height of the rectangle to draw the option in
6038 * Draws a radio button indicator in the given rectangle on @window with
6039 * the given parameters.
6042 gtk_paint_option (GtkStyle *style,
6044 GtkStateType state_type,
6045 GtkShadowType shadow_type,
6048 const gchar *detail,
6054 g_return_if_fail (GTK_IS_STYLE (style));
6055 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
6057 GTK_STYLE_GET_CLASS (style)->draw_option (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
6062 * @style: a #GtkStyle
6063 * @window: a #GdkWindow
6064 * @state_type: a state
6065 * @shadow_type: the type of shadow to draw
6066 * @area: clip rectangle
6067 * @widget: the widget
6068 * @detail: a style detail
6069 * @x: x origin of the rectangle to draw the tab in
6070 * @y: y origin of the rectangle to draw the tab in
6071 * @width: the width of the rectangle to draw the tab in
6072 * @height: the height of the rectangle to draw the tab in
6074 * Draws an option menu tab (i.e. the up and down pointing arrows)
6075 * in the given rectangle on @window using the given parameters.
6078 gtk_paint_tab (GtkStyle *style,
6080 GtkStateType state_type,
6081 GtkShadowType shadow_type,
6084 const gchar *detail,
6090 g_return_if_fail (GTK_IS_STYLE (style));
6091 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
6093 GTK_STYLE_GET_CLASS (style)->draw_tab (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
6097 * gtk_paint_shadow_gap:
6098 * @style: a #GtkStyle
6099 * @window: a #GdkWindow
6100 * @state_type: a state
6101 * @shadow_type: type of shadow to draw
6102 * @area: clip rectangle
6103 * @widget: the widget
6104 * @detail: a style detail
6105 * @x: x origin of the rectangle
6106 * @y: y origin of the rectangle
6107 * @width: width of the rectangle
6108 * @height: width of the rectangle
6109 * @gap_side: side in which to leave the gap
6110 * @gap_x: starting position of the gap
6111 * @gap_width: width of the gap
6113 * Draws a shadow around the given rectangle in @window
6114 * using the given style and state and shadow type, leaving a
6118 gtk_paint_shadow_gap (GtkStyle *style,
6120 GtkStateType state_type,
6121 GtkShadowType shadow_type,
6129 GtkPositionType gap_side,
6133 g_return_if_fail (GTK_IS_STYLE (style));
6134 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
6136 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);
6141 * gtk_paint_box_gap:
6142 * @style: a #GtkStyle
6143 * @window: a #GdkWindow
6144 * @state_type: a state
6145 * @shadow_type: type of shadow to draw
6146 * @area: clip rectangle
6147 * @widget: the widget
6148 * @detail: a style detail
6149 * @x: x origin of the rectangle
6150 * @y: y origin of the rectangle
6151 * @width: width of the rectangle
6152 * @height: width of the rectangle
6153 * @gap_side: side in which to leave the gap
6154 * @gap_x: starting position of the gap
6155 * @gap_width: width of the gap
6157 * Draws a box in @window using the given style and state and shadow type,
6158 * leaving a gap in one side.
6161 gtk_paint_box_gap (GtkStyle *style,
6163 GtkStateType state_type,
6164 GtkShadowType shadow_type,
6172 GtkPositionType gap_side,
6176 g_return_if_fail (GTK_IS_STYLE (style));
6177 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
6179 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);
6183 * gtk_paint_extension:
6184 * @style: a #GtkStyle
6185 * @window: a #GdkWindow
6186 * @state_type: a state
6187 * @shadow_type: type of shadow to draw
6188 * @area: clip rectangle
6189 * @widget: the widget
6190 * @detail: a style detail
6191 * @x: x origin of the extension
6192 * @y: y origin of the extension
6193 * @width: width of the extension
6194 * @height: width of the extension
6195 * @gap_side: the side on to which the extension is attached
6197 * Draws an extension, i.e. a notebook tab.
6200 gtk_paint_extension (GtkStyle *style,
6202 GtkStateType state_type,
6203 GtkShadowType shadow_type,
6211 GtkPositionType gap_side)
6213 g_return_if_fail (GTK_IS_STYLE (style));
6214 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
6216 GTK_STYLE_GET_CLASS (style)->draw_extension (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, gap_side);
6221 * @style: a #GtkStyle
6222 * @window: a #GdkWindow
6223 * @state_type: a state
6224 * @area: clip rectangle
6225 * @widget: the widget
6226 * @detail: a style detail
6227 * @x: the x origin of the rectangle around which to draw a focus indicator
6228 * @y: the y origin of the rectangle around which to draw a focus indicator
6229 * @width: the width of the rectangle around which to draw a focus indicator
6230 * @height: the height of the rectangle around which to draw a focus indicator
6232 * Draws a focus indicator around the given rectangle on @window using the
6236 gtk_paint_focus (GtkStyle *style,
6238 GtkStateType state_type,
6241 const gchar *detail,
6247 g_return_if_fail (GTK_IS_STYLE (style));
6248 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
6250 GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, state_type, area, widget, detail, x, y, width, height);
6254 gtk_paint_slider (GtkStyle *style,
6256 GtkStateType state_type,
6257 GtkShadowType shadow_type,
6260 const gchar *detail,
6265 GtkOrientation orientation)
6267 g_return_if_fail (GTK_IS_STYLE (style));
6268 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
6270 GTK_STYLE_GET_CLASS (style)->draw_slider (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, orientation);
6275 * @style: a #GtkStyle
6276 * @window: a #GdkWindow
6277 * @state_type: a state
6278 * @shadow_type: type of shadow to draw
6279 * @area: clip rectangle
6280 * @widget: the widget
6281 * @detail: a style detail
6282 * @x: x origin of the handle
6283 * @y: y origin of the handle
6284 * @width: with of the handle
6285 * @height: height of the handle
6286 * @orientation: the orientation of the handle
6288 * Draws a handle as used in #GtkHandleBox and #GtkPaned.
6291 gtk_paint_handle (GtkStyle *style,
6293 GtkStateType state_type,
6294 GtkShadowType shadow_type,
6297 const gchar *detail,
6302 GtkOrientation orientation)
6304 g_return_if_fail (GTK_IS_STYLE (style));
6305 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
6307 GTK_STYLE_GET_CLASS (style)->draw_handle (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, orientation);
6311 * gtk_paint_expander:
6312 * @style: a #GtkStyle
6313 * @window: a #GdkWindow
6314 * @state_type: a state
6315 * @area: clip rectangle
6316 * @widget: the widget
6317 * @detail: a style detail
6318 * @x: the x position to draw the expander at
6319 * @y: the y position to draw the expander at
6320 * @expander_style: the style to draw the expander in
6322 * Draws an expander as used in #GtkTreeView.
6325 gtk_paint_expander (GtkStyle *style,
6327 GtkStateType state_type,
6330 const gchar *detail,
6333 GtkExpanderStyle expander_style)
6335 g_return_if_fail (GTK_IS_STYLE (style));
6336 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
6338 GTK_STYLE_GET_CLASS (style)->draw_expander (style, window, state_type, area,
6339 widget, detail, x, y, expander_style);
6343 gtk_paint_layout (GtkStyle *style,
6345 GtkStateType state_type,
6349 const gchar *detail,
6352 PangoLayout *layout)
6354 g_return_if_fail (GTK_IS_STYLE (style));
6355 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
6357 GTK_STYLE_GET_CLASS (style)->draw_layout (style, window, state_type, use_text, area,
6358 widget, detail, x, y, layout);
6362 * gtk_paint_resize_grip:
6363 * @style: a #GtkStyle
6364 * @window: a #GdkWindow
6365 * @state_type: a state
6366 * @area: clip rectangle
6367 * @widget: the widget
6368 * @detail: a style detail
6369 * @edge: the edge in which to draw the resize grip
6370 * @x: the x origin of the rectangle in which to draw the resize grip
6371 * @y: the y origin of the rectangle in which to draw the resize grip
6372 * @width: the width of the rectangle in which to draw the resize grip
6373 * @height: the height of the rectangle in which to draw the resize grip
6375 * Draws a resize grip in the given rectangle on @window using the given
6379 gtk_paint_resize_grip (GtkStyle *style,
6381 GtkStateType state_type,
6384 const gchar *detail,
6392 g_return_if_fail (GTK_IS_STYLE (style));
6393 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
6395 GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, window, state_type,
6396 area, widget, detail,
6397 edge, x, y, width, height);
6402 * @border_: a #GtkBorder.
6403 * @returns: a copy of @border_.
6405 * Copies a #GtkBorder structure.
6408 gtk_border_copy (const GtkBorder *border)
6410 return (GtkBorder *)g_memdup (border, sizeof (GtkBorder));
6415 * @border_: a #GtkBorder.
6417 * Frees a #GtkBorder structure.
6420 gtk_border_free (GtkBorder *border)
6426 gtk_border_get_type (void)
6428 static GType our_type = 0;
6431 our_type = g_boxed_type_register_static ("GtkBorder",
6432 (GBoxedCopyFunc) gtk_border_copy,
6433 (GBoxedFreeFunc) gtk_border_free);
6439 gtk_style_get_font_internal (GtkStyle *style)
6441 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
6443 if (style->private_font && style->private_font_desc)
6445 if (!style->font_desc ||
6446 !pango_font_description_equal (style->private_font_desc, style->font_desc))
6448 gdk_font_unref (style->private_font);
6449 style->private_font = NULL;
6451 if (style->private_font_desc)
6453 pango_font_description_free (style->private_font_desc);
6454 style->private_font_desc = NULL;
6459 if (!style->private_font)
6461 GdkDisplay *display;
6463 if (style->colormap)
6465 display = gdk_screen_get_display (gdk_colormap_get_screen (style->colormap));
6469 display = gdk_display_get_default ();
6470 GTK_NOTE (MULTIHEAD,
6471 g_warning ("gtk_style_get_font() should not be called on an unattached style"));
6474 if (style->font_desc)
6476 style->private_font = gdk_font_from_description_for_display (display, style->font_desc);
6477 style->private_font_desc = pango_font_description_copy (style->font_desc);
6480 if (!style->private_font)
6481 style->private_font = gdk_font_load_for_display (display, "fixed");
6483 if (!style->private_font)
6484 g_error ("Unable to load \"fixed\" font");
6487 return style->private_font;
6491 * gtk_style_get_font:
6492 * @style: a #GtkStyle
6494 * Gets the #GdkFont to use for the given style. This is
6495 * meant only as a replacement for direct access to @style->font
6496 * and should not be used in new code. New code should
6497 * use @style->font_desc instead.
6499 * Return value: the #GdkFont for the style. This font is owned
6500 * by the style; if you want to keep around a copy, you must
6501 * call gdk_font_ref().
6504 gtk_style_get_font (GtkStyle *style)
6506 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
6508 return gtk_style_get_font_internal (style);
6512 * gtk_style_set_font:
6513 * @style: a #GtkStyle.
6514 * @font: a #GdkFont, or %NULL to use the #GdkFont corresponding
6515 * to style->font_desc.
6517 * Sets the #GdkFont to use for a given style. This is
6518 * meant only as a replacement for direct access to style->font
6519 * and should not be used in new code. New code should
6520 * use style->font_desc instead.
6523 gtk_style_set_font (GtkStyle *style,
6528 g_return_if_fail (GTK_IS_STYLE (style));
6530 old_font = style->private_font;
6532 style->private_font = font;
6534 gdk_font_ref (font);
6537 gdk_font_unref (old_font);
6539 if (style->private_font_desc)
6541 pango_font_description_free (style->private_font_desc);
6542 style->private_font_desc = NULL;
6546 typedef struct _CursorInfo CursorInfo;
6552 GdkGC *secondary_gc;
6556 style_unrealize_cursor_gcs (GtkStyle *style)
6560 cursor_info = g_object_get_data (G_OBJECT (style), "gtk-style-cursor-info");
6563 if (cursor_info->primary_gc)
6564 gtk_gc_release (cursor_info->primary_gc);
6566 if (cursor_info->secondary_gc)
6567 gtk_gc_release (cursor_info->secondary_gc);
6569 g_free (cursor_info);
6570 g_object_set_data (G_OBJECT (style), "gtk-style-cursor-info", NULL);
6575 make_cursor_gc (GtkWidget *widget,
6576 const gchar *property_name,
6577 const GdkColor *fallback)
6579 GdkGCValues gc_values;
6580 GdkGCValuesMask gc_values_mask;
6581 GdkColor *cursor_color;
6583 gtk_widget_style_get (widget, property_name, &cursor_color, NULL);
6585 gc_values_mask = GDK_GC_FOREGROUND;
6588 gc_values.foreground = *cursor_color;
6589 gdk_color_free (cursor_color);
6592 gc_values.foreground = *fallback;
6594 gdk_rgb_find_color (widget->style->colormap, &gc_values.foreground);
6595 return gtk_gc_get (widget->style->depth, widget->style->colormap, &gc_values, gc_values_mask);
6599 * _gtk_get_insertion_cursor_gc:
6600 * @widget: a #GtkWidget
6601 * @is_primary: if the cursor should be the primary cursor color.
6603 * Get a GC suitable for drawing the primary or secondary text
6606 * Note: the return value is ref'ed because calls to this function
6607 * on other widgets could result in this the GC being released
6608 * which would be an unexpected side effect. If made public,
6609 * this function should possibly be called create_insertion_cursor_gc().
6611 * Return value: an appropriate #GdkGC. Call g_object_unref() on
6612 * the gc when you are done with it; this GC may be shared with
6613 * other users, so you must not modify the GC except for temporarily
6614 * setting the clip before drawing with the GC, and then unsetting the clip
6618 _gtk_get_insertion_cursor_gc (GtkWidget *widget,
6619 gboolean is_primary)
6621 CursorInfo *cursor_info;
6623 cursor_info = g_object_get_data (G_OBJECT (widget->style), "gtk-style-cursor-info");
6626 cursor_info = g_new (CursorInfo, 1);
6627 g_object_set_data (G_OBJECT (widget->style), "gtk-style-cursor-info", cursor_info);
6628 cursor_info->primary_gc = NULL;
6629 cursor_info->secondary_gc = NULL;
6630 cursor_info->for_type = G_TYPE_INVALID;
6633 /* We have to keep track of the type because gtk_widget_style_get()
6634 * can return different results when called on the same property and
6635 * same style but for different widgets. :-(. That is,
6636 * GtkEntry::cursor-color = "red" in a style will modify the cursor
6637 * color for entries but not for text view.
6639 if (cursor_info->for_type != G_OBJECT_TYPE (widget))
6641 cursor_info->for_type = G_OBJECT_TYPE (widget);
6642 if (cursor_info->primary_gc)
6644 gtk_gc_release (cursor_info->primary_gc);
6645 cursor_info->primary_gc = NULL;
6647 if (cursor_info->secondary_gc)
6649 gtk_gc_release (cursor_info->secondary_gc);
6650 cursor_info->secondary_gc = NULL;
6656 if (!cursor_info->primary_gc)
6657 cursor_info->primary_gc = make_cursor_gc (widget,
6659 &widget->style->black);
6661 return g_object_ref (cursor_info->primary_gc);
6665 static const GdkColor gray = { 0, 0x8888, 0x8888, 0x8888 };
6667 if (!cursor_info->secondary_gc)
6668 cursor_info->secondary_gc = make_cursor_gc (widget,
6669 "secondary-cursor-color",
6672 return g_object_ref (cursor_info->secondary_gc);
6677 * _gtk_draw_insertion_cursor:
6678 * @widget: a #GtkWidget
6679 * @drawable: a #GdkDrawable
6681 * @location: location where to draw the cursor (@location->width is ignored)
6682 * @direction: whether the cursor is left-to-right or
6683 * right-to-left. Should never be #GTK_TEXT_DIR_NONE
6684 * @draw_arrow: %TRUE to draw a directional arrow on the
6685 * cursor. Should be %FALSE unless the cursor is split.
6687 * Draws a text caret on @drawable at @location. This is not a style function
6688 * but merely a convenience function for drawing the standard cursor shape.
6691 _gtk_draw_insertion_cursor (GtkWidget *widget,
6692 GdkDrawable *drawable,
6694 GdkRectangle *location,
6695 GtkTextDirection direction,
6696 gboolean draw_arrow)
6702 gfloat cursor_aspect_ratio;
6705 g_return_if_fail (direction != GTK_TEXT_DIR_NONE);
6707 gtk_widget_style_get (widget, "cursor-aspect-ratio", &cursor_aspect_ratio, NULL);
6709 stem_width = location->height * cursor_aspect_ratio + 1;
6710 arrow_width = stem_width + 1;
6712 /* put (stem_width % 2) on the proper side of the cursor */
6713 if (direction == GTK_TEXT_DIR_LTR)
6714 offset = stem_width / 2;
6716 offset = stem_width - stem_width / 2;
6718 for (i = 0; i < stem_width; i++)
6719 gdk_draw_line (drawable, gc,
6720 location->x + i - offset, location->y,
6721 location->x + i - offset, location->y + location->height - 1);
6725 if (direction == GTK_TEXT_DIR_RTL)
6727 x = location->x - offset - 1;
6728 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
6730 for (i = 0; i < arrow_width; i++)
6732 gdk_draw_line (drawable, gc,
6734 x, y + 2 * arrow_width - i - 1);
6738 else if (direction == GTK_TEXT_DIR_LTR)
6740 x = location->x + stem_width - offset;
6741 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
6743 for (i = 0; i < arrow_width; i++)
6745 gdk_draw_line (drawable, gc,
6747 x, y + 2 * arrow_width - i - 1);