Commit 88b78953 authored by Carlos Garnacho's avatar Carlos Garnacho

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.
parent c575733e
......@@ -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);
}
......@@ -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__ */
......@@ -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);
......
......@@ -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;
......
......@@ -128,6 +128,21 @@ gtk_widget_path_prepend_type (GtkWidgetPath *path,
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_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);
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment