diff options
author | Christian Hergert <christian@hergert.me> | 2015-05-29 20:03:11 -0700 |
---|---|---|
committer | Christian Hergert <christian@hergert.me> | 2015-05-29 20:03:11 -0700 |
commit | aa07c40748777d38b726863475794255551bb52b (patch) | |
tree | 12a64478dea2157e2a4b0c26d0c2ed783f204ad5 /gtk/gtklistbox.c | |
parent | bb93c1cecd23e487d04e005cb89eb09f8d4e2d0b (diff) | |
download | gtk+-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.c | 45 |
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); |