Merge branch 'columnview-scrolling' into 'master'
columnview: Implement horizontal scrolling See merge request GNOME/gtk!1998
This commit is contained in:
@@ -34,6 +34,8 @@
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkscrollable.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtksizerequest.h"
|
||||
#include "gtkadjustment.h"
|
||||
|
||||
/**
|
||||
* SECTION:gtkcolumnview
|
||||
@@ -63,6 +65,8 @@ struct _GtkColumnView
|
||||
GtkColumnListItemFactory *factory;
|
||||
|
||||
GtkSorter *sorter;
|
||||
|
||||
GtkAdjustment *hadjustment;
|
||||
};
|
||||
|
||||
struct _GtkColumnViewClass
|
||||
@@ -169,48 +173,55 @@ 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;
|
||||
|
||||
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
|
||||
@@ -220,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);
|
||||
@@ -229,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
|
||||
@@ -244,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)
|
||||
{
|
||||
@@ -262,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);
|
||||
}
|
||||
@@ -291,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:
|
||||
@@ -335,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;
|
||||
|
||||
Reference in New Issue
Block a user