[gtk+/wip/baedert/listbox-child-invisible] GtkListBox: Set invisible rows to child-invisible
- From: Timm Bäder <baedert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/baedert/listbox-child-invisible] GtkListBox: Set invisible rows to child-invisible
- Date: Tue, 12 Jan 2016 18:47:18 +0000 (UTC)
commit 48fed20825cc01cefba470a1d3c1400c245eb5c4
Author: Timm Bäder <mail baedert org>
Date: Wed Jan 6 13:40:03 2016 +0100
GtkListBox: Set invisible rows to child-invisible
gtk/gtklistbox.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 115 insertions(+), 7 deletions(-)
---
diff --git a/gtk/gtklistbox.c b/gtk/gtklistbox.c
index 3b2c1ac..6d5aabb 100644
--- a/gtk/gtklistbox.c
+++ b/gtk/gtklistbox.c
@@ -972,13 +972,94 @@ gtk_list_box_set_placeholder (GtkListBox *box,
if (placeholder)
{
- gtk_widget_set_parent (GTK_WIDGET (placeholder), GTK_WIDGET (box));
- gtk_widget_set_child_visible (GTK_WIDGET (placeholder),
+ gtk_widget_set_parent (placeholder, GTK_WIDGET (box));
+ gtk_widget_set_child_visible (placeholder,
priv->n_visible_rows == 0);
}
}
+static int
+row_allocation_y_cmp (gconstpointer a,
+ gconstpointer b,
+ gpointer user_data)
+{
+ int y = GPOINTER_TO_INT (b);
+ GtkListBoxRowPrivate *row_priv = ROW_PRIV (a);
+
+ if (y >= row_priv->y && y < (row_priv->y + row_priv->height))
+ {
+ return 0;
+ }
+ else if (row_priv->header)
+ {
+ /* Headers are separate widgets, belong to one row and aren't part of that row's
+ * priv->height, priv->y, or allocation... */
+ GtkAllocation header_alloc;
+ gtk_widget_get_allocated_size (row_priv->header, &header_alloc, NULL);
+ g_assert (header_alloc.y <= row_priv->y);
+ if (y >= header_alloc.y && y < (header_alloc.y + header_alloc.height))
+ return 0;
+ else if (y < header_alloc.y)
+ return 1;
+ else if (y > header_alloc.y + header_alloc.height)
+ return -1;
+ }
+ else if (y < row_priv->y)
+ {
+ return 1;
+ }
+
+ return -1;
+}
+
+
+static void
+apply_child_visibility (GtkListBox *box, int from, int to, gboolean setting)
+{
+ GtkListBoxPrivate *priv = BOX_PRIV (box);
+ GSequenceIter *top_iter, *bottom_iter, *iter;
+
+ top_iter = g_sequence_lookup (priv->children,
+ GINT_TO_POINTER (from),
+ row_allocation_y_cmp,
+ NULL);
+
+ if (!top_iter)
+ return;
+
+ bottom_iter = g_sequence_lookup (priv->children,
+ GINT_TO_POINTER (to),
+ row_allocation_y_cmp,
+ NULL);
+
+ if (!bottom_iter)
+ bottom_iter = g_sequence_get_end_iter (priv->children);
+ else if (bottom_iter != g_sequence_get_end_iter (priv->children))
+ bottom_iter = g_sequence_iter_next (bottom_iter);
+
+ for (iter = top_iter;
+ iter != bottom_iter;
+ iter = g_sequence_iter_next (iter))
+ gtk_widget_set_child_visible (GTK_WIDGET (g_sequence_get (iter)), setting);
+}
+
+static void
+adjustment_changed_cb (GtkAdjustment *source, gpointer user_data)
+{
+ static int old_value;
+ static int old_page_size;
+
+ int value = (int)gtk_adjustment_get_value (source);
+ int page_size = (int)gtk_adjustment_get_page_size (source);
+
+ apply_child_visibility (user_data, old_value, old_value + old_page_size, FALSE);
+ apply_child_visibility (user_data, value, value + page_size, TRUE);
+
+ old_value = value;
+ old_page_size = page_size;
+}
+
/**
* gtk_list_box_set_adjustment:
* @box: a #GtkListBox
@@ -1005,9 +1086,21 @@ gtk_list_box_set_adjustment (GtkListBox *box,
g_return_if_fail (adjustment == NULL || GTK_IS_ADJUSTMENT (adjustment));
if (adjustment)
- g_object_ref_sink (adjustment);
+ {
+ g_signal_connect (G_OBJECT (adjustment),
+ "value-changed",
+ G_CALLBACK (adjustment_changed_cb),
+ box);
+ g_object_ref_sink (adjustment);
+ }
if (priv->adjustment)
- g_object_unref (priv->adjustment);
+ {
+ if (priv->adjustment != adjustment)
+ g_signal_handlers_disconnect_by_func (G_OBJECT (priv->adjustment),
+ adjustment_changed_cb,
+ box);
+ g_object_unref (priv->adjustment);
+ }
priv->adjustment = adjustment;
}
@@ -1226,6 +1319,12 @@ gtk_list_box_invalidate_filter (GtkListBox *box)
{
g_return_if_fail (GTK_IS_LIST_BOX (box));
+ if (BOX_PRIV (box)->filter_func == NULL)
+ {
+ g_warning ("%s called on GtkListBox instance %p, which has no filter function set.", __FUNCTION__,
box);
+ return;
+ }
+
gtk_list_box_apply_filter_all (box);
gtk_list_box_invalidate_headers (box);
gtk_widget_queue_resize (GTK_WIDGET (box));
@@ -2184,7 +2283,7 @@ list_box_add_visible_rows (GtkListBox *box,
if (priv->placeholder &&
(was_zero || priv->n_visible_rows == 0))
- gtk_widget_set_child_visible (GTK_WIDGET (priv->placeholder),
+ gtk_widget_set_child_visible (priv->placeholder,
priv->n_visible_rows == 0);
}
@@ -2695,6 +2794,7 @@ static void
gtk_list_box_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
+ GtkListBoxPrivate *priv = BOX_PRIV (widget);
GtkAllocation clip;
GdkWindow *window;
GtkAllocation child_allocation;
@@ -2718,6 +2818,10 @@ gtk_list_box_size_allocate (GtkWidget *widget,
&clip);
_gtk_widget_set_simple_clip (widget, &clip);
+
+ // XXX Maybe rename the function...
+ if (priv->adjustment)
+ adjustment_changed_cb (priv->adjustment, widget);
}
@@ -2884,12 +2988,16 @@ gtk_list_box_insert (GtkListBox *box,
ROW_PRIV (row)->iter = iter;
gtk_widget_set_parent (GTK_WIDGET (row), GTK_WIDGET (box));
- gtk_widget_set_child_visible (GTK_WIDGET (row), TRUE);
+ gtk_widget_set_child_visible (GTK_WIDGET (row), (priv->adjustment == NULL));
ROW_PRIV (row)->visible = gtk_widget_get_visible (GTK_WIDGET (row));
if (ROW_PRIV (row)->visible)
list_box_add_visible_rows (box, 1);
- gtk_list_box_apply_filter (box, row);
+
+ if (priv->filter_func)
+ gtk_list_box_apply_filter (box, row);
+
gtk_list_box_update_row_style (box, row);
+
if (gtk_widget_get_visible (GTK_WIDGET (box)))
{
gtk_list_box_update_header (box, ROW_PRIV (row)->iter);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]