From e59e38b58120f8d998b5e204506fc552e2efd00d Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 29 May 2015 23:37:42 -0400 Subject: [PATCH] GtkFlowBox: support positional css selectors As in the previous commit for GtkListBox, support :first-child, :last-child, :nth-child() and :last-nth-child() selectors here. --- gtk/gtkflowbox.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/gtk/gtkflowbox.c b/gtk/gtkflowbox.c index 9e9e840145..66cff35c37 100644 --- a/gtk/gtkflowbox.c +++ b/gtk/gtkflowbox.c @@ -60,6 +60,7 @@ #include "gtkprivate.h" #include "gtkorientableprivate.h" #include "gtkintl.h" +#include "gtkcssnodeprivate.h" #include "a11y/gtkflowboxaccessibleprivate.h" #include "a11y/gtkflowboxchildaccessible.h" @@ -4006,6 +4007,27 @@ gtk_flow_box_new (void) return (GtkWidget *)g_object_new (GTK_TYPE_FLOW_BOX, NULL); } +static void +gtk_flow_box_insert_css_node (GtkListBox *box, + GtkWidget *child, + GSequenceIter *iter) +{ + GSequenceIter *prev_iter; + GtkCssNode *child_node; + GtkCssNode *sibling_node; + GtkWidget *sibling; + + child_node = gtk_widget_get_css_node (child); + prev_iter = g_sequence_iter_prev (iter); + + if (prev_iter != iter) + { + sibling = g_sequence_get (prev_iter); + sibling_node = gtk_widget_get_css_node (sibling); + gtk_css_node_set_after (child_node, sibling_node); + } +} + /** * gtk_flow_box_insert: * @box: a #GtkFlowBox @@ -4060,6 +4082,8 @@ gtk_flow_box_insert (GtkFlowBox *box, iter = g_sequence_insert_before (pos, child); } + gtk_flow_box_insert_css_node (box, GTK_WIDGET (child), iter); + CHILD_PRIV (child)->iter = iter; gtk_widget_set_parent (GTK_WIDGET (child), GTK_WIDGET (box)); gtk_flow_box_apply_filter (box, child); @@ -4806,6 +4830,25 @@ gtk_flow_box_sort (GtkFlowBoxChild *a, return priv->sort_func (a, b, priv->sort_data); } +static void +gtk_flow_box_css_node_foreach (gpointer data, + gpointer user_data) +{ + GtkWidget **previous = user_data; + GtkWidget *row = data; + GtkCssNode *row_node; + GtkCssNode *prev_node; + + if (*previous) + { + prev_node = gtk_widget_get_css_node (*previous); + row_node = gtk_widget_get_css_node (row); + gtk_css_node_set_after (row_node, prev_node); + } + + *previous = row; +} + /** * gtk_flow_box_invalidate_sort: * @box: a #GtkFlowBox @@ -4821,6 +4864,7 @@ void gtk_flow_box_invalidate_sort (GtkFlowBox *box) { GtkFlowBoxPrivate *priv; + GtkWidget *previous = NULL; g_return_if_fail (GTK_IS_FLOW_BOX (box)); @@ -4828,8 +4872,8 @@ gtk_flow_box_invalidate_sort (GtkFlowBox *box) if (priv->sort_func != NULL) { - g_sequence_sort (priv->children, - (GCompareDataFunc)gtk_flow_box_sort, box); + g_sequence_sort (priv->children, (GCompareDataFunc)gtk_flow_box_sort, box); + g_sequence_foreach (priv->children, gtk_flow_box_css_node_foreach, &previous); gtk_widget_queue_resize (GTK_WIDGET (box)); } }