1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 2010 Carlos Garnacho <carlosg@gnome.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
24 #include <gobject/gvaluecollector.h>
26 #include "gtkstylecontext.h"
27 #include "gtktypebuiltins.h"
28 #include "gtkthemingengine.h"
30 #include "gtkwidget.h"
31 #include "gtkwindow.h"
32 #include "gtkprivate.h"
33 #include "gtkanimationdescription.h"
34 #include "gtktimeline.h"
37 * SECTION:gtkstylecontext
38 * @Short_description: rendering UI elements
39 * @Title: GtkStyleContext
42 * #GtkStyleContext is an object that stores styling information affecting
43 * a widget defined by #GtkWidgetPath.
45 * In order to construct the final style information, #GtkStyleContext
46 * queries information from all attached #GtkStyleProviders. Style providers
47 * can be either attached explicitly to the context through
48 * gtk_style_context_add_provider(), or to the screen through
49 * gtk_style_context_add_provider_for_screen(). The resulting style is a
50 * combination of all provider's information in priority order.
52 * For GTK+ widgets, any #GtkStyleContext returned by
53 * gtk_widget_get_style_context() will already have a #GtkWidgetPath, a
54 * #GdkScreen and RTL/LTR information set, the style context will be also
55 * updated automatically if any of these settings change on the widget.
57 * If you are using are the theming layer standalone, you will need to set a
58 * widget path and a screen yourself to the created style context through
59 * gtk_style_context_set_path() and gtk_style_context_set_screen(), as well
60 * as updating the context yourself using gtk_style_context_invalidate()
61 * whenever any of the conditions change, such as a change in the
62 * #GtkSettings:gtk-theme-name property or a hierarchy change in the rendered
65 * <refsect2 id="gtkstylecontext-animations">
66 * <title>Transition animations</title>
68 * #GtkStyleContext has built-in support for state change transitions.
71 * For simple widgets where state changes affect the whole widget area,
72 * calling gtk_style_context_notify_state_change() with a %NULL identifier
73 * would be sufficient.
76 * If a widget needs to declare several animatable regions (i.e. not
77 * affecting the whole widget area), its #GtkWidget::draw signal handler
78 * needs to wrap the render operations for the different regions around
79 * gtk_style_context_push_animatable_region() and
80 * gtk_style_context_pop_animatable_region(). These functions take an
81 * unique identifier within the style context, for simple widgets with
82 * little animatable regions, an enum may be used:
85 * <title>Using an enum as animatable region identifier</title>
96 * spin_button_draw (GtkWidget *widget,
99 * GtkStyleContext *context;
101 * context = gtk_widget_get_style_context (widget);
103 * gtk_style_context_push_animatable_region (context,
104 * GUINT_TO_POINTER (REGION_ENTRY));
106 * gtk_render_background (cr, 0, 0, 100, 30);
107 * gtk_render_frame (cr, 0, 0, 100, 30);
109 * gtk_style_context_pop_animatable_region (context);
116 * For complex widgets with an arbitrary number of animatable regions, it
117 * is up to the implementation to come up with a way to univocally identify
118 * an animatable region, pointers to internal structs would suffice.
121 * <title>Using an arbitrary pointer as animatable region identifier</title>
124 * notebook_draw_tab (GtkWidget *widget,
125 * NotebookPage *page,
128 * gtk_style_context_push_animatable_region (context, page);
129 * gtk_render_extension (cr, page->x, page->y, page->width, page->height);
130 * gtk_style_context_pop_animatable_region (context);
135 * The widget also needs to notify the style context about a state change
136 * for a given animatable region so the animation is triggered.
139 * <title>Triggering a state change animation on a region</title>
142 * notebook_motion_notify (GtkWidget *widget,
143 * GdkEventMotion *event)
145 * GtkStyleContext *context;
146 * NotebookPage *page;
148 * context = gtk_widget_get_style_context (widget);
149 * page = find_page_under_pointer (widget, event);
150 * gtk_style_context_notify_state_change (context,
151 * gtk_widget_get_window (widget),
153 * GTK_STATE_PRELIGHT,
160 * gtk_style_context_notify_state_change() accepts %NULL region IDs as a
161 * special value, in this case, the whole widget area will be updated
166 * <refsect2 id="gtkstylecontext-custom-styling">
167 * <title>Custom styling in UI libraries and applications</title>
169 * If you are developing a library with custom #GtkWidget<!-- -->s that
170 * render differently than standard components, you may need to add a
171 * #GtkStyleProvider yourself with the %GTK_STYLE_PROVIDER_PRIORITY_FALLBACK
172 * priority, either a #GtkCssProvider or a custom object implementing the
173 * #GtkStyleProvider interface. This way theming engines may still attempt
174 * to style your UI elements in a different way if needed so.
177 * If you are using custom styling on an applications, you probably want then
178 * to make your style information prevail to the theme's, so you must use
179 * a #GtkStyleProvider with the %GTK_STYLE_PROVIDER_PRIORITY_APPLICATION
180 * priority, keep in mind that the user settings in $HOME/.gtk-3.0.css will
181 * still take precedence over your changes, as it uses the
182 * %GTK_STYLE_PROVIDER_PRIORITY_USER priority.
185 * If a custom theming engine is needed, you probably want to implement a
186 * #GtkStyleProvider yourself so it points to your #GtkThemingEngine
187 * implementation, as #GtkCssProvider uses gtk_theming_engine_load()
188 * which loads the theming engine module from the standard paths.
193 typedef struct GtkStyleContextPrivate GtkStyleContextPrivate;
194 typedef struct GtkStyleProviderData GtkStyleProviderData;
195 typedef struct GtkStyleInfo GtkStyleInfo;
196 typedef struct GtkRegion GtkRegion;
197 typedef struct PropertyValue PropertyValue;
198 typedef struct AnimationInfo AnimationInfo;
199 typedef struct StyleData StyleData;
204 GtkRegionFlags flags;
207 struct GtkStyleProviderData
209 GtkStyleProvider *provider;
222 GArray *style_classes;
224 GtkJunctionSides junction_sides;
225 GtkStateFlags state_flags;
230 GtkStyleProperties *store;
231 GSList *icon_factories;
232 GArray *property_cache;
237 GtkTimeline *timeline;
242 gboolean target_value;
244 cairo_region_t *invalidation_region;
248 struct GtkStyleContextPrivate
253 GList *providers_last;
255 GtkWidgetPath *widget_path;
256 GHashTable *style_data;
258 StyleData *current_data;
260 GSList *animation_regions;
263 guint animations_invalidated : 1;
264 guint invalidating_context : 1;
266 GtkThemingEngine *theming_engine;
268 GtkTextDirection direction;
282 guint signals[LAST_SIGNAL] = { 0 };
284 static GQuark provider_list_quark = 0;
286 static void gtk_style_context_finalize (GObject *object);
288 static void gtk_style_context_impl_set_property (GObject *object,
292 static void gtk_style_context_impl_get_property (GObject *object,
298 G_DEFINE_TYPE (GtkStyleContext, gtk_style_context, G_TYPE_OBJECT)
301 gtk_style_context_class_init (GtkStyleContextClass *klass)
303 GObjectClass *object_class = G_OBJECT_CLASS (klass);
305 object_class->finalize = gtk_style_context_finalize;
306 object_class->set_property = gtk_style_context_impl_set_property;
307 object_class->get_property = gtk_style_context_impl_get_property;
310 g_signal_new (I_("changed"),
311 G_TYPE_FROM_CLASS (object_class),
313 G_STRUCT_OFFSET (GtkStyleContextClass, changed),
315 g_cclosure_marshal_VOID__VOID,
318 g_object_class_install_property (object_class,
320 g_param_spec_object ("screen",
322 P_("The associated GdkScreen"),
324 GTK_PARAM_READWRITE));
325 g_object_class_install_property (object_class,
327 g_param_spec_enum ("direction",
329 P_("Text direction"),
330 GTK_TYPE_TEXT_DIRECTION,
332 GTK_PARAM_READWRITE));
334 g_type_class_add_private (object_class, sizeof (GtkStyleContextPrivate));
337 static GtkStyleInfo *
338 style_info_new (void)
342 info = g_slice_new0 (GtkStyleInfo);
343 info->style_classes = g_array_new (FALSE, FALSE, sizeof (GQuark));
344 info->regions = g_array_new (FALSE, FALSE, sizeof (GtkRegion));
350 style_info_free (GtkStyleInfo *info)
352 g_array_free (info->style_classes, TRUE);
353 g_array_free (info->regions, TRUE);
354 g_slice_free (GtkStyleInfo, info);
357 static GtkStyleInfo *
358 style_info_copy (const GtkStyleInfo *info)
362 copy = style_info_new ();
363 g_array_insert_vals (copy->style_classes, 0,
364 info->style_classes->data,
365 info->style_classes->len);
367 g_array_insert_vals (copy->regions, 0,
371 copy->junction_sides = info->junction_sides;
372 copy->state_flags = info->state_flags;
378 style_info_hash (gconstpointer elem)
380 const GtkStyleInfo *info;
385 for (i = 0; i < info->style_classes->len; i++)
387 hash += g_array_index (info->style_classes, GQuark, i);
391 for (i = 0; i < info->regions->len; i++)
395 region = &g_array_index (info->regions, GtkRegion, i);
396 hash += region->class_quark;
397 hash += region->flags;
405 style_info_equal (gconstpointer elem1,
408 const GtkStyleInfo *info1, *info2;
413 if (info1->junction_sides != info2->junction_sides)
416 if (info1->style_classes->len != info2->style_classes->len)
419 if (memcmp (info1->style_classes->data,
420 info2->style_classes->data,
421 info1->style_classes->len * sizeof (GQuark)) != 0)
424 if (info1->regions->len != info2->regions->len)
427 if (memcmp (info1->regions->data,
428 info2->regions->data,
429 info1->regions->len * sizeof (GtkRegion)) != 0)
436 style_data_new (void)
440 data = g_slice_new0 (StyleData);
441 data->store = gtk_style_properties_new ();
447 clear_property_cache (StyleData *data)
451 if (!data->property_cache)
454 for (i = 0; i < data->property_cache->len; i++)
456 PropertyValue *node = &g_array_index (data->property_cache, PropertyValue, i);
458 g_param_spec_unref (node->pspec);
459 g_value_unset (&node->value);
462 g_array_free (data->property_cache, TRUE);
463 data->property_cache = NULL;
467 style_data_free (StyleData *data)
469 g_object_unref (data->store);
470 clear_property_cache (data);
472 g_slist_foreach (data->icon_factories, (GFunc) g_object_unref, NULL);
473 g_slist_free (data->icon_factories);
475 g_slice_free (StyleData, data);
479 gtk_style_context_init (GtkStyleContext *style_context)
481 GtkStyleContextPrivate *priv;
484 priv = style_context->priv = G_TYPE_INSTANCE_GET_PRIVATE (style_context,
485 GTK_TYPE_STYLE_CONTEXT,
486 GtkStyleContextPrivate);
488 priv->style_data = g_hash_table_new_full (style_info_hash,
490 (GDestroyNotify) style_info_free,
491 (GDestroyNotify) style_data_free);
492 priv->theming_engine = g_object_ref ((gpointer) gtk_theming_engine_load (NULL));
494 priv->direction = GTK_TEXT_DIR_RTL;
496 /* Create default info store */
497 info = style_info_new ();
498 priv->info_stack = g_slist_prepend (priv->info_stack, info);
501 static GtkStyleProviderData *
502 style_provider_data_new (GtkStyleProvider *provider,
505 GtkStyleProviderData *data;
507 data = g_slice_new (GtkStyleProviderData);
508 data->provider = g_object_ref (provider);
509 data->priority = priority;
515 style_provider_data_free (GtkStyleProviderData *data)
517 g_object_unref (data->provider);
518 g_slice_free (GtkStyleProviderData, data);
522 animation_info_free (AnimationInfo *info)
524 g_object_unref (info->timeline);
525 g_object_unref (info->window);
527 if (info->invalidation_region)
528 cairo_region_destroy (info->invalidation_region);
530 g_array_free (info->rectangles, TRUE);
531 g_slice_free (AnimationInfo, info);
535 timeline_frame_cb (GtkTimeline *timeline,
543 if (info->invalidation_region &&
544 !cairo_region_is_empty (info->invalidation_region))
545 gdk_window_invalidate_region (info->window, info->invalidation_region, TRUE);
547 gdk_window_invalidate_rect (info->window, NULL, TRUE);
551 timeline_finished_cb (GtkTimeline *timeline,
554 GtkStyleContextPrivate *priv;
555 GtkStyleContext *context;
560 priv = context->priv;
562 for (l = priv->animations; l; l = l->next)
566 if (info->timeline == timeline)
568 priv->animations = g_slist_delete_link (priv->animations, l);
570 /* Invalidate one last time the area, so the final content is painted */
571 if (info->invalidation_region &&
572 !cairo_region_is_empty (info->invalidation_region))
573 gdk_window_invalidate_region (info->window, info->invalidation_region, TRUE);
575 gdk_window_invalidate_rect (info->window, NULL, TRUE);
577 animation_info_free (info);
583 static AnimationInfo *
584 animation_info_new (GtkStyleContext *context,
587 GtkTimelineProgressType progress_type,
590 gboolean target_value,
595 info = g_slice_new0 (AnimationInfo);
597 info->rectangles = g_array_new (FALSE, FALSE, sizeof (cairo_rectangle_int_t));
598 info->timeline = gtk_timeline_new (duration);
599 info->window = g_object_ref (window);
601 info->target_value = target_value;
602 info->region_id = region_id;
604 gtk_timeline_set_progress_type (info->timeline, progress_type);
605 gtk_timeline_set_loop (info->timeline, loop);
607 if (!loop && !target_value)
609 gtk_timeline_set_direction (info->timeline, GTK_TIMELINE_DIRECTION_BACKWARD);
610 gtk_timeline_rewind (info->timeline);
613 g_signal_connect (info->timeline, "frame",
614 G_CALLBACK (timeline_frame_cb), info);
615 g_signal_connect (info->timeline, "finished",
616 G_CALLBACK (timeline_finished_cb), context);
618 gtk_timeline_start (info->timeline);
623 static AnimationInfo *
624 animation_info_lookup (GtkStyleContext *context,
628 GtkStyleContextPrivate *priv;
631 priv = context->priv;
633 for (l = priv->animations; l; l = l->next)
639 if (info->state == state &&
640 info->region_id == region_id)
648 gtk_style_context_finalize (GObject *object)
650 GtkStyleContextPrivate *priv;
651 GtkStyleContext *style_context;
654 style_context = GTK_STYLE_CONTEXT (object);
655 priv = style_context->priv;
657 if (priv->widget_path)
658 gtk_widget_path_free (priv->widget_path);
660 g_hash_table_destroy (priv->style_data);
662 g_list_foreach (priv->providers, (GFunc) style_provider_data_free, NULL);
663 g_list_free (priv->providers);
665 g_slist_foreach (priv->info_stack, (GFunc) style_info_free, NULL);
666 g_slist_free (priv->info_stack);
668 g_slist_free (priv->animation_regions);
670 for (l = priv->animations; l; l = l->next)
671 animation_info_free ((AnimationInfo *) l->data);
673 g_slist_free (priv->animations);
675 if (priv->theming_engine)
676 g_object_unref (priv->theming_engine);
678 G_OBJECT_CLASS (gtk_style_context_parent_class)->finalize (object);
682 gtk_style_context_impl_set_property (GObject *object,
687 GtkStyleContextPrivate *priv;
688 GtkStyleContext *style_context;
690 style_context = GTK_STYLE_CONTEXT (object);
691 priv = style_context->priv;
696 gtk_style_context_set_screen (style_context,
697 g_value_get_object (value));
700 gtk_style_context_set_direction (style_context,
701 g_value_get_enum (value));
704 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
710 gtk_style_context_impl_get_property (GObject *object,
715 GtkStyleContextPrivate *priv;
716 GtkStyleContext *style_context;
718 style_context = GTK_STYLE_CONTEXT (object);
719 priv = style_context->priv;
724 g_value_set_object (value, priv->screen);
727 g_value_set_enum (value, priv->direction);
730 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
736 find_next_candidate (GList *local,
741 GtkStyleProviderData *local_data, *global_data;
743 local_data = local->data;
744 global_data = global->data;
746 if (local_data->priority < global_data->priority)
760 build_properties (GtkStyleContext *context,
761 StyleData *style_data,
764 GtkStyleContextPrivate *priv;
765 GList *elem, *list, *global_list = NULL;
767 priv = context->priv;
768 list = priv->providers;
771 global_list = g_object_get_qdata (G_OBJECT (priv->screen), provider_list_quark);
773 while ((elem = find_next_candidate (list, global_list)) != NULL)
775 GtkStyleProviderData *data;
776 GtkStyleProperties *provider_style;
783 global_list = global_list->next;
785 provider_style = gtk_style_provider_get_style (data->provider, path);
789 gtk_style_properties_merge (style_data->store, provider_style, TRUE);
790 g_object_unref (provider_style);
796 build_icon_factories (GtkStyleContext *context,
797 StyleData *style_data,
800 GtkStyleContextPrivate *priv;
801 GList *elem, *list, *global_list = NULL;
803 priv = context->priv;
804 list = priv->providers_last;
808 global_list = g_object_get_qdata (G_OBJECT (priv->screen), provider_list_quark);
809 global_list = g_list_last (global_list);
812 while ((elem = find_next_candidate (list, global_list)) != NULL)
814 GtkIconFactory *factory;
815 GtkStyleProviderData *data;
822 global_list = global_list->prev;
824 factory = gtk_style_provider_get_icon_factory (data->provider, path);
827 style_data->icon_factories = g_slist_prepend (style_data->icon_factories, factory);
832 create_query_path (GtkStyleContext *context)
834 GtkStyleContextPrivate *priv;
839 priv = context->priv;
840 path = gtk_widget_path_copy (priv->widget_path);
841 pos = gtk_widget_path_length (path) - 1;
843 info = priv->info_stack->data;
845 /* Set widget regions */
846 for (i = 0; i < info->regions->len; i++)
850 region = &g_array_index (info->regions, GtkRegion, i);
851 gtk_widget_path_iter_add_region (path, pos,
852 g_quark_to_string (region->class_quark),
856 /* Set widget classes */
857 for (i = 0; i < info->style_classes->len; i++)
861 quark = g_array_index (info->style_classes, GQuark, i);
862 gtk_widget_path_iter_add_class (path, pos,
863 g_quark_to_string (quark));
870 style_data_lookup (GtkStyleContext *context)
872 GtkStyleContextPrivate *priv;
875 priv = context->priv;
877 /* Current data in use is cached, just return it */
878 if (priv->current_data)
879 return priv->current_data;
881 g_assert (priv->widget_path != NULL);
883 data = g_hash_table_lookup (priv->style_data, priv->info_stack->data);
889 data = style_data_new ();
890 path = create_query_path (context);
892 build_properties (context, data, path);
893 build_icon_factories (context, data, path);
895 g_hash_table_insert (priv->style_data,
896 style_info_copy (priv->info_stack->data),
899 gtk_widget_path_free (path);
902 priv->current_data = data;
904 if (priv->theming_engine)
905 g_object_unref (priv->theming_engine);
907 gtk_style_properties_get (data->store, 0,
908 "engine", &priv->theming_engine,
914 style_provider_add (GList **list,
915 GtkStyleProvider *provider,
918 GtkStyleProviderData *new_data;
919 gboolean added = FALSE;
922 new_data = style_provider_data_new (provider, priority);
926 GtkStyleProviderData *data;
930 /* Provider was already attached to the style
931 * context, remove in order to add the new data
933 if (data->provider == provider)
940 /* Remove and free link */
941 *list = g_list_remove_link (*list, link);
942 style_provider_data_free (link->data);
943 g_list_free_1 (link);
949 data->priority > priority)
951 *list = g_list_insert_before (*list, l, new_data);
959 *list = g_list_append (*list, new_data);
963 style_provider_remove (GList **list,
964 GtkStyleProvider *provider)
970 GtkStyleProviderData *data;
974 if (data->provider == provider)
976 *list = g_list_remove_link (*list, l);
977 style_provider_data_free (l->data);
990 * gtk_style_context_new:
992 * Creates a standalone #GtkStyleContext, this style context
993 * won't be attached to any widget nor screen, so you may want
994 * to call gtk_style_context_set_path() and
995 * gtk_style_context_set_screen() yourself.
998 * This function is only useful when using the theming layer
999 * separated from GTK+, if you are using #GtkStyleContext to
1000 * theme #GtkWidget<!-- -->s, use gtk_widget_get_style_context()
1001 * in order to get a style context ready to theme the widget.
1004 * Returns: A newly created #GtkStyleContext.
1007 gtk_style_context_new (void)
1009 return g_object_new (GTK_TYPE_STYLE_CONTEXT, NULL);
1013 * gtk_style_context_add_provider:
1014 * @context: a #GtkStyleContext
1015 * @provider: a #GtkStyleProvider
1016 * @priority: the priority of the style provider. The lower
1017 * it is, the earlier it will be used in the style
1018 * construction. Typically this will be in the range
1019 * between %GTK_STYLE_PROVIDER_PRIORITY_FALLBACK and
1020 * %GTK_STYLE_PROVIDER_PRIORITY_USER
1022 * Adds a style provider to @context, to be used in style construction.
1027 gtk_style_context_add_provider (GtkStyleContext *context,
1028 GtkStyleProvider *provider,
1031 GtkStyleContextPrivate *priv;
1033 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
1034 g_return_if_fail (GTK_IS_STYLE_PROVIDER (provider));
1036 priv = context->priv;
1037 style_provider_add (&priv->providers, provider, priority);
1038 priv->providers_last = g_list_last (priv->providers);
1040 gtk_style_context_invalidate (context);
1044 * gtk_style_context_remove_provider:
1045 * @context: a #GtkStyleContext
1046 * @provider: a #GtkStyleProvider
1048 * Removes @provider from the style providers list in @context.
1053 gtk_style_context_remove_provider (GtkStyleContext *context,
1054 GtkStyleProvider *provider)
1056 GtkStyleContextPrivate *priv;
1058 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
1059 g_return_if_fail (GTK_IS_STYLE_PROVIDER (provider));
1061 priv = context->priv;
1063 if (style_provider_remove (&priv->providers, provider))
1065 priv->providers_last = g_list_last (priv->providers);
1067 gtk_style_context_invalidate (context);
1072 * gtk_style_context_reset_widgets:
1073 * @screen: a #GdkScreen
1075 * This function recomputes the styles for all widgets under a particular
1076 * #GdkScreen. This is useful when some global parameter has changed that
1077 * affects the appearance of all widgets, because when a widget gets a new
1078 * style, it will both redraw and recompute any cached information about
1079 * its appearance. As an example, it is used when the color scheme changes
1080 * in the related #GtkSettings object.
1085 gtk_style_context_reset_widgets (GdkScreen *screen)
1087 GList *list, *toplevels;
1089 toplevels = gtk_window_list_toplevels ();
1090 g_list_foreach (toplevels, (GFunc) g_object_ref, NULL);
1092 for (list = toplevels; list; list = list->next)
1094 if (gtk_widget_get_screen (list->data) == screen)
1095 gtk_widget_reset_style (list->data);
1097 g_object_unref (list->data);
1100 g_list_free (toplevels);
1104 * gtk_style_context_add_provider_for_screen:
1105 * @screen: a #GdkScreen
1106 * @provider: a #GtkStyleProvider
1107 * @priority: the priority of the style provider. The lower
1108 * it is, the earlier it will be used in the style
1109 * construction. Typically this will be in the range
1110 * between %GTK_STYLE_PROVIDER_PRIORITY_FALLBACK and
1111 * %GTK_STYLE_PROVIDER_PRIORITY_USER
1113 * Adds a global style provider to @screen, which will be used
1114 * in style construction for all #GtkStyleContext<!-- -->s under
1120 gtk_style_context_add_provider_for_screen (GdkScreen *screen,
1121 GtkStyleProvider *provider,
1124 GList *providers, *list;
1126 g_return_if_fail (GDK_IS_SCREEN (screen));
1127 g_return_if_fail (GTK_IS_STYLE_PROVIDER (provider));
1129 if (G_UNLIKELY (!provider_list_quark))
1130 provider_list_quark = g_quark_from_static_string ("gtk-provider-list-quark");
1132 list = providers = g_object_get_qdata (G_OBJECT (screen), provider_list_quark);
1133 style_provider_add (&list, provider, priority);
1135 if (list != providers)
1136 g_object_set_qdata (G_OBJECT (screen), provider_list_quark, list);
1138 gtk_style_context_reset_widgets (screen);
1142 * gtk_style_context_remove_provider_for_screen:
1143 * @screen: a #GdkScreen
1144 * @provider: a #GtkStyleProvider
1146 * Removes @provider from the global style providers list in @screen.
1151 gtk_style_context_remove_provider_for_screen (GdkScreen *screen,
1152 GtkStyleProvider *provider)
1154 GList *providers, *list;
1156 g_return_if_fail (GDK_IS_SCREEN (screen));
1157 g_return_if_fail (GTK_IS_STYLE_PROVIDER (provider));
1159 if (G_UNLIKELY (!provider_list_quark))
1162 list = providers = g_object_get_qdata (G_OBJECT (screen), provider_list_quark);
1164 if (style_provider_remove (&list, provider))
1166 if (list != providers)
1167 g_object_set_qdata (G_OBJECT (screen), provider_list_quark, list);
1169 gtk_style_context_reset_widgets (screen);
1174 * gtk_style_context_get_property:
1175 * @context: a #GtkStyleContext
1176 * @property: style property name
1177 * @state: state to retrieve the property value for
1178 * @value: (out) (transfer full): return location for the style property value.
1180 * Gets a style property from @context for the given state. When done with @value,
1181 * g_value_unset() needs to be called to free any allocated memory.
1186 gtk_style_context_get_property (GtkStyleContext *context,
1187 const gchar *property,
1188 GtkStateFlags state,
1191 GtkStyleContextPrivate *priv;
1194 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
1195 g_return_if_fail (property != NULL);
1196 g_return_if_fail (value != NULL);
1198 priv = context->priv;
1200 g_return_if_fail (priv->widget_path != NULL);
1202 data = style_data_lookup (context);
1203 gtk_style_properties_get_property (data->store, property, state, value);
1207 * gtk_style_context_get_valist:
1208 * @context: a #GtkStyleContext
1209 * @state: state to retrieve the property values for
1210 * @args: va_list of property name/return location pairs, followed by %NULL
1212 * Retrieves several style property values from @context for a given state.
1217 gtk_style_context_get_valist (GtkStyleContext *context,
1218 GtkStateFlags state,
1221 GtkStyleContextPrivate *priv;
1224 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
1226 priv = context->priv;
1227 g_return_if_fail (priv->widget_path != NULL);
1229 data = style_data_lookup (context);
1230 gtk_style_properties_get_valist (data->store, state, args);
1234 * gtk_style_context_get:
1235 * @context: a #GtkStyleContext
1236 * @state: state to retrieve the property values for
1237 * @...: property name /return value pairs, followed by %NULL
1239 * Retrieves several style property values from @context for a
1245 gtk_style_context_get (GtkStyleContext *context,
1246 GtkStateFlags state,
1249 GtkStyleContextPrivate *priv;
1253 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
1255 priv = context->priv;
1256 g_return_if_fail (priv->widget_path != NULL);
1258 data = style_data_lookup (context);
1260 va_start (args, state);
1261 gtk_style_properties_get_valist (data->store, state, args);
1266 * gtk_style_context_set_state:
1267 * @context: a #GtkStyleContext
1268 * @flags: state to represent
1270 * Sets the style to be used when rendering with any
1271 * of the "gtk_render_" prefixed functions.
1276 gtk_style_context_set_state (GtkStyleContext *context,
1277 GtkStateFlags flags)
1279 GtkStyleContextPrivate *priv;
1282 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
1284 priv = context->priv;
1285 info = priv->info_stack->data;
1286 info->state_flags = flags;
1290 * gtk_style_context_get_state:
1291 * @context: a #GtkStyleContext
1293 * returns the state used when rendering.
1295 * Returns: the state flags
1300 gtk_style_context_get_state (GtkStyleContext *context)
1302 GtkStyleContextPrivate *priv;
1305 g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), 0);
1307 priv = context->priv;
1308 info = priv->info_stack->data;
1310 return info->state_flags;
1314 context_has_animatable_region (GtkStyleContext *context,
1317 GtkStyleContextPrivate *priv;
1320 /* NULL region_id means everything
1321 * rendered through the style context
1326 priv = context->priv;
1328 for (r = priv->animation_regions; r; r = r->next)
1330 if (r->data == region_id)
1338 * gtk_style_context_state_is_running:
1339 * @context: a #GtkStyleContext
1340 * @state: a widget state
1341 * @progress: (out): return location for the transition progress
1343 * Returns %TRUE if there is a transition animation running for the
1344 * current region (see gtk_style_context_push_animatable_region()).
1346 * If @progress is not %NULL, the animation progress will be returned
1347 * there, 0.0 means the state is closest to being %FALSE, while 1.0 means
1348 * it's closest to being %TRUE. This means transition animations will
1349 * run from 0 to 1 when @state is being set to %TRUE and from 1 to 0 when
1350 * it's being set to %FALSE.
1352 * Returns: %TRUE if there is a running transition animation for @state.
1357 gtk_style_context_state_is_running (GtkStyleContext *context,
1361 GtkStyleContextPrivate *priv;
1362 AnimationInfo *info;
1365 g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), FALSE);
1367 priv = context->priv;
1369 for (l = priv->animations; l; l = l->next)
1373 if (info->state == state &&
1374 context_has_animatable_region (context, info->region_id))
1377 *progress = gtk_timeline_get_progress (info->timeline);
1387 * gtk_style_context_set_path:
1388 * @context: a #GtkStyleContext
1389 * @path: a #GtkWidgetPath
1391 * Sets the #GtkWidgetPath used for style matching. As a
1392 * consequence, the style will be regenerated to match
1393 * the new given path. If you are using a #GtkStyleContext
1394 * returned from gtk_widget_get_style_context(), you do
1395 * not need to call this yourself.
1400 gtk_style_context_set_path (GtkStyleContext *context,
1401 GtkWidgetPath *path)
1403 GtkStyleContextPrivate *priv;
1405 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
1406 g_return_if_fail (path != NULL);
1408 priv = context->priv;
1410 if (priv->widget_path)
1412 gtk_widget_path_free (priv->widget_path);
1413 priv->widget_path = NULL;
1417 priv->widget_path = gtk_widget_path_copy (path);
1419 gtk_style_context_invalidate (context);
1423 * gtk_style_context_get_path:
1424 * @context: a #GtkStyleContext
1426 * Returns the widget path used for style matching.
1428 * Returns: (transfer none): A #GtkWidgetPath
1432 G_CONST_RETURN GtkWidgetPath *
1433 gtk_style_context_get_path (GtkStyleContext *context)
1435 GtkStyleContextPrivate *priv;
1437 priv = context->priv;
1438 return priv->widget_path;
1442 * gtk_style_context_save:
1443 * @context: a #GtkStyleContext
1445 * Saves the @context state, so all modifications done through
1446 * gtk_style_context_add_class(), gtk_style_context_remove_class(),
1447 * gtk_style_context_add_region(), gtk_style_context_remove_region()
1448 * or gtk_style_context_set_junction_sides() can be reverted in one
1449 * go through gtk_style_context_restore().
1454 gtk_style_context_save (GtkStyleContext *context)
1456 GtkStyleContextPrivate *priv;
1459 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
1461 priv = context->priv;
1463 g_assert (priv->info_stack != NULL);
1465 info = style_info_copy (priv->info_stack->data);
1466 priv->info_stack = g_slist_prepend (priv->info_stack, info);
1470 * gtk_style_context_restore:
1471 * @context: a #GtkStyleContext
1473 * Restores @context state to a previous stage. See
1474 * gtk_style_context_save().
1479 gtk_style_context_restore (GtkStyleContext *context)
1481 GtkStyleContextPrivate *priv;
1484 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
1486 priv = context->priv;
1488 if (priv->info_stack)
1490 info = priv->info_stack->data;
1491 priv->info_stack = g_slist_remove (priv->info_stack, info);
1492 style_info_free (info);
1495 if (!priv->info_stack)
1497 g_warning ("Unpaired gtk_style_context_restore() call");
1499 /* Create default region */
1500 info = style_info_new ();
1501 priv->info_stack = g_slist_prepend (priv->info_stack, info);
1504 priv->current_data = NULL;
1508 style_class_find (GArray *array,
1513 gboolean found = FALSE;
1519 if (!array || array->len == 0)
1523 max = array->len - 1;
1529 mid = (min + max) / 2;
1530 item = g_array_index (array, GQuark, mid);
1532 if (class_quark == item)
1537 else if (class_quark > item)
1538 min = pos = mid + 1;
1545 while (!found && min <= max);
1554 region_find (GArray *array,
1559 gboolean found = FALSE;
1565 if (!array || array->len == 0)
1569 max = array->len - 1;
1575 mid = (min + max) / 2;
1576 region = &g_array_index (array, GtkRegion, mid);
1578 if (region->class_quark == class_quark)
1583 else if (region->class_quark > class_quark)
1584 min = pos = mid + 1;
1591 while (!found && min <= max);
1600 * gtk_style_context_add_class:
1601 * @context: a #GtkStyleContext
1602 * @class_name: class name to use in styling
1604 * Sets a class name to @context, so posterior calls to
1605 * gtk_style_context_get() or any of the gtk_render_*
1606 * functions will make use of this new class for styling.
1608 * In the CSS file format, a #GtkEntry defining an "entry"
1609 * class, would be matched by:
1612 * GtkEntry.entry { ... }
1615 * While any widget defining an "entry" class would be
1624 gtk_style_context_add_class (GtkStyleContext *context,
1625 const gchar *class_name)
1627 GtkStyleContextPrivate *priv;
1632 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
1633 g_return_if_fail (class_name != NULL);
1635 priv = context->priv;
1636 class_quark = g_quark_from_string (class_name);
1638 g_assert (priv->info_stack != NULL);
1639 info = priv->info_stack->data;
1641 if (!style_class_find (info->style_classes, class_quark, &position))
1643 g_array_insert_val (info->style_classes, position, class_quark);
1645 /* Unset current data, as it likely changed due to the class change */
1646 priv->current_data = NULL;
1651 * gtk_style_context_remove_class:
1652 * @context: a #GtkStyleContext
1653 * @class_name: class name to remove
1655 * Removes @class_name from @context.
1660 gtk_style_context_remove_class (GtkStyleContext *context,
1661 const gchar *class_name)
1663 GtkStyleContextPrivate *priv;
1668 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
1669 g_return_if_fail (class_name != NULL);
1671 class_quark = g_quark_try_string (class_name);
1676 priv = context->priv;
1678 g_assert (priv->info_stack != NULL);
1679 info = priv->info_stack->data;
1681 if (style_class_find (info->style_classes, class_quark, &position))
1683 g_array_remove_index (info->style_classes, position);
1685 /* Unset current data, as it likely changed due to the class change */
1686 priv->current_data = NULL;
1691 * gtk_style_context_has_class:
1692 * @context: a #GtkStyleContext
1693 * @class_name: a class name
1695 * Returns %TRUE if @context currently has defined the
1698 * Returns: %TRUE if @context has @class_name defined
1703 gtk_style_context_has_class (GtkStyleContext *context,
1704 const gchar *class_name)
1706 GtkStyleContextPrivate *priv;
1710 g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), FALSE);
1711 g_return_val_if_fail (class_name != NULL, FALSE);
1713 class_quark = g_quark_try_string (class_name);
1718 priv = context->priv;
1720 g_assert (priv->info_stack != NULL);
1721 info = priv->info_stack->data;
1723 if (style_class_find (info->style_classes, class_quark, NULL))
1730 * gtk_style_context_list_classes:
1731 * @context: a #GtkStyleContext
1733 * Returns the list of classes currently defined in @context.
1735 * Returns: (transfer container) (element-type utf8): a #GList of
1736 * strings with the currently defined classes. The contents
1737 * of the list are owned by GTK+, but you must free the list
1738 * itself with g_list_free() when you are done with it.
1743 gtk_style_context_list_classes (GtkStyleContext *context)
1745 GtkStyleContextPrivate *priv;
1747 GList *classes = NULL;
1750 g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), NULL);
1752 priv = context->priv;
1754 g_assert (priv->info_stack != NULL);
1755 info = priv->info_stack->data;
1757 for (i = 0; i < info->style_classes->len; i++)
1761 quark = g_array_index (info->style_classes, GQuark, i);
1762 classes = g_list_prepend (classes, (gchar *) g_quark_to_string (quark));
1769 * gtk_style_context_list_regions:
1770 * @context: a #GtkStyleContext
1773 * Returns the list of regions currently defined in @context.
1775 * Returns: (transfer container) (element-type utf8): a #GList of
1776 * strings with the currently defined regions. The contents
1777 * of the list are owned by GTK+, but you must free the list
1778 * itself with g_list_free() when you are done with it.
1783 gtk_style_context_list_regions (GtkStyleContext *context)
1785 GtkStyleContextPrivate *priv;
1787 GList *classes = NULL;
1790 g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), NULL);
1792 priv = context->priv;
1794 g_assert (priv->info_stack != NULL);
1795 info = priv->info_stack->data;
1797 for (i = 0; i < info->regions->len; i++)
1800 const gchar *class_name;
1802 region = &g_array_index (info->regions, GtkRegion, i);
1804 class_name = g_quark_to_string (region->class_quark);
1805 classes = g_list_prepend (classes, (gchar *) class_name);
1812 * gtk_style_context_add_region:
1813 * @context: a #GtkStyleContext
1814 * @region_name: region name to use in styling
1815 * @flags: flags that apply to the region
1817 * Sets a region to @context, so posterior calls to
1818 * gtk_style_context_get() or any of the gtk_render_*
1819 * functions will make use of this new region for styling.
1821 * In the CSS file format, a #GtkTreeView defining a "row"
1822 * region, would be matched by:
1825 * GtkTreeView row { ... }
1828 * pseudo-classes are used for matching @flags, so the two
1831 * GtkTreeView row:nth-child (even) { ... }
1832 * GtkTreeView row:nth-child (odd) { ... }
1835 * would apply to even and odd rows, respectively.
1840 gtk_style_context_add_region (GtkStyleContext *context,
1841 const gchar *region_name,
1842 GtkRegionFlags flags)
1844 GtkStyleContextPrivate *priv;
1846 GQuark region_quark;
1849 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
1850 g_return_if_fail (region_name != NULL);
1852 priv = context->priv;
1853 region_quark = g_quark_from_string (region_name);
1855 g_assert (priv->info_stack != NULL);
1856 info = priv->info_stack->data;
1858 if (!region_find (info->regions, region_quark, &position))
1862 region.class_quark = region_quark;
1863 region.flags = flags;
1865 g_array_insert_val (info->regions, position, region);
1867 /* Unset current data, as it likely changed due to the region change */
1868 priv->current_data = NULL;
1873 * gtk_style_context_remove_region:
1874 * @context: a #GtkStyleContext
1875 * @region_name: region name to unset
1877 * Removes a region from @context
1882 gtk_style_context_remove_region (GtkStyleContext *context,
1883 const gchar *region_name)
1885 GtkStyleContextPrivate *priv;
1887 GQuark region_quark;
1890 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
1891 g_return_if_fail (region_name != NULL);
1893 region_quark = g_quark_try_string (region_name);
1898 priv = context->priv;
1900 g_assert (priv->info_stack != NULL);
1901 info = priv->info_stack->data;
1903 if (region_find (info->regions, region_quark, &position))
1905 g_array_remove_index (info->regions, position);
1907 /* Unset current data, as it likely changed due to the region change */
1908 priv->current_data = NULL;
1913 * gtk_style_context_has_region:
1914 * @context: a #GtkStyleContext
1915 * @region_name: a region name
1916 * @flags_return: (out) (allow-none): return location for region flags
1918 * Returns %TRUE if @context has the region defined. If @flags_return is
1919 * not %NULL, it is set to the flags affecting the region.
1921 * Returns: %TRUE if region is defined
1926 gtk_style_context_has_region (GtkStyleContext *context,
1927 const gchar *region_name,
1928 GtkRegionFlags *flags_return)
1930 GtkStyleContextPrivate *priv;
1932 GQuark region_quark;
1935 g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), FALSE);
1936 g_return_val_if_fail (region_name != NULL, FALSE);
1941 region_quark = g_quark_try_string (region_name);
1946 priv = context->priv;
1948 g_assert (priv->info_stack != NULL);
1949 info = priv->info_stack->data;
1951 if (region_find (info->regions, region_quark, &position))
1957 region = &g_array_index (info->regions, GtkRegion, position);
1958 *flags_return = region->flags;
1967 style_property_values_cmp (gconstpointer bsearch_node1,
1968 gconstpointer bsearch_node2)
1970 const PropertyValue *val1 = bsearch_node1;
1971 const PropertyValue *val2 = bsearch_node2;
1973 if (val1->widget_type == val2->widget_type)
1974 return val1->pspec < val2->pspec ? -1 : val1->pspec == val2->pspec ? 0 : 1;
1976 return val1->widget_type < val2->widget_type ? -1 : 1;
1980 _gtk_style_context_peek_style_property (GtkStyleContext *context,
1984 GtkStyleContextPrivate *priv;
1985 PropertyValue *pcache, key = { 0 };
1986 GList *global_list = NULL;
1990 priv = context->priv;
1991 data = style_data_lookup (context);
1993 key.widget_type = widget_type;
1996 /* need value cache array */
1997 if (!data->property_cache)
1998 data->property_cache = g_array_new (FALSE, FALSE, sizeof (PropertyValue));
2001 pcache = bsearch (&key,
2002 data->property_cache->data, data->property_cache->len,
2003 sizeof (PropertyValue), style_property_values_cmp);
2005 return &pcache->value;
2009 while (i < data->property_cache->len &&
2010 style_property_values_cmp (&key, &g_array_index (data->property_cache, PropertyValue, i)) >= 0)
2013 g_array_insert_val (data->property_cache, i, key);
2014 pcache = &g_array_index (data->property_cache, PropertyValue, i);
2016 /* cache miss, initialize value type, then set contents */
2017 g_param_spec_ref (pcache->pspec);
2018 g_value_init (&pcache->value, G_PARAM_SPEC_VALUE_TYPE (pspec));
2022 global_list = g_object_get_qdata (G_OBJECT (priv->screen), provider_list_quark);
2023 global_list = g_list_last (global_list);
2026 if (priv->widget_path)
2028 GList *list, *global, *elem;
2030 list = priv->providers_last;
2031 global = global_list;
2033 while ((elem = find_next_candidate (list, global)) != NULL)
2035 GtkStyleProviderData *provider_data;
2037 provider_data = elem->data;
2042 global = global->prev;
2044 if (gtk_style_provider_get_style_property (provider_data->provider,
2045 priv->widget_path, pspec,
2048 /* Resolve symbolic colors to GdkColor/GdkRGBA */
2049 if (G_VALUE_TYPE (&pcache->value) == GTK_TYPE_SYMBOLIC_COLOR)
2051 GtkSymbolicColor *color;
2054 color = g_value_get_boxed (&pcache->value);
2056 if (gtk_symbolic_color_resolve (color, data->store, &rgba))
2058 g_value_unset (&pcache->value);
2060 if (G_PARAM_SPEC_VALUE_TYPE (pspec) == GDK_TYPE_RGBA)
2062 g_value_init (&pcache->value, GDK_TYPE_RGBA);
2063 g_value_set_boxed (&pcache->value, &rgba);
2069 rgb.red = rgba.red * 65535. + 0.5;
2070 rgb.green = rgba.green * 65535. + 0.5;
2071 rgb.blue = rgba.blue * 65535. + 0.5;
2073 g_value_init (&pcache->value, GDK_TYPE_COLOR);
2074 g_value_set_boxed (&pcache->value, &rgb);
2078 g_param_value_set_default (pspec, &pcache->value);
2081 return &pcache->value;
2086 /* not supplied by any provider, revert to default */
2087 g_param_value_set_default (pspec, &pcache->value);
2089 return &pcache->value;
2093 * gtk_style_context_get_style_property:
2094 * @context: a #GtkStyleContext
2095 * @property_name: the name of the widget style property
2096 * @value: (out) (transfer full): Return location for the property value, free with
2097 * g_value_unset() after use.
2099 * Gets the value for a widget style property.
2102 gtk_style_context_get_style_property (GtkStyleContext *context,
2103 const gchar *property_name,
2106 GtkStyleContextPrivate *priv;
2107 GtkWidgetClass *widget_class;
2109 const GValue *peek_value;
2112 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
2113 g_return_if_fail (property_name != NULL);
2114 g_return_if_fail (value != NULL);
2116 priv = context->priv;
2118 if (!priv->widget_path)
2121 widget_type = gtk_widget_path_get_widget_type (priv->widget_path);
2123 widget_class = g_type_class_ref (widget_type);
2124 pspec = gtk_widget_class_find_style_property (widget_class, property_name);
2125 g_type_class_unref (widget_class);
2129 g_warning ("%s: widget class `%s' has no style property named `%s'",
2131 g_type_name (widget_type),
2136 peek_value = _gtk_style_context_peek_style_property (context,
2140 if (G_VALUE_TYPE (value) == G_VALUE_TYPE (peek_value))
2141 g_value_copy (peek_value, value);
2142 else if (g_value_type_transformable (G_VALUE_TYPE (peek_value), G_VALUE_TYPE (value)))
2143 g_value_transform (peek_value, value);
2145 g_warning ("can't retrieve style property `%s' of type `%s' as value of type `%s'",
2147 G_VALUE_TYPE_NAME (peek_value),
2148 G_VALUE_TYPE_NAME (value));
2152 * gtk_style_context_get_style_valist:
2153 * @context: a #GtkStyleContext
2154 * @args: va_list of property name/return location pairs, followed by %NULL
2156 * Retrieves several widget style properties from @context according to the
2162 gtk_style_context_get_style_valist (GtkStyleContext *context,
2165 GtkStyleContextPrivate *priv;
2166 const gchar *prop_name;
2168 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
2170 prop_name = va_arg (args, const gchar *);
2171 priv = context->priv;
2173 if (!priv->widget_path)
2178 GtkWidgetClass *widget_class;
2180 const GValue *peek_value;
2184 widget_type = gtk_widget_path_get_widget_type (priv->widget_path);
2186 widget_class = g_type_class_ref (widget_type);
2187 pspec = gtk_widget_class_find_style_property (widget_class, prop_name);
2188 g_type_class_unref (widget_class);
2192 g_warning ("%s: widget class `%s' has no style property named `%s'",
2194 g_type_name (widget_type),
2199 peek_value = _gtk_style_context_peek_style_property (context,
2203 G_VALUE_LCOPY (peek_value, args, 0, &error);
2207 g_warning ("can't retrieve style property `%s' of type `%s': %s",
2209 G_VALUE_TYPE_NAME (peek_value),
2214 prop_name = va_arg (args, const gchar *);
2219 * gtk_style_context_get_style:
2220 * @context: a #GtkStyleContext
2221 * @...: property name /return value pairs, followed by %NULL
2223 * Retrieves several widget style properties from @context according to the
2229 gtk_style_context_get_style (GtkStyleContext *context,
2234 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
2236 va_start (args, context);
2237 gtk_style_context_get_style_valist (context, args);
2243 * gtk_style_context_lookup_icon_set:
2244 * @context: a #GtkStyleContext
2245 * @stock_id: an icon name
2247 * Looks up @stock_id in the icon factories associated to @context and
2248 * the default icon factory, returning an icon set if found, otherwise
2251 * Returns: (transfer none): The looked up %GtkIconSet, or %NULL
2254 gtk_style_context_lookup_icon_set (GtkStyleContext *context,
2255 const gchar *stock_id)
2257 GtkStyleContextPrivate *priv;
2261 g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), NULL);
2262 g_return_val_if_fail (stock_id != NULL, NULL);
2264 priv = context->priv;
2265 g_return_val_if_fail (priv->widget_path != NULL, NULL);
2267 data = style_data_lookup (context);
2269 for (list = data->icon_factories; list; list = list->next)
2271 GtkIconFactory *factory;
2272 GtkIconSet *icon_set;
2274 factory = list->data;
2275 icon_set = gtk_icon_factory_lookup (factory, stock_id);
2281 return gtk_icon_factory_lookup_default (stock_id);
2285 * gtk_style_context_set_screen:
2286 * @context: a #GtkStyleContext
2287 * @screen: a #GdkScreen
2289 * Sets the screen to which @context will be attached to, @screen
2290 * is used in order to reconstruct style based on the global providers
2291 * list. If you are using a #GtkStyleContext returned from
2292 * gtk_widget_get_style_context(), you do not need to call this yourself.
2297 gtk_style_context_set_screen (GtkStyleContext *context,
2300 GtkStyleContextPrivate *priv;
2302 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
2304 priv = context->priv;
2305 priv->screen = screen;
2307 g_object_notify (G_OBJECT (context), "screen");
2309 gtk_style_context_invalidate (context);
2313 * gtk_style_context_get_screen:
2314 * @context: a #GtkStyleContext
2316 * Returns the #GdkScreen to which @context is attached to.
2318 * Returns: a #GdkScreen, or %NULL.
2321 gtk_style_context_get_screen (GtkStyleContext *context)
2323 GtkStyleContextPrivate *priv;
2325 g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), NULL);
2327 priv = context->priv;
2328 return priv->screen;
2332 * gtk_style_context_set_direction:
2333 * @context: a #GtkStyleContext
2334 * @direction: the new direction.
2336 * Sets the reading direction for rendering purposes. If you are
2337 * using a #GtkStyleContext returned from gtk_widget_get_style_context(),
2338 * you do not need to call this yourself.
2343 gtk_style_context_set_direction (GtkStyleContext *context,
2344 GtkTextDirection direction)
2346 GtkStyleContextPrivate *priv;
2348 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
2350 priv = context->priv;
2351 priv->direction = direction;
2353 g_object_notify (G_OBJECT (context), "direction");
2357 * gtk_style_context_get_direction:
2358 * @context: a #GtkStyleContext
2360 * Returns the widget direction used for rendering.
2362 * Returns: the widget direction
2367 gtk_style_context_get_direction (GtkStyleContext *context)
2369 GtkStyleContextPrivate *priv;
2371 g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), GTK_TEXT_DIR_LTR);
2373 priv = context->priv;
2374 return priv->direction;
2378 * gtk_style_context_set_junction_sides:
2379 * @context: a #GtkStyleContext
2380 * @sides: sides where rendered elements are visually connected to other elements.
2382 * Sets the sides where rendered elements (mostly through gtk_render_frame()) will
2383 * visually connect with other visual elements. This is merely a guideline that may
2384 * be honored or not in theming engines.
2389 gtk_style_context_set_junction_sides (GtkStyleContext *context,
2390 GtkJunctionSides sides)
2392 GtkStyleContextPrivate *priv;
2395 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
2397 priv = context->priv;
2398 info = priv->info_stack->data;
2399 info->junction_sides = sides;
2403 * gtk_style_context_get_junction_sides:
2404 * @context: a #GtkStyleContext
2406 * Returns the sides where rendered elements connect visually with others.
2408 * Returns: the junction sides
2413 gtk_style_context_get_junction_sides (GtkStyleContext *context)
2415 GtkStyleContextPrivate *priv;
2418 g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), 0);
2420 priv = context->priv;
2421 info = priv->info_stack->data;
2422 return info->junction_sides;
2426 * gtk_style_context_lookup_color:
2427 * @context: a #GtkStyleContext
2428 * @color_name: color name to lookup
2429 * @color: (out): Return location for the looked up color
2431 * Looks up and resolves a color name in the @context color map.
2433 * Returns: %TRUE if @color_name was found and resolved, %FALSE otherwise
2436 gtk_style_context_lookup_color (GtkStyleContext *context,
2437 const gchar *color_name,
2440 GtkStyleContextPrivate *priv;
2441 GtkSymbolicColor *sym_color;
2444 g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), FALSE);
2445 g_return_val_if_fail (color_name != NULL, FALSE);
2446 g_return_val_if_fail (color != NULL, FALSE);
2448 priv = context->priv;
2449 g_return_val_if_fail (priv->widget_path != NULL, FALSE);
2451 data = style_data_lookup (context);
2452 sym_color = gtk_style_properties_lookup_color (data->store, color_name);
2457 return gtk_symbolic_color_resolve (sym_color, data->store, color);
2461 * gtk_style_context_notify_state_change:
2462 * @context: a #GtkStyleContext
2463 * @window: a #GdkWindow
2464 * @region_id: (allow-none): animatable region to notify on, or %NULL.
2465 * See gtk_style_context_push_animatable_region()
2466 * @state: state to trigger transition for
2467 * @state_value: target value of @state
2469 * Notifies a state change on @context, so if the current style makes use
2470 * of transition animations, one will be started so all rendered elements
2471 * under @region_id are animated for state @state being set to value @state_value.
2473 * The @window parameter is used in order to invalidate the rendered area
2474 * as the animation runs, so make sure it is the same window that is being
2475 * rendered on by the gtk_render_*() methods.
2477 * If @region_id is %NULL, all rendered elements using @context will be
2478 * affected by this state transition.
2480 * As a practical example, a #GtkButton notifying a state transition on
2481 * the prelight state:
2483 * gtk_style_context_notify_state_change (context,
2484 * gtk_widget_get_window (widget),
2485 * NULL, GTK_STATE_PRELIGHT,
2486 * button->in_button);
2489 * Could be handled in the CSS file like this:
2492 * background-color: #f00;
2496 * background-color: #fff;
2497 * transition: 200ms linear;
2501 * This combination would animate the button background from red to white
2502 * if a pointer enters the button, and back to red if the pointer leaves
2508 gtk_style_context_notify_state_change (GtkStyleContext *context,
2512 gboolean state_value)
2514 GtkStyleContextPrivate *priv;
2515 GtkAnimationDescription *desc;
2516 AnimationInfo *info;
2517 GtkStateFlags flags;
2520 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
2521 g_return_if_fail (GDK_IS_WINDOW (window));
2522 g_return_if_fail (state > GTK_STATE_NORMAL && state <= GTK_STATE_FOCUSED);
2524 priv = context->priv;
2525 g_return_if_fail (priv->widget_path != NULL);
2527 state_value = (state_value == TRUE);
2531 case GTK_STATE_ACTIVE:
2532 flags = GTK_STATE_FLAG_ACTIVE;
2534 case GTK_STATE_PRELIGHT:
2535 flags = GTK_STATE_FLAG_PRELIGHT;
2537 case GTK_STATE_SELECTED:
2538 flags = GTK_STATE_FLAG_SELECTED;
2540 case GTK_STATE_INSENSITIVE:
2541 flags = GTK_STATE_FLAG_INSENSITIVE;
2543 case GTK_STATE_INCONSISTENT:
2544 flags = GTK_STATE_FLAG_INCONSISTENT;
2546 case GTK_STATE_FOCUSED:
2547 flags = GTK_STATE_FLAG_FOCUSED;
2549 case GTK_STATE_NORMAL:
2555 /* Find out if there is any animation description for the given
2556 * state, it will fallback to the normal state as well if necessary.
2558 data = style_data_lookup (context);
2559 gtk_style_properties_get (data->store, flags,
2560 "transition", &desc,
2566 if (gtk_animation_description_get_duration (desc) == 0)
2568 gtk_animation_description_unref (desc);
2572 info = animation_info_lookup (context, region_id, state);
2575 info->target_value != state_value)
2577 /* Target values are the opposite */
2578 if (!gtk_timeline_get_loop (info->timeline))
2580 /* Reverse the animation */
2581 if (gtk_timeline_get_direction (info->timeline) == GTK_TIMELINE_DIRECTION_FORWARD)
2582 gtk_timeline_set_direction (info->timeline, GTK_TIMELINE_DIRECTION_BACKWARD);
2584 gtk_timeline_set_direction (info->timeline, GTK_TIMELINE_DIRECTION_FORWARD);
2586 info->target_value = state_value;
2590 /* Take it out of its looping state */
2591 gtk_timeline_set_loop (info->timeline, FALSE);
2596 info = animation_info_new (context, region_id,
2597 gtk_animation_description_get_duration (desc),
2598 gtk_animation_description_get_progress_type (desc),
2599 gtk_animation_description_get_loop (desc),
2600 state, state_value, window);
2602 priv->animations = g_slist_prepend (priv->animations, info);
2603 priv->animations_invalidated = TRUE;
2606 gtk_animation_description_unref (desc);
2610 * gtk_style_context_push_animatable_region:
2611 * @context: a #GtkStyleContext
2612 * @region_id: unique identifier for the animatable region
2614 * Pushes an animatable region, so all further gtk_render_*() calls between
2615 * this call and the following gtk_style_context_pop_animatable_region() will
2616 * potentially show transition animations for if gtk_style_context_notify_state_change()
2617 * is called for a given state, and the theme/style used contemplates the use of
2618 * transition animations for state changes.
2620 * The @region_id used must be unique in @context so the theming engine may
2621 * univocally identify rendered elements subject to a state transition.
2626 gtk_style_context_push_animatable_region (GtkStyleContext *context,
2629 GtkStyleContextPrivate *priv;
2631 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
2632 g_return_if_fail (region_id != NULL);
2634 priv = context->priv;
2635 priv->animation_regions = g_slist_prepend (priv->animation_regions, region_id);
2639 * gtk_style_context_pop_animatable_region:
2640 * @context: a #GtkStyleContext
2642 * Pops an animatable region from @context. See gtk_style_context_push_animatable_region().
2647 gtk_style_context_pop_animatable_region (GtkStyleContext *context)
2649 GtkStyleContextPrivate *priv;
2651 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
2653 priv = context->priv;
2654 priv->animation_regions = g_slist_delete_link (priv->animation_regions,
2655 priv->animation_regions);
2659 _gtk_style_context_invalidate_animation_areas (GtkStyleContext *context)
2661 GtkStyleContextPrivate *priv;
2664 priv = context->priv;
2666 for (l = priv->animations; l; l = l->next)
2668 AnimationInfo *info;
2672 /* A NULL invalidation region means it has to be recreated on
2673 * the next expose event, this happens usually after a widget
2674 * allocation change, so the next expose after it will update
2675 * the invalidation region.
2677 if (info->invalidation_region)
2679 cairo_region_destroy (info->invalidation_region);
2680 info->invalidation_region = NULL;
2684 priv->animations_invalidated = TRUE;
2688 _gtk_style_context_coalesce_animation_areas (GtkStyleContext *context,
2692 GtkStyleContextPrivate *priv;
2695 priv = context->priv;
2697 if (!priv->animations_invalidated)
2700 for (l = priv->animations; l; l = l->next)
2702 AnimationInfo *info;
2707 if (info->invalidation_region)
2710 /* FIXME: If this happens there's not much
2711 * point in keeping the animation running.
2713 if (info->rectangles->len == 0)
2716 info->invalidation_region = cairo_region_create ();
2718 for (i = 0; i <info->rectangles->len; i++)
2720 cairo_rectangle_int_t *rect;
2722 rect = &g_array_index (info->rectangles, cairo_rectangle_int_t, i);
2726 cairo_region_union_rectangle (info->invalidation_region, rect);
2729 g_array_remove_range (info->rectangles, 0, info->rectangles->len);
2732 priv->animations_invalidated = FALSE;
2736 store_animation_region (GtkStyleContext *context,
2742 GtkStyleContextPrivate *priv;
2745 priv = context->priv;
2747 if (!priv->animations_invalidated)
2750 for (l = priv->animations; l; l = l->next)
2752 AnimationInfo *info;
2756 /* The animation doesn't need updatring
2757 * the invalidation area, bail out.
2759 if (info->invalidation_region)
2762 if (context_has_animatable_region (context, info->region_id))
2764 cairo_rectangle_int_t rect;
2768 rect.width = (gint) width;
2769 rect.height = (gint) height;
2771 g_array_append_val (info->rectangles, rect);
2777 * gtk_style_context_invalidate:
2778 * @context: a #GtkStyleContext.
2780 * Invalidates @context style information, so it will be reconstructed
2781 * again. If you're using a #GtkStyleContext returned from
2782 * gtk_widget_get_style_context(), you do not need to call this yourself.
2787 gtk_style_context_invalidate (GtkStyleContext *context)
2789 GtkStyleContextPrivate *priv;
2791 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
2793 priv = context->priv;
2795 /* Avoid reentrancy */
2796 if (priv->invalidating_context)
2799 priv->invalidating_context = TRUE;
2801 g_hash_table_remove_all (priv->style_data);
2802 priv->current_data = NULL;
2804 g_signal_emit (context, signals[CHANGED], 0);
2806 priv->invalidating_context = FALSE;
2810 * gtk_style_context_set_background:
2811 * @context: a #GtkStyleContext
2812 * @window: a #GdkWindow
2814 * Sets the background of @window to the background pattern or
2815 * color specified in @context for its current state.
2820 gtk_style_context_set_background (GtkStyleContext *context,
2823 GtkStateFlags state;
2824 cairo_pattern_t *pattern;
2827 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
2828 g_return_if_fail (GDK_IS_WINDOW (window));
2830 state = gtk_style_context_get_state (context);
2831 gtk_style_context_get (context, state,
2832 "background-image", &pattern,
2836 gdk_window_set_background_pattern (window, pattern);
2837 cairo_pattern_destroy (pattern);
2841 gtk_style_context_get (context, state,
2842 "background-color", &color,
2846 gdk_window_set_background_rgba (window, color);
2847 gdk_rgba_free (color);
2855 * @context: a #GtkStyleContext
2857 * @x: X origin of the rectangle
2858 * @y: Y origin of the rectangle
2859 * @width: rectangle width
2860 * @height: rectangle height
2862 * Renders a checkmark (as in a #GtkCheckButton), the %GTK_STATE_FLAG_ACTIVE
2863 * state will determine whether the check is on or off, and
2864 * %GTK_STATE_FLAG_INCONSISTENT whether it should be marked as undefined.
2869 gtk_render_check (GtkStyleContext *context,
2876 GtkStyleContextPrivate *priv;
2877 GtkThemingEngineClass *engine_class;
2879 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
2880 g_return_if_fail (cr != NULL);
2882 priv = context->priv;
2883 engine_class = GTK_THEMING_ENGINE_GET_CLASS (priv->theming_engine);
2885 store_animation_region (context, x, y, width, height);
2887 _gtk_theming_engine_set_context (priv->theming_engine, context);
2888 engine_class->render_check (priv->theming_engine, cr,
2889 x, y, width, height);
2893 * gtk_render_option:
2894 * @context: a #GtkStyleContext
2896 * @x: X origin of the rectangle
2897 * @y: Y origin of the rectangle
2898 * @width: rectangle width
2899 * @height: rectangle height
2901 * Renders an option mark (as in a #GtkRadioButton), the %GTK_STATE_FLAG_ACTIVE
2902 * state will determine whether the option is on or off, and
2903 * %GTK_STATE_FLAG_INCONSISTENT whether it should be marked as undefined.
2908 gtk_render_option (GtkStyleContext *context,
2915 GtkStyleContextPrivate *priv;
2916 GtkThemingEngineClass *engine_class;
2918 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
2919 g_return_if_fail (cr != NULL);
2921 priv = context->priv;
2922 engine_class = GTK_THEMING_ENGINE_GET_CLASS (priv->theming_engine);
2924 store_animation_region (context, x, y, width, height);
2926 _gtk_theming_engine_set_context (priv->theming_engine, context);
2927 engine_class->render_option (priv->theming_engine, cr,
2928 x, y, width, height);
2933 * @context: a #GtkStyleContext
2935 * @angle: arrow angle from 0 to 2 * %G_PI, being 0 the arrow pointing to the north
2936 * @x: Center X for the render area
2937 * @y: Center Y for the render area
2938 * @size: square side for render area
2940 * Renders an arrow pointing to @angle.
2945 gtk_render_arrow (GtkStyleContext *context,
2952 GtkStyleContextPrivate *priv;
2953 GtkThemingEngineClass *engine_class;
2955 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
2956 g_return_if_fail (cr != NULL);
2958 priv = context->priv;
2959 engine_class = GTK_THEMING_ENGINE_GET_CLASS (priv->theming_engine);
2961 store_animation_region (context, x, y, size, size);
2963 _gtk_theming_engine_set_context (priv->theming_engine, context);
2964 engine_class->render_arrow (priv->theming_engine, cr,
2969 * gtk_render_background:
2970 * @context: a #GtkStyleContext
2972 * @x: X origin of the rectangle
2973 * @y: Y origin of the rectangle
2974 * @width: rectangle width
2975 * @height: rectangle height
2977 * Renders the background of an element.
2982 gtk_render_background (GtkStyleContext *context,
2989 GtkStyleContextPrivate *priv;
2990 GtkThemingEngineClass *engine_class;
2992 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
2993 g_return_if_fail (cr != NULL);
2995 priv = context->priv;
2996 engine_class = GTK_THEMING_ENGINE_GET_CLASS (priv->theming_engine);
2998 store_animation_region (context, x, y, width, height);
3000 _gtk_theming_engine_set_context (priv->theming_engine, context);
3001 engine_class->render_background (priv->theming_engine, cr, x, y, width, height);
3006 * @context: a #GtkStyleContext
3008 * @x: X origin of the rectangle
3009 * @y: Y origin of the rectangle
3010 * @width: rectangle width
3011 * @height: rectangle height
3013 * Renders a frame around the rectangle defined by @x, @y, @width, @height.
3018 gtk_render_frame (GtkStyleContext *context,
3025 GtkStyleContextPrivate *priv;
3026 GtkThemingEngineClass *engine_class;
3028 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
3029 g_return_if_fail (cr != NULL);
3031 priv = context->priv;
3032 engine_class = GTK_THEMING_ENGINE_GET_CLASS (priv->theming_engine);
3034 store_animation_region (context, x, y, width, height);
3036 _gtk_theming_engine_set_context (priv->theming_engine, context);
3037 engine_class->render_frame (priv->theming_engine, cr, x, y, width, height);
3041 * gtk_render_expander:
3042 * @context: a #GtkStyleContext
3044 * @x: X origin of the rectangle
3045 * @y: Y origin of the rectangle
3046 * @width: rectangle width
3047 * @height: rectangle height
3049 * Renders an expander (as used in #GtkTreeView and #GtkExpander) in the area
3050 * defined by @x, @y, @width, @height. The state %GTK_STATE_FLAG_ACTIVE determines
3051 * whether the expander is collapsed or expanded.
3056 gtk_render_expander (GtkStyleContext *context,
3063 GtkStyleContextPrivate *priv;
3064 GtkThemingEngineClass *engine_class;
3066 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
3067 g_return_if_fail (cr != NULL);
3069 priv = context->priv;
3070 engine_class = GTK_THEMING_ENGINE_GET_CLASS (priv->theming_engine);
3072 store_animation_region (context, x, y, width, height);
3074 _gtk_theming_engine_set_context (priv->theming_engine, context);
3075 engine_class->render_expander (priv->theming_engine, cr, x, y, width, height);
3080 * @context: a #GtkStyleContext
3082 * @x: X origin of the rectangle
3083 * @y: Y origin of the rectangle
3084 * @width: rectangle width
3085 * @height: rectangle height
3087 * Renders a focus indicator on the rectangle determined by @x, @y, @width, @height.
3092 gtk_render_focus (GtkStyleContext *context,
3099 GtkStyleContextPrivate *priv;
3100 GtkThemingEngineClass *engine_class;
3102 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
3103 g_return_if_fail (cr != NULL);
3105 priv = context->priv;
3106 engine_class = GTK_THEMING_ENGINE_GET_CLASS (priv->theming_engine);
3108 store_animation_region (context, x, y, width, height);
3110 _gtk_theming_engine_set_context (priv->theming_engine, context);
3111 engine_class->render_focus (priv->theming_engine, cr, x, y, width, height);
3115 * gtk_render_layout:
3116 * @context: a #GtkStyleContext
3120 * @layout: the #PangoLayout to render
3122 * Renders @layout on the coordinates @x, @y
3127 gtk_render_layout (GtkStyleContext *context,
3131 PangoLayout *layout)
3133 GtkStyleContextPrivate *priv;
3134 GtkThemingEngineClass *engine_class;
3136 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
3137 g_return_if_fail (cr != NULL);
3139 priv = context->priv;
3140 engine_class = GTK_THEMING_ENGINE_GET_CLASS (priv->theming_engine);
3142 _gtk_theming_engine_set_context (priv->theming_engine, context);
3143 engine_class->render_layout (priv->theming_engine, cr, x, y, layout);
3148 * @context: a #GtkStyleContext
3150 * @x0: X coordinate for the origin of the line
3151 * @y0: Y coordinate for the origin of the line
3152 * @x1: X coordinate for the end of the line
3153 * @y1: Y coordinate for the end of the line
3155 * Renders a line from (x0, y0) to (x1, y1).
3160 gtk_render_line (GtkStyleContext *context,
3167 GtkStyleContextPrivate *priv;
3168 GtkThemingEngineClass *engine_class;
3170 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
3171 g_return_if_fail (cr != NULL);
3173 priv = context->priv;
3174 engine_class = GTK_THEMING_ENGINE_GET_CLASS (priv->theming_engine);
3176 _gtk_theming_engine_set_context (priv->theming_engine, context);
3177 engine_class->render_line (priv->theming_engine, cr, x0, y0, x1, y1);
3181 * gtk_render_slider:
3182 * @context: a #GtkStyleContext
3184 * @x: X origin of the rectangle
3185 * @y: Y origin of the rectangle
3186 * @width: rectangle width
3187 * @height: rectangle height
3188 * @orientation: orientation of the slider
3190 * Renders a slider (as in #GtkScale) in the rectangle defined by @x, @y,
3191 * @width, @height. @orientation defines whether the slider is vertical
3197 gtk_render_slider (GtkStyleContext *context,
3203 GtkOrientation orientation)
3205 GtkStyleContextPrivate *priv;
3206 GtkThemingEngineClass *engine_class;
3208 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
3209 g_return_if_fail (cr != NULL);
3211 priv = context->priv;
3212 engine_class = GTK_THEMING_ENGINE_GET_CLASS (priv->theming_engine);
3214 store_animation_region (context, x, y, width, height);
3216 _gtk_theming_engine_set_context (priv->theming_engine, context);
3217 engine_class->render_slider (priv->theming_engine, cr, x, y, width, height, orientation);
3221 * gtk_render_frame_gap:
3222 * @context: a #GtkStyleContext
3224 * @x: X origin of the rectangle
3225 * @y: Y origin of the rectangle
3226 * @width: rectangle width
3227 * @height: rectangle height
3228 * @gap_side: side where the gap is
3229 * @xy0_gap: initial coordinate (X or Y depending on @gap_side) for the gap
3230 * @xy1_gap: end coordinate (X or Y depending on @gap_side) for the gap
3232 * Renders a frame around the rectangle defined by (@x, @y, @width, @height),
3233 * leaving a gap on one side. @xy0_gap and @xy1_gap will mean X coordinates for
3234 * %GTK_POS_TOP and %GTK_POS_BOTTOM gap sides, and Y coordinates for %GTK_POS_LEFT
3235 * and %GTK_POS_RIGHT.
3240 gtk_render_frame_gap (GtkStyleContext *context,
3246 GtkPositionType gap_side,
3250 GtkStyleContextPrivate *priv;
3251 GtkThemingEngineClass *engine_class;
3253 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
3254 g_return_if_fail (cr != NULL);
3256 priv = context->priv;
3257 engine_class = GTK_THEMING_ENGINE_GET_CLASS (priv->theming_engine);
3259 store_animation_region (context, x, y, width, height);
3261 _gtk_theming_engine_set_context (priv->theming_engine, context);
3262 engine_class->render_frame_gap (priv->theming_engine, cr,
3263 x, y, width, height, gap_side,
3268 * gtk_render_extension:
3269 * @context: a #GtkStyleContext
3271 * @x: X origin of the rectangle
3272 * @y: Y origin of the rectangle
3273 * @width: rectangle width
3274 * @height: rectangle height
3275 * @gap_side: side where the gap is
3277 * Renders a extension (as in a #GtkNotebook tab) in the rectangle
3278 * defined by @x, @y, @width, @height. The side where the extension
3279 * connects to is defined by @gap_side.
3284 gtk_render_extension (GtkStyleContext *context,
3290 GtkPositionType gap_side)
3292 GtkStyleContextPrivate *priv;
3293 GtkThemingEngineClass *engine_class;
3295 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
3296 g_return_if_fail (cr != NULL);
3298 priv = context->priv;
3299 engine_class = GTK_THEMING_ENGINE_GET_CLASS (priv->theming_engine);
3301 store_animation_region (context, x, y, width, height);
3303 _gtk_theming_engine_set_context (priv->theming_engine, context);
3304 engine_class->render_extension (priv->theming_engine, cr, x, y, width, height, gap_side);
3308 * gtk_render_handle:
3309 * @context: a #GtkStyleContext
3311 * @x: X origin of the rectangle
3312 * @y: Y origin of the rectangle
3313 * @width: rectangle width
3314 * @height: rectangle height
3316 * Renders a handle (as in #GtkHandleBox, #GtkPaned and
3317 * #GtkWindow<!-- -->'s resize grip), in the rectangle
3318 * determined by @x, @y, @width, @height.
3323 gtk_render_handle (GtkStyleContext *context,
3330 GtkStyleContextPrivate *priv;
3331 GtkThemingEngineClass *engine_class;
3333 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
3334 g_return_if_fail (cr != NULL);
3336 priv = context->priv;
3337 engine_class = GTK_THEMING_ENGINE_GET_CLASS (priv->theming_engine);
3339 store_animation_region (context, x, y, width, height);
3341 _gtk_theming_engine_set_context (priv->theming_engine, context);
3342 engine_class->render_handle (priv->theming_engine, cr, x, y, width, height);
3346 * gtk_render_activity:
3347 * @context: a #GtkStyleContext
3349 * @x: X origin of the rectangle
3350 * @y: Y origin of the rectangle
3351 * @width: rectangle width
3352 * @height: rectangle height
3354 * Renders an activity area (Such as in #GtkSpinner or the
3355 * fill line in #GtkRange), the state %GTK_STATE_FLAG_ACTIVE
3356 * determines whether there is activity going on.
3361 gtk_render_activity (GtkStyleContext *context,
3368 GtkStyleContextPrivate *priv;
3369 GtkThemingEngineClass *engine_class;
3371 g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
3372 g_return_if_fail (cr != NULL);
3374 priv = context->priv;
3375 engine_class = GTK_THEMING_ENGINE_GET_CLASS (priv->theming_engine);
3377 store_animation_region (context, x, y, width, height);
3379 _gtk_theming_engine_set_context (priv->theming_engine, context);
3380 engine_class->render_activity (priv->theming_engine, cr, x, y, width, height);
3384 * gtk_render_icon_pixbuf:
3385 * @context: a #GtkStyleContext
3386 * @source: the #GtkIconSource specifying the icon to render
3387 * @size: (type int): the size to render the icon at. A size of (GtkIconSize) -1
3388 * means render at the size of the source and don't scale.
3390 * Renders the icon specified by @source at the given @size, returning the result
3393 * Returns: (transfer full): a newly-created #GdkPixbuf containing the rendered icon
3398 gtk_render_icon_pixbuf (GtkStyleContext *context,
3399 const GtkIconSource *source,
3402 GtkStyleContextPrivate *priv;
3403 GtkThemingEngineClass *engine_class;
3405 g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), NULL);
3406 g_return_val_if_fail (size == -1 || size <= GTK_ICON_SIZE_DIALOG, NULL);
3407 g_return_val_if_fail (source != NULL, NULL);
3409 priv = context->priv;
3410 engine_class = GTK_THEMING_ENGINE_GET_CLASS (priv->theming_engine);
3412 _gtk_theming_engine_set_context (priv->theming_engine, context);
3413 return engine_class->render_icon_pixbuf (priv->theming_engine, source, size);