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.
This commit is contained in:
@@ -532,6 +532,8 @@ gtk_column_view_column_set_sorter
|
||||
gtk_column_view_column_get_sorter
|
||||
gtk_column_view_column_set_visible
|
||||
gtk_column_view_column_get_visible
|
||||
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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -61,6 +61,8 @@ struct _GtkColumnViewColumn
|
||||
int allocation_offset;
|
||||
int allocation_size;
|
||||
|
||||
int fixed_width;
|
||||
|
||||
gboolean visible;
|
||||
|
||||
/* This list isn't sorted - this is just caching for performance */
|
||||
@@ -80,6 +82,7 @@ enum
|
||||
PROP_TITLE,
|
||||
PROP_SORTER,
|
||||
PROP_VISIBLE,
|
||||
PROP_FIXED_WIDTH,
|
||||
|
||||
N_PROPS
|
||||
};
|
||||
@@ -133,6 +136,10 @@ gtk_column_view_column_get_property (GObject *object,
|
||||
g_value_set_boolean (value, self->visible);
|
||||
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;
|
||||
@@ -165,6 +172,10 @@ gtk_column_view_column_set_property (GObject *object,
|
||||
gtk_column_view_column_set_visible (self, g_value_get_boolean (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;
|
||||
@@ -240,6 +251,19 @@ gtk_column_view_column_class_init (GtkColumnViewColumnClass *klass)
|
||||
TRUE,
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -249,6 +273,7 @@ gtk_column_view_column_init (GtkColumnViewColumn *self)
|
||||
self->minimum_size_request = -1;
|
||||
self->natural_size_request = -1;
|
||||
self->visible = TRUE;
|
||||
self->fixed_width = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -357,6 +382,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;
|
||||
@@ -721,3 +752,66 @@ gtk_column_view_column_get_visible (GtkColumnViewColumn *self)
|
||||
|
||||
return self->visible;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
@@ -78,6 +78,12 @@ void gtk_column_view_column_set_visible (GtkColu
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_column_view_column_get_visible (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__ */
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user