[gtk+/wip/cssnode3: 43/88] cssnode: Refactor node tree modification code
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/cssnode3: 43/88] cssnode: Refactor node tree modification code
- Date: Thu, 5 Mar 2015 19:54:25 +0000 (UTC)
commit e6c08b3b8814fff4105543dcc9b06be3eda4b4b2
Author: Benjamin Otte <otte redhat com>
Date: Mon Feb 9 22:03:13 2015 +0100
cssnode: Refactor node tree modification code
This allows adding more API for it.
It also includes code that tracks modifications and invalidates siblings
and their positions whenever nodes get added or removed.
gtk/gtkcssnode.c | 142 +++++++++++++++++++++++++++++++---------------
gtk/gtkcssnodeprivate.h | 2 +-
2 files changed, 97 insertions(+), 47 deletions(-)
---
diff --git a/gtk/gtkcssnode.c b/gtk/gtkcssnode.c
index 816c667..92b165d 100644
--- a/gtk/gtkcssnode.c
+++ b/gtk/gtkcssnode.c
@@ -359,73 +359,118 @@ gtk_css_node_parent_will_be_set (GtkCssNode *node)
GTK_CSS_NODE_GET_CLASS (node)->dequeue_validate (node);
}
-void
-gtk_css_node_set_parent (GtkCssNode *node,
- GtkCssNode *parent)
+static void
+gtk_css_node_unlink_from_siblings (GtkCssNode *node)
{
- if (node->parent == parent)
+ if (GTK_IS_CSS_TRANSIENT_NODE (node))
return;
- /* Take a reference here so the whole function has a reference */
- g_object_ref (node);
+ if (node->previous_sibling)
+ node->previous_sibling->next_sibling = node->next_sibling;
+ else
+ node->parent->first_child = node->next_sibling;
- if (node->parent != NULL)
+ if (node->next_sibling)
+ node->next_sibling->previous_sibling = node->previous_sibling;
+ else
+ node->parent->last_child = node->previous_sibling;
+
+ node->previous_sibling = NULL;
+ node->next_sibling = NULL;
+}
+
+static void
+gtk_css_node_link_to_siblings (GtkCssNode *node,
+ GtkCssNode *new_previous)
+{
+ if (GTK_IS_CSS_TRANSIENT_NODE (node))
+ return;
+
+ if (new_previous)
{
- if (!GTK_IS_CSS_TRANSIENT_NODE (node))
- {
- if (node->previous_sibling)
- node->previous_sibling->next_sibling = node->next_sibling;
- else
- node->parent->first_child = node->next_sibling;
+ node->previous_sibling = new_previous;
+ node->next_sibling = new_previous->next_sibling;
+ new_previous->next_sibling = node;
+ }
+ else
+ {
+ node->next_sibling = node->parent->first_child;
+ node->parent->first_child = node;
+ }
+
+ if (node->next_sibling)
+ node->next_sibling->previous_sibling = node;
+ else
+ node->parent->last_child = node;
+}
- if (node->next_sibling)
- node->next_sibling->previous_sibling = node->previous_sibling;
- else
- node->parent->last_child = node->previous_sibling;
+static void
+gtk_css_node_set_children_changed (GtkCssNode *node)
+{
+ if (node->children_changed)
+ return;
- node->parent->n_children--;
- }
+ node->children_changed = TRUE;
+ gtk_css_node_set_invalid (node, TRUE);
+}
- node->parent = NULL;
- node->next_sibling = NULL;
- node->previous_sibling = NULL;
+static void
+gtk_css_node_reposition (GtkCssNode *node,
+ GtkCssNode *parent,
+ GtkCssNode *previous)
+{
+ g_assert (! (parent == NULL && previous != NULL));
- g_object_unref (node);
+ /* Take a reference here so the whole function has a reference */
+ g_object_ref (node);
- if (parent == NULL)
- gtk_css_node_parent_was_unset (node);
- }
+ if (node->parent != NULL)
+ gtk_css_node_unlink_from_siblings (node);
- if (parent)
+ if (node->parent != parent)
{
if (node->parent == NULL)
- gtk_css_node_parent_will_be_set (node);
+ {
+ gtk_css_node_parent_will_be_set (node);
+ }
+ else
+ {
+ g_object_unref (node);
+ gtk_css_node_set_children_changed (node->parent);
+ }
node->parent = parent;
- if (!GTK_IS_CSS_TRANSIENT_NODE (node))
+ if (parent)
{
- parent->n_children++;
+ gtk_css_node_set_children_changed (parent);
+ g_object_ref (node);
- if (parent->last_child)
- {
- parent->last_child->next_sibling = node;
- node->previous_sibling = parent->last_child;
- }
- parent->last_child = node;
-
- if (parent->first_child == NULL)
- parent->first_child = node;
+ if (node->invalid)
+ gtk_css_node_set_invalid (parent, TRUE);
+ }
+ else
+ {
+ gtk_css_node_parent_was_unset (node);
}
-
- if (node->invalid)
- gtk_css_node_set_invalid (parent, TRUE);
}
+ if (parent)
+ gtk_css_node_link_to_siblings (node, previous);
+
gtk_css_node_invalidate (node, GTK_CSS_CHANGE_ANY_PARENT | GTK_CSS_CHANGE_ANY_SIBLING);
- if (node->parent == NULL)
- g_object_unref (node);
+ g_object_unref (node);
+}
+
+void
+gtk_css_node_set_parent (GtkCssNode *node,
+ GtkCssNode *parent)
+{
+ if (node->parent == parent)
+ return;
+
+ gtk_css_node_reposition (node, parent, parent ? parent->last_child : NULL);
}
GtkCssNode *
@@ -638,6 +683,11 @@ gtk_css_node_propagate_pending_changes (GtkCssNode *cssnode)
return;
change = _gtk_css_change_for_child (cssnode->pending_changes);
+ if (cssnode->children_changed)
+ {
+ change |= GTK_CSS_CHANGE_POSITION | GTK_CSS_CHANGE_ANY_SIBLING;
+ cssnode->children_changed = FALSE;
+ }
for (child = gtk_css_node_get_first_child (cssnode);
child;
@@ -671,11 +721,11 @@ gtk_css_node_validate (GtkCssNode *cssnode,
if (G_UNLIKELY (gtk_get_debug_flags () & GTK_DEBUG_NO_CSS_CACHE))
change = GTK_CSS_CHANGE_ANY;
+ gtk_css_node_propagate_pending_changes (cssnode);
+
if (!cssnode->invalid && change == 0 && _gtk_bitmask_is_empty (parent_changes))
return;
- gtk_css_node_propagate_pending_changes (cssnode);
-
gtk_css_node_set_invalid (cssnode, FALSE);
change = cssnode->pending_changes;
diff --git a/gtk/gtkcssnodeprivate.h b/gtk/gtkcssnodeprivate.h
index 4207d2f..b1339b0 100644
--- a/gtk/gtkcssnodeprivate.h
+++ b/gtk/gtkcssnodeprivate.h
@@ -43,7 +43,6 @@ struct _GtkCssNode
GtkCssNode *next_sibling;
GtkCssNode *first_child;
GtkCssNode *last_child;
- guint n_children;
GtkCssNodeDeclaration *decl;
GtkCssStyle *style;
@@ -51,6 +50,7 @@ struct _GtkCssNode
GtkCssChange pending_changes; /* changes that accumulated since the style was last
computed */
guint invalid :1; /* node or a child needs to be validated (even if just for
animation) */
+ guint children_changed :1; /* the children changed since last validation */
};
struct _GtkCssNodeClass
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]