mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-27 06:00:22 +00:00
cssnode: Add visibility concept
This allows hiding nodes of invisible widgets. And that in turn makes sure :nth-child() works as expected.
This commit is contained in:
parent
ee91fb71ca
commit
2694545468
@ -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;
|
||||
|
@ -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
|
||||
@ -564,6 +568,25 @@ gtk_css_node_get_style (GtkCssNode *cssnode)
|
||||
return cssnode->style;
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user