1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 *
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.
8 *
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.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 /*
19 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
20 * file for a list of people on the GTK+ Team. See the ChangeLog
21 * files for a list of changes. These files are distributed with
22 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
23 */
24
25 #include "config.h"
26
27 #define GDK_DISABLE_DEPRECATION_WARNINGS
28
29 #include <math.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <gobject/gvaluecollector.h>
33 #include "gtkmarshalers.h"
34 #include "gtkpango.h"
35 #include "gtkrc.h"
36 #include "gtkspinbutton.h"
37 #include "gtkstyle.h"
38 #include "gtkstylecontextprivate.h"
39 #include "gtkwidget.h"
40 #include "gtkwidgetprivate.h"
41 #include "gtkiconfactory.h"
42 #include "gtkintl.h"
43 #include "gtkdebug.h"
44 #include "gtkrender.h"
45 #include "gtkborder.h"
46 #include "gtkwidgetpath.h"
47
48 /**
49 * SECTION:gtkstyle
50 * @Short_description: Deprecated object that holds style information
51 * for widgets
52 * @Title: GtkStyle
53 *
54 * A #GtkStyle object encapsulates the information that provides the look and
55 * feel for a widget.
56 *
57 * > In GTK+ 3.0, GtkStyle has been deprecated and replaced by
58 * > #GtkStyleContext.
59 *
60 * Each #GtkWidget has an associated #GtkStyle object that is used when
61 * rendering that widget. Also, a #GtkStyle holds information for the five
62 * possible widget states though not every widget supports all five
63 * states; see #GtkStateType.
64 *
65 * Usually the #GtkStyle for a widget is the same as the default style that
66 * is set by GTK+ and modified the theme engine.
67 *
68 * Usually applications should not need to use or modify the #GtkStyle of
69 * their widgets.
70 */
71
72
73 #define LIGHTNESS_MULT 1.3
74 #define DARKNESS_MULT 0.7
75
76 /* --- typedefs & structures --- */
77 typedef struct {
78 GType widget_type;
79 GParamSpec *pspec;
80 GValue value;
81 } PropertyValue;
82
83 typedef struct {
84 GtkStyleContext *context;
85 gulong context_changed_id;
86 } GtkStylePrivate;
87
88 #define GTK_STYLE_GET_PRIVATE(obj) ((GtkStylePrivate *) gtk_style_get_instance_private ((GtkStyle *) (obj)))
89
90 enum {
91 PROP_0,
92 PROP_CONTEXT
93 };
94
95 /* --- prototypes --- */
96 static void gtk_style_finalize (GObject *object);
97 static void gtk_style_constructed (GObject *object);
98 static void gtk_style_set_property (GObject *object,
99 guint prop_id,
100 const GValue *value,
101 GParamSpec *pspec);
102 static void gtk_style_get_property (GObject *object,
103 guint prop_id,
104 GValue *value,
105 GParamSpec *pspec);
106
107 static void gtk_style_real_realize (GtkStyle *style);
108 static void gtk_style_real_unrealize (GtkStyle *style);
109 static void gtk_style_real_copy (GtkStyle *style,
110 GtkStyle *src);
111 static void gtk_style_real_set_background (GtkStyle *style,
112 GdkWindow *window,
113 GtkStateType state_type);
114 static GtkStyle *gtk_style_real_clone (GtkStyle *style);
115 static void gtk_style_real_init_from_rc (GtkStyle *style,
116 GtkRcStyle *rc_style);
117 static GdkPixbuf *gtk_default_render_icon (GtkStyle *style,
118 const GtkIconSource *source,
119 GtkTextDirection direction,
120 GtkStateType state,
121 GtkIconSize size,
122 GtkWidget *widget,
123 const gchar *detail);
124 static void gtk_default_draw_hline (GtkStyle *style,
125 cairo_t *cr,
126 GtkStateType state_type,
127 GtkWidget *widget,
128 const gchar *detail,
129 gint x1,
130 gint x2,
131 gint y);
132 static void gtk_default_draw_vline (GtkStyle *style,
133 cairo_t *cr,
134 GtkStateType state_type,
135 GtkWidget *widget,
136 const gchar *detail,
137 gint y1,
138 gint y2,
139 gint x);
140 static void gtk_default_draw_shadow (GtkStyle *style,
141 cairo_t *cr,
142 GtkStateType state_type,
143 GtkShadowType shadow_type,
144 GtkWidget *widget,
145 const gchar *detail,
146 gint x,
147 gint y,
148 gint width,
149 gint height);
150 static void gtk_default_draw_arrow (GtkStyle *style,
151 cairo_t *cr,
152 GtkStateType state_type,
153 GtkShadowType shadow_type,
154 GtkWidget *widget,
155 const gchar *detail,
156 GtkArrowType arrow_type,
157 gboolean fill,
158 gint x,
159 gint y,
160 gint width,
161 gint height);
162 static void gtk_default_draw_diamond (GtkStyle *style,
163 cairo_t *cr,
164 GtkStateType state_type,
165 GtkShadowType shadow_type,
166 GtkWidget *widget,
167 const gchar *detail,
168 gint x,
169 gint y,
170 gint width,
171 gint height);
172 static void gtk_default_draw_box (GtkStyle *style,
173 cairo_t *cr,
174 GtkStateType state_type,
175 GtkShadowType shadow_type,
176 GtkWidget *widget,
177 const gchar *detail,
178 gint x,
179 gint y,
180 gint width,
181 gint height);
182 static void gtk_default_draw_flat_box (GtkStyle *style,
183 cairo_t *cr,
184 GtkStateType state_type,
185 GtkShadowType shadow_type,
186 GtkWidget *widget,
187 const gchar *detail,
188 gint x,
189 gint y,
190 gint width,
191 gint height);
192 static void gtk_default_draw_check (GtkStyle *style,
193 cairo_t *cr,
194 GtkStateType state_type,
195 GtkShadowType shadow_type,
196 GtkWidget *widget,
197 const gchar *detail,
198 gint x,
199 gint y,
200 gint width,
201 gint height);
202 static void gtk_default_draw_option (GtkStyle *style,
203 cairo_t *cr,
204 GtkStateType state_type,
205 GtkShadowType shadow_type,
206 GtkWidget *widget,
207 const gchar *detail,
208 gint x,
209 gint y,
210 gint width,
211 gint height);
212 static void gtk_default_draw_tab (GtkStyle *style,
213 cairo_t *cr,
214 GtkStateType state_type,
215 GtkShadowType shadow_type,
216 GtkWidget *widget,
217 const gchar *detail,
218 gint x,
219 gint y,
220 gint width,
221 gint height);
222 static void gtk_default_draw_shadow_gap (GtkStyle *style,
223 cairo_t *cr,
224 GtkStateType state_type,
225 GtkShadowType shadow_type,
226 GtkWidget *widget,
227 const gchar *detail,
228 gint x,
229 gint y,
230 gint width,
231 gint height,
232 GtkPositionType gap_side,
233 gint gap_x,
234 gint gap_width);
235 static void gtk_default_draw_box_gap (GtkStyle *style,
236 cairo_t *cr,
237 GtkStateType state_type,
238 GtkShadowType shadow_type,
239 GtkWidget *widget,
240 const gchar *detail,
241 gint x,
242 gint y,
243 gint width,
244 gint height,
245 GtkPositionType gap_side,
246 gint gap_x,
247 gint gap_width);
248 static void gtk_default_draw_extension (GtkStyle *style,
249 cairo_t *cr,
250 GtkStateType state_type,
251 GtkShadowType shadow_type,
252 GtkWidget *widget,
253 const gchar *detail,
254 gint x,
255 gint y,
256 gint width,
257 gint height,
258 GtkPositionType gap_side);
259 static void gtk_default_draw_focus (GtkStyle *style,
260 cairo_t *cr,
261 GtkStateType state_type,
262 GtkWidget *widget,
263 const gchar *detail,
264 gint x,
265 gint y,
266 gint width,
267 gint height);
268 static void gtk_default_draw_slider (GtkStyle *style,
269 cairo_t *cr,
270 GtkStateType state_type,
271 GtkShadowType shadow_type,
272 GtkWidget *widget,
273 const gchar *detail,
274 gint x,
275 gint y,
276 gint width,
277 gint height,
278 GtkOrientation orientation);
279 static void gtk_default_draw_handle (GtkStyle *style,
280 cairo_t *cr,
281 GtkStateType state_type,
282 GtkShadowType shadow_type,
283 GtkWidget *widget,
284 const gchar *detail,
285 gint x,
286 gint y,
287 gint width,
288 gint height,
289 GtkOrientation orientation);
290 static void gtk_default_draw_expander (GtkStyle *style,
291 cairo_t *cr,
292 GtkStateType state_type,
293 GtkWidget *widget,
294 const gchar *detail,
295 gint x,
296 gint y,
297 GtkExpanderStyle expander_style);
298 static void gtk_default_draw_layout (GtkStyle *style,
299 cairo_t *cr,
300 GtkStateType state_type,
301 gboolean use_text,
302 GtkWidget *widget,
303 const gchar *detail,
304 gint x,
305 gint y,
306 PangoLayout *layout);
307 static void gtk_default_draw_resize_grip (GtkStyle *style,
308 cairo_t *cr,
309 GtkStateType state_type,
310 GtkWidget *widget,
311 const gchar *detail,
312 GdkWindowEdge edge,
313 gint x,
314 gint y,
315 gint width,
316 gint height);
317 static void gtk_default_draw_spinner (GtkStyle *style,
318 cairo_t *cr,
319 GtkStateType state_type,
320 GtkWidget *widget,
321 const gchar *detail,
322 guint step,
323 gint x,
324 gint y,
325 gint width,
326 gint height);
327
328 static void rgb_to_hls (gdouble *r,
329 gdouble *g,
330 gdouble *b);
331 static void hls_to_rgb (gdouble *h,
332 gdouble *l,
333 gdouble *s);
334
335 static void transform_detail_string (const gchar *detail,
336 GtkStyleContext *context);
337
338 /*
339 * Data for default check and radio buttons
340 */
341
342 static const GtkRequisition default_option_indicator_size = { 7, 13 };
343 static const GtkBorder default_option_indicator_spacing = { 7, 5, 2, 2 };
344
345 #define GTK_GRAY 0xdcdc, 0xdada, 0xd5d5
346 #define GTK_DARK_GRAY 0xc4c4, 0xc2c2, 0xbdbd
347 #define GTK_LIGHT_GRAY 0xeeee, 0xebeb, 0xe7e7
348 #define GTK_WHITE 0xffff, 0xffff, 0xffff
349 #define GTK_BLUE 0x4b4b, 0x6969, 0x8383
350 #define GTK_VERY_DARK_GRAY 0x9c9c, 0x9a9a, 0x9494
351 #define GTK_BLACK 0x0000, 0x0000, 0x0000
352 #define GTK_WEAK_GRAY 0x7530, 0x7530, 0x7530
353
354 /* --- variables --- */
355 static const GdkColor gtk_default_normal_fg = { 0, GTK_BLACK };
356 static const GdkColor gtk_default_active_fg = { 0, GTK_BLACK };
357 static const GdkColor gtk_default_prelight_fg = { 0, GTK_BLACK };
358 static const GdkColor gtk_default_selected_fg = { 0, GTK_WHITE };
359 static const GdkColor gtk_default_insensitive_fg = { 0, GTK_WEAK_GRAY };
360
361 static const GdkColor gtk_default_normal_bg = { 0, GTK_GRAY };
362 static const GdkColor gtk_default_active_bg = { 0, GTK_DARK_GRAY };
363 static const GdkColor gtk_default_prelight_bg = { 0, GTK_LIGHT_GRAY };
364 static const GdkColor gtk_default_selected_bg = { 0, GTK_BLUE };
365 static const GdkColor gtk_default_insensitive_bg = { 0, GTK_GRAY };
366 static const GdkColor gtk_default_selected_base = { 0, GTK_BLUE };
367 static const GdkColor gtk_default_active_base = { 0, GTK_VERY_DARK_GRAY };
368
369 static GQuark quark_default_style;
370
371 /* --- signals --- */
372 static guint realize_signal = 0;
373 static guint unrealize_signal = 0;
374
G_DEFINE_TYPE_WITH_PRIVATE(GtkStyle,gtk_style,G_TYPE_OBJECT)375 G_DEFINE_TYPE_WITH_PRIVATE (GtkStyle, gtk_style, G_TYPE_OBJECT)
376
377 /* --- functions --- */
378
379 static void
380 gtk_style_init (GtkStyle *style)
381 {
382 gint i;
383
384 style->font_desc = pango_font_description_from_string ("Sans 10");
385
386 style->attach_count = 0;
387
388 style->black.red = 0;
389 style->black.green = 0;
390 style->black.blue = 0;
391
392 style->white.red = 65535;
393 style->white.green = 65535;
394 style->white.blue = 65535;
395
396 style->fg[GTK_STATE_NORMAL] = gtk_default_normal_fg;
397 style->fg[GTK_STATE_ACTIVE] = gtk_default_active_fg;
398 style->fg[GTK_STATE_PRELIGHT] = gtk_default_prelight_fg;
399 style->fg[GTK_STATE_SELECTED] = gtk_default_selected_fg;
400 style->fg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
401
402 style->bg[GTK_STATE_NORMAL] = gtk_default_normal_bg;
403 style->bg[GTK_STATE_ACTIVE] = gtk_default_active_bg;
404 style->bg[GTK_STATE_PRELIGHT] = gtk_default_prelight_bg;
405 style->bg[GTK_STATE_SELECTED] = gtk_default_selected_bg;
406 style->bg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_bg;
407
408 for (i = 0; i < 4; i++)
409 {
410 style->text[i] = style->fg[i];
411 style->base[i] = style->white;
412 }
413
414 style->base[GTK_STATE_SELECTED] = gtk_default_selected_base;
415 style->text[GTK_STATE_SELECTED] = style->white;
416 style->base[GTK_STATE_ACTIVE] = gtk_default_active_base;
417 style->text[GTK_STATE_ACTIVE] = style->white;
418 style->base[GTK_STATE_INSENSITIVE] = gtk_default_prelight_bg;
419 style->text[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
420
421 style->rc_style = NULL;
422
423 style->xthickness = 2;
424 style->ythickness = 2;
425
426 style->property_cache = NULL;
427 }
428
429 static void
gtk_style_class_init(GtkStyleClass * klass)430 gtk_style_class_init (GtkStyleClass *klass)
431 {
432 GObjectClass *object_class = G_OBJECT_CLASS (klass);
433
434 object_class->finalize = gtk_style_finalize;
435 object_class->set_property = gtk_style_set_property;
436 object_class->get_property = gtk_style_get_property;
437 object_class->constructed = gtk_style_constructed;
438
439 klass->clone = gtk_style_real_clone;
440 klass->copy = gtk_style_real_copy;
441 klass->init_from_rc = gtk_style_real_init_from_rc;
442 klass->realize = gtk_style_real_realize;
443 klass->unrealize = gtk_style_real_unrealize;
444 klass->set_background = gtk_style_real_set_background;
445 klass->render_icon = gtk_default_render_icon;
446
447 klass->draw_hline = gtk_default_draw_hline;
448 klass->draw_vline = gtk_default_draw_vline;
449 klass->draw_shadow = gtk_default_draw_shadow;
450 klass->draw_arrow = gtk_default_draw_arrow;
451 klass->draw_diamond = gtk_default_draw_diamond;
452 klass->draw_box = gtk_default_draw_box;
453 klass->draw_flat_box = gtk_default_draw_flat_box;
454 klass->draw_check = gtk_default_draw_check;
455 klass->draw_option = gtk_default_draw_option;
456 klass->draw_tab = gtk_default_draw_tab;
457 klass->draw_shadow_gap = gtk_default_draw_shadow_gap;
458 klass->draw_box_gap = gtk_default_draw_box_gap;
459 klass->draw_extension = gtk_default_draw_extension;
460 klass->draw_focus = gtk_default_draw_focus;
461 klass->draw_slider = gtk_default_draw_slider;
462 klass->draw_handle = gtk_default_draw_handle;
463 klass->draw_expander = gtk_default_draw_expander;
464 klass->draw_layout = gtk_default_draw_layout;
465 klass->draw_resize_grip = gtk_default_draw_resize_grip;
466 klass->draw_spinner = gtk_default_draw_spinner;
467
468 g_object_class_install_property (object_class,
469 PROP_CONTEXT,
470 g_param_spec_object ("context",
471 P_("Style context"),
472 P_("GtkStyleContext to get style from"),
473 GTK_TYPE_STYLE_CONTEXT,
474 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
475
476 /**
477 * GtkStyle::realize:
478 * @style: the object which received the signal
479 *
480 * Emitted when the style has been initialized for a particular
481 * visual. Connecting to this signal is probably seldom
482 * useful since most of the time applications and widgets only
483 * deal with styles that have been already realized.
484 *
485 * Since: 2.4
486 */
487 realize_signal = g_signal_new (I_("realize"),
488 G_TYPE_FROM_CLASS (object_class),
489 G_SIGNAL_RUN_FIRST,
490 G_STRUCT_OFFSET (GtkStyleClass, realize),
491 NULL, NULL,
492 NULL,
493 G_TYPE_NONE, 0);
494 /**
495 * GtkStyle::unrealize:
496 * @style: the object which received the signal
497 *
498 * Emitted when the aspects of the style specific to a particular visual
499 * is being cleaned up. A connection to this signal can be useful
500 * if a widget wants to cache objects as object data on #GtkStyle.
501 * This signal provides a convenient place to free such cached objects.
502 *
503 * Since: 2.4
504 */
505 unrealize_signal = g_signal_new (I_("unrealize"),
506 G_TYPE_FROM_CLASS (object_class),
507 G_SIGNAL_RUN_FIRST,
508 G_STRUCT_OFFSET (GtkStyleClass, unrealize),
509 NULL, NULL,
510 NULL,
511 G_TYPE_NONE, 0);
512 }
513
514 static void
gtk_style_finalize(GObject * object)515 gtk_style_finalize (GObject *object)
516 {
517 GtkStyle *style = GTK_STYLE (object);
518 GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
519 gint i;
520
521 g_return_if_fail (style->attach_count == 0);
522
523 /* All the styles in the list have the same
524 * style->styles pointer. If we delete the
525 * *first* style from the list, we need to update
526 * the style->styles pointers from all the styles.
527 * Otherwise we simply remove the node from
528 * the list.
529 */
530 if (style->styles)
531 {
532 if (style->styles->data != style)
533 style->styles = g_slist_remove (style->styles, style);
534 else
535 {
536 GSList *tmp_list = style->styles->next;
537
538 while (tmp_list)
539 {
540 GTK_STYLE (tmp_list->data)->styles = style->styles->next;
541 tmp_list = tmp_list->next;
542 }
543 g_slist_free_1 (style->styles);
544 }
545 }
546
547 g_slist_free_full (style->icon_factories, g_object_unref);
548
549 pango_font_description_free (style->font_desc);
550
551 if (style->private_font_desc)
552 pango_font_description_free (style->private_font_desc);
553
554 if (style->rc_style)
555 g_object_unref (style->rc_style);
556
557 if (priv->context)
558 {
559 if (priv->context_changed_id)
560 g_signal_handler_disconnect (priv->context, priv->context_changed_id);
561
562 g_object_unref (priv->context);
563 }
564
565 for (i = 0; i < 5; i++)
566 {
567 if (style->background[i])
568 cairo_pattern_destroy (style->background[i]);
569 }
570
571 G_OBJECT_CLASS (gtk_style_parent_class)->finalize (object);
572 }
573
574 static void
gtk_style_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)575 gtk_style_set_property (GObject *object,
576 guint prop_id,
577 const GValue *value,
578 GParamSpec *pspec)
579 {
580 GtkStylePrivate *priv;
581
582 priv = GTK_STYLE_GET_PRIVATE (object);
583
584 switch (prop_id)
585 {
586 case PROP_CONTEXT:
587 priv->context = g_value_dup_object (value);
588 break;
589 default:
590 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
591 break;
592 }
593 }
594
595 static void
gtk_style_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)596 gtk_style_get_property (GObject *object,
597 guint prop_id,
598 GValue *value,
599 GParamSpec *pspec)
600 {
601 GtkStylePrivate *priv;
602
603 priv = GTK_STYLE_GET_PRIVATE (object);
604
605 switch (prop_id)
606 {
607 case PROP_CONTEXT:
608 g_value_set_object (value, priv->context);
609 break;
610 default:
611 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
612 break;
613 }
614 }
615
616 static gboolean
set_color_from_context(GtkStyle * style,GtkStateType state,GtkStyleContext * context,GtkRcFlags prop)617 set_color_from_context (GtkStyle *style,
618 GtkStateType state,
619 GtkStyleContext *context,
620 GtkRcFlags prop)
621 {
622 GdkRGBA *color = NULL;
623 GdkColor *dest = { 0 }; /* Shut up gcc */
624 GtkStateFlags flags;
625
626 flags = gtk_style_context_get_state (context);
627
628 switch (prop)
629 {
630 case GTK_RC_BG:
631 gtk_style_context_get (context, flags,
632 "background-color", &color,
633 NULL);
634 dest = &style->bg[state];
635 break;
636 case GTK_RC_FG:
637 gtk_style_context_get (context, flags,
638 "color", &color,
639 NULL);
640 dest = &style->fg[state];
641 break;
642 case GTK_RC_TEXT:
643 gtk_style_context_get (context, flags,
644 "color", &color,
645 NULL);
646 dest = &style->text[state];
647 break;
648 case GTK_RC_BASE:
649 gtk_style_context_get (context, flags,
650 "background-color", &color,
651 NULL);
652 dest = &style->base[state];
653 break;
654 }
655
656 if (!color)
657 return FALSE;
658
659 if (!(color->alpha > 0.01))
660 {
661 gdk_rgba_free (color);
662 return FALSE;
663 }
664
665 dest->pixel = 0;
666 dest->red = CLAMP ((guint) (color->red * 65535), 0, 65535);
667 dest->green = CLAMP ((guint) (color->green * 65535), 0, 65535);
668 dest->blue = CLAMP ((guint) (color->blue * 65535), 0, 65535);
669 gdk_rgba_free (color);
670
671 return TRUE;
672 }
673
674 static void
set_color(GtkStyle * style,GtkStyleContext * context,GtkStateType state,GtkRcFlags prop)675 set_color (GtkStyle *style,
676 GtkStyleContext *context,
677 GtkStateType state,
678 GtkRcFlags prop)
679 {
680 /* Try to fill in the values from the associated GtkStyleContext.
681 * Since fully-transparent black is a very common default (e.g. for
682 * background-color properties), and we must store the result in a GdkColor
683 * to retain API compatibility, in case the fetched color is fully transparent
684 * we give themes a fallback style class they can style, before using the
685 * hardcoded default values.
686 */
687 if (!set_color_from_context (style, state, context, prop))
688 {
689 gtk_style_context_save (context);
690 gtk_style_context_add_class (context, "gtkstyle-fallback");
691 set_color_from_context (style, state, context, prop);
692 gtk_style_context_restore (context);
693 }
694 }
695
696 static void
gtk_style_update_from_context(GtkStyle * style)697 gtk_style_update_from_context (GtkStyle *style)
698 {
699 GtkStylePrivate *priv;
700 GtkStateType state;
701 GtkStateFlags flags;
702 GtkBorder padding;
703 gint i;
704
705 priv = GTK_STYLE_GET_PRIVATE (style);
706
707 for (state = GTK_STATE_NORMAL; state <= GTK_STATE_INSENSITIVE; state++)
708 {
709 switch (state)
710 {
711 case GTK_STATE_ACTIVE:
712 flags = GTK_STATE_FLAG_ACTIVE;
713 break;
714 case GTK_STATE_PRELIGHT:
715 flags = GTK_STATE_FLAG_PRELIGHT;
716 break;
717 case GTK_STATE_SELECTED:
718 flags = GTK_STATE_FLAG_SELECTED;
719 break;
720 case GTK_STATE_INSENSITIVE:
721 flags = GTK_STATE_FLAG_INSENSITIVE;
722 break;
723 default:
724 flags = 0;
725 }
726
727 gtk_style_context_save (priv->context);
728 gtk_style_context_set_state (priv->context, flags);
729
730 if (gtk_style_context_has_class (priv->context, "entry"))
731 {
732 gtk_style_context_save (priv->context);
733 gtk_style_context_remove_class (priv->context, "entry");
734 set_color (style, priv->context, state, GTK_RC_BG);
735 set_color (style, priv->context, state, GTK_RC_FG);
736 gtk_style_context_restore (priv->context);
737
738 set_color (style, priv->context, state, GTK_RC_BASE);
739 set_color (style, priv->context, state, GTK_RC_TEXT);
740 }
741 else
742 {
743 gtk_style_context_save (priv->context);
744 gtk_style_context_add_class (priv->context, "entry");
745 set_color (style, priv->context, state, GTK_RC_BASE);
746 set_color (style, priv->context, state, GTK_RC_TEXT);
747 gtk_style_context_restore (priv->context);
748
749 set_color (style, priv->context, state, GTK_RC_BG);
750 set_color (style, priv->context, state, GTK_RC_FG);
751 }
752
753 gtk_style_context_restore (priv->context);
754 }
755
756 if (style->font_desc)
757 pango_font_description_free (style->font_desc);
758
759 flags = gtk_style_context_get_state (priv->context);
760 gtk_style_context_get (priv->context, flags,
761 "font", &style->font_desc,
762 NULL);
763 gtk_style_context_get_padding (priv->context, flags, &padding);
764
765 style->xthickness = padding.left;
766 style->ythickness = padding.top;
767
768 for (i = 0; i < 5; i++)
769 {
770 _gtk_style_shade (&style->bg[i], &style->light[i], LIGHTNESS_MULT);
771 _gtk_style_shade (&style->bg[i], &style->dark[i], DARKNESS_MULT);
772
773 style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
774 style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
775 style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
776
777 style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
778 style->text_aa[i].green = (style->text[i].green + style->base[i].green) / 2;
779 style->text_aa[i].blue = (style->text[i].blue + style->base[i].blue) / 2;
780 }
781
782 style->black.red = 0x0000;
783 style->black.green = 0x0000;
784 style->black.blue = 0x0000;
785
786 style->white.red = 0xffff;
787 style->white.green = 0xffff;
788 style->white.blue = 0xffff;
789
790 for (i = 0; i < 5; i++)
791 {
792 if (style->background[i])
793 cairo_pattern_destroy (style->background[i]);
794
795 style->background[i] = cairo_pattern_create_rgb (style->bg[i].red / 65535.0,
796 style->bg[i].green / 65535.0,
797 style->bg[i].blue / 65535.0);
798 }
799 }
800
801 static void
style_context_changed(GtkStyleContext * context,gpointer user_data)802 style_context_changed (GtkStyleContext *context,
803 gpointer user_data)
804 {
805 gtk_style_update_from_context (GTK_STYLE (user_data));
806 }
807
808 static void
gtk_style_constructed(GObject * object)809 gtk_style_constructed (GObject *object)
810 {
811 GtkStylePrivate *priv;
812
813 priv = GTK_STYLE_GET_PRIVATE (object);
814
815 if (priv->context)
816 {
817 gtk_style_update_from_context (GTK_STYLE (object));
818
819 priv->context_changed_id = g_signal_connect (priv->context, "changed",
820 G_CALLBACK (style_context_changed), object);
821 }
822 }
823
824 /**
825 * gtk_style_copy:
826 * @style: a #GtkStyle
827 *
828 * Creates a copy of the passed in #GtkStyle object.
829 *
830 * Returns: (transfer full): a copy of @style
831 *
832 * Deprecated:3.0: Use #GtkStyleContext instead
833 */
834 GtkStyle*
gtk_style_copy(GtkStyle * style)835 gtk_style_copy (GtkStyle *style)
836 {
837 GtkStyle *new_style;
838
839 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
840
841 new_style = GTK_STYLE_GET_CLASS (style)->clone (style);
842 GTK_STYLE_GET_CLASS (style)->copy (new_style, style);
843
844 return new_style;
845 }
846
847 GtkStyle*
_gtk_style_new_for_path(GdkScreen * screen,GtkWidgetPath * path)848 _gtk_style_new_for_path (GdkScreen *screen,
849 GtkWidgetPath *path)
850 {
851 GtkStyleContext *context;
852 GtkStyle *style;
853
854 context = gtk_style_context_new ();
855
856 if (screen)
857 gtk_style_context_set_screen (context, screen);
858
859 gtk_style_context_set_path (context, path);
860
861 style = g_object_new (GTK_TYPE_STYLE,
862 "context", context,
863 NULL);
864
865 g_object_unref (context);
866
867 return style;
868 }
869
870 /**
871 * gtk_style_new:
872 *
873 * Creates a new #GtkStyle.
874 *
875 * Returns: a new #GtkStyle.
876 *
877 * Deprecated: 3.0: Use #GtkStyleContext
878 */
879 GtkStyle*
gtk_style_new(void)880 gtk_style_new (void)
881 {
882 GtkWidgetPath *path;
883 GtkStyle *style;
884
885 path = gtk_widget_path_new ();
886 gtk_widget_path_append_type (path, GTK_TYPE_WIDGET);
887
888 style = _gtk_style_new_for_path (gdk_screen_get_default (), path);
889
890 gtk_widget_path_free (path);
891
892 return style;
893 }
894
895 /**
896 * gtk_style_has_context:
897 * @style: a #GtkStyle
898 *
899 * Returns whether @style has an associated #GtkStyleContext.
900 *
901 * Returns: %TRUE if @style has a #GtkStyleContext
902 *
903 * Since: 3.0
904 */
905 gboolean
gtk_style_has_context(GtkStyle * style)906 gtk_style_has_context (GtkStyle *style)
907 {
908 GtkStylePrivate *priv;
909
910 priv = GTK_STYLE_GET_PRIVATE (style);
911
912 return priv->context != NULL;
913 }
914
915 /**
916 * gtk_style_attach: (skip)
917 * @style: a #GtkStyle.
918 * @window: a #GdkWindow.
919 *
920 * Attaches a style to a window; this process allocates the
921 * colors and creates the GC’s for the style - it specializes
922 * it to a particular visual. The process may involve the creation
923 * of a new style if the style has already been attached to a
924 * window with a different style and visual.
925 *
926 * Since this function may return a new object, you have to use it
927 * in the following way:
928 * `style = gtk_style_attach (style, window)`
929 *
930 * Returns: Either @style, or a newly-created #GtkStyle.
931 * If the style is newly created, the style parameter
932 * will be unref'ed, and the new style will have
933 * a reference count belonging to the caller.
934 *
935 * Deprecated:3.0: Use gtk_widget_style_attach() instead
936 */
937 GtkStyle*
gtk_style_attach(GtkStyle * style,GdkWindow * window)938 gtk_style_attach (GtkStyle *style,
939 GdkWindow *window)
940 {
941 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
942 g_return_val_if_fail (window != NULL, NULL);
943
944 return style;
945 }
946
947 /**
948 * gtk_style_detach:
949 * @style: a #GtkStyle
950 *
951 * Detaches a style from a window. If the style is not attached
952 * to any windows anymore, it is unrealized. See gtk_style_attach().
953 *
954 * Deprecated:3.0: Use #GtkStyleContext instead
955 */
956 void
gtk_style_detach(GtkStyle * style)957 gtk_style_detach (GtkStyle *style)
958 {
959 g_return_if_fail (GTK_IS_STYLE (style));
960 }
961
962 /**
963 * gtk_style_lookup_icon_set:
964 * @style: a #GtkStyle
965 * @stock_id: an icon name
966 *
967 * Looks up @stock_id in the icon factories associated with @style
968 * and the default icon factory, returning an icon set if found,
969 * otherwise %NULL.
970 *
971 * Returns: (transfer none): icon set of @stock_id
972 *
973 * Deprecated:3.0: Use gtk_style_context_lookup_icon_set() instead
974 */
975 GtkIconSet*
gtk_style_lookup_icon_set(GtkStyle * style,const char * stock_id)976 gtk_style_lookup_icon_set (GtkStyle *style,
977 const char *stock_id)
978 {
979 GtkStylePrivate *priv;
980
981 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
982 g_return_val_if_fail (stock_id != NULL, NULL);
983
984 priv = GTK_STYLE_GET_PRIVATE (style);
985
986 if (priv->context)
987 return gtk_style_context_lookup_icon_set (priv->context, stock_id);
988
989 return gtk_icon_factory_lookup_default (stock_id);
990 }
991
992 /**
993 * gtk_style_lookup_color:
994 * @style: a #GtkStyle
995 * @color_name: the name of the logical color to look up
996 * @color: (out): the #GdkColor to fill in
997 *
998 * Looks up @color_name in the style’s logical color mappings,
999 * filling in @color and returning %TRUE if found, otherwise
1000 * returning %FALSE. Do not cache the found mapping, because
1001 * it depends on the #GtkStyle and might change when a theme
1002 * switch occurs.
1003 *
1004 * Returns: %TRUE if the mapping was found.
1005 *
1006 * Since: 2.10
1007 *
1008 * Deprecated:3.0: Use gtk_style_context_lookup_color() instead
1009 **/
1010 gboolean
gtk_style_lookup_color(GtkStyle * style,const char * color_name,GdkColor * color)1011 gtk_style_lookup_color (GtkStyle *style,
1012 const char *color_name,
1013 GdkColor *color)
1014 {
1015 GtkStylePrivate *priv;
1016 gboolean result;
1017 GdkRGBA rgba;
1018
1019 g_return_val_if_fail (GTK_IS_STYLE (style), FALSE);
1020 g_return_val_if_fail (color_name != NULL, FALSE);
1021 g_return_val_if_fail (color != NULL, FALSE);
1022
1023 priv = GTK_STYLE_GET_PRIVATE (style);
1024
1025 if (!priv->context)
1026 return FALSE;
1027
1028 result = gtk_style_context_lookup_color (priv->context, color_name, &rgba);
1029
1030 if (color)
1031 {
1032 color->red = (guint16) (rgba.red * 65535);
1033 color->green = (guint16) (rgba.green * 65535);
1034 color->blue = (guint16) (rgba.blue * 65535);
1035 color->pixel = 0;
1036 }
1037
1038 return result;
1039 }
1040
1041 /**
1042 * gtk_style_set_background:
1043 * @style: a #GtkStyle
1044 * @window: a #GdkWindow
1045 * @state_type: a state
1046 *
1047 * Sets the background of @window to the background color or pixmap
1048 * specified by @style for the given state.
1049 *
1050 * Deprecated:3.0: Use gtk_style_context_set_background() instead
1051 */
1052 void
gtk_style_set_background(GtkStyle * style,GdkWindow * window,GtkStateType state_type)1053 gtk_style_set_background (GtkStyle *style,
1054 GdkWindow *window,
1055 GtkStateType state_type)
1056 {
1057 g_return_if_fail (GTK_IS_STYLE (style));
1058 g_return_if_fail (window != NULL);
1059
1060 GTK_STYLE_GET_CLASS (style)->set_background (style, window, state_type);
1061 }
1062
1063 /* Default functions */
1064 static GtkStyle *
gtk_style_real_clone(GtkStyle * style)1065 gtk_style_real_clone (GtkStyle *style)
1066 {
1067 GtkStylePrivate *priv;
1068
1069 priv = GTK_STYLE_GET_PRIVATE (style);
1070
1071 return g_object_new (G_OBJECT_TYPE (style),
1072 "context", priv->context,
1073 NULL);
1074 }
1075
1076 static void
gtk_style_real_copy(GtkStyle * style,GtkStyle * src)1077 gtk_style_real_copy (GtkStyle *style,
1078 GtkStyle *src)
1079 {
1080 gint i;
1081
1082 for (i = 0; i < 5; i++)
1083 {
1084 style->fg[i] = src->fg[i];
1085 style->bg[i] = src->bg[i];
1086 style->text[i] = src->text[i];
1087 style->base[i] = src->base[i];
1088
1089 if (style->background[i])
1090 cairo_pattern_destroy (style->background[i]),
1091 style->background[i] = src->background[i];
1092 if (style->background[i])
1093 cairo_pattern_reference (style->background[i]);
1094 }
1095
1096 if (style->font_desc)
1097 pango_font_description_free (style->font_desc);
1098 if (src->font_desc)
1099 style->font_desc = pango_font_description_copy (src->font_desc);
1100 else
1101 style->font_desc = NULL;
1102
1103 style->xthickness = src->xthickness;
1104 style->ythickness = src->ythickness;
1105
1106 if (style->rc_style)
1107 g_object_unref (style->rc_style);
1108 style->rc_style = src->rc_style;
1109 if (src->rc_style)
1110 g_object_ref (src->rc_style);
1111
1112 g_slist_free_full (style->icon_factories, g_object_unref);
1113 style->icon_factories = g_slist_copy (src->icon_factories);
1114 g_slist_foreach (style->icon_factories, (GFunc) g_object_ref, NULL);
1115 }
1116
1117 static void
gtk_style_real_init_from_rc(GtkStyle * style,GtkRcStyle * rc_style)1118 gtk_style_real_init_from_rc (GtkStyle *style,
1119 GtkRcStyle *rc_style)
1120 {
1121 }
1122
1123 /**
1124 * gtk_style_get_style_property:
1125 * @style: a #GtkStyle
1126 * @widget_type: the #GType of a descendant of #GtkWidget
1127 * @property_name: the name of the style property to get
1128 * @value: (out): a #GValue where the value of the property being
1129 * queried will be stored
1130 *
1131 * Queries the value of a style property corresponding to a
1132 * widget class is in the given style.
1133 *
1134 * Since: 2.16
1135 */
1136 void
gtk_style_get_style_property(GtkStyle * style,GType widget_type,const gchar * property_name,GValue * value)1137 gtk_style_get_style_property (GtkStyle *style,
1138 GType widget_type,
1139 const gchar *property_name,
1140 GValue *value)
1141 {
1142 GtkStylePrivate *priv;
1143 GtkWidgetClass *klass;
1144 GParamSpec *pspec;
1145 const GValue *peek_value;
1146
1147 klass = g_type_class_ref (widget_type);
1148 pspec = gtk_widget_class_find_style_property (klass, property_name);
1149 g_type_class_unref (klass);
1150
1151 if (!pspec)
1152 {
1153 g_warning ("%s: widget class `%s' has no property named `%s'",
1154 G_STRLOC,
1155 g_type_name (widget_type),
1156 property_name);
1157 return;
1158 }
1159
1160 priv = GTK_STYLE_GET_PRIVATE (style);
1161 peek_value = _gtk_style_context_peek_style_property (priv->context,
1162 widget_type,
1163 pspec);
1164
1165 if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec))
1166 g_value_copy (peek_value, value);
1167 else if (g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
1168 g_value_transform (peek_value, value);
1169 else
1170 g_warning ("can't retrieve style property `%s' of type `%s' as value of type `%s'",
1171 pspec->name,
1172 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1173 G_VALUE_TYPE_NAME (value));
1174 }
1175
1176 /**
1177 * gtk_style_get_valist:
1178 * @style: a #GtkStyle
1179 * @widget_type: the #GType of a descendant of #GtkWidget
1180 * @first_property_name: the name of the first style property to get
1181 * @var_args: a va_list of pairs of property names and
1182 * locations to return the property values, starting with the
1183 * location for @first_property_name.
1184 *
1185 * Non-vararg variant of gtk_style_get().
1186 * Used primarily by language bindings.
1187 *
1188 * Since: 2.16
1189 */
1190 void
gtk_style_get_valist(GtkStyle * style,GType widget_type,const gchar * first_property_name,va_list var_args)1191 gtk_style_get_valist (GtkStyle *style,
1192 GType widget_type,
1193 const gchar *first_property_name,
1194 va_list var_args)
1195 {
1196 GtkStylePrivate *priv;
1197 const char *property_name;
1198 GtkWidgetClass *klass;
1199
1200 g_return_if_fail (GTK_IS_STYLE (style));
1201
1202 klass = g_type_class_ref (widget_type);
1203
1204 priv = GTK_STYLE_GET_PRIVATE (style);
1205 property_name = first_property_name;
1206 while (property_name)
1207 {
1208 GParamSpec *pspec;
1209 const GValue *peek_value;
1210 gchar *error;
1211
1212 pspec = gtk_widget_class_find_style_property (klass, property_name);
1213
1214 if (!pspec)
1215 {
1216 g_warning ("%s: widget class `%s' has no property named `%s'",
1217 G_STRLOC,
1218 g_type_name (widget_type),
1219 property_name);
1220 break;
1221 }
1222
1223 peek_value = _gtk_style_context_peek_style_property (priv->context, widget_type,
1224 pspec);
1225 G_VALUE_LCOPY (peek_value, var_args, 0, &error);
1226 if (error)
1227 {
1228 g_warning ("%s: %s", G_STRLOC, error);
1229 g_free (error);
1230 break;
1231 }
1232
1233 property_name = va_arg (var_args, gchar*);
1234 }
1235
1236 g_type_class_unref (klass);
1237 }
1238
1239 /**
1240 * gtk_style_get:
1241 * @style: a #GtkStyle
1242 * @widget_type: the #GType of a descendant of #GtkWidget
1243 * @first_property_name: the name of the first style property to get
1244 * @...: pairs of property names and locations to
1245 * return the property values, starting with the location for
1246 * @first_property_name, terminated by %NULL.
1247 *
1248 * Gets the values of a multiple style properties for @widget_type
1249 * from @style.
1250 *
1251 * Since: 2.16
1252 */
1253 void
gtk_style_get(GtkStyle * style,GType widget_type,const gchar * first_property_name,...)1254 gtk_style_get (GtkStyle *style,
1255 GType widget_type,
1256 const gchar *first_property_name,
1257 ...)
1258 {
1259 va_list var_args;
1260
1261 va_start (var_args, first_property_name);
1262 gtk_style_get_valist (style, widget_type, first_property_name, var_args);
1263 va_end (var_args);
1264 }
1265
1266 static void
gtk_style_real_realize(GtkStyle * style)1267 gtk_style_real_realize (GtkStyle *style)
1268 {
1269 }
1270
1271 static void
gtk_style_real_unrealize(GtkStyle * style)1272 gtk_style_real_unrealize (GtkStyle *style)
1273 {
1274 }
1275
1276 static void
gtk_style_real_set_background(GtkStyle * style,GdkWindow * window,GtkStateType state_type)1277 gtk_style_real_set_background (GtkStyle *style,
1278 GdkWindow *window,
1279 GtkStateType state_type)
1280 {
1281 gdk_window_set_background_pattern (window, style->background[state_type]);
1282 }
1283
1284 /**
1285 * gtk_style_render_icon:
1286 * @style: a #GtkStyle
1287 * @source: the #GtkIconSource specifying the icon to render
1288 * @direction: a text direction
1289 * @state: a state
1290 * @size: (type int): the size to render the icon at (#GtkIconSize). A size of
1291 * `(GtkIconSize)-1` means render at the size of the source and
1292 * don’t scale.
1293 * @widget: (allow-none): the widget
1294 * @detail: (allow-none): a style detail
1295 *
1296 * Renders the icon specified by @source at the given @size
1297 * according to the given parameters and returns the result in a
1298 * pixbuf.
1299 *
1300 * Returns: (transfer full): a newly-created #GdkPixbuf
1301 * containing the rendered icon
1302 *
1303 * Deprecated:3.0: Use gtk_render_icon_pixbuf() instead
1304 */
1305 GdkPixbuf *
gtk_style_render_icon(GtkStyle * style,const GtkIconSource * source,GtkTextDirection direction,GtkStateType state,GtkIconSize size,GtkWidget * widget,const gchar * detail)1306 gtk_style_render_icon (GtkStyle *style,
1307 const GtkIconSource *source,
1308 GtkTextDirection direction,
1309 GtkStateType state,
1310 GtkIconSize size,
1311 GtkWidget *widget,
1312 const gchar *detail)
1313 {
1314 GdkPixbuf *pixbuf;
1315
1316 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1317 g_return_val_if_fail (GTK_STYLE_GET_CLASS (style)->render_icon != NULL, NULL);
1318
1319 pixbuf = GTK_STYLE_GET_CLASS (style)->render_icon (style, source, direction, state,
1320 size, widget, detail);
1321
1322 g_return_val_if_fail (pixbuf != NULL, NULL);
1323
1324 return pixbuf;
1325 }
1326
1327 /* Default functions */
1328
1329 /**
1330 * gtk_style_apply_default_background:
1331 * @style:
1332 * @cr:
1333 * @window:
1334 * @state_type:
1335 * @x:
1336 * @y:
1337 * @width:
1338 * @height:
1339 *
1340 * Deprecated:3.0: Use #GtkStyleContext instead
1341 */
1342 void
gtk_style_apply_default_background(GtkStyle * style,cairo_t * cr,GdkWindow * window,GtkStateType state_type,gint x,gint y,gint width,gint height)1343 gtk_style_apply_default_background (GtkStyle *style,
1344 cairo_t *cr,
1345 GdkWindow *window,
1346 GtkStateType state_type,
1347 gint x,
1348 gint y,
1349 gint width,
1350 gint height)
1351 {
1352 cairo_save (cr);
1353
1354 if (style->background[state_type] == NULL)
1355 {
1356 GdkWindow *parent = gdk_window_get_parent (window);
1357 int x_offset, y_offset;
1358
1359 if (parent)
1360 {
1361 gdk_window_get_position (window, &x_offset, &y_offset);
1362 cairo_translate (cr, -x_offset, -y_offset);
1363 gtk_style_apply_default_background (style, cr,
1364 parent, state_type,
1365 x + x_offset, y + y_offset,
1366 width, height);
1367 goto out;
1368 }
1369 else
1370 gdk_cairo_set_source_color (cr, &style->bg[state_type]);
1371 }
1372 else
1373 cairo_set_source (cr, style->background[state_type]);
1374
1375 cairo_rectangle (cr, x, y, width, height);
1376 cairo_fill (cr);
1377
1378 out:
1379 cairo_restore (cr);
1380 }
1381
1382 static GdkPixbuf *
gtk_default_render_icon(GtkStyle * style,const GtkIconSource * source,GtkTextDirection direction,GtkStateType state,GtkIconSize size,GtkWidget * widget,const gchar * detail)1383 gtk_default_render_icon (GtkStyle *style,
1384 const GtkIconSource *source,
1385 GtkTextDirection direction,
1386 GtkStateType state,
1387 GtkIconSize size,
1388 GtkWidget *widget,
1389 const gchar *detail)
1390 {
1391 GtkStyleContext *context;
1392 GtkStylePrivate *priv;
1393 GtkStateFlags flags = 0;
1394 GdkPixbuf *pixbuf;
1395
1396 if (widget)
1397 context = gtk_widget_get_style_context (widget);
1398 else
1399 {
1400 priv = GTK_STYLE_GET_PRIVATE (style);
1401 context = priv->context;
1402 }
1403
1404 if (!context)
1405 return NULL;
1406
1407 gtk_style_context_save (context);
1408
1409 if (detail)
1410 transform_detail_string (detail, context);
1411
1412 switch (state)
1413 {
1414 case GTK_STATE_PRELIGHT:
1415 flags |= GTK_STATE_FLAG_PRELIGHT;
1416 break;
1417 case GTK_STATE_INSENSITIVE:
1418 flags |= GTK_STATE_FLAG_INSENSITIVE;
1419 break;
1420 default:
1421 break;
1422 }
1423
1424 gtk_style_context_set_state (context, flags);
1425
1426 pixbuf = gtk_render_icon_pixbuf (context, source, size);
1427
1428 gtk_style_context_restore (context);
1429
1430 return pixbuf;
1431 }
1432
1433 static void
_cairo_draw_line(cairo_t * cr,GdkColor * color,gint x1,gint y1,gint x2,gint y2)1434 _cairo_draw_line (cairo_t *cr,
1435 GdkColor *color,
1436 gint x1,
1437 gint y1,
1438 gint x2,
1439 gint y2)
1440 {
1441 cairo_save (cr);
1442
1443 gdk_cairo_set_source_color (cr, color);
1444 cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
1445
1446 cairo_move_to (cr, x1 + 0.5, y1 + 0.5);
1447 cairo_line_to (cr, x2 + 0.5, y2 + 0.5);
1448 cairo_stroke (cr);
1449
1450 cairo_restore (cr);
1451 }
1452
1453 static void
transform_detail_string(const gchar * detail,GtkStyleContext * context)1454 transform_detail_string (const gchar *detail,
1455 GtkStyleContext *context)
1456 {
1457 if (!detail)
1458 return;
1459
1460 if (strcmp (detail, "arrow") == 0)
1461 gtk_style_context_add_class (context, "arrow");
1462 else if (strcmp (detail, "button") == 0)
1463 gtk_style_context_add_class (context, "button");
1464 else if (strcmp (detail, "buttondefault") == 0)
1465 {
1466 gtk_style_context_add_class (context, "button");
1467 gtk_style_context_add_class (context, "default");
1468 }
1469 else if (strcmp (detail, "calendar") == 0)
1470 gtk_style_context_add_class (context, "calendar");
1471 else if (strcmp (detail, "cellcheck") == 0)
1472 {
1473 gtk_style_context_add_class (context, "cell");
1474 gtk_style_context_add_class (context, "check");
1475 }
1476 else if (strcmp (detail, "cellradio") == 0)
1477 {
1478 gtk_style_context_add_class (context, "cell");
1479 gtk_style_context_add_class (context, "radio");
1480 }
1481 else if (strcmp (detail, "checkbutton") == 0)
1482 gtk_style_context_add_class (context, "check");
1483 else if (strcmp (detail, "check") == 0)
1484 {
1485 gtk_style_context_add_class (context, "check");
1486 gtk_style_context_add_class (context, "menu");
1487 }
1488 else if (strcmp (detail, "radiobutton") == 0)
1489 {
1490 gtk_style_context_add_class (context, "radio");
1491 }
1492 else if (strcmp (detail, "option") == 0)
1493 {
1494 gtk_style_context_add_class (context, "radio");
1495 gtk_style_context_add_class (context, "menu");
1496 }
1497 else if (strcmp (detail, "entry") == 0 ||
1498 strcmp (detail, "entry_bg") == 0)
1499 gtk_style_context_add_class (context, "entry");
1500 else if (strcmp (detail, "expander") == 0)
1501 gtk_style_context_add_class (context, "expander");
1502 else if (strcmp (detail, "tooltip") == 0)
1503 gtk_style_context_add_class (context, "tooltip");
1504 else if (strcmp (detail, "frame") == 0)
1505 gtk_style_context_add_class (context, "frame");
1506 else if (strcmp (detail, "scrolled_window") == 0)
1507 gtk_style_context_add_class (context, "scrolled-window");
1508 else if (strcmp (detail, "viewport") == 0 ||
1509 strcmp (detail, "viewportbin") == 0)
1510 gtk_style_context_add_class (context, "viewport");
1511 else if (strncmp (detail, "trough", 6) == 0)
1512 gtk_style_context_add_class (context, "trough");
1513 else if (strcmp (detail, "spinbutton") == 0)
1514 gtk_style_context_add_class (context, "spinbutton");
1515 else if (strcmp (detail, "spinbutton_up") == 0)
1516 {
1517 gtk_style_context_add_class (context, "spinbutton");
1518 gtk_style_context_add_class (context, "button");
1519 gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
1520 }
1521 else if (strcmp (detail, "spinbutton_down") == 0)
1522 {
1523 gtk_style_context_add_class (context, "spinbutton");
1524 gtk_style_context_add_class (context, "button");
1525 gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
1526 }
1527 else if ((detail[0] == 'h' || detail[0] == 'v') &&
1528 strncmp (&detail[1], "scrollbar_", 10) == 0)
1529 {
1530 gtk_style_context_add_class (context, "button");
1531 gtk_style_context_add_class (context, "scrollbar");
1532 }
1533 else if (strcmp (detail, "slider") == 0)
1534 {
1535 gtk_style_context_add_class (context, "slider");
1536 gtk_style_context_add_class (context, "scrollbar");
1537 }
1538 else if (strcmp (detail, "vscale") == 0 ||
1539 strcmp (detail, "hscale") == 0)
1540 {
1541 gtk_style_context_add_class (context, "slider");
1542 gtk_style_context_add_class (context, "scale");
1543 }
1544 else if (strcmp (detail, "menuitem") == 0)
1545 {
1546 gtk_style_context_add_class (context, "menuitem");
1547 gtk_style_context_add_class (context, "menu");
1548 }
1549 else if (strcmp (detail, "menu") == 0)
1550 {
1551 gtk_style_context_add_class (context, "popup");
1552 gtk_style_context_add_class (context, "menu");
1553 }
1554 else if (strcmp (detail, "accellabel") == 0)
1555 gtk_style_context_add_class (context, "accelerator");
1556 else if (strcmp (detail, "menubar") == 0)
1557 gtk_style_context_add_class (context, "menubar");
1558 else if (strcmp (detail, "base") == 0)
1559 gtk_style_context_add_class (context, "background");
1560 else if (strcmp (detail, "bar") == 0 ||
1561 strcmp (detail, "progressbar") == 0)
1562 gtk_style_context_add_class (context, "progressbar");
1563 else if (strcmp (detail, "toolbar") == 0)
1564 gtk_style_context_add_class (context, "toolbar");
1565 else if (strcmp (detail, "handlebox_bin") == 0)
1566 gtk_style_context_add_class (context, "dock");
1567 else if (strcmp (detail, "notebook") == 0)
1568 gtk_style_context_add_class (context, "notebook");
1569 else if (strcmp (detail, "tab") == 0)
1570 {
1571 gtk_style_context_add_class (context, "notebook");
1572 gtk_style_context_add_region (context, GTK_STYLE_REGION_TAB, 0);
1573 }
1574 else if (g_str_has_prefix (detail, "cell"))
1575 {
1576 GtkRegionFlags row, col;
1577 gboolean ruled = FALSE;
1578 GStrv tokens;
1579 guint i;
1580
1581 tokens = g_strsplit (detail, "_", -1);
1582 row = col = 0;
1583 i = 0;
1584
1585 while (tokens[i])
1586 {
1587 if (strcmp (tokens[i], "even") == 0)
1588 row |= GTK_REGION_EVEN;
1589 else if (strcmp (tokens[i], "odd") == 0)
1590 row |= GTK_REGION_ODD;
1591 else if (strcmp (tokens[i], "start") == 0)
1592 col |= GTK_REGION_FIRST;
1593 else if (strcmp (tokens[i], "end") == 0)
1594 col |= GTK_REGION_LAST;
1595 else if (strcmp (tokens[i], "ruled") == 0)
1596 ruled = TRUE;
1597 else if (strcmp (tokens[i], "sorted") == 0)
1598 col |= GTK_REGION_SORTED;
1599
1600 i++;
1601 }
1602
1603 if (!ruled)
1604 row &= ~(GTK_REGION_EVEN | GTK_REGION_ODD);
1605
1606 gtk_style_context_add_class (context, "cell");
1607 gtk_style_context_add_region (context, "row", row);
1608 gtk_style_context_add_region (context, "column", col);
1609
1610 g_strfreev (tokens);
1611 }
1612 }
1613
1614 static void
gtk_default_draw_hline(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkWidget * widget,const gchar * detail,gint x1,gint x2,gint y)1615 gtk_default_draw_hline (GtkStyle *style,
1616 cairo_t *cr,
1617 GtkStateType state_type,
1618 GtkWidget *widget,
1619 const gchar *detail,
1620 gint x1,
1621 gint x2,
1622 gint y)
1623 {
1624 GtkStyleContext *context;
1625 GtkStylePrivate *priv;
1626
1627 if (widget)
1628 context = gtk_widget_get_style_context (widget);
1629 else
1630 {
1631 priv = GTK_STYLE_GET_PRIVATE (style);
1632 context = priv->context;
1633 }
1634
1635 gtk_style_context_save (context);
1636
1637 if (detail)
1638 transform_detail_string (detail, context);
1639
1640 cairo_save (cr);
1641
1642 gtk_render_line (context, cr,
1643 x1, y, x2, y);
1644
1645 cairo_restore (cr);
1646
1647 gtk_style_context_restore (context);
1648 }
1649
1650
1651 static void
gtk_default_draw_vline(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkWidget * widget,const gchar * detail,gint y1,gint y2,gint x)1652 gtk_default_draw_vline (GtkStyle *style,
1653 cairo_t *cr,
1654 GtkStateType state_type,
1655 GtkWidget *widget,
1656 const gchar *detail,
1657 gint y1,
1658 gint y2,
1659 gint x)
1660 {
1661 GtkStyleContext *context;
1662 GtkStylePrivate *priv;
1663
1664 if (widget)
1665 context = gtk_widget_get_style_context (widget);
1666 else
1667 {
1668 priv = GTK_STYLE_GET_PRIVATE (style);
1669 context = priv->context;
1670 }
1671
1672 gtk_style_context_save (context);
1673
1674 if (detail)
1675 transform_detail_string (detail, context);
1676
1677 cairo_save (cr);
1678
1679 gtk_render_line (context, cr,
1680 x, y1, x, y2);
1681
1682 cairo_restore (cr);
1683 gtk_style_context_restore (context);
1684 }
1685
1686 static void
gtk_default_draw_shadow(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkShadowType shadow_type,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height)1687 gtk_default_draw_shadow (GtkStyle *style,
1688 cairo_t *cr,
1689 GtkStateType state_type,
1690 GtkShadowType shadow_type,
1691 GtkWidget *widget,
1692 const gchar *detail,
1693 gint x,
1694 gint y,
1695 gint width,
1696 gint height)
1697 {
1698 GtkStyleContext *context;
1699 GtkStylePrivate *priv;
1700
1701 if (shadow_type == GTK_SHADOW_NONE)
1702 return;
1703
1704 if (widget)
1705 context = gtk_widget_get_style_context (widget);
1706 else
1707 {
1708 priv = GTK_STYLE_GET_PRIVATE (style);
1709 context = priv->context;
1710 }
1711
1712 gtk_style_context_save (context);
1713
1714 if (detail)
1715 transform_detail_string (detail, context);
1716
1717 cairo_save (cr);
1718
1719 gtk_render_frame (context, cr,
1720 (gdouble) x,
1721 (gdouble) y,
1722 (gdouble) width,
1723 (gdouble) height);
1724
1725 cairo_restore (cr);
1726 gtk_style_context_restore (context);
1727 }
1728
1729 static void
draw_arrow(cairo_t * cr,GdkColor * color,GtkArrowType arrow_type,gint x,gint y,gint width,gint height)1730 draw_arrow (cairo_t *cr,
1731 GdkColor *color,
1732 GtkArrowType arrow_type,
1733 gint x,
1734 gint y,
1735 gint width,
1736 gint height)
1737 {
1738 gdk_cairo_set_source_color (cr, color);
1739 cairo_save (cr);
1740
1741 if (arrow_type == GTK_ARROW_DOWN)
1742 {
1743 cairo_move_to (cr, x, y);
1744 cairo_line_to (cr, x + width, y);
1745 cairo_line_to (cr, x + width / 2., y + height);
1746 }
1747 else if (arrow_type == GTK_ARROW_UP)
1748 {
1749 cairo_move_to (cr, x, y + height);
1750 cairo_line_to (cr, x + width / 2., y);
1751 cairo_line_to (cr, x + width, y + height);
1752 }
1753 else if (arrow_type == GTK_ARROW_LEFT)
1754 {
1755 cairo_move_to (cr, x + width, y);
1756 cairo_line_to (cr, x + width, y + height);
1757 cairo_line_to (cr, x, y + height / 2.);
1758 }
1759 else if (arrow_type == GTK_ARROW_RIGHT)
1760 {
1761 cairo_move_to (cr, x, y);
1762 cairo_line_to (cr, x + width, y + height / 2.);
1763 cairo_line_to (cr, x, y + height);
1764 }
1765
1766 cairo_close_path (cr);
1767 cairo_fill (cr);
1768
1769 cairo_restore (cr);
1770 }
1771
1772 static void
gtk_default_draw_arrow(GtkStyle * style,cairo_t * cr,GtkStateType state,GtkShadowType shadow,GtkWidget * widget,const gchar * detail,GtkArrowType arrow_type,gboolean fill,gint x,gint y,gint width,gint height)1773 gtk_default_draw_arrow (GtkStyle *style,
1774 cairo_t *cr,
1775 GtkStateType state,
1776 GtkShadowType shadow,
1777 GtkWidget *widget,
1778 const gchar *detail,
1779 GtkArrowType arrow_type,
1780 gboolean fill,
1781 gint x,
1782 gint y,
1783 gint width,
1784 gint height)
1785 {
1786 GtkStyleContext *context;
1787 GtkStylePrivate *priv;
1788 GtkStateFlags flags = 0;
1789 gdouble angle, size;
1790
1791 if (arrow_type == GTK_ARROW_NONE)
1792 return;
1793
1794 if (widget)
1795 context = gtk_widget_get_style_context (widget);
1796 else
1797 {
1798 priv = GTK_STYLE_GET_PRIVATE (style);
1799 context = priv->context;
1800 }
1801
1802 gtk_style_context_save (context);
1803
1804 if (detail)
1805 transform_detail_string (detail, context);
1806
1807 switch (arrow_type)
1808 {
1809 case GTK_ARROW_UP:
1810 angle = 0;
1811 size = width;
1812 break;
1813 case GTK_ARROW_RIGHT:
1814 angle = G_PI / 2;
1815 size = height;
1816 break;
1817 case GTK_ARROW_DOWN:
1818 angle = G_PI;
1819 size = width;
1820 break;
1821 case GTK_ARROW_LEFT:
1822 angle = 3 * (G_PI / 2);
1823 size = height;
1824 break;
1825 default:
1826 g_assert_not_reached ();
1827 }
1828
1829 switch (state)
1830 {
1831 case GTK_STATE_PRELIGHT:
1832 flags |= GTK_STATE_FLAG_PRELIGHT;
1833 break;
1834 case GTK_STATE_SELECTED:
1835 flags |= GTK_STATE_FLAG_SELECTED;
1836 break;
1837 case GTK_STATE_INSENSITIVE:
1838 flags |= GTK_STATE_FLAG_INSENSITIVE;
1839 break;
1840 case GTK_STATE_ACTIVE:
1841 flags |= GTK_STATE_FLAG_ACTIVE;
1842 break;
1843 default:
1844 break;
1845 }
1846
1847 gtk_style_context_set_state (context, flags);
1848
1849 cairo_save (cr);
1850
1851 gtk_render_arrow (context,
1852 cr, angle,
1853 (gdouble) x,
1854 (gdouble) y,
1855 size);
1856
1857 cairo_restore (cr);
1858 gtk_style_context_restore (context);
1859 }
1860
1861 static void
gtk_default_draw_diamond(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkShadowType shadow_type,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height)1862 gtk_default_draw_diamond (GtkStyle *style,
1863 cairo_t *cr,
1864 GtkStateType state_type,
1865 GtkShadowType shadow_type,
1866 GtkWidget *widget,
1867 const gchar *detail,
1868 gint x,
1869 gint y,
1870 gint width,
1871 gint height)
1872 {
1873 gint half_width;
1874 gint half_height;
1875 GdkColor *outer_nw = NULL;
1876 GdkColor *outer_ne = NULL;
1877 GdkColor *outer_sw = NULL;
1878 GdkColor *outer_se = NULL;
1879 GdkColor *middle_nw = NULL;
1880 GdkColor *middle_ne = NULL;
1881 GdkColor *middle_sw = NULL;
1882 GdkColor *middle_se = NULL;
1883 GdkColor *inner_nw = NULL;
1884 GdkColor *inner_ne = NULL;
1885 GdkColor *inner_sw = NULL;
1886 GdkColor *inner_se = NULL;
1887
1888 half_width = width / 2;
1889 half_height = height / 2;
1890
1891 switch (shadow_type)
1892 {
1893 case GTK_SHADOW_IN:
1894 inner_sw = inner_se = &style->bg[state_type];
1895 middle_sw = middle_se = &style->light[state_type];
1896 outer_sw = outer_se = &style->light[state_type];
1897 inner_nw = inner_ne = &style->black;
1898 middle_nw = middle_ne = &style->dark[state_type];
1899 outer_nw = outer_ne = &style->dark[state_type];
1900 break;
1901
1902 case GTK_SHADOW_OUT:
1903 inner_sw = inner_se = &style->dark[state_type];
1904 middle_sw = middle_se = &style->dark[state_type];
1905 outer_sw = outer_se = &style->black;
1906 inner_nw = inner_ne = &style->bg[state_type];
1907 middle_nw = middle_ne = &style->light[state_type];
1908 outer_nw = outer_ne = &style->light[state_type];
1909 break;
1910
1911 case GTK_SHADOW_ETCHED_IN:
1912 inner_sw = inner_se = &style->bg[state_type];
1913 middle_sw = middle_se = &style->dark[state_type];
1914 outer_sw = outer_se = &style->light[state_type];
1915 inner_nw = inner_ne = &style->bg[state_type];
1916 middle_nw = middle_ne = &style->light[state_type];
1917 outer_nw = outer_ne = &style->dark[state_type];
1918 break;
1919
1920 case GTK_SHADOW_ETCHED_OUT:
1921 inner_sw = inner_se = &style->bg[state_type];
1922 middle_sw = middle_se = &style->light[state_type];
1923 outer_sw = outer_se = &style->dark[state_type];
1924 inner_nw = inner_ne = &style->bg[state_type];
1925 middle_nw = middle_ne = &style->dark[state_type];
1926 outer_nw = outer_ne = &style->light[state_type];
1927 break;
1928
1929 default:
1930
1931 break;
1932 }
1933
1934 if (inner_sw)
1935 {
1936 _cairo_draw_line (cr, inner_sw,
1937 x + 2, y + half_height,
1938 x + half_width, y + height - 2);
1939 _cairo_draw_line (cr, inner_se,
1940 x + half_width, y + height - 2,
1941 x + width - 2, y + half_height);
1942 _cairo_draw_line (cr, middle_sw,
1943 x + 1, y + half_height,
1944 x + half_width, y + height - 1);
1945 _cairo_draw_line (cr, middle_se,
1946 x + half_width, y + height - 1,
1947 x + width - 1, y + half_height);
1948 _cairo_draw_line (cr, outer_sw,
1949 x, y + half_height,
1950 x + half_width, y + height);
1951 _cairo_draw_line (cr, outer_se,
1952 x + half_width, y + height,
1953 x + width, y + half_height);
1954
1955 _cairo_draw_line (cr, inner_nw,
1956 x + 2, y + half_height,
1957 x + half_width, y + 2);
1958 _cairo_draw_line (cr, inner_ne,
1959 x + half_width, y + 2,
1960 x + width - 2, y + half_height);
1961 _cairo_draw_line (cr, middle_nw,
1962 x + 1, y + half_height,
1963 x + half_width, y + 1);
1964 _cairo_draw_line (cr, middle_ne,
1965 x + half_width, y + 1,
1966 x + width - 1, y + half_height);
1967 _cairo_draw_line (cr, outer_nw,
1968 x, y + half_height,
1969 x + half_width, y);
1970 _cairo_draw_line (cr, outer_ne,
1971 x + half_width, y,
1972 x + width, y + half_height);
1973 }
1974 }
1975
1976 static void
option_menu_get_props(GtkWidget * widget,GtkRequisition * indicator_size,GtkBorder * indicator_spacing)1977 option_menu_get_props (GtkWidget *widget,
1978 GtkRequisition *indicator_size,
1979 GtkBorder *indicator_spacing)
1980 {
1981 GtkRequisition *tmp_size = NULL;
1982 GtkBorder *tmp_spacing = NULL;
1983
1984 if (tmp_size)
1985 {
1986 *indicator_size = *tmp_size;
1987 gtk_requisition_free (tmp_size);
1988 }
1989 else
1990 *indicator_size = default_option_indicator_size;
1991
1992 if (tmp_spacing)
1993 {
1994 *indicator_spacing = *tmp_spacing;
1995 gtk_border_free (tmp_spacing);
1996 }
1997 else
1998 *indicator_spacing = default_option_indicator_spacing;
1999 }
2000
2001 static void
gtk_default_draw_box(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkShadowType shadow_type,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height)2002 gtk_default_draw_box (GtkStyle *style,
2003 cairo_t *cr,
2004 GtkStateType state_type,
2005 GtkShadowType shadow_type,
2006 GtkWidget *widget,
2007 const gchar *detail,
2008 gint x,
2009 gint y,
2010 gint width,
2011 gint height)
2012 {
2013 GtkStyleContext *context;
2014 GtkStylePrivate *priv;
2015 GtkStateFlags flags = 0;
2016
2017 if (widget)
2018 context = gtk_widget_get_style_context (widget);
2019 else
2020 {
2021 priv = GTK_STYLE_GET_PRIVATE (style);
2022 context = priv->context;
2023 }
2024
2025 gtk_style_context_save (context);
2026
2027 if (detail)
2028 transform_detail_string (detail, context);
2029
2030 switch (state_type)
2031 {
2032 case GTK_STATE_ACTIVE:
2033 flags |= GTK_STATE_FLAG_ACTIVE;
2034 break;
2035 case GTK_STATE_PRELIGHT:
2036 flags |= GTK_STATE_FLAG_PRELIGHT;
2037 break;
2038 case GTK_STATE_SELECTED:
2039 flags |= GTK_STATE_FLAG_SELECTED;
2040 break;
2041 case GTK_STATE_INSENSITIVE:
2042 flags |= GTK_STATE_FLAG_INSENSITIVE;
2043 break;
2044 default:
2045 break;
2046 }
2047
2048 if (shadow_type == GTK_SHADOW_IN)
2049 flags |= GTK_STATE_FLAG_ACTIVE;
2050
2051 gtk_style_context_set_state (context, flags);
2052
2053 cairo_save (cr);
2054
2055 gtk_render_background (context, cr, x, y, width, height);
2056
2057 if (shadow_type != GTK_SHADOW_NONE)
2058 gtk_render_frame (context, cr, x, y, width, height);
2059
2060 cairo_restore (cr);
2061 gtk_style_context_restore (context);
2062 }
2063
2064 static void
gtk_default_draw_flat_box(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkShadowType shadow_type,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height)2065 gtk_default_draw_flat_box (GtkStyle *style,
2066 cairo_t *cr,
2067 GtkStateType state_type,
2068 GtkShadowType shadow_type,
2069 GtkWidget *widget,
2070 const gchar *detail,
2071 gint x,
2072 gint y,
2073 gint width,
2074 gint height)
2075 {
2076 GtkStyleContext *context;
2077 GtkStylePrivate *priv;
2078 GtkStateFlags flags = 0;
2079
2080 if (widget)
2081 context = gtk_widget_get_style_context (widget);
2082 else
2083 {
2084 priv = GTK_STYLE_GET_PRIVATE (style);
2085 context = priv->context;
2086 }
2087
2088 gtk_style_context_save (context);
2089
2090 if (detail)
2091 transform_detail_string (detail, context);
2092
2093 switch (state_type)
2094 {
2095 case GTK_STATE_PRELIGHT:
2096 flags |= GTK_STATE_FLAG_PRELIGHT;
2097 break;
2098 case GTK_STATE_SELECTED:
2099 flags |= GTK_STATE_FLAG_SELECTED;
2100 break;
2101 case GTK_STATE_INSENSITIVE:
2102 flags |= GTK_STATE_FLAG_INSENSITIVE;
2103 break;
2104 case GTK_STATE_ACTIVE:
2105 flags |= GTK_STATE_FLAG_ACTIVE;
2106 break;
2107 case GTK_STATE_FOCUSED:
2108 flags |= GTK_STATE_FLAG_FOCUSED;
2109 break;
2110 default:
2111 break;
2112 }
2113
2114 gtk_style_context_set_state (context, flags);
2115
2116 cairo_save (cr);
2117
2118 gtk_render_background (context, cr,
2119 (gdouble) x,
2120 (gdouble) y,
2121 (gdouble) width,
2122 (gdouble) height);
2123
2124 cairo_restore (cr);
2125 gtk_style_context_restore (context);
2126 }
2127
2128 static void
gtk_default_draw_check(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkShadowType shadow_type,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height)2129 gtk_default_draw_check (GtkStyle *style,
2130 cairo_t *cr,
2131 GtkStateType state_type,
2132 GtkShadowType shadow_type,
2133 GtkWidget *widget,
2134 const gchar *detail,
2135 gint x,
2136 gint y,
2137 gint width,
2138 gint height)
2139 {
2140 GtkStyleContext *context;
2141 GtkStylePrivate *priv;
2142 GtkStateFlags flags = 0;
2143
2144 if (widget)
2145 context = gtk_widget_get_style_context (widget);
2146 else
2147 {
2148 priv = GTK_STYLE_GET_PRIVATE (style);
2149 context = priv->context;
2150 }
2151
2152 gtk_style_context_save (context);
2153
2154 if (detail)
2155 transform_detail_string (detail, context);
2156
2157 switch (state_type)
2158 {
2159 case GTK_STATE_PRELIGHT:
2160 flags |= GTK_STATE_FLAG_PRELIGHT;
2161 break;
2162 case GTK_STATE_SELECTED:
2163 flags |= GTK_STATE_FLAG_SELECTED;
2164 break;
2165 case GTK_STATE_INSENSITIVE:
2166 flags |= GTK_STATE_FLAG_INSENSITIVE;
2167 break;
2168 default:
2169 break;
2170 }
2171
2172 if (shadow_type == GTK_SHADOW_IN)
2173 flags |= GTK_STATE_FLAG_ACTIVE;
2174 else if (shadow_type == GTK_SHADOW_ETCHED_IN)
2175 flags |= GTK_STATE_FLAG_INCONSISTENT;
2176
2177 gtk_style_context_set_state (context, flags);
2178
2179 cairo_save (cr);
2180
2181 gtk_render_check (context,
2182 cr, x, y,
2183 width, height);
2184
2185 cairo_restore (cr);
2186 gtk_style_context_restore (context);
2187 }
2188
2189 static void
gtk_default_draw_option(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkShadowType shadow_type,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height)2190 gtk_default_draw_option (GtkStyle *style,
2191 cairo_t *cr,
2192 GtkStateType state_type,
2193 GtkShadowType shadow_type,
2194 GtkWidget *widget,
2195 const gchar *detail,
2196 gint x,
2197 gint y,
2198 gint width,
2199 gint height)
2200 {
2201 GtkStyleContext *context;
2202 GtkStylePrivate *priv;
2203 GtkStateFlags flags = 0;
2204
2205 if (widget)
2206 context = gtk_widget_get_style_context (widget);
2207 else
2208 {
2209 priv = GTK_STYLE_GET_PRIVATE (style);
2210 context = priv->context;
2211 }
2212
2213 gtk_style_context_save (context);
2214
2215 if (detail)
2216 transform_detail_string (detail, context);
2217
2218 switch (state_type)
2219 {
2220 case GTK_STATE_PRELIGHT:
2221 flags |= GTK_STATE_FLAG_PRELIGHT;
2222 break;
2223 case GTK_STATE_SELECTED:
2224 flags |= GTK_STATE_FLAG_SELECTED;
2225 break;
2226 case GTK_STATE_INSENSITIVE:
2227 flags |= GTK_STATE_FLAG_INSENSITIVE;
2228 break;
2229 default:
2230 break;
2231 }
2232
2233 if (shadow_type == GTK_SHADOW_IN)
2234 flags |= GTK_STATE_FLAG_ACTIVE;
2235 else if (shadow_type == GTK_SHADOW_ETCHED_IN)
2236 flags |= GTK_STATE_FLAG_INCONSISTENT;
2237
2238 gtk_style_context_set_state (context, flags);
2239
2240 cairo_save (cr);
2241 gtk_render_option (context, cr,
2242 (gdouble) x,
2243 (gdouble) y,
2244 (gdouble) width,
2245 (gdouble) height);
2246
2247 cairo_restore (cr);
2248 gtk_style_context_restore (context);
2249 }
2250
2251 static void
gtk_default_draw_tab(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkShadowType shadow_type,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height)2252 gtk_default_draw_tab (GtkStyle *style,
2253 cairo_t *cr,
2254 GtkStateType state_type,
2255 GtkShadowType shadow_type,
2256 GtkWidget *widget,
2257 const gchar *detail,
2258 gint x,
2259 gint y,
2260 gint width,
2261 gint height)
2262 {
2263 #define ARROW_SPACE 4
2264
2265 GtkRequisition indicator_size;
2266 GtkBorder indicator_spacing;
2267 gint arrow_height;
2268
2269 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
2270
2271 indicator_size.width += (indicator_size.width % 2) - 1;
2272 arrow_height = indicator_size.width / 2 + 1;
2273
2274 x += (width - indicator_size.width) / 2;
2275 y += (height - (2 * arrow_height + ARROW_SPACE)) / 2;
2276
2277 if (state_type == GTK_STATE_INSENSITIVE)
2278 {
2279 draw_arrow (cr, &style->white,
2280 GTK_ARROW_UP, x + 1, y + 1,
2281 indicator_size.width, arrow_height);
2282
2283 draw_arrow (cr, &style->white,
2284 GTK_ARROW_DOWN, x + 1, y + arrow_height + ARROW_SPACE + 1,
2285 indicator_size.width, arrow_height);
2286 }
2287
2288 draw_arrow (cr, &style->fg[state_type],
2289 GTK_ARROW_UP, x, y,
2290 indicator_size.width, arrow_height);
2291
2292
2293 draw_arrow (cr, &style->fg[state_type],
2294 GTK_ARROW_DOWN, x, y + arrow_height + ARROW_SPACE,
2295 indicator_size.width, arrow_height);
2296 }
2297
2298 static void
gtk_default_draw_shadow_gap(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkShadowType shadow_type,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height,GtkPositionType gap_side,gint gap_x,gint gap_width)2299 gtk_default_draw_shadow_gap (GtkStyle *style,
2300 cairo_t *cr,
2301 GtkStateType state_type,
2302 GtkShadowType shadow_type,
2303 GtkWidget *widget,
2304 const gchar *detail,
2305 gint x,
2306 gint y,
2307 gint width,
2308 gint height,
2309 GtkPositionType gap_side,
2310 gint gap_x,
2311 gint gap_width)
2312 {
2313 GtkStyleContext *context;
2314 GtkStylePrivate *priv;
2315 GtkStateFlags flags = 0;
2316
2317 if (shadow_type == GTK_SHADOW_NONE)
2318 return;
2319
2320 if (widget)
2321 context = gtk_widget_get_style_context (widget);
2322 else
2323 {
2324 priv = GTK_STYLE_GET_PRIVATE (style);
2325 context = priv->context;
2326 }
2327
2328 gtk_style_context_save (context);
2329
2330 if (detail)
2331 transform_detail_string (detail, context);
2332
2333 switch (state_type)
2334 {
2335 case GTK_STATE_ACTIVE:
2336 flags |= GTK_STATE_FLAG_ACTIVE;
2337 break;
2338 case GTK_STATE_PRELIGHT:
2339 flags |= GTK_STATE_FLAG_PRELIGHT;
2340 break;
2341 case GTK_STATE_SELECTED:
2342 flags |= GTK_STATE_FLAG_SELECTED;
2343 break;
2344 case GTK_STATE_INSENSITIVE:
2345 flags |= GTK_STATE_FLAG_INSENSITIVE;
2346 break;
2347 default:
2348 break;
2349 }
2350
2351 gtk_style_context_set_state (context, flags);
2352
2353 cairo_save (cr);
2354 gtk_render_frame_gap (context, cr,
2355 (gdouble) x,
2356 (gdouble) y,
2357 (gdouble) width,
2358 (gdouble) height,
2359 gap_side,
2360 (gdouble) gap_x,
2361 (gdouble) gap_x + gap_width);
2362
2363 cairo_restore (cr);
2364 gtk_style_context_restore (context);
2365 }
2366
2367 static void
gtk_default_draw_box_gap(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkShadowType shadow_type,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height,GtkPositionType gap_side,gint gap_x,gint gap_width)2368 gtk_default_draw_box_gap (GtkStyle *style,
2369 cairo_t *cr,
2370 GtkStateType state_type,
2371 GtkShadowType shadow_type,
2372 GtkWidget *widget,
2373 const gchar *detail,
2374 gint x,
2375 gint y,
2376 gint width,
2377 gint height,
2378 GtkPositionType gap_side,
2379 gint gap_x,
2380 gint gap_width)
2381 {
2382 GtkStyleContext *context;
2383 GtkStylePrivate *priv;
2384 GtkStateFlags flags = 0;
2385
2386 if (widget)
2387 context = gtk_widget_get_style_context (widget);
2388 else
2389 {
2390 priv = GTK_STYLE_GET_PRIVATE (style);
2391 context = priv->context;
2392 }
2393
2394 gtk_style_context_save (context);
2395
2396 if (detail)
2397 transform_detail_string (detail, context);
2398
2399 switch (state_type)
2400 {
2401 case GTK_STATE_ACTIVE:
2402 flags |= GTK_STATE_FLAG_ACTIVE;
2403 break;
2404 case GTK_STATE_PRELIGHT:
2405 flags |= GTK_STATE_FLAG_PRELIGHT;
2406 break;
2407 case GTK_STATE_SELECTED:
2408 flags |= GTK_STATE_FLAG_SELECTED;
2409 break;
2410 case GTK_STATE_INSENSITIVE:
2411 flags |= GTK_STATE_FLAG_INSENSITIVE;
2412 break;
2413 default:
2414 break;
2415 }
2416
2417 gtk_style_context_set_state (context, flags);
2418
2419 cairo_save (cr);
2420 gtk_render_background (context, cr,
2421 (gdouble) x,
2422 (gdouble) y,
2423 (gdouble) width,
2424 (gdouble) height);
2425
2426
2427 if (shadow_type != GTK_SHADOW_NONE)
2428 gtk_render_frame_gap (context, cr,
2429 (gdouble) x,
2430 (gdouble) y,
2431 (gdouble) width,
2432 (gdouble) height,
2433 gap_side,
2434 (gdouble) gap_x,
2435 (gdouble) gap_x + gap_width);
2436
2437 cairo_restore (cr);
2438 gtk_style_context_restore (context);
2439 }
2440
2441 static void
gtk_default_draw_extension(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkShadowType shadow_type,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height,GtkPositionType gap_side)2442 gtk_default_draw_extension (GtkStyle *style,
2443 cairo_t *cr,
2444 GtkStateType state_type,
2445 GtkShadowType shadow_type,
2446 GtkWidget *widget,
2447 const gchar *detail,
2448 gint x,
2449 gint y,
2450 gint width,
2451 gint height,
2452 GtkPositionType gap_side)
2453 {
2454 GtkStyleContext *context;
2455 GtkStylePrivate *priv;
2456 GtkStateFlags flags = 0;
2457
2458 if (widget)
2459 context = gtk_widget_get_style_context (widget);
2460 else
2461 {
2462 priv = GTK_STYLE_GET_PRIVATE (style);
2463 context = priv->context;
2464 }
2465
2466 gtk_style_context_save (context);
2467
2468 if (detail)
2469 transform_detail_string (detail, context);
2470
2471 switch (state_type)
2472 {
2473 case GTK_STATE_ACTIVE:
2474 flags |= GTK_STATE_FLAG_ACTIVE;
2475 break;
2476 case GTK_STATE_PRELIGHT:
2477 flags |= GTK_STATE_FLAG_PRELIGHT;
2478 break;
2479 case GTK_STATE_SELECTED:
2480 flags |= GTK_STATE_FLAG_SELECTED;
2481 break;
2482 case GTK_STATE_INSENSITIVE:
2483 flags |= GTK_STATE_FLAG_INSENSITIVE;
2484 break;
2485 default:
2486 break;
2487 }
2488
2489 gtk_style_context_set_state (context, flags);
2490
2491 cairo_save (cr);
2492
2493 gtk_render_extension (context, cr,
2494 (gdouble) x,
2495 (gdouble) y,
2496 (gdouble) width,
2497 (gdouble) height,
2498 gap_side);
2499
2500 cairo_restore (cr);
2501 gtk_style_context_restore (context);
2502 }
2503
2504 static void
gtk_default_draw_focus(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height)2505 gtk_default_draw_focus (GtkStyle *style,
2506 cairo_t *cr,
2507 GtkStateType state_type,
2508 GtkWidget *widget,
2509 const gchar *detail,
2510 gint x,
2511 gint y,
2512 gint width,
2513 gint height)
2514 {
2515 GtkStyleContext *context;
2516 GtkStylePrivate *priv;
2517
2518 if (widget)
2519 context = gtk_widget_get_style_context (widget);
2520 else
2521 {
2522 priv = GTK_STYLE_GET_PRIVATE (style);
2523 context = priv->context;
2524 }
2525
2526 gtk_style_context_save (context);
2527
2528 if (detail)
2529 transform_detail_string (detail, context);
2530
2531 cairo_save (cr);
2532
2533 gtk_render_focus (context, cr,
2534 (gdouble) x,
2535 (gdouble) y,
2536 (gdouble) width,
2537 (gdouble) height);
2538
2539 cairo_restore (cr);
2540 gtk_style_context_restore (context);
2541 }
2542
2543 static void
gtk_default_draw_slider(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkShadowType shadow_type,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height,GtkOrientation orientation)2544 gtk_default_draw_slider (GtkStyle *style,
2545 cairo_t *cr,
2546 GtkStateType state_type,
2547 GtkShadowType shadow_type,
2548 GtkWidget *widget,
2549 const gchar *detail,
2550 gint x,
2551 gint y,
2552 gint width,
2553 gint height,
2554 GtkOrientation orientation)
2555 {
2556 GtkStyleContext *context;
2557 GtkStylePrivate *priv;
2558 GtkStateFlags flags = 0;
2559
2560 if (widget)
2561 context = gtk_widget_get_style_context (widget);
2562 else
2563 {
2564 priv = GTK_STYLE_GET_PRIVATE (style);
2565 context = priv->context;
2566 }
2567
2568 gtk_style_context_save (context);
2569
2570 if (detail)
2571 transform_detail_string (detail, context);
2572
2573 switch (state_type)
2574 {
2575 case GTK_STATE_PRELIGHT:
2576 flags |= GTK_STATE_FLAG_PRELIGHT;
2577 break;
2578 case GTK_STATE_SELECTED:
2579 flags |= GTK_STATE_FLAG_SELECTED;
2580 break;
2581 case GTK_STATE_INSENSITIVE:
2582 flags |= GTK_STATE_FLAG_INSENSITIVE;
2583 break;
2584 default:
2585 break;
2586 }
2587
2588 gtk_style_context_set_state (context, flags);
2589
2590 cairo_save (cr);
2591
2592 gtk_render_slider (context, cr, x, y, width, height, orientation);
2593
2594 cairo_restore (cr);
2595 gtk_style_context_restore (context);
2596 }
2597
2598 static void
gtk_default_draw_handle(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkShadowType shadow_type,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height,GtkOrientation orientation)2599 gtk_default_draw_handle (GtkStyle *style,
2600 cairo_t *cr,
2601 GtkStateType state_type,
2602 GtkShadowType shadow_type,
2603 GtkWidget *widget,
2604 const gchar *detail,
2605 gint x,
2606 gint y,
2607 gint width,
2608 gint height,
2609 GtkOrientation orientation)
2610 {
2611 GtkStyleContext *context;
2612 GtkStylePrivate *priv;
2613 GtkStateFlags flags = 0;
2614
2615 if (widget)
2616 context = gtk_widget_get_style_context (widget);
2617 else
2618 {
2619 priv = GTK_STYLE_GET_PRIVATE (style);
2620 context = priv->context;
2621 }
2622
2623 gtk_style_context_save (context);
2624
2625 if (detail)
2626 transform_detail_string (detail, context);
2627
2628 switch (state_type)
2629 {
2630 case GTK_STATE_PRELIGHT:
2631 flags |= GTK_STATE_FLAG_PRELIGHT;
2632 break;
2633 case GTK_STATE_SELECTED:
2634 flags |= GTK_STATE_FLAG_SELECTED;
2635 break;
2636 case GTK_STATE_INSENSITIVE:
2637 flags |= GTK_STATE_FLAG_INSENSITIVE;
2638 break;
2639 default:
2640 break;
2641 }
2642
2643 gtk_style_context_set_state (context, flags);
2644
2645 cairo_save (cr);
2646
2647 gtk_render_handle (context, cr,
2648 (gdouble) x,
2649 (gdouble) y,
2650 (gdouble) width,
2651 (gdouble) height);
2652
2653 cairo_restore (cr);
2654 gtk_style_context_restore (context);
2655 }
2656
2657 static void
gtk_default_draw_expander(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkWidget * widget,const gchar * detail,gint x,gint y,GtkExpanderStyle expander_style)2658 gtk_default_draw_expander (GtkStyle *style,
2659 cairo_t *cr,
2660 GtkStateType state_type,
2661 GtkWidget *widget,
2662 const gchar *detail,
2663 gint x,
2664 gint y,
2665 GtkExpanderStyle expander_style)
2666 {
2667 GtkStyleContext *context;
2668 GtkStylePrivate *priv;
2669 GtkStateFlags flags = 0;
2670 gint size;
2671
2672 if (widget)
2673 context = gtk_widget_get_style_context (widget);
2674 else
2675 {
2676 priv = GTK_STYLE_GET_PRIVATE (style);
2677 context = priv->context;
2678 }
2679
2680 gtk_style_context_save (context);
2681
2682 if (detail)
2683 transform_detail_string (detail, context);
2684
2685 gtk_style_context_add_class (context, "expander");
2686
2687 switch (state_type)
2688 {
2689 case GTK_STATE_PRELIGHT:
2690 flags |= GTK_STATE_FLAG_PRELIGHT;
2691 break;
2692 case GTK_STATE_SELECTED:
2693 flags |= GTK_STATE_FLAG_SELECTED;
2694 break;
2695 case GTK_STATE_INSENSITIVE:
2696 flags |= GTK_STATE_FLAG_INSENSITIVE;
2697 break;
2698 default:
2699 break;
2700 }
2701
2702 if (widget &&
2703 gtk_widget_class_find_style_property (GTK_WIDGET_GET_CLASS (widget),
2704 "expander-size"))
2705 gtk_widget_style_get (widget, "expander-size", &size, NULL);
2706 else
2707 size = 12;
2708
2709 if (expander_style == GTK_EXPANDER_EXPANDED)
2710 flags |= GTK_STATE_FLAG_ACTIVE;
2711
2712 gtk_style_context_set_state (context, flags);
2713
2714 cairo_save (cr);
2715
2716 gtk_render_expander (context, cr,
2717 (gdouble) x - (size / 2),
2718 (gdouble) y - (size / 2),
2719 (gdouble) size,
2720 (gdouble) size);
2721
2722 cairo_restore (cr);
2723 gtk_style_context_restore (context);
2724 }
2725
2726 static void
gtk_default_draw_layout(GtkStyle * style,cairo_t * cr,GtkStateType state_type,gboolean use_text,GtkWidget * widget,const gchar * detail,gint x,gint y,PangoLayout * layout)2727 gtk_default_draw_layout (GtkStyle *style,
2728 cairo_t *cr,
2729 GtkStateType state_type,
2730 gboolean use_text,
2731 GtkWidget *widget,
2732 const gchar *detail,
2733 gint x,
2734 gint y,
2735 PangoLayout *layout)
2736 {
2737 GtkStyleContext *context;
2738 GtkStylePrivate *priv;
2739 GtkStateFlags flags = 0;
2740
2741 if (widget)
2742 context = gtk_widget_get_style_context (widget);
2743 else
2744 {
2745 priv = GTK_STYLE_GET_PRIVATE (style);
2746 context = priv->context;
2747 }
2748
2749 gtk_style_context_save (context);
2750
2751 if (detail)
2752 transform_detail_string (detail, context);
2753
2754 switch (state_type)
2755 {
2756 case GTK_STATE_PRELIGHT:
2757 flags |= GTK_STATE_FLAG_PRELIGHT;
2758 break;
2759 case GTK_STATE_SELECTED:
2760 flags |= GTK_STATE_FLAG_SELECTED;
2761 break;
2762 case GTK_STATE_INSENSITIVE:
2763 flags |= GTK_STATE_FLAG_INSENSITIVE;
2764 break;
2765 default:
2766 break;
2767 }
2768
2769 gtk_style_context_set_state (context, flags);
2770
2771 cairo_save (cr);
2772
2773 gtk_render_layout (context, cr,
2774 (gdouble) x,
2775 (gdouble) y,
2776 layout);
2777
2778 cairo_restore (cr);
2779 gtk_style_context_restore (context);
2780 }
2781
2782 static void
gtk_default_draw_resize_grip(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkWidget * widget,const gchar * detail,GdkWindowEdge edge,gint x,gint y,gint width,gint height)2783 gtk_default_draw_resize_grip (GtkStyle *style,
2784 cairo_t *cr,
2785 GtkStateType state_type,
2786 GtkWidget *widget,
2787 const gchar *detail,
2788 GdkWindowEdge edge,
2789 gint x,
2790 gint y,
2791 gint width,
2792 gint height)
2793 {
2794 GtkStyleContext *context;
2795 GtkStylePrivate *priv;
2796 GtkStateFlags flags = 0;
2797 GtkJunctionSides sides = 0;
2798
2799 if (widget)
2800 context = gtk_widget_get_style_context (widget);
2801 else
2802 {
2803 priv = GTK_STYLE_GET_PRIVATE (style);
2804 context = priv->context;
2805 }
2806
2807 gtk_style_context_save (context);
2808
2809 if (detail)
2810 transform_detail_string (detail, context);
2811
2812 gtk_style_context_add_class (context, "grip");
2813
2814 switch (state_type)
2815 {
2816 case GTK_STATE_PRELIGHT:
2817 flags |= GTK_STATE_FLAG_PRELIGHT;
2818 break;
2819 case GTK_STATE_SELECTED:
2820 flags |= GTK_STATE_FLAG_SELECTED;
2821 break;
2822 case GTK_STATE_INSENSITIVE:
2823 flags |= GTK_STATE_FLAG_INSENSITIVE;
2824 break;
2825 default:
2826 break;
2827 }
2828
2829 gtk_style_context_set_state (context, flags);
2830
2831 switch (edge)
2832 {
2833 case GDK_WINDOW_EDGE_NORTH_WEST:
2834 sides = GTK_JUNCTION_CORNER_TOPLEFT;
2835 break;
2836 case GDK_WINDOW_EDGE_NORTH:
2837 sides = GTK_JUNCTION_TOP;
2838 break;
2839 case GDK_WINDOW_EDGE_NORTH_EAST:
2840 sides = GTK_JUNCTION_CORNER_TOPRIGHT;
2841 break;
2842 case GDK_WINDOW_EDGE_WEST:
2843 sides = GTK_JUNCTION_LEFT;
2844 break;
2845 case GDK_WINDOW_EDGE_EAST:
2846 sides = GTK_JUNCTION_RIGHT;
2847 break;
2848 case GDK_WINDOW_EDGE_SOUTH_WEST:
2849 sides = GTK_JUNCTION_CORNER_BOTTOMLEFT;
2850 break;
2851 case GDK_WINDOW_EDGE_SOUTH:
2852 sides = GTK_JUNCTION_BOTTOM;
2853 break;
2854 case GDK_WINDOW_EDGE_SOUTH_EAST:
2855 sides = GTK_JUNCTION_CORNER_BOTTOMRIGHT;
2856 break;
2857 }
2858
2859 gtk_style_context_set_junction_sides (context, sides);
2860
2861 cairo_save (cr);
2862
2863 gtk_render_handle (context, cr,
2864 (gdouble) x,
2865 (gdouble) y,
2866 (gdouble) width,
2867 (gdouble) height);
2868
2869 cairo_restore (cr);
2870 gtk_style_context_restore (context);
2871 }
2872
2873 static void
gtk_default_draw_spinner(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkWidget * widget,const gchar * detail,guint step,gint x,gint y,gint width,gint height)2874 gtk_default_draw_spinner (GtkStyle *style,
2875 cairo_t *cr,
2876 GtkStateType state_type,
2877 GtkWidget *widget,
2878 const gchar *detail,
2879 guint step,
2880 gint x,
2881 gint y,
2882 gint width,
2883 gint height)
2884 {
2885 GdkColor *color;
2886 guint num_steps;
2887 gdouble dx, dy;
2888 gdouble radius;
2889 gdouble half;
2890 gint i;
2891 guint real_step;
2892
2893 num_steps = 12;
2894 real_step = step % num_steps;
2895
2896 /* set a clip region for the expose event */
2897 cairo_rectangle (cr, x, y, width, height);
2898 cairo_clip (cr);
2899
2900 cairo_translate (cr, x, y);
2901
2902 /* draw clip region */
2903 cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
2904
2905 color = &style->fg[state_type];
2906 dx = width / 2;
2907 dy = height / 2;
2908 radius = MIN (width / 2, height / 2);
2909 half = num_steps / 2;
2910
2911 for (i = 0; i < num_steps; i++)
2912 {
2913 gint inset = 0.7 * radius;
2914
2915 /* transparency is a function of time and intial value */
2916 gdouble t = (gdouble) ((i + num_steps - real_step)
2917 % num_steps) / num_steps;
2918
2919 cairo_save (cr);
2920
2921 cairo_set_source_rgba (cr,
2922 color->red / 65535.,
2923 color->green / 65535.,
2924 color->blue / 65535.,
2925 t);
2926
2927 cairo_set_line_width (cr, 2.0);
2928 cairo_move_to (cr,
2929 dx + (radius - inset) * cos (i * G_PI / half),
2930 dy + (radius - inset) * sin (i * G_PI / half));
2931 cairo_line_to (cr,
2932 dx + radius * cos (i * G_PI / half),
2933 dy + radius * sin (i * G_PI / half));
2934 cairo_stroke (cr);
2935
2936 cairo_restore (cr);
2937 }
2938 }
2939
2940 void
_gtk_style_shade(const GdkColor * a,GdkColor * b,gdouble k)2941 _gtk_style_shade (const GdkColor *a,
2942 GdkColor *b,
2943 gdouble k)
2944 {
2945 gdouble red;
2946 gdouble green;
2947 gdouble blue;
2948
2949 red = (gdouble) a->red / 65535.0;
2950 green = (gdouble) a->green / 65535.0;
2951 blue = (gdouble) a->blue / 65535.0;
2952
2953 rgb_to_hls (&red, &green, &blue);
2954
2955 green *= k;
2956 if (green > 1.0)
2957 green = 1.0;
2958 else if (green < 0.0)
2959 green = 0.0;
2960
2961 blue *= k;
2962 if (blue > 1.0)
2963 blue = 1.0;
2964 else if (blue < 0.0)
2965 blue = 0.0;
2966
2967 hls_to_rgb (&red, &green, &blue);
2968
2969 b->red = red * 65535.0;
2970 b->green = green * 65535.0;
2971 b->blue = blue * 65535.0;
2972 }
2973
2974 static void
rgb_to_hls(gdouble * r,gdouble * g,gdouble * b)2975 rgb_to_hls (gdouble *r,
2976 gdouble *g,
2977 gdouble *b)
2978 {
2979 gdouble min;
2980 gdouble max;
2981 gdouble red;
2982 gdouble green;
2983 gdouble blue;
2984 gdouble h, l, s;
2985 gdouble delta;
2986
2987 red = *r;
2988 green = *g;
2989 blue = *b;
2990
2991 if (red > green)
2992 {
2993 if (red > blue)
2994 max = red;
2995 else
2996 max = blue;
2997
2998 if (green < blue)
2999 min = green;
3000 else
3001 min = blue;
3002 }
3003 else
3004 {
3005 if (green > blue)
3006 max = green;
3007 else
3008 max = blue;
3009
3010 if (red < blue)
3011 min = red;
3012 else
3013 min = blue;
3014 }
3015
3016 l = (max + min) / 2;
3017 s = 0;
3018 h = 0;
3019
3020 if (max != min)
3021 {
3022 if (l <= 0.5)
3023 s = (max - min) / (max + min);
3024 else
3025 s = (max - min) / (2 - max - min);
3026
3027 delta = max -min;
3028 if (red == max)
3029 h = (green - blue) / delta;
3030 else if (green == max)
3031 h = 2 + (blue - red) / delta;
3032 else if (blue == max)
3033 h = 4 + (red - green) / delta;
3034
3035 h *= 60;
3036 if (h < 0.0)
3037 h += 360;
3038 }
3039
3040 *r = h;
3041 *g = l;
3042 *b = s;
3043 }
3044
3045 static void
hls_to_rgb(gdouble * h,gdouble * l,gdouble * s)3046 hls_to_rgb (gdouble *h,
3047 gdouble *l,
3048 gdouble *s)
3049 {
3050 gdouble hue;
3051 gdouble lightness;
3052 gdouble saturation;
3053 gdouble m1, m2;
3054 gdouble r, g, b;
3055
3056 lightness = *l;
3057 saturation = *s;
3058
3059 if (lightness <= 0.5)
3060 m2 = lightness * (1 + saturation);
3061 else
3062 m2 = lightness + saturation - lightness * saturation;
3063 m1 = 2 * lightness - m2;
3064
3065 if (saturation == 0)
3066 {
3067 *h = lightness;
3068 *l = lightness;
3069 *s = lightness;
3070 }
3071 else
3072 {
3073 hue = *h + 120;
3074 while (hue > 360)
3075 hue -= 360;
3076 while (hue < 0)
3077 hue += 360;
3078
3079 if (hue < 60)
3080 r = m1 + (m2 - m1) * hue / 60;
3081 else if (hue < 180)
3082 r = m2;
3083 else if (hue < 240)
3084 r = m1 + (m2 - m1) * (240 - hue) / 60;
3085 else
3086 r = m1;
3087
3088 hue = *h;
3089 while (hue > 360)
3090 hue -= 360;
3091 while (hue < 0)
3092 hue += 360;
3093
3094 if (hue < 60)
3095 g = m1 + (m2 - m1) * hue / 60;
3096 else if (hue < 180)
3097 g = m2;
3098 else if (hue < 240)
3099 g = m1 + (m2 - m1) * (240 - hue) / 60;
3100 else
3101 g = m1;
3102
3103 hue = *h - 120;
3104 while (hue > 360)
3105 hue -= 360;
3106 while (hue < 0)
3107 hue += 360;
3108
3109 if (hue < 60)
3110 b = m1 + (m2 - m1) * hue / 60;
3111 else if (hue < 180)
3112 b = m2;
3113 else if (hue < 240)
3114 b = m1 + (m2 - m1) * (240 - hue) / 60;
3115 else
3116 b = m1;
3117
3118 *h = r;
3119 *l = g;
3120 *s = b;
3121 }
3122 }
3123
3124
3125 /**
3126 * gtk_paint_hline:
3127 * @style: a #GtkStyle
3128 * @cr: a #caio_t
3129 * @state_type: a state
3130 * @widget: (allow-none): the widget
3131 * @detail: (allow-none): a style detail
3132 * @x1: the starting x coordinate
3133 * @x2: the ending x coordinate
3134 * @y: the y coordinate
3135 *
3136 * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @cr
3137 * using the given style and state.
3138 *
3139 * Deprecated:3.0: Use gtk_render_line() instead
3140 **/
3141 void
gtk_paint_hline(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkWidget * widget,const gchar * detail,gint x1,gint x2,gint y)3142 gtk_paint_hline (GtkStyle *style,
3143 cairo_t *cr,
3144 GtkStateType state_type,
3145 GtkWidget *widget,
3146 const gchar *detail,
3147 gint x1,
3148 gint x2,
3149 gint y)
3150 {
3151 g_return_if_fail (GTK_IS_STYLE (style));
3152 g_return_if_fail (cr != NULL);
3153 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
3154
3155 cairo_save (cr);
3156
3157 GTK_STYLE_GET_CLASS (style)->draw_hline (style, cr, state_type,
3158 widget, detail,
3159 x1, x2, y);
3160
3161 cairo_restore (cr);
3162 }
3163
3164 /**
3165 * gtk_paint_vline:
3166 * @style: a #GtkStyle
3167 * @cr: a #cairo_t
3168 * @state_type: a state
3169 * @widget: (allow-none): the widget
3170 * @detail: (allow-none): a style detail
3171 * @y1_: the starting y coordinate
3172 * @y2_: the ending y coordinate
3173 * @x: the x coordinate
3174 *
3175 * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @cr
3176 * using the given style and state.
3177 *
3178 * Deprecated:3.0: Use gtk_render_line() instead
3179 */
3180 void
gtk_paint_vline(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkWidget * widget,const gchar * detail,gint y1_,gint y2_,gint x)3181 gtk_paint_vline (GtkStyle *style,
3182 cairo_t *cr,
3183 GtkStateType state_type,
3184 GtkWidget *widget,
3185 const gchar *detail,
3186 gint y1_,
3187 gint y2_,
3188 gint x)
3189 {
3190 g_return_if_fail (GTK_IS_STYLE (style));
3191 g_return_if_fail (cr != NULL);
3192 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
3193
3194 cairo_save (cr);
3195
3196 GTK_STYLE_GET_CLASS (style)->draw_vline (style, cr, state_type,
3197 widget, detail,
3198 y1_, y2_, x);
3199
3200 cairo_restore (cr);
3201 }
3202
3203 /**
3204 * gtk_paint_shadow:
3205 * @style: a #GtkStyle
3206 * @cr: a #cairo_t
3207 * @state_type: a state
3208 * @shadow_type: type of shadow to draw
3209 * @widget: (allow-none): the widget
3210 * @detail: (allow-none): a style detail
3211 * @x: x origin of the rectangle
3212 * @y: y origin of the rectangle
3213 * @width: width of the rectangle
3214 * @height: width of the rectangle
3215 *
3216 * Draws a shadow around the given rectangle in @cr
3217 * using the given style and state and shadow type.
3218 *
3219 * Deprecated:3.0: Use gtk_render_frame() instead
3220 */
3221 void
gtk_paint_shadow(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkShadowType shadow_type,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height)3222 gtk_paint_shadow (GtkStyle *style,
3223 cairo_t *cr,
3224 GtkStateType state_type,
3225 GtkShadowType shadow_type,
3226 GtkWidget *widget,
3227 const gchar *detail,
3228 gint x,
3229 gint y,
3230 gint width,
3231 gint height)
3232 {
3233 g_return_if_fail (GTK_IS_STYLE (style));
3234 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
3235 g_return_if_fail (cr != NULL);
3236 g_return_if_fail (width >= 0);
3237 g_return_if_fail (height >= 0);
3238
3239 cairo_save (cr);
3240
3241 GTK_STYLE_GET_CLASS (style)->draw_shadow (style, cr, state_type, shadow_type,
3242 widget, detail,
3243 x, y, width, height);
3244
3245 cairo_restore (cr);
3246 }
3247
3248 /**
3249 * gtk_paint_arrow:
3250 * @style: a #GtkStyle
3251 * @cr: a #cairo_t
3252 * @state_type: a state
3253 * @shadow_type: the type of shadow to draw
3254 * @widget: (allow-none): the widget
3255 * @detail: (allow-none): a style detail
3256 * @arrow_type: the type of arrow to draw
3257 * @fill: %TRUE if the arrow tip should be filled
3258 * @x: x origin of the rectangle to draw the arrow in
3259 * @y: y origin of the rectangle to draw the arrow in
3260 * @width: width of the rectangle to draw the arrow in
3261 * @height: height of the rectangle to draw the arrow in
3262 *
3263 * Draws an arrow in the given rectangle on @cr using the given
3264 * parameters. @arrow_type determines the direction of the arrow.
3265 *
3266 * Deprecated:3.0: Use gtk_render_arrow() instead
3267 */
3268 void
gtk_paint_arrow(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkShadowType shadow_type,GtkWidget * widget,const gchar * detail,GtkArrowType arrow_type,gboolean fill,gint x,gint y,gint width,gint height)3269 gtk_paint_arrow (GtkStyle *style,
3270 cairo_t *cr,
3271 GtkStateType state_type,
3272 GtkShadowType shadow_type,
3273 GtkWidget *widget,
3274 const gchar *detail,
3275 GtkArrowType arrow_type,
3276 gboolean fill,
3277 gint x,
3278 gint y,
3279 gint width,
3280 gint height)
3281 {
3282 g_return_if_fail (GTK_IS_STYLE (style));
3283 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
3284 g_return_if_fail (cr != NULL);
3285 g_return_if_fail (width >= 0);
3286 g_return_if_fail (height >= 0);
3287
3288 cairo_save (cr);
3289
3290 GTK_STYLE_GET_CLASS (style)->draw_arrow (style, cr, state_type, shadow_type,
3291 widget, detail,
3292 arrow_type, fill, x, y, width, height);
3293
3294 cairo_restore (cr);
3295 }
3296
3297 /**
3298 * gtk_paint_diamond:
3299 * @style: a #GtkStyle
3300 * @cr: a #cairo_t
3301 * @state_type: a state
3302 * @shadow_type: the type of shadow to draw
3303 * @widget: (allow-none): the widget
3304 * @detail: (allow-none): a style detail
3305 * @x: x origin of the rectangle to draw the diamond in
3306 * @y: y origin of the rectangle to draw the diamond in
3307 * @width: width of the rectangle to draw the diamond in
3308 * @height: height of the rectangle to draw the diamond in
3309 *
3310 * Draws a diamond in the given rectangle on @window using the given
3311 * parameters.
3312 *
3313 * Deprecated:3.0: Use cairo instead
3314 */
3315 void
gtk_paint_diamond(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkShadowType shadow_type,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height)3316 gtk_paint_diamond (GtkStyle *style,
3317 cairo_t *cr,
3318 GtkStateType state_type,
3319 GtkShadowType shadow_type,
3320 GtkWidget *widget,
3321 const gchar *detail,
3322 gint x,
3323 gint y,
3324 gint width,
3325 gint height)
3326 {
3327 g_return_if_fail (GTK_IS_STYLE (style));
3328 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
3329 g_return_if_fail (cr != NULL);
3330 g_return_if_fail (width >= 0);
3331 g_return_if_fail (height >= 0);
3332
3333 cairo_save (cr);
3334
3335 GTK_STYLE_GET_CLASS (style)->draw_diamond (style, cr, state_type, shadow_type,
3336 widget, detail,
3337 x, y, width, height);
3338
3339 cairo_restore (cr);
3340 }
3341
3342 /**
3343 * gtk_paint_box:
3344 * @style: a #GtkStyle
3345 * @cr: a #cairo_t
3346 * @state_type: a state
3347 * @shadow_type: the type of shadow to draw
3348 * @widget: (allow-none): the widget
3349 * @detail: (allow-none): a style detail
3350 * @x: x origin of the box
3351 * @y: y origin of the box
3352 * @width: the width of the box
3353 * @height: the height of the box
3354 *
3355 * Draws a box on @cr with the given parameters.
3356 *
3357 * Deprecated:3.0: Use gtk_render_frame() and gtk_render_background() instead
3358 */
3359 void
gtk_paint_box(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkShadowType shadow_type,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height)3360 gtk_paint_box (GtkStyle *style,
3361 cairo_t *cr,
3362 GtkStateType state_type,
3363 GtkShadowType shadow_type,
3364 GtkWidget *widget,
3365 const gchar *detail,
3366 gint x,
3367 gint y,
3368 gint width,
3369 gint height)
3370 {
3371 g_return_if_fail (GTK_IS_STYLE (style));
3372 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
3373 g_return_if_fail (cr != NULL);
3374
3375 cairo_save (cr);
3376
3377 GTK_STYLE_GET_CLASS (style)->draw_box (style, cr, state_type, shadow_type,
3378 widget, detail,
3379 x, y, width, height);
3380
3381 cairo_restore (cr);
3382 }
3383
3384 /**
3385 * gtk_paint_flat_box:
3386 * @style: a #GtkStyle
3387 * @cr: a #cairo_t
3388 * @state_type: a state
3389 * @shadow_type: the type of shadow to draw
3390 * @widget: (allow-none): the widget
3391 * @detail: (allow-none): a style detail
3392 * @x: x origin of the box
3393 * @y: y origin of the box
3394 * @width: the width of the box
3395 * @height: the height of the box
3396 *
3397 * Draws a flat box on @cr with the given parameters.
3398 *
3399 * Deprecated:3.0: Use gtk_render_frame() and gtk_render_background() instead
3400 */
3401 void
gtk_paint_flat_box(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkShadowType shadow_type,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height)3402 gtk_paint_flat_box (GtkStyle *style,
3403 cairo_t *cr,
3404 GtkStateType state_type,
3405 GtkShadowType shadow_type,
3406 GtkWidget *widget,
3407 const gchar *detail,
3408 gint x,
3409 gint y,
3410 gint width,
3411 gint height)
3412 {
3413 g_return_if_fail (GTK_IS_STYLE (style));
3414 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
3415 g_return_if_fail (cr != NULL);
3416 g_return_if_fail (width >= 0);
3417 g_return_if_fail (height >= 0);
3418
3419 cairo_save (cr);
3420
3421 GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, cr, state_type, shadow_type,
3422 widget, detail,
3423 x, y, width, height);
3424
3425 cairo_restore (cr);
3426 }
3427
3428 /**
3429 * gtk_paint_check:
3430 * @style: a #GtkStyle
3431 * @cr: a #cairo_t
3432 * @state_type: a state
3433 * @shadow_type: the type of shadow to draw
3434 * @widget: (allow-none): the widget
3435 * @detail: (allow-none): a style detail
3436 * @x: x origin of the rectangle to draw the check in
3437 * @y: y origin of the rectangle to draw the check in
3438 * @width: the width of the rectangle to draw the check in
3439 * @height: the height of the rectangle to draw the check in
3440 *
3441 * Draws a check button indicator in the given rectangle on @cr with
3442 * the given parameters.
3443 *
3444 * Deprecated:3.0: Use gtk_render_check() instead
3445 */
3446 void
gtk_paint_check(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkShadowType shadow_type,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height)3447 gtk_paint_check (GtkStyle *style,
3448 cairo_t *cr,
3449 GtkStateType state_type,
3450 GtkShadowType shadow_type,
3451 GtkWidget *widget,
3452 const gchar *detail,
3453 gint x,
3454 gint y,
3455 gint width,
3456 gint height)
3457 {
3458 g_return_if_fail (GTK_IS_STYLE (style));
3459 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
3460 g_return_if_fail (cr != NULL);
3461
3462 cairo_save (cr);
3463
3464 GTK_STYLE_GET_CLASS (style)->draw_check (style, cr, state_type, shadow_type,
3465 widget, detail,
3466 x, y, width, height);
3467
3468 cairo_restore (cr);
3469 }
3470
3471 /**
3472 * gtk_paint_option:
3473 * @style: a #GtkStyle
3474 * @cr: a #cairo_t
3475 * @state_type: a state
3476 * @shadow_type: the type of shadow to draw
3477 * @widget: (allow-none): the widget
3478 * @detail: (allow-none): a style detail
3479 * @x: x origin of the rectangle to draw the option in
3480 * @y: y origin of the rectangle to draw the option in
3481 * @width: the width of the rectangle to draw the option in
3482 * @height: the height of the rectangle to draw the option in
3483 *
3484 * Draws a radio button indicator in the given rectangle on @cr with
3485 * the given parameters.
3486 *
3487 * Deprecated:3.0: Use gtk_render_option() instead
3488 */
3489 void
gtk_paint_option(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkShadowType shadow_type,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height)3490 gtk_paint_option (GtkStyle *style,
3491 cairo_t *cr,
3492 GtkStateType state_type,
3493 GtkShadowType shadow_type,
3494 GtkWidget *widget,
3495 const gchar *detail,
3496 gint x,
3497 gint y,
3498 gint width,
3499 gint height)
3500 {
3501 g_return_if_fail (GTK_IS_STYLE (style));
3502 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
3503 g_return_if_fail (cr != NULL);
3504
3505 cairo_save (cr);
3506
3507 GTK_STYLE_GET_CLASS (style)->draw_option (style, cr, state_type, shadow_type,
3508 widget, detail,
3509 x, y, width, height);
3510
3511 cairo_restore (cr);
3512 }
3513
3514 /**
3515 * gtk_paint_tab:
3516 * @style: a #GtkStyle
3517 * @cr: a #cairo_t
3518 * @state_type: a state
3519 * @shadow_type: the type of shadow to draw
3520 * @widget: (allow-none): the widget
3521 * @detail: (allow-none): a style detail
3522 * @x: x origin of the rectangle to draw the tab in
3523 * @y: y origin of the rectangle to draw the tab in
3524 * @width: the width of the rectangle to draw the tab in
3525 * @height: the height of the rectangle to draw the tab in
3526 *
3527 * Draws an option menu tab (i.e. the up and down pointing arrows)
3528 * in the given rectangle on @cr using the given parameters.
3529 *
3530 * Deprecated:3.0: Use cairo instead
3531 */
3532 void
gtk_paint_tab(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkShadowType shadow_type,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height)3533 gtk_paint_tab (GtkStyle *style,
3534 cairo_t *cr,
3535 GtkStateType state_type,
3536 GtkShadowType shadow_type,
3537 GtkWidget *widget,
3538 const gchar *detail,
3539 gint x,
3540 gint y,
3541 gint width,
3542 gint height)
3543 {
3544 g_return_if_fail (GTK_IS_STYLE (style));
3545 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
3546 g_return_if_fail (cr != NULL);
3547
3548 cairo_save (cr);
3549
3550 GTK_STYLE_GET_CLASS (style)->draw_tab (style, cr, state_type, shadow_type,
3551 widget, detail,
3552 x, y, width, height);
3553
3554 cairo_restore (cr);
3555 }
3556
3557 /**
3558 * gtk_paint_shadow_gap:
3559 * @style: a #GtkStyle
3560 * @cr: a #cairo_t
3561 * @state_type: a state
3562 * @shadow_type: type of shadow to draw
3563 * @widget: (allow-none): the widget
3564 * @detail: (allow-none): a style detail
3565 * @x: x origin of the rectangle
3566 * @y: y origin of the rectangle
3567 * @width: width of the rectangle
3568 * @height: width of the rectangle
3569 * @gap_side: side in which to leave the gap
3570 * @gap_x: starting position of the gap
3571 * @gap_width: width of the gap
3572 *
3573 * Draws a shadow around the given rectangle in @cr
3574 * using the given style and state and shadow type, leaving a
3575 * gap in one side.
3576 *
3577 * Deprecated:3.0: Use gtk_render_frame_gap() instead
3578 */
3579 void
gtk_paint_shadow_gap(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkShadowType shadow_type,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height,GtkPositionType gap_side,gint gap_x,gint gap_width)3580 gtk_paint_shadow_gap (GtkStyle *style,
3581 cairo_t *cr,
3582 GtkStateType state_type,
3583 GtkShadowType shadow_type,
3584 GtkWidget *widget,
3585 const gchar *detail,
3586 gint x,
3587 gint y,
3588 gint width,
3589 gint height,
3590 GtkPositionType gap_side,
3591 gint gap_x,
3592 gint gap_width)
3593 {
3594 g_return_if_fail (GTK_IS_STYLE (style));
3595 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
3596 g_return_if_fail (cr != NULL);
3597 g_return_if_fail (width >= 0);
3598 g_return_if_fail (height >= 0);
3599
3600 cairo_save (cr);
3601
3602 GTK_STYLE_GET_CLASS (style)->draw_shadow_gap (style, cr, state_type, shadow_type,
3603 widget, detail,
3604 x, y, width, height, gap_side, gap_x, gap_width);
3605
3606 cairo_restore (cr);
3607 }
3608
3609 /**
3610 * gtk_paint_box_gap:
3611 * @style: a #GtkStyle
3612 * @cr: a #cairo_t
3613 * @state_type: a state
3614 * @shadow_type: type of shadow to draw
3615 * @widget: (allow-none): the widget
3616 * @detail: (allow-none): a style detail
3617 * @x: x origin of the rectangle
3618 * @y: y origin of the rectangle
3619 * @width: width of the rectangle
3620 * @height: width of the rectangle
3621 * @gap_side: side in which to leave the gap
3622 * @gap_x: starting position of the gap
3623 * @gap_width: width of the gap
3624 *
3625 * Draws a box in @cr using the given style and state and shadow type,
3626 * leaving a gap in one side.
3627 *
3628 * Deprecated:3.0: Use gtk_render_frame_gap() instead
3629 */
3630 void
gtk_paint_box_gap(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkShadowType shadow_type,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height,GtkPositionType gap_side,gint gap_x,gint gap_width)3631 gtk_paint_box_gap (GtkStyle *style,
3632 cairo_t *cr,
3633 GtkStateType state_type,
3634 GtkShadowType shadow_type,
3635 GtkWidget *widget,
3636 const gchar *detail,
3637 gint x,
3638 gint y,
3639 gint width,
3640 gint height,
3641 GtkPositionType gap_side,
3642 gint gap_x,
3643 gint gap_width)
3644 {
3645 g_return_if_fail (GTK_IS_STYLE (style));
3646 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
3647 g_return_if_fail (cr != NULL);
3648 g_return_if_fail (width >= 0);
3649 g_return_if_fail (height >= 0);
3650
3651 cairo_save (cr);
3652
3653 GTK_STYLE_GET_CLASS (style)->draw_box_gap (style, cr, state_type, shadow_type,
3654 widget, detail,
3655 x, y, width, height, gap_side, gap_x, gap_width);
3656
3657 cairo_restore (cr);
3658 }
3659
3660 /**
3661 * gtk_paint_extension:
3662 * @style: a #GtkStyle
3663 * @cr: a #cairo_t
3664 * @state_type: a state
3665 * @shadow_type: type of shadow to draw
3666 * @widget: (allow-none): the widget
3667 * @detail: (allow-none): a style detail
3668 * @x: x origin of the extension
3669 * @y: y origin of the extension
3670 * @width: width of the extension
3671 * @height: width of the extension
3672 * @gap_side: the side on to which the extension is attached
3673 *
3674 * Draws an extension, i.e. a notebook tab.
3675 *
3676 * Deprecated:3.0: Use gtk_render_extension() instead
3677 **/
3678 void
gtk_paint_extension(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkShadowType shadow_type,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height,GtkPositionType gap_side)3679 gtk_paint_extension (GtkStyle *style,
3680 cairo_t *cr,
3681 GtkStateType state_type,
3682 GtkShadowType shadow_type,
3683 GtkWidget *widget,
3684 const gchar *detail,
3685 gint x,
3686 gint y,
3687 gint width,
3688 gint height,
3689 GtkPositionType gap_side)
3690 {
3691 g_return_if_fail (GTK_IS_STYLE (style));
3692 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
3693 g_return_if_fail (cr != NULL);
3694 g_return_if_fail (width >= 0);
3695 g_return_if_fail (height >= 0);
3696
3697 cairo_save (cr);
3698
3699 GTK_STYLE_GET_CLASS (style)->draw_extension (style, cr, state_type, shadow_type,
3700 widget, detail,
3701 x, y, width, height, gap_side);
3702
3703 cairo_restore (cr);
3704 }
3705
3706 /**
3707 * gtk_paint_focus:
3708 * @style: a #GtkStyle
3709 * @cr: a #cairo_t
3710 * @state_type: a state
3711 * @widget: (allow-none): the widget
3712 * @detail: (allow-none): a style detail
3713 * @x: the x origin of the rectangle around which to draw a focus indicator
3714 * @y: the y origin of the rectangle around which to draw a focus indicator
3715 * @width: the width of the rectangle around which to draw a focus indicator
3716 * @height: the height of the rectangle around which to draw a focus indicator
3717 *
3718 * Draws a focus indicator around the given rectangle on @cr using the
3719 * given style.
3720 *
3721 * Deprecated:3.0: Use gtk_render_focus() instead
3722 */
3723 void
gtk_paint_focus(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height)3724 gtk_paint_focus (GtkStyle *style,
3725 cairo_t *cr,
3726 GtkStateType state_type,
3727 GtkWidget *widget,
3728 const gchar *detail,
3729 gint x,
3730 gint y,
3731 gint width,
3732 gint height)
3733 {
3734 g_return_if_fail (GTK_IS_STYLE (style));
3735 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
3736 g_return_if_fail (cr != NULL);
3737 g_return_if_fail (width >= 0);
3738 g_return_if_fail (height >= 0);
3739
3740 cairo_save (cr);
3741
3742 GTK_STYLE_GET_CLASS (style)->draw_focus (style, cr, state_type,
3743 widget, detail,
3744 x, y, width, height);
3745
3746 cairo_restore (cr);
3747 }
3748
3749 /**
3750 * gtk_paint_slider:
3751 * @style: a #GtkStyle
3752 * @cr: a #cairo_t
3753 * @state_type: a state
3754 * @shadow_type: a shadow
3755 * @widget: (allow-none): the widget
3756 * @detail: (allow-none): a style detail
3757 * @x: the x origin of the rectangle in which to draw a slider
3758 * @y: the y origin of the rectangle in which to draw a slider
3759 * @width: the width of the rectangle in which to draw a slider
3760 * @height: the height of the rectangle in which to draw a slider
3761 * @orientation: the orientation to be used
3762 *
3763 * Draws a slider in the given rectangle on @cr using the
3764 * given style and orientation.
3765 *
3766 * Deprecated:3.0: Use gtk_render_slider() instead
3767 **/
3768 void
gtk_paint_slider(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkShadowType shadow_type,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height,GtkOrientation orientation)3769 gtk_paint_slider (GtkStyle *style,
3770 cairo_t *cr,
3771 GtkStateType state_type,
3772 GtkShadowType shadow_type,
3773 GtkWidget *widget,
3774 const gchar *detail,
3775 gint x,
3776 gint y,
3777 gint width,
3778 gint height,
3779 GtkOrientation orientation)
3780 {
3781 g_return_if_fail (GTK_IS_STYLE (style));
3782 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
3783 g_return_if_fail (cr != NULL);
3784 g_return_if_fail (width >= 0);
3785 g_return_if_fail (height >= 0);
3786
3787 cairo_save (cr);
3788
3789 GTK_STYLE_GET_CLASS (style)->draw_slider (style, cr, state_type, shadow_type,
3790 widget, detail,
3791 x, y, width, height, orientation);
3792
3793 cairo_restore (cr);
3794 }
3795
3796 /**
3797 * gtk_paint_handle:
3798 * @style: a #GtkStyle
3799 * @cr: a #cairo_t
3800 * @state_type: a state
3801 * @shadow_type: type of shadow to draw
3802 * @widget: (allow-none): the widget
3803 * @detail: (allow-none): a style detail
3804 * @x: x origin of the handle
3805 * @y: y origin of the handle
3806 * @width: with of the handle
3807 * @height: height of the handle
3808 * @orientation: the orientation of the handle
3809 *
3810 * Draws a handle as used in #GtkHandleBox and #GtkPaned.
3811 *
3812 * Deprecated:3.0: Use gtk_render_handle() instead
3813 **/
3814 void
gtk_paint_handle(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkShadowType shadow_type,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height,GtkOrientation orientation)3815 gtk_paint_handle (GtkStyle *style,
3816 cairo_t *cr,
3817 GtkStateType state_type,
3818 GtkShadowType shadow_type,
3819 GtkWidget *widget,
3820 const gchar *detail,
3821 gint x,
3822 gint y,
3823 gint width,
3824 gint height,
3825 GtkOrientation orientation)
3826 {
3827 g_return_if_fail (GTK_IS_STYLE (style));
3828 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
3829 g_return_if_fail (cr != NULL);
3830 g_return_if_fail (width >= 0);
3831 g_return_if_fail (height >= 0);
3832
3833 cairo_save (cr);
3834
3835 GTK_STYLE_GET_CLASS (style)->draw_handle (style, cr, state_type, shadow_type,
3836 widget, detail,
3837 x, y, width, height, orientation);
3838
3839 cairo_restore (cr);
3840 }
3841
3842 /**
3843 * gtk_paint_expander:
3844 * @style: a #GtkStyle
3845 * @cr: a #cairo_t
3846 * @state_type: a state
3847 * @widget: (allow-none): the widget
3848 * @detail: (allow-none): a style detail
3849 * @x: the x position to draw the expander at
3850 * @y: the y position to draw the expander at
3851 * @expander_style: the style to draw the expander in; determines
3852 * whether the expander is collapsed, expanded, or in an
3853 * intermediate state.
3854 *
3855 * Draws an expander as used in #GtkTreeView. @x and @y specify the
3856 * center the expander. The size of the expander is determined by the
3857 * “expander-size” style property of @widget. (If widget is not
3858 * specified or doesn’t have an “expander-size” property, an
3859 * unspecified default size will be used, since the caller doesn't
3860 * have sufficient information to position the expander, this is
3861 * likely not useful.) The expander is expander_size pixels tall
3862 * in the collapsed position and expander_size pixels wide in the
3863 * expanded position.
3864 *
3865 * Deprecated:3.0: Use gtk_render_expander() instead
3866 **/
3867 void
gtk_paint_expander(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkWidget * widget,const gchar * detail,gint x,gint y,GtkExpanderStyle expander_style)3868 gtk_paint_expander (GtkStyle *style,
3869 cairo_t *cr,
3870 GtkStateType state_type,
3871 GtkWidget *widget,
3872 const gchar *detail,
3873 gint x,
3874 gint y,
3875 GtkExpanderStyle expander_style)
3876 {
3877 g_return_if_fail (GTK_IS_STYLE (style));
3878 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
3879 g_return_if_fail (cr != NULL);
3880
3881 cairo_save (cr);
3882
3883 GTK_STYLE_GET_CLASS (style)->draw_expander (style, cr, state_type,
3884 widget, detail,
3885 x, y, expander_style);
3886
3887 cairo_restore (cr);
3888 }
3889
3890 /**
3891 * gtk_paint_layout:
3892 * @style: a #GtkStyle
3893 * @cr: a #cairo_t
3894 * @state_type: a state
3895 * @use_text: whether to use the text or foreground
3896 * graphics context of @style
3897 * @widget: (allow-none): the widget
3898 * @detail: (allow-none): a style detail
3899 * @x: x origin
3900 * @y: y origin
3901 * @layout: the layout to draw
3902 *
3903 * Draws a layout on @cr using the given parameters.
3904 *
3905 * Deprecated:3.0: Use gtk_render_layout() instead
3906 **/
3907 void
gtk_paint_layout(GtkStyle * style,cairo_t * cr,GtkStateType state_type,gboolean use_text,GtkWidget * widget,const gchar * detail,gint x,gint y,PangoLayout * layout)3908 gtk_paint_layout (GtkStyle *style,
3909 cairo_t *cr,
3910 GtkStateType state_type,
3911 gboolean use_text,
3912 GtkWidget *widget,
3913 const gchar *detail,
3914 gint x,
3915 gint y,
3916 PangoLayout *layout)
3917 {
3918 g_return_if_fail (GTK_IS_STYLE (style));
3919 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
3920 g_return_if_fail (cr != NULL);
3921
3922 cairo_save (cr);
3923
3924 GTK_STYLE_GET_CLASS (style)->draw_layout (style, cr, state_type, use_text,
3925 widget, detail,
3926 x, y, layout);
3927
3928 cairo_restore (cr);
3929 }
3930
3931 /**
3932 * gtk_paint_resize_grip:
3933 * @style: a #GtkStyle
3934 * @cr: a #cairo_t
3935 * @state_type: a state
3936 * @widget: (allow-none): the widget
3937 * @detail: (allow-none): a style detail
3938 * @edge: the edge in which to draw the resize grip
3939 * @x: the x origin of the rectangle in which to draw the resize grip
3940 * @y: the y origin of the rectangle in which to draw the resize grip
3941 * @width: the width of the rectangle in which to draw the resize grip
3942 * @height: the height of the rectangle in which to draw the resize grip
3943 *
3944 * Draws a resize grip in the given rectangle on @cr using the given
3945 * parameters.
3946 *
3947 * Deprecated:3.0: Use gtk_render_handle() instead
3948 */
3949 void
gtk_paint_resize_grip(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkWidget * widget,const gchar * detail,GdkWindowEdge edge,gint x,gint y,gint width,gint height)3950 gtk_paint_resize_grip (GtkStyle *style,
3951 cairo_t *cr,
3952 GtkStateType state_type,
3953 GtkWidget *widget,
3954 const gchar *detail,
3955 GdkWindowEdge edge,
3956 gint x,
3957 gint y,
3958 gint width,
3959 gint height)
3960 {
3961 g_return_if_fail (GTK_IS_STYLE (style));
3962 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
3963 g_return_if_fail (cr != NULL);
3964
3965 cairo_save (cr);
3966
3967 GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, cr, state_type,
3968 widget, detail,
3969 edge, x, y, width, height);
3970 cairo_restore (cr);
3971 }
3972
3973 /**
3974 * gtk_paint_spinner:
3975 * @style: a #GtkStyle
3976 * @cr: a #cairo_t
3977 * @state_type: a state
3978 * @widget: (allow-none): the widget (may be %NULL)
3979 * @detail: (allow-none): a style detail (may be %NULL)
3980 * @step: the nth step
3981 * @x: the x origin of the rectangle in which to draw the spinner
3982 * @y: the y origin of the rectangle in which to draw the spinner
3983 * @width: the width of the rectangle in which to draw the spinner
3984 * @height: the height of the rectangle in which to draw the spinner
3985 *
3986 * Draws a spinner on @window using the given parameters.
3987 *
3988 * Deprecated: 3.0: Use gtk_render_icon() and the #GtkStyleContext
3989 * you are drawing instead
3990 */
3991 void
gtk_paint_spinner(GtkStyle * style,cairo_t * cr,GtkStateType state_type,GtkWidget * widget,const gchar * detail,guint step,gint x,gint y,gint width,gint height)3992 gtk_paint_spinner (GtkStyle *style,
3993 cairo_t *cr,
3994 GtkStateType state_type,
3995 GtkWidget *widget,
3996 const gchar *detail,
3997 guint step,
3998 gint x,
3999 gint y,
4000 gint width,
4001 gint height)
4002 {
4003 g_return_if_fail (GTK_IS_STYLE (style));
4004 g_return_if_fail (cr != NULL);
4005 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_spinner != NULL);
4006
4007 cairo_save (cr);
4008
4009 GTK_STYLE_GET_CLASS (style)->draw_spinner (style, cr, state_type,
4010 widget, detail,
4011 step, x, y, width, height);
4012
4013 cairo_restore (cr);
4014 }
4015
4016 static GtkStyle *
gtk_widget_get_default_style_for_screen(GdkScreen * screen)4017 gtk_widget_get_default_style_for_screen (GdkScreen *screen)
4018 {
4019 GtkStyle *default_style;
4020
4021 if G_UNLIKELY (quark_default_style == 0)
4022 quark_default_style = g_quark_from_static_string ("gtk-legacy-default-style");
4023
4024 default_style = g_object_get_qdata (G_OBJECT (screen), quark_default_style);
4025 if (default_style == NULL)
4026 {
4027 default_style = gtk_style_new ();
4028 g_object_set_qdata_full (G_OBJECT (screen),
4029 quark_default_style,
4030 default_style,
4031 g_object_unref);
4032 }
4033
4034 return default_style;
4035 }
4036
4037 /**
4038 * gtk_widget_get_default_style:
4039 *
4040 * Returns the default style used by all widgets initially.
4041 *
4042 * Returns: (transfer none): the default style. This #GtkStyle
4043 * object is owned by GTK+ and should not be modified or freed.
4044 *
4045 * Deprecated:3.0: Use #GtkStyleContext instead, and
4046 * gtk_css_provider_get_default() to obtain a #GtkStyleProvider
4047 * with the default widget style information.
4048 */
4049 GtkStyle *
gtk_widget_get_default_style(void)4050 gtk_widget_get_default_style (void)
4051 {
4052 static GtkStyle *default_style = NULL;
4053 GtkStyle *style = NULL;
4054 GdkScreen *screen = gdk_screen_get_default ();
4055
4056 if (screen)
4057 style = gtk_widget_get_default_style_for_screen (screen);
4058 else
4059 {
4060 if (default_style == NULL)
4061 default_style = gtk_style_new ();
4062 style = default_style;
4063 }
4064
4065 return style;
4066 }
4067
4068 /**
4069 * gtk_widget_style_attach:
4070 * @widget: a #GtkWidget
4071 *
4072 * This function attaches the widget’s #GtkStyle to the widget's
4073 * #GdkWindow. It is a replacement for
4074 *
4075 * |[
4076 * widget->style = gtk_style_attach (widget->style, widget->window);
4077 * ]|
4078 *
4079 * and should only ever be called in a derived widget’s “realize”
4080 * implementation which does not chain up to its parent class'
4081 * “realize” implementation, because one of the parent classes
4082 * (finally #GtkWidget) would attach the style itself.
4083 *
4084 * Since: 2.20
4085 *
4086 * Deprecated: 3.0: This step is unnecessary with #GtkStyleContext.
4087 **/
4088 void
gtk_widget_style_attach(GtkWidget * widget)4089 gtk_widget_style_attach (GtkWidget *widget)
4090 {
4091 g_return_if_fail (GTK_IS_WIDGET (widget));
4092 g_return_if_fail (gtk_widget_get_realized (widget));
4093 }
4094
4095 /**
4096 * gtk_widget_has_rc_style:
4097 * @widget: a #GtkWidget
4098 *
4099 * Determines if the widget style has been looked up through the rc mechanism.
4100 *
4101 * Returns: %TRUE if the widget has been looked up through the rc
4102 * mechanism, %FALSE otherwise.
4103 *
4104 * Since: 2.20
4105 *
4106 * Deprecated:3.0: Use #GtkStyleContext instead
4107 **/
4108 gboolean
gtk_widget_has_rc_style(GtkWidget * widget)4109 gtk_widget_has_rc_style (GtkWidget *widget)
4110 {
4111 g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
4112
4113 return FALSE;
4114 }
4115
4116 /**
4117 * gtk_widget_set_style:
4118 * @widget: a #GtkWidget
4119 * @style: (allow-none): a #GtkStyle, or %NULL to remove the effect
4120 * of a previous call to gtk_widget_set_style() and go back to
4121 * the default style
4122 *
4123 * Used to set the #GtkStyle for a widget (@widget->style). Since
4124 * GTK 3, this function does nothing, the passed in style is ignored.
4125 *
4126 * Deprecated:3.0: Use #GtkStyleContext instead
4127 */
4128 void
gtk_widget_set_style(GtkWidget * widget,GtkStyle * style)4129 gtk_widget_set_style (GtkWidget *widget,
4130 GtkStyle *style)
4131 {
4132 g_return_if_fail (GTK_IS_WIDGET (widget));
4133 }
4134
4135 /**
4136 * gtk_widget_ensure_style:
4137 * @widget: a #GtkWidget
4138 *
4139 * Ensures that @widget has a style (@widget->style).
4140 *
4141 * Not a very useful function; most of the time, if you
4142 * want the style, the widget is realized, and realized
4143 * widgets are guaranteed to have a style already.
4144 *
4145 * Deprecated:3.0: Use #GtkStyleContext instead
4146 */
4147 void
gtk_widget_ensure_style(GtkWidget * widget)4148 gtk_widget_ensure_style (GtkWidget *widget)
4149 {
4150 GtkStyle *style;
4151 g_return_if_fail (GTK_IS_WIDGET (widget));
4152
4153 style = _gtk_widget_get_style (widget);
4154 if (style == gtk_widget_get_default_style ())
4155 {
4156 g_object_unref (style);
4157 _gtk_widget_set_style (widget, NULL);
4158 }
4159 }
4160
4161 /**
4162 * gtk_widget_get_style:
4163 * @widget: a #GtkWidget
4164 *
4165 * Simply an accessor function that returns @widget->style.
4166 *
4167 * Returns: (transfer none): the widget’s #GtkStyle
4168 *
4169 * Deprecated:3.0: Use #GtkStyleContext instead
4170 */
4171 GtkStyle*
gtk_widget_get_style(GtkWidget * widget)4172 gtk_widget_get_style (GtkWidget *widget)
4173 {
4174 GtkStyle *style;
4175 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
4176
4177 style = _gtk_widget_get_style (widget);
4178
4179 if (style == NULL)
4180 {
4181 style = g_object_new (GTK_TYPE_STYLE,
4182 "context", gtk_widget_get_style_context (widget),
4183 NULL);
4184 _gtk_widget_set_style (widget, style);
4185 }
4186
4187 return style;
4188 }
4189
4190 /**
4191 * gtk_widget_modify_style:
4192 * @widget: a #GtkWidget
4193 * @style: the #GtkRcStyle-struct holding the style modifications
4194 *
4195 * Modifies style values on the widget.
4196 *
4197 * Modifications made using this technique take precedence over
4198 * style values set via an RC file, however, they will be overridden
4199 * if a style is explicitly set on the widget using gtk_widget_set_style().
4200 * The #GtkRcStyle-struct is designed so each field can either be
4201 * set or unset, so it is possible, using this function, to modify some
4202 * style values and leave the others unchanged.
4203 *
4204 * Note that modifications made with this function are not cumulative
4205 * with previous calls to gtk_widget_modify_style() or with such
4206 * functions as gtk_widget_modify_fg(). If you wish to retain
4207 * previous values, you must first call gtk_widget_get_modifier_style(),
4208 * make your modifications to the returned style, then call
4209 * gtk_widget_modify_style() with that style. On the other hand,
4210 * if you first call gtk_widget_modify_style(), subsequent calls
4211 * to such functions gtk_widget_modify_fg() will have a cumulative
4212 * effect with the initial modifications.
4213 *
4214 * Deprecated:3.0: Use #GtkStyleContext with a custom #GtkStyleProvider instead
4215 */
4216 void
gtk_widget_modify_style(GtkWidget * widget,GtkRcStyle * style)4217 gtk_widget_modify_style (GtkWidget *widget,
4218 GtkRcStyle *style)
4219 {
4220 g_return_if_fail (GTK_IS_WIDGET (widget));
4221 g_return_if_fail (GTK_IS_RC_STYLE (style));
4222
4223 g_object_set_data_full (G_OBJECT (widget),
4224 "gtk-rc-style",
4225 gtk_rc_style_copy (style),
4226 (GDestroyNotify) g_object_unref);
4227 }
4228
4229 /**
4230 * gtk_widget_get_modifier_style:
4231 * @widget: a #GtkWidget
4232 *
4233 * Returns the current modifier style for the widget. (As set by
4234 * gtk_widget_modify_style().) If no style has previously set, a new
4235 * #GtkRcStyle will be created with all values unset, and set as the
4236 * modifier style for the widget. If you make changes to this rc
4237 * style, you must call gtk_widget_modify_style(), passing in the
4238 * returned rc style, to make sure that your changes take effect.
4239 *
4240 * Caution: passing the style back to gtk_widget_modify_style() will
4241 * normally end up destroying it, because gtk_widget_modify_style() copies
4242 * the passed-in style and sets the copy as the new modifier style,
4243 * thus dropping any reference to the old modifier style. Add a reference
4244 * to the modifier style if you want to keep it alive.
4245 *
4246 * Returns: (transfer none): the modifier style for the widget.
4247 * This rc style is owned by the widget. If you want to keep a
4248 * pointer to value this around, you must add a refcount using
4249 * g_object_ref().
4250 *
4251 * Deprecated:3.0: Use #GtkStyleContext with a custom #GtkStyleProvider instead
4252 */
4253 GtkRcStyle *
gtk_widget_get_modifier_style(GtkWidget * widget)4254 gtk_widget_get_modifier_style (GtkWidget *widget)
4255 {
4256 GtkRcStyle *rc_style;
4257
4258 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
4259
4260 rc_style = g_object_get_data (G_OBJECT (widget), "gtk-rc-style");
4261
4262 if (!rc_style)
4263 {
4264 rc_style = gtk_rc_style_new ();
4265 g_object_set_data_full (G_OBJECT (widget),
4266 "gtk-rc-style",
4267 rc_style,
4268 (GDestroyNotify) g_object_unref);
4269 }
4270
4271 return rc_style;
4272 }
4273
4274 static void
gtk_widget_modify_color_component(GtkWidget * widget,GtkRcFlags component,GtkStateType state,const GdkColor * color)4275 gtk_widget_modify_color_component (GtkWidget *widget,
4276 GtkRcFlags component,
4277 GtkStateType state,
4278 const GdkColor *color)
4279 {
4280 GtkRcStyle *rc_style = gtk_widget_get_modifier_style (widget);
4281
4282 if (color)
4283 {
4284 switch (component)
4285 {
4286 case GTK_RC_FG:
4287 rc_style->fg[state] = *color;
4288 break;
4289 case GTK_RC_BG:
4290 rc_style->bg[state] = *color;
4291 break;
4292 case GTK_RC_TEXT:
4293 rc_style->text[state] = *color;
4294 break;
4295 case GTK_RC_BASE:
4296 rc_style->base[state] = *color;
4297 break;
4298 default:
4299 g_assert_not_reached();
4300 }
4301
4302 rc_style->color_flags[state] |= component;
4303 }
4304 else
4305 rc_style->color_flags[state] &= ~component;
4306
4307 gtk_widget_modify_style (widget, rc_style);
4308 }
4309
4310 /**
4311 * gtk_widget_modify_fg:
4312 * @widget: a #GtkWidget
4313 * @state: the state for which to set the foreground color
4314 * @color: (allow-none): the color to assign (does not need to be allocated),
4315 * or %NULL to undo the effect of previous calls to
4316 * of gtk_widget_modify_fg().
4317 *
4318 * Sets the foreground color for a widget in a particular state.
4319 *
4320 * All other style values are left untouched.
4321 * See also gtk_widget_modify_style().
4322 *
4323 * Deprecated:3.0: Use gtk_widget_override_color() instead
4324 */
4325 void
gtk_widget_modify_fg(GtkWidget * widget,GtkStateType state,const GdkColor * color)4326 gtk_widget_modify_fg (GtkWidget *widget,
4327 GtkStateType state,
4328 const GdkColor *color)
4329 {
4330 GtkStateFlags flags;
4331 GdkRGBA rgba;
4332
4333 g_return_if_fail (GTK_IS_WIDGET (widget));
4334 g_return_if_fail (state >= GTK_STATE_NORMAL && state <= GTK_STATE_INSENSITIVE);
4335
4336 switch (state)
4337 {
4338 case GTK_STATE_ACTIVE:
4339 flags = GTK_STATE_FLAG_ACTIVE;
4340 break;
4341 case GTK_STATE_PRELIGHT:
4342 flags = GTK_STATE_FLAG_PRELIGHT;
4343 break;
4344 case GTK_STATE_SELECTED:
4345 flags = GTK_STATE_FLAG_SELECTED;
4346 break;
4347 case GTK_STATE_INSENSITIVE:
4348 flags = GTK_STATE_FLAG_INSENSITIVE;
4349 break;
4350 case GTK_STATE_NORMAL:
4351 default:
4352 flags = 0;
4353 }
4354
4355 if (color)
4356 {
4357 rgba.red = color->red / 65535.;
4358 rgba.green = color->green / 65535.;
4359 rgba.blue = color->blue / 65535.;
4360 rgba.alpha = 1;
4361
4362 gtk_widget_override_color (widget, flags, &rgba);
4363 }
4364 else
4365 gtk_widget_override_color (widget, flags, NULL);
4366 }
4367
4368 /**
4369 * gtk_widget_modify_bg:
4370 * @widget: a #GtkWidget
4371 * @state: the state for which to set the background color
4372 * @color: (allow-none): the color to assign (does not need
4373 * to be allocated), or %NULL to undo the effect of previous
4374 * calls to of gtk_widget_modify_bg().
4375 *
4376 * Sets the background color for a widget in a particular state.
4377 *
4378 * All other style values are left untouched.
4379 * See also gtk_widget_modify_style().
4380 *
4381 * > Note that “no window” widgets (which have the %GTK_NO_WINDOW
4382 * > flag set) draw on their parent container’s window and thus may
4383 * > not draw any background themselves. This is the case for e.g.
4384 * > #GtkLabel.
4385 * >
4386 * > To modify the background of such widgets, you have to set the
4387 * > background color on their parent; if you want to set the background
4388 * > of a rectangular area around a label, try placing the label in
4389 * > a #GtkEventBox widget and setting the background color on that.
4390 *
4391 * Deprecated:3.0: Use gtk_widget_override_background_color() instead
4392 */
4393 void
gtk_widget_modify_bg(GtkWidget * widget,GtkStateType state,const GdkColor * color)4394 gtk_widget_modify_bg (GtkWidget *widget,
4395 GtkStateType state,
4396 const GdkColor *color)
4397 {
4398 GtkStateFlags flags;
4399 GdkRGBA rgba;
4400
4401 g_return_if_fail (GTK_IS_WIDGET (widget));
4402 g_return_if_fail (state >= GTK_STATE_NORMAL && state <= GTK_STATE_INSENSITIVE);
4403
4404 switch (state)
4405 {
4406 case GTK_STATE_ACTIVE:
4407 flags = GTK_STATE_FLAG_ACTIVE;
4408 break;
4409 case GTK_STATE_PRELIGHT:
4410 flags = GTK_STATE_FLAG_PRELIGHT;
4411 break;
4412 case GTK_STATE_SELECTED:
4413 flags = GTK_STATE_FLAG_SELECTED;
4414 break;
4415 case GTK_STATE_INSENSITIVE:
4416 flags = GTK_STATE_FLAG_INSENSITIVE;
4417 break;
4418 case GTK_STATE_NORMAL:
4419 default:
4420 flags = 0;
4421 }
4422
4423 if (color)
4424 {
4425 rgba.red = color->red / 65535.;
4426 rgba.green = color->green / 65535.;
4427 rgba.blue = color->blue / 65535.;
4428 rgba.alpha = 1;
4429
4430 gtk_widget_override_background_color (widget, flags, &rgba);
4431 }
4432 else
4433 gtk_widget_override_background_color (widget, flags, NULL);
4434 }
4435
4436 /**
4437 * gtk_widget_modify_text:
4438 * @widget: a #GtkWidget
4439 * @state: the state for which to set the text color
4440 * @color: (allow-none): the color to assign (does not need to
4441 * be allocated), or %NULL to undo the effect of previous
4442 * calls to of gtk_widget_modify_text().
4443 *
4444 * Sets the text color for a widget in a particular state.
4445 *
4446 * All other style values are left untouched.
4447 * The text color is the foreground color used along with the
4448 * base color (see gtk_widget_modify_base()) for widgets such
4449 * as #GtkEntry and #GtkTextView.
4450 * See also gtk_widget_modify_style().
4451 *
4452 * Deprecated:3.0: Use gtk_widget_override_color() instead
4453 */
4454 void
gtk_widget_modify_text(GtkWidget * widget,GtkStateType state,const GdkColor * color)4455 gtk_widget_modify_text (GtkWidget *widget,
4456 GtkStateType state,
4457 const GdkColor *color)
4458 {
4459 g_return_if_fail (GTK_IS_WIDGET (widget));
4460 g_return_if_fail (state >= GTK_STATE_NORMAL && state <= GTK_STATE_INSENSITIVE);
4461
4462 gtk_widget_modify_color_component (widget, GTK_RC_TEXT, state, color);
4463 }
4464
4465 /**
4466 * gtk_widget_modify_base:
4467 * @widget: a #GtkWidget
4468 * @state: the state for which to set the base color
4469 * @color: (allow-none): the color to assign (does not need to
4470 * be allocated), or %NULL to undo the effect of previous
4471 * calls to of gtk_widget_modify_base().
4472 *
4473 * Sets the base color for a widget in a particular state.
4474 * All other style values are left untouched. The base color
4475 * is the background color used along with the text color
4476 * (see gtk_widget_modify_text()) for widgets such as #GtkEntry
4477 * and #GtkTextView. See also gtk_widget_modify_style().
4478 *
4479 * > Note that “no window” widgets (which have the %GTK_NO_WINDOW
4480 * > flag set) draw on their parent container’s window and thus may
4481 * > not draw any background themselves. This is the case for e.g.
4482 * > #GtkLabel.
4483 * >
4484 * > To modify the background of such widgets, you have to set the
4485 * > base color on their parent; if you want to set the background
4486 * > of a rectangular area around a label, try placing the label in
4487 * > a #GtkEventBox widget and setting the base color on that.
4488 *
4489 * Deprecated:3.0: Use gtk_widget_override_background_color() instead
4490 */
4491 void
gtk_widget_modify_base(GtkWidget * widget,GtkStateType state,const GdkColor * color)4492 gtk_widget_modify_base (GtkWidget *widget,
4493 GtkStateType state,
4494 const GdkColor *color)
4495 {
4496 g_return_if_fail (GTK_IS_WIDGET (widget));
4497 g_return_if_fail (state >= GTK_STATE_NORMAL && state <= GTK_STATE_INSENSITIVE);
4498
4499 gtk_widget_modify_color_component (widget, GTK_RC_BASE, state, color);
4500 }
4501
4502 /**
4503 * gtk_widget_modify_cursor:
4504 * @widget: a #GtkWidget
4505 * @primary: (nullable): the color to use for primary cursor (does not
4506 * need to be allocated), or %NULL to undo the effect of previous
4507 * calls to of gtk_widget_modify_cursor().
4508 * @secondary: (nullable): the color to use for secondary cursor (does
4509 * not need to be allocated), or %NULL to undo the effect of
4510 * previous calls to of gtk_widget_modify_cursor().
4511 *
4512 * Sets the cursor color to use in a widget, overriding the #GtkWidget
4513 * cursor-color and secondary-cursor-color
4514 * style properties.
4515 *
4516 * All other style values are left untouched.
4517 * See also gtk_widget_modify_style().
4518 *
4519 * Since: 2.12
4520 *
4521 * Deprecated: 3.0: Use gtk_widget_override_cursor() instead.
4522 */
4523 void
gtk_widget_modify_cursor(GtkWidget * widget,const GdkColor * primary,const GdkColor * secondary)4524 gtk_widget_modify_cursor (GtkWidget *widget,
4525 const GdkColor *primary,
4526 const GdkColor *secondary)
4527 {
4528 GdkRGBA primary_rgba, secondary_rgba;
4529
4530 g_return_if_fail (GTK_IS_WIDGET (widget));
4531
4532 primary_rgba.red = primary->red / 65535.;
4533 primary_rgba.green = primary->green / 65535.;
4534 primary_rgba.blue = primary->blue / 65535.;
4535 primary_rgba.alpha = 1;
4536
4537 secondary_rgba.red = secondary->red / 65535.;
4538 secondary_rgba.green = secondary->green / 65535.;
4539 secondary_rgba.blue = secondary->blue / 65535.;
4540 secondary_rgba.alpha = 1;
4541
4542 gtk_widget_override_cursor (widget, &primary_rgba, &secondary_rgba);
4543 }
4544
4545 /**
4546 * gtk_widget_modify_font:
4547 * @widget: a #GtkWidget
4548 * @font_desc: (allow-none): the font description to use, or %NULL
4549 * to undo the effect of previous calls to gtk_widget_modify_font()
4550 *
4551 * Sets the font to use for a widget.
4552 *
4553 * All other style values are left untouched.
4554 * See also gtk_widget_modify_style().
4555 *
4556 * Deprecated:3.0: Use gtk_widget_override_font() instead
4557 */
4558 void
gtk_widget_modify_font(GtkWidget * widget,PangoFontDescription * font_desc)4559 gtk_widget_modify_font (GtkWidget *widget,
4560 PangoFontDescription *font_desc)
4561 {
4562 g_return_if_fail (GTK_IS_WIDGET (widget));
4563
4564 gtk_widget_override_font (widget, font_desc);
4565 }
4566
4567 /**
4568 * gtk_widget_reset_rc_styles:
4569 * @widget: a #GtkWidget.
4570 *
4571 * Reset the styles of @widget and all descendents, so when
4572 * they are looked up again, they get the correct values
4573 * for the currently loaded RC file settings.
4574 *
4575 * This function is not useful for applications.
4576 *
4577 * Deprecated:3.0: Use #GtkStyleContext instead, and gtk_widget_reset_style()
4578 */
4579 void
gtk_widget_reset_rc_styles(GtkWidget * widget)4580 gtk_widget_reset_rc_styles (GtkWidget *widget)
4581 {
4582 g_return_if_fail (GTK_IS_WIDGET (widget));
4583
4584 gtk_widget_reset_style (widget);
4585 }
4586
4587 /**
4588 * gtk_widget_path:
4589 * @widget: a #GtkWidget
4590 * @path_length: (out) (allow-none): location to store length of the path,
4591 * or %NULL
4592 * @path: (out) (allow-none): location to store allocated path string,
4593 * or %NULL
4594 * @path_reversed: (out) (allow-none): location to store allocated reverse
4595 * path string, or %NULL
4596 *
4597 * Obtains the full path to @widget. The path is simply the name of a
4598 * widget and all its parents in the container hierarchy, separated by
4599 * periods. The name of a widget comes from
4600 * gtk_widget_get_name(). Paths are used to apply styles to a widget
4601 * in gtkrc configuration files. Widget names are the type of the
4602 * widget by default (e.g. “GtkButton”) or can be set to an
4603 * application-specific value with gtk_widget_set_name(). By setting
4604 * the name of a widget, you allow users or theme authors to apply
4605 * styles to that specific widget in their gtkrc
4606 * file. @path_reversed_p fills in the path in reverse order,
4607 * i.e. starting with @widget’s name instead of starting with the name
4608 * of @widget’s outermost ancestor.
4609 *
4610 * Deprecated:3.0: Use gtk_widget_get_path() instead
4611 **/
4612 void
gtk_widget_path(GtkWidget * widget,guint * path_length,gchar ** path,gchar ** path_reversed)4613 gtk_widget_path (GtkWidget *widget,
4614 guint *path_length,
4615 gchar **path,
4616 gchar **path_reversed)
4617 {
4618 static gchar *rev_path = NULL;
4619 static guint tmp_path_len = 0;
4620 guint len;
4621
4622 #define INIT_PATH_SIZE (512)
4623
4624 g_return_if_fail (GTK_IS_WIDGET (widget));
4625
4626 len = 0;
4627 do
4628 {
4629 const gchar *string;
4630 const gchar *s;
4631 gchar *d;
4632 guint l;
4633
4634 string = gtk_widget_get_name (widget);
4635 l = strlen (string);
4636 while (tmp_path_len <= len + l + 1)
4637 {
4638 tmp_path_len += INIT_PATH_SIZE;
4639 rev_path = g_realloc (rev_path, tmp_path_len);
4640 }
4641 s = string + l - 1;
4642 d = rev_path + len;
4643 while (s >= string)
4644 *(d++) = *(s--);
4645 len += l;
4646
4647 widget = gtk_widget_get_parent (widget);
4648
4649 if (widget)
4650 rev_path[len++] = '.';
4651 else
4652 rev_path[len++] = 0;
4653 }
4654 while (widget);
4655
4656 if (path_length)
4657 *path_length = len - 1;
4658 if (path_reversed)
4659 *path_reversed = g_strdup (rev_path);
4660 if (path)
4661 {
4662 *path = g_strdup (rev_path);
4663 g_strreverse (*path);
4664 }
4665 }
4666
4667 /**
4668 * gtk_widget_class_path:
4669 * @widget: a #GtkWidget
4670 * @path_length: (out) (optional): location to store the length of the
4671 * class path, or %NULL
4672 * @path: (out) (optional): location to store the class path as an
4673 * allocated string, or %NULL
4674 * @path_reversed: (out) (optional): location to store the reverse
4675 * class path as an allocated string, or %NULL
4676 *
4677 * Same as gtk_widget_path(), but always uses the name of a widget’s type,
4678 * never uses a custom name set with gtk_widget_set_name().
4679 *
4680 * Deprecated:3.0: Use gtk_widget_get_path() instead
4681 **/
4682 void
gtk_widget_class_path(GtkWidget * widget,guint * path_length,gchar ** path,gchar ** path_reversed)4683 gtk_widget_class_path (GtkWidget *widget,
4684 guint *path_length,
4685 gchar **path,
4686 gchar **path_reversed)
4687 {
4688 static gchar *rev_path = NULL;
4689 static guint tmp_path_len = 0;
4690 guint len;
4691
4692 g_return_if_fail (GTK_IS_WIDGET (widget));
4693
4694 len = 0;
4695 do
4696 {
4697 const gchar *string;
4698 const gchar *s;
4699 gchar *d;
4700 guint l;
4701
4702 string = g_type_name (G_OBJECT_TYPE (widget));
4703 l = strlen (string);
4704 while (tmp_path_len <= len + l + 1)
4705 {
4706 tmp_path_len += INIT_PATH_SIZE;
4707 rev_path = g_realloc (rev_path, tmp_path_len);
4708 }
4709 s = string + l - 1;
4710 d = rev_path + len;
4711 while (s >= string)
4712 *(d++) = *(s--);
4713 len += l;
4714
4715 widget = gtk_widget_get_parent (widget);
4716
4717 if (widget)
4718 rev_path[len++] = '.';
4719 else
4720 rev_path[len++] = 0;
4721 }
4722 while (widget);
4723
4724 if (path_length)
4725 *path_length = len - 1;
4726 if (path_reversed)
4727 *path_reversed = g_strdup (rev_path);
4728 if (path)
4729 {
4730 *path = g_strdup (rev_path);
4731 g_strreverse (*path);
4732 }
4733 }
4734
4735 /**
4736 * gtk_widget_render_icon:
4737 * @widget: a #GtkWidget
4738 * @stock_id: a stock ID
4739 * @size: (type int): a stock size (#GtkIconSize). A size of `(GtkIconSize)-1`
4740 * means render at the size of the source and don’t scale (if there are
4741 * multiple source sizes, GTK+ picks one of the available sizes).
4742 * @detail: (allow-none): render detail to pass to theme engine
4743 *
4744 * A convenience function that uses the theme settings for @widget
4745 * to look up @stock_id and render it to a pixbuf. @stock_id should
4746 * be a stock icon ID such as #GTK_STOCK_OPEN or #GTK_STOCK_OK. @size
4747 * should be a size such as #GTK_ICON_SIZE_MENU. @detail should be a
4748 * string that identifies the widget or code doing the rendering, so
4749 * that theme engines can special-case rendering for that widget or
4750 * code.
4751 *
4752 * The pixels in the returned #GdkPixbuf are shared with the rest of
4753 * the application and should not be modified. The pixbuf should be
4754 * freed after use with g_object_unref().
4755 *
4756 * Returns: (nullable) (transfer full): a new pixbuf, or %NULL if the
4757 * stock ID wasn’t known
4758 *
4759 * Deprecated: 3.0: Use gtk_widget_render_icon_pixbuf() instead.
4760 **/
4761 GdkPixbuf*
gtk_widget_render_icon(GtkWidget * widget,const gchar * stock_id,GtkIconSize size,const gchar * detail)4762 gtk_widget_render_icon (GtkWidget *widget,
4763 const gchar *stock_id,
4764 GtkIconSize size,
4765 const gchar *detail)
4766 {
4767 gtk_widget_ensure_style (widget);
4768
4769 return gtk_widget_render_icon_pixbuf (widget, stock_id, size);
4770 }
4771