From befdd8bb66685d000a3191025a1523571302d988 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 16 Dec 2019 19:22:03 -0500 Subject: [PATCH 1/2] columnview: Revise scroll-minimum handling Tweak the behavior slightly. We don't show a scrollbar as long as we have at least min-size available, but we still give the entire size to the child, up to nat-size. This matches how viewports handle scroll-minimum. --- gtk/gtkcolumnview.c | 66 +++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/gtk/gtkcolumnview.c b/gtk/gtkcolumnview.c index e94875ae71..2f62aec830 100644 --- a/gtk/gtkcolumnview.c +++ b/gtk/gtkcolumnview.c @@ -34,6 +34,7 @@ #include "gtkprivate.h" #include "gtkscrollable.h" #include "gtkwidgetprivate.h" +#include "gtksizerequest.h" /** * SECTION:gtkcolumnview @@ -171,46 +172,53 @@ gtk_column_view_allocate_columns (GtkColumnView *self, GtkScrollablePolicy scroll_policy; int col_min, col_nat, widget_min, widget_nat, extra, col_size, x; guint i; + int n; + GtkRequestedSize *sizes; - gtk_column_view_measure_across (self, &col_min, &col_nat); - gtk_widget_measure (GTK_WIDGET (self), - GTK_ORIENTATION_HORIZONTAL, -1, - &widget_min, &widget_nat, - NULL, NULL); - - scroll_policy = gtk_scrollable_get_hscroll_policy (GTK_SCROLLABLE (self->listview)); - if (scroll_policy == GTK_SCROLL_MINIMUM) - { - extra = widget_min - col_min; - col_size = col_min; - } - else - { - extra = widget_nat - col_nat; - col_size = col_nat; - } - width -= extra; - width = MAX (width, col_size); - - x = 0; - for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (self->columns)); i++) + n = g_list_model_get_n_items (G_LIST_MODEL (self->columns)); + sizes = g_newa (GtkRequestedSize, n); + for (i = 0; i < n; i++) { GtkColumnViewColumn *column; column = g_list_model_get_item (G_LIST_MODEL (self->columns), i); - gtk_column_view_column_measure (column, &col_min, &col_nat); - if (scroll_policy == GTK_SCROLL_MINIMUM) - col_size = col_min; + if (gtk_column_view_column_get_visible (column)) + gtk_column_view_column_measure (column, &sizes[i].minimum_size, &sizes[i].natural_size); else - col_size = col_nat; + sizes[i].minimum_size = sizes[i].natural_size = 0; + g_object_unref (column); + } - gtk_column_view_column_allocate (column, x, col_size); - x += col_size; + gtk_column_view_measure_across (self, &col_min, &col_nat); + + scroll_policy = gtk_scrollable_get_hscroll_policy (GTK_SCROLLABLE (self->listview)); + if (scroll_policy == GTK_SCROLL_MINIMUM) + { + extra = MAX (width - col_min, 0); + gtk_distribute_natural_allocation (extra, n, sizes); + } + + x = 0; + for (i = 0; i < n; i++) + { + GtkColumnViewColumn *column; + + column = g_list_model_get_item (G_LIST_MODEL (self->columns), i); + if (gtk_column_view_column_get_visible (column)) + { + if (scroll_policy == GTK_SCROLL_MINIMUM) + col_size = sizes[i].minimum_size; + else + col_size = sizes[i].natural_size; + + gtk_column_view_column_allocate (column, x, col_size); + x += col_size; + } g_object_unref (column); } - return width + extra; + return x; } static void From f0a0e20b2fb64d8961f58f046949ed363d6e3d36 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 31 May 2020 21:09:00 -0400 Subject: [PATCH 2/2] columnview: Implement horizontal scrolling The listview inside always thinks it gets its full size, and updates its horizontal adjustment accordingly. So keep our own adjustment, and update it when allocating. --- gtk/gtkcolumnview.c | 50 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/gtk/gtkcolumnview.c b/gtk/gtkcolumnview.c index 2f62aec830..84a85a4aa5 100644 --- a/gtk/gtkcolumnview.c +++ b/gtk/gtkcolumnview.c @@ -35,6 +35,7 @@ #include "gtkscrollable.h" #include "gtkwidgetprivate.h" #include "gtksizerequest.h" +#include "gtkadjustment.h" /** * SECTION:gtkcolumnview @@ -64,6 +65,8 @@ struct _GtkColumnView GtkColumnListItemFactory *factory; GtkSorter *sorter; + + GtkAdjustment *hadjustment; }; struct _GtkColumnViewClass @@ -170,7 +173,7 @@ gtk_column_view_allocate_columns (GtkColumnView *self, int width) { GtkScrollablePolicy scroll_policy; - int col_min, col_nat, widget_min, widget_nat, extra, col_size, x; + int col_min, col_nat, extra, col_size, x; guint i; int n; GtkRequestedSize *sizes; @@ -228,8 +231,9 @@ gtk_column_view_allocate (GtkWidget *widget, int baseline) { GtkColumnView *self = GTK_COLUMN_VIEW (widget); - int full_width, header_height, min, nat; + int full_width, header_height, min, nat, x; + x = gtk_adjustment_get_value (self->hadjustment); full_width = gtk_column_view_allocate_columns (self, width); gtk_widget_measure (self->header, GTK_ORIENTATION_VERTICAL, full_width, &min, &nat, NULL, NULL); @@ -237,11 +241,14 @@ gtk_column_view_allocate (GtkWidget *widget, header_height = min; else header_height = nat; - gtk_widget_allocate (self->header, full_width, header_height, -1, NULL); + gtk_widget_allocate (self->header, full_width, header_height, -1, + gsk_transform_translate (NULL, &GRAPHENE_POINT_INIT (-x, 0))); gtk_widget_allocate (GTK_WIDGET (self->listview), full_width, height - header_height, -1, - gsk_transform_translate (NULL, &GRAPHENE_POINT_INIT (0, header_height))); + gsk_transform_translate (NULL, &GRAPHENE_POINT_INIT (-x, header_height))); + + gtk_adjustment_configure (self->hadjustment, x, 0, full_width, width * 0.1, width * 0.9, width); } static void @@ -252,6 +259,23 @@ gtk_column_view_activate_cb (GtkListView *listview, g_signal_emit (self, signals[ACTIVATE], 0, pos); } +static void +adjustment_value_changed_cb (GtkAdjustment *adjustment, + GtkColumnView *self) +{ + gtk_widget_queue_allocate (GTK_WIDGET (self)); +} + +static void +clear_adjustment (GtkColumnView *self) +{ + if (self->hadjustment == NULL) + return; + + g_signal_handlers_disconnect_by_func (self->hadjustment, adjustment_value_changed_cb, self); + g_clear_object (&self->hadjustment); +} + static void gtk_column_view_dispose (GObject *object) { @@ -270,6 +294,7 @@ gtk_column_view_dispose (GObject *object) g_clear_object (&self->factory); g_clear_object (&self->sorter); + clear_adjustment (self); G_OBJECT_CLASS (gtk_column_view_parent_class)->dispose (object); } @@ -299,7 +324,7 @@ gtk_column_view_get_property (GObject *object, break; case PROP_HADJUSTMENT: - g_value_set_object (value, gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (self->listview))); + g_value_set_object (value, self->hadjustment); break; case PROP_HSCROLL_POLICY: @@ -343,13 +368,24 @@ gtk_column_view_set_property (GObject *object, GParamSpec *pspec) { GtkColumnView *self = GTK_COLUMN_VIEW (object); + GtkAdjustment *adjustment; switch (property_id) { case PROP_HADJUSTMENT: - if (gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (self->listview)) != g_value_get_object (value)) + adjustment = g_value_get_object (value); + if (adjustment == NULL) + adjustment = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0); + g_object_ref_sink (adjustment); + + if (self->hadjustment != adjustment) { - gtk_scrollable_set_hadjustment (GTK_SCROLLABLE (self->listview), g_value_get_object (value)); + clear_adjustment (self); + + self->hadjustment = adjustment; + + g_signal_connect (adjustment, "value-changed", G_CALLBACK (adjustment_value_changed_cb), self); + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_HADJUSTMENT]); } break;