summaryrefslogtreecommitdiff
path: root/gtk/gtklistbox.c
diff options
context:
space:
mode:
authorChristian Hergert <christian@hergert.me>2015-05-29 20:03:11 -0700
committerChristian Hergert <christian@hergert.me>2015-05-29 20:03:11 -0700
commitaa07c40748777d38b726863475794255551bb52b (patch)
tree12a64478dea2157e2a4b0c26d0c2ed783f204ad5 /gtk/gtklistbox.c
parentbb93c1cecd23e487d04e005cb89eb09f8d4e2d0b (diff)
downloadgtk+-aa07c40748777d38b726863475794255551bb52b.tar.gz
listbox: add support for :first-child, :last-child and others
This applies the proper CSS child ordering semantics using GtkCssNode to GtkListBox. You can now use :first-child, :last-child, :nth-child(), and :last-nth-child() selectors. For example, this allows styling row separators using CSS while ignoring the separator on the last row. GtkListBoxRow { border-bottom: 1px solid @borders; } GtkListBoxRow:last-child { border-bottom: none; } When the sort ordering of the listbox changes, we also update the CSS node ordering.
Diffstat (limited to 'gtk/gtklistbox.c')
-rw-r--r--gtk/gtklistbox.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/gtk/gtklistbox.c b/gtk/gtklistbox.c
index 554cd42c98..9e6286185e 100644
--- a/gtk/gtklistbox.c
+++ b/gtk/gtklistbox.c
@@ -18,6 +18,7 @@
#include "config.h"
#include "gtkadjustmentprivate.h"
+#include "gtkcssnodeprivate.h"
#include "gtklistbox.h"
#include "gtkwidget.h"
#include "gtkmarshalers.h"
@@ -1166,6 +1167,25 @@ do_sort (GtkListBoxRow *a,
return priv->sort_func (a, b, priv->sort_func_target);
}
+static void
+gtk_list_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_list_box_invalidate_sort:
* @box: a #GtkListBox
@@ -1180,10 +1200,12 @@ void
gtk_list_box_invalidate_sort (GtkListBox *box)
{
GtkListBoxPrivate *priv = BOX_PRIV (box);
+ GtkWidget *previous = NULL;
g_return_if_fail (GTK_IS_LIST_BOX (box));
g_sequence_sort (priv->children, (GCompareDataFunc)do_sort, box);
+ g_sequence_foreach (priv->children, gtk_list_box_css_node_foreach, &previous);
gtk_list_box_invalidate_headers (box);
gtk_widget_queue_resize (GTK_WIDGET (box));
@@ -2599,6 +2621,27 @@ gtk_list_box_prepend (GtkListBox *box,
gtk_list_box_insert (box, child, 0);
}
+static void
+gtk_list_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_list_box_insert:
* @box: a #GtkListBox
@@ -2650,6 +2693,8 @@ gtk_list_box_insert (GtkListBox *box,
iter = g_sequence_insert_before (current_iter, row);
}
+ gtk_list_box_insert_css_node (box, GTK_WIDGET (row), iter);
+
ROW_PRIV (row)->iter = iter;
gtk_widget_set_parent (GTK_WIDGET (row), GTK_WIDGET (box));
gtk_widget_set_child_visible (GTK_WIDGET (row), TRUE);