[gtk+] stylecontext: Handle parent in CssNode code



commit 721dce73e088ed92e74a5b6593f58e91621cc6ea
Author: Benjamin Otte <otte redhat com>
Date:   Mon Jan 26 02:18:06 2015 +0100

    stylecontext: Handle parent in CssNode code
    
    Make CssNode a real tree with a DOM-like API.

 gtk/gtkcssnode.c        |   75 +++++++++++++++++++++++++++++++++++++++++++++-
 gtk/gtkcssnodeprivate.h |   12 +++++++-
 gtk/gtkstylecontext.c   |   22 ++++++-------
 gtk/gtkwidget.c         |    4 +-
 4 files changed, 96 insertions(+), 17 deletions(-)
---
diff --git a/gtk/gtkcssnode.c b/gtk/gtkcssnode.c
index 6e0b962..4e33010 100644
--- a/gtk/gtkcssnode.c
+++ b/gtk/gtkcssnode.c
@@ -19,6 +19,8 @@
 
 #include "gtkcssnodeprivate.h"
 
+#include "gtkcsstransientnodeprivate.h"
+
 G_DEFINE_TYPE (GtkCssNode, gtk_css_node, G_TYPE_OBJECT)
 
 static void
@@ -70,10 +72,55 @@ gtk_css_node_init (GtkCssNode *cssnode)
 }
 
 void
-gtk_css_node_set_parent (GtkCssNode *cssnode,
+gtk_css_node_set_parent (GtkCssNode *node,
                          GtkCssNode *parent)
 {
-  cssnode->parent = parent;
+  if (node->parent == parent)
+    return;
+
+  if (node->parent != NULL)
+    {
+      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;
+
+          if (node->next_sibling)
+            node->next_sibling->previous_sibling = node->previous_sibling;
+          else
+            node->parent->last_child = node->previous_sibling;
+
+          node->parent->n_children--;
+        }
+
+      node->parent = NULL;
+      node->next_sibling = NULL;
+      node->previous_sibling = NULL;
+    }
+
+  if (parent)
+    {
+      node->parent = parent;
+
+      if (!GTK_IS_CSS_TRANSIENT_NODE (node))
+        {
+          parent->n_children++;
+
+          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;
+        }
+    }
+
+  gtk_css_node_invalidate (node, GTK_CSS_CHANGE_ANY_PARENT | GTK_CSS_CHANGE_ANY_SIBLING);
 }
 
 GtkCssNode *
@@ -82,6 +129,30 @@ gtk_css_node_get_parent (GtkCssNode *cssnode)
   return cssnode->parent;
 }
 
+GtkCssNode *
+gtk_css_node_get_first_child (GtkCssNode *cssnode)
+{
+  return cssnode->first_child;
+}
+
+GtkCssNode *
+gtk_css_node_get_last_child (GtkCssNode *cssnode)
+{
+  return cssnode->last_child;
+}
+
+GtkCssNode *
+gtk_css_node_get_previous_sibling (GtkCssNode *cssnode)
+{
+  return cssnode->previous_sibling;
+}
+
+GtkCssNode *
+gtk_css_node_get_next_sibling (GtkCssNode *cssnode)
+{
+  return cssnode->next_sibling;
+}
+
 void
 gtk_css_node_set_style (GtkCssNode  *cssnode,
                         GtkCssStyle *style)
diff --git a/gtk/gtkcssnodeprivate.h b/gtk/gtkcssnodeprivate.h
index 46aafb0..c00c875 100644
--- a/gtk/gtkcssnodeprivate.h
+++ b/gtk/gtkcssnodeprivate.h
@@ -37,8 +37,14 @@ struct _GtkCssNode
 {
   GObject object;
 
+  GtkCssNode *parent;
+  GtkCssNode *previous_sibling;
+  GtkCssNode *next_sibling;
+  GtkCssNode *first_child;
+  GtkCssNode *last_child;
+  guint n_children;
+
   GtkCssNodeDeclaration *decl;
-  GtkCssNode            *parent;
   GtkCssStyle           *style;
 };
 
@@ -57,6 +63,10 @@ GType                   gtk_css_node_get_type           (void) G_GNUC_CONST;
 void                    gtk_css_node_set_parent         (GtkCssNode            *cssnode,
                                                          GtkCssNode            *parent);
 GtkCssNode *            gtk_css_node_get_parent         (GtkCssNode            *cssnode);
+GtkCssNode *            gtk_css_node_get_first_child    (GtkCssNode            *cssnode);
+GtkCssNode *            gtk_css_node_get_last_child     (GtkCssNode            *cssnode);
+GtkCssNode *            gtk_css_node_get_previous_sibling(GtkCssNode           *cssnode);
+GtkCssNode *            gtk_css_node_get_next_sibling   (GtkCssNode            *cssnode);
 
 void                    gtk_css_node_set_widget_type    (GtkCssNode            *cssnode,
                                                          GType                  widget_type);
diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c
index 3b5e4cd..681d9e3 100644
--- a/gtk/gtkstylecontext.c
+++ b/gtk/gtkstylecontext.c
@@ -288,22 +288,14 @@ static GtkCssStyle *
 gtk_css_node_get_parent_style (GtkStyleContext *context,
                                GtkCssNode      *cssnode)
 {
-  GtkStyleContextPrivate *priv;
   GtkCssNode *parent;
 
   parent = gtk_css_node_get_parent (cssnode);
 
-  g_assert (parent == NULL || gtk_css_node_get_style (parent) != NULL);
-
-  if (parent)
-    return gtk_css_node_get_style (parent);
-
-  priv = context->priv;
-
-  if (priv->parent)
-    return gtk_style_context_lookup_style (priv->parent);
-
-  return NULL;
+  if (parent == NULL)
+    return NULL;
+  
+  return gtk_css_node_get_style (parent);
 }
 
 static void
@@ -1513,6 +1505,12 @@ gtk_style_context_set_parent (GtkStyleContext *context,
       g_object_ref (parent);
       if (priv->invalid)
         gtk_style_context_set_invalid (parent, TRUE);
+      gtk_css_node_set_parent (gtk_style_context_get_root (context),
+                               gtk_style_context_get_root (parent));
+    }
+  else
+    {
+      gtk_css_node_set_parent (gtk_style_context_get_root (context), NULL);
     }
 
   gtk_style_context_clear_parent (context);
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 25ba751..00c8c4b 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -16444,11 +16444,11 @@ gtk_widget_get_style_context (GtkWidget *widget)
       if (frame_clock)
         gtk_style_context_set_frame_clock (priv->context, frame_clock);
 
+      _gtk_style_context_set_widget (priv->context, widget);
+
       if (priv->parent)
         gtk_style_context_set_parent (priv->context,
                                       gtk_widget_get_style_context (priv->parent));
-
-      _gtk_style_context_set_widget (priv->context, widget);
     }
 
   return widget->priv->context;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]