[gtk/columnview-scrolling: 2/2] columnview: Implement horizontal scrolling
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/columnview-scrolling: 2/2] columnview: Implement horizontal scrolling
- Date: Sun, 31 May 2020 14:56:13 +0000 (UTC)
commit 16704147ba06f38c658585169f4f67a438c25f60
Author: Matthias Clasen <mclasen redhat com>
Date: Tue Dec 17 00:34:14 2019 -0500
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 in size_allocate.
docs/reference/gtk/gtk4-sections.txt | 2 +
gtk/gtkcolumnview.c | 50 ++++++++++++++++---
gtk/gtkcolumnviewcell.c | 8 +++
gtk/gtkcolumnviewcolumn.c | 95 ++++++++++++++++++++++++++++++++++++
gtk/gtkcolumnviewcolumn.h | 7 +++
gtk/gtkcolumnviewtitle.c | 8 +++
6 files changed, 163 insertions(+), 7 deletions(-)
---
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index 808ef6fc4b..775ad3021f 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -530,6 +530,8 @@ gtk_column_view_column_set_title
gtk_column_view_column_get_title
gtk_column_view_column_set_sorter
gtk_column_view_column_get_sorter
+gtk_column_view_column_set_fixed_width
+gtk_column_view_column_get_fixed_width
<SUBSECTION Standard>
GTK_COLUMN_VIEW_COLUMN
GTK_COLUMN_VIEW_COLUMN_CLASS
diff --git a/gtk/gtkcolumnview.c b/gtk/gtkcolumnview.c
index 503c4c41b1..e190b812bc 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;
diff --git a/gtk/gtkcolumnviewcell.c b/gtk/gtkcolumnviewcell.c
index ecaa39dd46..766e79736e 100644
--- a/gtk/gtkcolumnviewcell.c
+++ b/gtk/gtkcolumnviewcell.c
@@ -53,10 +53,18 @@ gtk_column_view_cell_measure (GtkWidget *widget,
int *minimum_baseline,
int *natural_baseline)
{
+ GtkColumnViewCell *cell = GTK_COLUMN_VIEW_CELL (widget);
GtkWidget *child = gtk_widget_get_first_child (widget);
if (child)
gtk_widget_measure (child, orientation, for_size, minimum, natural, minimum_baseline, natural_baseline);
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ int fixed_width = gtk_column_view_column_get_fixed_width (cell->column);
+ if (fixed_width > -1)
+ *minimum = *natural = fixed_width;
+ }
}
static void
diff --git a/gtk/gtkcolumnviewcolumn.c b/gtk/gtkcolumnviewcolumn.c
index de240b0d4e..bbedd6906d 100644
--- a/gtk/gtkcolumnviewcolumn.c
+++ b/gtk/gtkcolumnviewcolumn.c
@@ -61,6 +61,8 @@ struct _GtkColumnViewColumn
int allocation_offset;
int allocation_size;
+ int fixed_width;
+
/* This list isn't sorted - this is just caching for performance */
GtkColumnViewCell *first_cell; /* no reference, just caching */
};
@@ -77,6 +79,7 @@ enum
PROP_FACTORY,
PROP_TITLE,
PROP_SORTER,
+ PROP_FIXED_WIDTH,
N_PROPS
};
@@ -126,6 +129,10 @@ gtk_column_view_column_get_property (GObject *object,
g_value_set_object (value, self->sorter);
break;
+ case PROP_FIXED_WIDTH:
+ g_value_set_int (value, self->fixed_width);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -154,6 +161,10 @@ gtk_column_view_column_set_property (GObject *object,
gtk_column_view_column_set_sorter (self, g_value_get_object (value));
break;
+ case PROP_FIXED_WIDTH:
+ gtk_column_view_column_set_fixed_width (self, g_value_get_int (value));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -217,6 +228,19 @@ gtk_column_view_column_class_init (GtkColumnViewColumnClass *klass)
GTK_TYPE_SORTER,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
+ /**
+ * GtkColumnViewColumn:fixed-width:
+ *
+ * If not -1, this is the width that the column is allocated,
+ * regardless of the size of its content.
+ */
+ properties[PROP_FIXED_WIDTH] =
+ g_param_spec_int ("fixed-width",
+ P_("Fixed width"),
+ P_("Fixed width of this column"),
+ -1, G_MAXINT, -1,
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
+
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
@@ -225,6 +249,8 @@ gtk_column_view_column_init (GtkColumnViewColumn *self)
{
self->minimum_size_request = -1;
self->natural_size_request = -1;
+
+ self->fixed_width = -1;
}
/**
@@ -333,6 +359,12 @@ gtk_column_view_column_measure (GtkColumnViewColumn *self,
int *minimum,
int *natural)
{
+ if (self->fixed_width > -1)
+ {
+ self->minimum_size_request = self->fixed_width;
+ self->natural_size_request = self->fixed_width;
+ }
+
if (self->minimum_size_request < 0)
{
GtkColumnViewCell *cell;
@@ -647,3 +679,66 @@ gtk_column_view_column_notify_sort (GtkColumnViewColumn *self)
if (self->header)
gtk_column_view_title_update (GTK_COLUMN_VIEW_TITLE (self->header));
}
+
+/**
+ * gtk_column_view_column_set_fixed_width:
+ * @self: a #GtkColumnViewColumn
+ * @fixed_width: the new fixed width, or -1
+ *
+ * If @fixed_width is not -1, sets the fixed width of @column;
+ * otherwise unsets it.
+ *
+ * Setting a fixed width overrides the automatically calculated
+ * width. Interactive resizing also sets the “fixed-width” property.
+ */
+void
+gtk_column_view_column_set_fixed_width (GtkColumnViewColumn *self,
+ int fixed_width)
+{
+ GtkOverflow overflow;
+ GtkColumnViewCell *cell;
+
+ g_return_if_fail (GTK_IS_COLUMN_VIEW_COLUMN (self));
+ g_return_if_fail (fixed_width >= -1);
+
+ if (self->fixed_width == fixed_width)
+ return;
+
+ self->fixed_width = fixed_width;
+
+ if (fixed_width > -1)
+ overflow = GTK_OVERFLOW_HIDDEN;
+ else
+ overflow = GTK_OVERFLOW_VISIBLE;
+
+ if (overflow != gtk_widget_get_overflow (GTK_WIDGET (self->header)))
+ {
+ if (self->header)
+ gtk_widget_set_overflow (GTK_WIDGET (self->header), overflow);
+
+ for (cell = self->first_cell; cell; cell = gtk_column_view_cell_get_next (cell))
+ {
+ gtk_widget_set_overflow (GTK_WIDGET (cell), overflow);
+ }
+ }
+
+ gtk_column_view_column_queue_resize (self);
+
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FIXED_WIDTH]);
+}
+
+/**
+ * gtk_column_view_column_get_fixed_width:
+ * @self: a #GtkColumnViewColumn
+ *
+ * Gets the fixed width of the column.
+ *
+ * Returns: the fixed with of the column
+ */
+int
+gtk_column_view_column_get_fixed_width (GtkColumnViewColumn *self)
+{
+ g_return_val_if_fail (GTK_IS_COLUMN_VIEW_COLUMN (self), -1);
+
+ return self->fixed_width;
+}
diff --git a/gtk/gtkcolumnviewcolumn.h b/gtk/gtkcolumnviewcolumn.h
index f74cedaa08..14deb8b480 100644
--- a/gtk/gtkcolumnviewcolumn.h
+++ b/gtk/gtkcolumnviewcolumn.h
@@ -72,6 +72,13 @@ void gtk_column_view_column_set_sorter (GtkColu
GDK_AVAILABLE_IN_ALL
GtkSorter * gtk_column_view_column_get_sorter (GtkColumnViewColumn *self);
+
+GDK_AVAILABLE_IN_ALL
+void gtk_column_view_column_set_fixed_width (GtkColumnViewColumn *self,
+ int
fixed_width);
+GDK_AVAILABLE_IN_ALL
+int gtk_column_view_column_get_fixed_width (GtkColumnViewColumn *self);
+
G_END_DECLS
#endif /* __GTK_COLUMN_VIEW_COLUMN_H__ */
diff --git a/gtk/gtkcolumnviewtitle.c b/gtk/gtkcolumnviewtitle.c
index 306064bcd8..e6bcf0ef5f 100644
--- a/gtk/gtkcolumnviewtitle.c
+++ b/gtk/gtkcolumnviewtitle.c
@@ -58,10 +58,18 @@ gtk_column_view_title_measure (GtkWidget *widget,
int *minimum_baseline,
int *natural_baseline)
{
+ GtkColumnViewTitle *self = GTK_COLUMN_VIEW_TITLE (widget);
GtkWidget *child = gtk_widget_get_first_child (widget);
if (child)
gtk_widget_measure (child, orientation, for_size, minimum, natural, minimum_baseline, natural_baseline);
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ int fixed_width = gtk_column_view_column_get_fixed_width (self->column);
+ if (fixed_width > -1)
+ *minimum = *natural = fixed_width;
+ }
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]