[gtk+/wip/cssnode3: 46/101] cssnode: Add visibility concept
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/cssnode3: 46/101] cssnode: Add visibility concept
- Date: Wed, 11 Mar 2015 00:23:28 +0000 (UTC)
commit e6b2e81d71711d37598c90889c83a84ccc713690
Author: Benjamin Otte <otte redhat com>
Date: Tue Feb 10 02:50:57 2015 +0100
cssnode: Add visibility concept
This allows hiding nodes of invisible widgets.
And that in turn makes sure :nth-child() works as expected.
gtk/gtkcssmatcher.c | 30 +++++++++++++++++++++++++-----
gtk/gtkcssnode.c | 34 +++++++++++++++++++++++++++++-----
gtk/gtkcssnodeprivate.h | 5 +++++
gtk/gtkcsswidgetnode.c | 2 ++
gtk/gtkwidget.c | 4 ++++
5 files changed, 65 insertions(+), 10 deletions(-)
---
diff --git a/gtk/gtkcssmatcher.c b/gtk/gtkcssmatcher.c
index 956271a..b2b5c75 100644
--- a/gtk/gtkcssmatcher.c
+++ b/gtk/gtkcssmatcher.c
@@ -256,13 +256,33 @@ gtk_css_matcher_node_get_parent (GtkCssMatcher *matcher,
return gtk_css_node_init_matcher (node, matcher);
}
+static GtkCssNode *
+get_previous_visible_sibling (GtkCssNode *node)
+{
+ do {
+ node = gtk_css_node_get_previous_sibling (node);
+ } while (node && !gtk_css_node_get_visible (node));
+
+ return node;
+}
+
+static GtkCssNode *
+get_next_visible_sibling (GtkCssNode *node)
+{
+ do {
+ node = gtk_css_node_get_next_sibling (node);
+ } while (node && !gtk_css_node_get_visible (node));
+
+ return node;
+}
+
static gboolean
gtk_css_matcher_node_get_previous (GtkCssMatcher *matcher,
const GtkCssMatcher *next)
{
GtkCssNode *node;
- node = gtk_css_node_get_previous_sibling (next->node.node);
+ node = get_previous_visible_sibling (next->node.node);
if (node == NULL)
return FALSE;
@@ -340,7 +360,7 @@ gtk_css_matcher_node_nth_child (GtkCssNode *node,
if (node == NULL)
return FALSE;
- node = gtk_css_node_get_previous_sibling (node);
+ node = get_previous_visible_sibling (node);
}
if (a == 0)
@@ -352,7 +372,7 @@ gtk_css_matcher_node_nth_child (GtkCssNode *node,
while (node)
{
b++;
- node = gtk_css_node_get_previous_sibling (node);
+ node = get_previous_visible_sibling (node);
}
return b % a == 0;
@@ -368,7 +388,7 @@ gtk_css_matcher_node_nth_last_child (GtkCssNode *node,
if (node == NULL)
return FALSE;
- node = gtk_css_node_get_next_sibling (node);
+ node = get_next_visible_sibling (node);
}
if (a == 0)
@@ -380,7 +400,7 @@ gtk_css_matcher_node_nth_last_child (GtkCssNode *node,
while (node)
{
b++;
- node = gtk_css_node_get_next_sibling (node);
+ node = get_next_visible_sibling (node);
}
return b % a == 0;
diff --git a/gtk/gtkcssnode.c b/gtk/gtkcssnode.c
index 402aa33..5040ff2 100644
--- a/gtk/gtkcssnode.c
+++ b/gtk/gtkcssnode.c
@@ -44,7 +44,7 @@ gtk_css_node_set_invalid (GtkCssNode *node,
if (node->parent)
{
- if (invalid)
+ if (invalid && node->visible)
gtk_css_node_set_invalid (node->parent, TRUE);
}
else
@@ -343,6 +343,8 @@ gtk_css_node_init (GtkCssNode *cssnode)
cssnode->decl = gtk_css_node_declaration_new ();
cssnode->style = g_object_ref (gtk_css_static_style_get_default ());
+
+ cssnode->visible = TRUE;
}
static void
@@ -436,17 +438,19 @@ gtk_css_node_reposition (GtkCssNode *node,
else
{
g_object_unref (node);
- gtk_css_node_set_children_changed (node->parent);
+ if (node->visible)
+ gtk_css_node_set_children_changed (node->parent);
}
node->parent = parent;
if (parent)
{
- gtk_css_node_set_children_changed (parent);
+ if (node->visible)
+ gtk_css_node_set_children_changed (parent);
g_object_ref (node);
- if (node->invalid)
+ if (node->invalid && node->visible)
gtk_css_node_set_invalid (parent, TRUE);
}
else
@@ -565,6 +569,25 @@ gtk_css_node_get_style (GtkCssNode *cssnode)
}
void
+gtk_css_node_set_visible (GtkCssNode *cssnode,
+ gboolean visible)
+{
+ if (cssnode->visible == visible)
+ return;
+
+ cssnode->visible = visible;
+
+ if (cssnode->parent)
+ gtk_css_node_set_children_changed (cssnode->parent);
+}
+
+gboolean
+gtk_css_node_get_visible (GtkCssNode *cssnode)
+{
+ return cssnode->visible;
+}
+
+void
gtk_css_node_set_widget_type (GtkCssNode *cssnode,
GType widget_type)
{
@@ -761,7 +784,8 @@ gtk_css_node_validate (GtkCssNode *cssnode,
child;
child = gtk_css_node_get_next_sibling (child))
{
- gtk_css_node_validate (child, timestamp, changes);
+ if (child->visible)
+ gtk_css_node_validate (child, timestamp, changes);
}
_gtk_bitmask_free (changes);
diff --git a/gtk/gtkcssnodeprivate.h b/gtk/gtkcssnodeprivate.h
index 3c6abfd..ea082ba 100644
--- a/gtk/gtkcssnodeprivate.h
+++ b/gtk/gtkcssnodeprivate.h
@@ -49,6 +49,7 @@ struct _GtkCssNode
GtkCssChange pending_changes; /* changes that accumulated since the style was last
computed */
+ guint visible :1; /* node will be skipped when validating or computing styles
*/
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 */
};
@@ -88,6 +89,10 @@ GtkCssNode * gtk_css_node_get_last_child (GtkCssNode *
GtkCssNode * gtk_css_node_get_previous_sibling(GtkCssNode *cssnode);
GtkCssNode * gtk_css_node_get_next_sibling (GtkCssNode *cssnode);
+void gtk_css_node_set_visible (GtkCssNode *cssnode,
+ gboolean visible);
+gboolean gtk_css_node_get_visible (GtkCssNode *cssnode);
+
void gtk_css_node_set_widget_type (GtkCssNode *cssnode,
GType widget_type);
GType gtk_css_node_get_widget_type (GtkCssNode *cssnode);
diff --git a/gtk/gtkcsswidgetnode.c b/gtk/gtkcsswidgetnode.c
index 5c89a98..d142c93 100644
--- a/gtk/gtkcsswidgetnode.c
+++ b/gtk/gtkcsswidgetnode.c
@@ -294,6 +294,8 @@ gtk_css_widget_node_new (GtkWidget *widget)
result = g_object_new (GTK_TYPE_CSS_WIDGET_NODE, NULL);
result->widget = widget;
+ gtk_css_node_set_visible (GTK_CSS_NODE (result),
+ gtk_widget_get_visible (widget));
return GTK_CSS_NODE (result);
}
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 9dc3eeb..ab31a82 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -4869,6 +4869,8 @@ gtk_widget_show (GtkWidget *widget)
gtk_widget_queue_compute_expand (widget->priv->parent);
}
+ gtk_css_node_set_visible (widget->priv->cssnode, TRUE);
+
g_signal_emit (widget, widget_signals[SHOW], 0);
g_object_notify (G_OBJECT (widget), "visible");
@@ -4967,6 +4969,8 @@ gtk_widget_hide (GtkWidget *widget)
gtk_widget_queue_compute_expand (widget);
}
+ gtk_css_node_set_visible (widget->priv->cssnode, FALSE);
+
g_signal_emit (widget, widget_signals[HIDE], 0);
if (!gtk_widget_is_toplevel (widget))
gtk_widget_queue_resize (widget);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]