[gtk+/gtk-style-context: 248/540] GtkContainer: Add method to get the GtkWidgetPath for a child.
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/gtk-style-context: 248/540] GtkContainer: Add method to get the GtkWidgetPath for a child.
- Date: Fri, 3 Dec 2010 02:56:59 +0000 (UTC)
commit 087c10afd9f6876201278a519a00b64a5a782e81
Author: Carlos Garnacho <carlosg gnome org>
Date: Mon Oct 11 00:23:40 2010 +0200
GtkContainer: Add method to get the GtkWidgetPath for a child.
This is now used throughout in order to have the full path for a given widget,
including intermediate named regions, the default implementation just returns
the GtkContainer's path copy, no intermediate regions between.
gtk/gtkcontainer.c | 22 ++++++++++
gtk/gtkcontainer.h | 5 ++
gtk/gtkstylecontext.c | 21 +++++-----
gtk/gtkwidget.c | 105 +++++++++++++++++++------------------------------
gtk/gtkwidgetpath.c | 15 +++++++
gtk/gtkwidgetpath.h | 2 +
6 files changed, 95 insertions(+), 75 deletions(-)
---
diff --git a/gtk/gtkcontainer.c b/gtk/gtkcontainer.c
index a37e361..8c09ba2 100644
--- a/gtk/gtkcontainer.c
+++ b/gtk/gtkcontainer.c
@@ -334,6 +334,9 @@ static void gtk_container_adjust_size_allocation (GtkWidget *widget,
static gchar* gtk_container_child_default_composite_name (GtkContainer *container,
GtkWidget *child);
+static GtkWidgetPath * gtk_container_real_get_path_for_child (GtkContainer *container,
+ GtkWidget *child);
+
/* GtkBuildable */
static void gtk_container_buildable_init (GtkBuildableIface *iface);
static void gtk_container_buildable_add_child (GtkBuildable *buildable,
@@ -465,6 +468,7 @@ gtk_container_class_init (GtkContainerClass *class)
class->set_focus_child = gtk_container_real_set_focus_child;
class->child_type = NULL;
class->composite_name = gtk_container_child_default_composite_name;
+ class->get_path_for_child = gtk_container_real_get_path_for_child;
g_object_class_install_property (gobject_class,
PROP_RESIZE_MODE,
@@ -2207,6 +2211,13 @@ gtk_container_get_all_children (GtkContainer *container)
return children;
}
+static GtkWidgetPath *
+gtk_container_real_get_path_for_child (GtkContainer *container,
+ GtkWidget *child)
+{
+ return gtk_widget_path_copy (gtk_widget_get_path (GTK_WIDGET (container)));
+}
+
static gboolean
gtk_container_focus (GtkWidget *widget,
GtkDirectionType direction)
@@ -3220,3 +3231,14 @@ _gtk_container_get_reallocate_redraws (GtkContainer *container)
{
return container->priv->reallocate_redraws;
}
+
+GtkWidgetPath *
+gtk_container_get_path_for_child (GtkContainer *container,
+ GtkWidget *child)
+{
+ g_return_val_if_fail (GTK_IS_CONTAINER (container), NULL);
+ g_return_val_if_fail (GTK_IS_WIDGET (child), NULL);
+ g_return_val_if_fail (container == (GtkContainer *) gtk_widget_get_parent (child), NULL);
+
+ return GTK_CONTAINER_GET_CLASS (container)->get_path_for_child (container, child);
+}
diff --git a/gtk/gtkcontainer.h b/gtk/gtkcontainer.h
index f469d89..94a8502 100644
--- a/gtk/gtkcontainer.h
+++ b/gtk/gtkcontainer.h
@@ -88,6 +88,8 @@ struct _GtkContainerClass
guint property_id,
GValue *value,
GParamSpec *pspec);
+ GtkWidgetPath * (*get_path_for_child) (GtkContainer *container,
+ GtkWidget *child);
/* Padding for future expansion */
void (*_gtk_reserved1) (void);
@@ -228,6 +230,9 @@ void _gtk_container_set_need_resize (GtkContainer *container,
gboolean need_resize);
gboolean _gtk_container_get_reallocate_redraws (GtkContainer *container);
+GtkWidgetPath * gtk_container_get_path_for_child (GtkContainer *container,
+ GtkWidget *child);
+
G_END_DECLS
#endif /* __GTK_CONTAINER_H__ */
diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c
index 69e7797..13d15f9 100644
--- a/gtk/gtkstylecontext.c
+++ b/gtk/gtkstylecontext.c
@@ -524,11 +524,14 @@ rebuild_properties (GtkStyleContext *context)
priv = context->priv;
list = priv->providers;
+ gtk_style_set_clear (priv->store);
+
+ if (!priv->widget_path)
+ return;
+
if (priv->screen)
global_list = g_object_get_qdata (G_OBJECT (priv->screen), provider_list_quark);
- gtk_style_set_clear (priv->store);
-
while ((elem = find_next_candidate (list, global_list)) != NULL)
{
GtkStyleProviderData *data;
@@ -566,11 +569,13 @@ rebuild_icon_factories (GtkStyleContext *context)
GList *elem, *list, *global_list = NULL;
priv = context->priv;
-
g_slist_foreach (priv->icon_factories, (GFunc) g_object_unref, NULL);
g_slist_free (priv->icon_factories);
priv->icon_factories = NULL;
+ if (!priv->widget_path)
+ return;
+
list = priv->providers_last;
if (priv->screen)
@@ -948,10 +953,9 @@ gtk_style_context_set_path (GtkStyleContext *context,
}
if (path)
- {
- priv->widget_path = gtk_widget_path_copy (path);
- gtk_style_context_invalidate (context);
- }
+ priv->widget_path = gtk_widget_path_copy (path);
+
+ gtk_style_context_invalidate (context);
}
G_CONST_RETURN GtkWidgetPath *
@@ -1953,9 +1957,6 @@ gtk_style_context_invalidate (GtkStyleContext *context)
if (priv->invalidating_context)
return;
- if (!priv->widget_path)
- return;
-
priv->invalidating_context = TRUE;
rebuild_properties (context);
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 3dfbc6c..4da12a1 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -374,6 +374,9 @@ struct _GtkWidgetPrivate
/* The widget's parent.
*/
GtkWidget *parent;
+
+ /* Widget's path for styling */
+ GtkWidgetPath *path;
};
enum {
@@ -7229,6 +7232,18 @@ gtk_widget_is_sensitive (GtkWidget *widget)
return widget->priv->sensitive && widget->priv->parent_sensitive;
}
+static void
+_gtk_widget_update_path (GtkWidget *widget)
+{
+ if (widget->priv->path)
+ {
+ gtk_widget_path_free (widget->priv->path);
+ widget->priv->path = NULL;
+ }
+
+ gtk_widget_get_path (widget);
+}
+
/**
* gtk_widget_set_parent:
* @widget: a #GtkWidget
@@ -7326,11 +7341,8 @@ gtk_widget_set_parent (GtkWidget *widget,
quark_style_context);
if (context)
{
- GtkWidgetPath *path;
-
- path = gtk_widget_get_path (widget);
- gtk_style_context_set_path (context, path);
- gtk_widget_path_free (path);
+ _gtk_widget_update_path (widget);
+ gtk_style_context_set_path (context, widget->priv->path);
gtk_style_context_set_screen (context,
gtk_widget_get_screen (widget));
@@ -8139,7 +8151,10 @@ reset_style_recurse (GtkWidget *widget, gpointer data)
context = g_object_get_qdata (G_OBJECT (widget),
quark_style_context);
if (context)
- gtk_style_context_invalidate (context);
+ {
+ _gtk_widget_update_path (widget);
+ gtk_style_context_set_path (context, widget->priv->path);
+ }
if (GTK_IS_CONTAINER (widget))
gtk_container_forall (GTK_CONTAINER (widget),
@@ -13267,71 +13282,34 @@ _gtk_widget_set_height_request_needed (GtkWidget *widget,
GtkWidgetPath *
gtk_widget_get_path (GtkWidget *widget)
{
- GtkStyleContext *context;
- GtkWidgetPath *path;
- GtkWidget *parent;
-
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
- parent = widget->priv->parent;
-
- path = gtk_widget_path_new ();
- gtk_widget_path_prepend_type (path, G_OBJECT_TYPE (widget));
-
- if (widget->priv->name)
- gtk_widget_path_iter_set_name (path, 0, widget->priv->name);
-
- context = g_object_get_qdata (G_OBJECT (widget),
- quark_style_context);
-
- if (context)
+ if (!widget->priv->path)
{
- GList *list, *l;
-
- list = l = gtk_style_context_list_regions (context);
-
- while (l)
- {
- GtkRegionFlags flags;
- const gchar *region_name;
-
- region_name = l->data;
- l = l->next;
-
- gtk_style_context_has_region (context, region_name, &flags);
- gtk_widget_path_iter_add_region (path, 0, region_name, flags);
- }
-
- g_list_free (list);
+ GtkWidget *parent;
+ guint pos;
- list = l = gtk_style_context_list_classes (context);
+ parent = widget->priv->parent;
- while (l)
+ if (parent)
+ widget->priv->path = gtk_container_get_path_for_child (GTK_CONTAINER (parent), widget);
+ else
{
- const gchar *class_name;
-
- class_name = l->data;
- l = l->next;
-
- gtk_widget_path_iter_add_class (path, 0, class_name);
+ /* Widget is either toplevel or unparented, treat both
+ * as toplevels style wise, since there are situations
+ * where style properties might be retrieved on that
+ * situation.
+ */
+ widget->priv->path = gtk_widget_path_new ();
}
- g_list_free (list);
- }
-
- while (parent)
- {
- guint position;
-
- position = gtk_widget_path_prepend_type (path, G_OBJECT_TYPE (parent));
-
- if (parent->priv->name)
- gtk_widget_path_iter_set_name (path, position, parent->priv->name);
+ pos = gtk_widget_path_append_type (widget->priv->path, G_OBJECT_TYPE (widget));
- parent = parent->priv->parent;
+ if (widget->priv->name)
+ gtk_widget_path_iter_set_name (widget->priv->path, pos, widget->priv->name);
}
- return path;
+ return widget->priv->path;
}
static void
@@ -13355,8 +13333,6 @@ gtk_widget_get_style_context (GtkWidget *widget)
if (G_UNLIKELY (!context))
{
- GtkWidgetPath *path;
-
context = g_object_new (GTK_TYPE_STYLE_CONTEXT,
"direction", gtk_widget_get_direction (widget),
NULL);
@@ -13371,9 +13347,8 @@ gtk_widget_get_style_context (GtkWidget *widget)
gtk_style_context_set_screen (context,
gtk_widget_get_screen (widget));
- path = gtk_widget_get_path (widget);
- gtk_style_context_set_path (context, path);
- gtk_widget_path_free (path);
+ _gtk_widget_update_path (widget);
+ gtk_style_context_set_path (context, widget->priv->path);
}
return context;
diff --git a/gtk/gtkwidgetpath.c b/gtk/gtkwidgetpath.c
index 933a2dc..c6cfbb5 100644
--- a/gtk/gtkwidgetpath.c
+++ b/gtk/gtkwidgetpath.c
@@ -129,6 +129,21 @@ gtk_widget_path_prepend_type (GtkWidgetPath *path,
g_return_val_if_fail (g_type_is_a (type, GTK_TYPE_WIDGET), 0);
new.type = type;
+ g_array_prepend_val (path->elems, new);
+
+ return 0;
+}
+
+guint
+gtk_widget_path_append_type (GtkWidgetPath *path,
+ GType type)
+{
+ GtkPathElement new = { 0 };
+
+ g_return_val_if_fail (path != NULL, 0);
+ g_return_val_if_fail (g_type_is_a (type, GTK_TYPE_WIDGET), 0);
+
+ new.type = type;
g_array_append_val (path->elems, new);
return path->elems->len - 1;
diff --git a/gtk/gtkwidgetpath.h b/gtk/gtkwidgetpath.h
index 234f79b..4e5c476 100644
--- a/gtk/gtkwidgetpath.h
+++ b/gtk/gtkwidgetpath.h
@@ -35,6 +35,8 @@ void gtk_widget_path_free (GtkWidgetPath *path);
guint gtk_widget_path_length (const GtkWidgetPath *path);
+guint gtk_widget_path_append_type (GtkWidgetPath *path,
+ GType type);
guint gtk_widget_path_prepend_type (GtkWidgetPath *path,
GType type);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]