From c9d5b77403c19fa851616e9b7857a7b8c1cbf362 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 20 Dec 2019 17:19:55 -0500 Subject: [PATCH 2/7] columnviewcolumn: Add reordering helpers Add helper functions that let us temporarily give a different allocation to headers. These will be used to implement interactive column reordering in GtkColumnView. --- gtk/gtkcolumnviewcolumn.c | 21 +++++++++++++++++++++ gtk/gtkcolumnviewcolumnprivate.h | 6 ++++++ 2 files changed, 27 insertions(+) diff --git a/gtk/gtkcolumnviewcolumn.c b/gtk/gtkcolumnviewcolumn.c index 6a09209648..8879457a7f 100644 --- a/gtk/gtkcolumnviewcolumn.c +++ b/gtk/gtkcolumnviewcolumn.c @@ -60,6 +60,7 @@ struct _GtkColumnViewColumn int natural_size_request; int allocation_offset; int allocation_size; + int header_position; int fixed_width; @@ -478,6 +479,7 @@ gtk_column_view_column_allocate (GtkColumnViewColumn *self, { self->allocation_offset = offset; self->allocation_size = size; + self->header_position = offset; } void @@ -947,3 +949,22 @@ gtk_column_view_column_get_header (GtkColumnViewColumn *self) { return self->header; } + +void +gtk_column_view_column_set_header_position (GtkColumnViewColumn *self, + int offset) +{ + self->header_position = offset; +} + +void +gtk_column_view_column_get_header_allocation (GtkColumnViewColumn *self, + int *offset, + int *size) +{ + if (offset) + *offset = self->header_position; + + if (size) + *size = self->allocation_size; +} diff --git a/gtk/gtkcolumnviewcolumnprivate.h b/gtk/gtkcolumnviewcolumnprivate.h index 925343f998..2fa9afa989 100644 --- a/gtk/gtkcolumnviewcolumnprivate.h +++ b/gtk/gtkcolumnviewcolumnprivate.h @@ -48,4 +48,10 @@ void gtk_column_view_column_get_allocation (GtkColu void gtk_column_view_column_notify_sort (GtkColumnViewColumn *self); +void gtk_column_view_column_set_header_position (GtkColumnViewColumn *self, + int offset); +void gtk_column_view_column_get_header_allocation (GtkColumnViewColumn *self, + int *offset, + int *size); + #endif /* __GTK_COLUMN_VIEW_COLUMN_PRIVATE_H__ */ From e6376931315e493c002a0aa382ec6a5c222e3b71 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 20 Dec 2019 17:28:37 -0500 Subject: [PATCH 3/7] columnviewlayout: Use header allocation for titles Normally, this will be identical to the column allocation, but we will temporarily change it during column reordering. --- gtk/gtkcolumnviewlayout.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/gtk/gtkcolumnviewlayout.c b/gtk/gtkcolumnviewlayout.c index c4ba28a112..05f218c525 100644 --- a/gtk/gtkcolumnviewlayout.c +++ b/gtk/gtkcolumnviewlayout.c @@ -118,11 +118,16 @@ gtk_column_view_layout_allocate (GtkLayoutManager *layout_manager, int col_x, col_width; if (GTK_IS_COLUMN_VIEW_CELL (child)) - column = gtk_column_view_cell_get_column (GTK_COLUMN_VIEW_CELL (child)); + { + column = gtk_column_view_cell_get_column (GTK_COLUMN_VIEW_CELL (child)); + gtk_column_view_column_get_allocation (column, &col_x, &col_width); + } else - column = gtk_column_view_title_get_column (GTK_COLUMN_VIEW_TITLE (child)); + { + column = gtk_column_view_title_get_column (GTK_COLUMN_VIEW_TITLE (child)); + gtk_column_view_column_get_header_allocation (column, &col_x, &col_width); + } - gtk_column_view_column_get_allocation (column, &col_x, &col_width); gtk_widget_size_allocate (child, &(GtkAllocation) { col_x, 0, col_width, height }, baseline); } } From 11b4e0d4c01f695e876664685ddd07d3f4c5f1df Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 3 Jun 2020 12:57:38 -0400 Subject: [PATCH 4/7] columnview: Add a GtkColumnView:reorderable property This property controls if users can reorder columns by drag-and-drop. It defaults to TRUE. --- docs/reference/gtk/gtk4-sections.txt | 2 + gtk/gtkcolumnview.c | 62 ++++++++++++++++++++++++++++ gtk/gtkcolumnview.h | 7 ++++ 3 files changed, 71 insertions(+) diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt index a43604c216..20f8352592 100644 --- a/docs/reference/gtk/gtk4-sections.txt +++ b/docs/reference/gtk/gtk4-sections.txt @@ -507,6 +507,8 @@ gtk_column_view_set_show_separators gtk_column_view_sort_by_column gtk_column_view_set_single_click_activate gtk_column_view_get_single_click_activate +gtk_column_view_set_reorderable +gtk_column_view_get_reorderable GTK_COLUMN_VIEW GTK_COLUMN_VIEW_CLASS diff --git a/gtk/gtkcolumnview.c b/gtk/gtkcolumnview.c index bda7cdbc61..414ca0d83d 100644 --- a/gtk/gtkcolumnview.c +++ b/gtk/gtkcolumnview.c @@ -70,6 +70,8 @@ struct _GtkColumnView GtkAdjustment *hadjustment; + gboolean reorderable; + gboolean in_column_resize; int drag_pos; int drag_x; @@ -92,6 +94,7 @@ enum PROP_VADJUSTMENT, PROP_VSCROLL_POLICY, PROP_SINGLE_CLICK_ACTIVATE, + PROP_REORDERABLE, N_PROPS }; @@ -361,6 +364,10 @@ gtk_column_view_get_property (GObject *object, g_value_set_boolean (value, gtk_column_view_get_single_click_activate (self)); break; + case PROP_REORDERABLE: + g_value_set_boolean (value, gtk_column_view_get_reorderable (self)); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -432,6 +439,10 @@ gtk_column_view_set_property (GObject *object, gtk_column_view_set_single_click_activate (self, g_value_get_boolean (value)); break; + case PROP_REORDERABLE: + gtk_column_view_set_reorderable (self, g_value_get_boolean (value)); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -528,6 +539,18 @@ gtk_column_view_class_init (GtkColumnViewClass *klass) FALSE, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY); + /** + * GtkColumnView:reorderable: + * + * Whether columns are reorderable + */ + properties[PROP_REORDERABLE] = + g_param_spec_boolean ("reorderable", + P_("Reorderable"), + P_("Whether columns are reorderable"), + TRUE, + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + g_object_class_install_properties (gobject_class, N_PROPS, properties); /** @@ -726,6 +749,8 @@ gtk_column_view_init (GtkColumnView *self) g_quark_from_static_string (I_("view"))); gtk_widget_set_overflow (GTK_WIDGET (self), GTK_OVERFLOW_HIDDEN); + + self->reorderable = TRUE; } /** @@ -1081,3 +1106,40 @@ gtk_column_view_get_single_click_activate (GtkColumnView *self) return gtk_list_view_get_single_click_activate (self->listview); } + +/** + * gtk_column_view_set_reorderable: + * @self: a #GtkColumnView + * @reorderable: whether columns should be reorderable + * + * Sets whether columns should be reorderable by dragging. + */ +void +gtk_column_view_set_reorderable (GtkColumnView *self, + gboolean reorderable) +{ + g_return_if_fail (GTK_IS_COLUMN_VIEW (self)); + + if (self->reorderable == reorderable) + return; + + self->reorderable = reorderable; + + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_REORDERABLE]); +} + +/** + * gtk_column_view_get_reorderable: + * @self: a #GtkColumnView + * + * Returns whether columns are reorderable. + * + * Returns: %TRUE if columns are reorderable + */ +gboolean +gtk_column_view_get_reorderable (GtkColumnView *self) +{ + g_return_val_if_fail (GTK_IS_COLUMN_VIEW (self), TRUE); + + return self->reorderable; +} diff --git a/gtk/gtkcolumnview.h b/gtk/gtkcolumnview.h index 0866b6449c..5cff5d73dc 100644 --- a/gtk/gtkcolumnview.h +++ b/gtk/gtkcolumnview.h @@ -92,6 +92,13 @@ void gtk_column_view_set_single_click_activate (GtkColumnView GDK_AVAILABLE_IN_ALL gboolean gtk_column_view_get_single_click_activate (GtkColumnView *self); +GDK_AVAILABLE_IN_ALL +void gtk_column_view_set_reorderable (GtkColumnView *self, + gboolean reorderable); +GDK_AVAILABLE_IN_ALL +gboolean gtk_column_view_get_reorderable (GtkColumnView *self); + + G_END_DECLS #endif /* __GTK_COLUMN_VIEW_H__ */ From 5d4893b3f0c1da67b5b4fcbfcffea1950ddded8b Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 20 Dec 2019 17:29:35 -0500 Subject: [PATCH 5/7] columnview: Interactive column reordering Allow rearranging columns by dragging, in the same way the treeview does. We add the "dnd" style class to the header while it is dragged, and we move the header of the dragged column to the end of its parents children, so that it gets drawn on top. --- gtk/gtkcolumnview.c | 130 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 129 insertions(+), 1 deletion(-) diff --git a/gtk/gtkcolumnview.c b/gtk/gtkcolumnview.c index 414ca0d83d..73704328b7 100644 --- a/gtk/gtkcolumnview.c +++ b/gtk/gtkcolumnview.c @@ -38,6 +38,7 @@ #include "gtkadjustment.h" #include "gtkgesturedrag.h" #include "gtkeventcontrollermotion.h" +#include "gtkdragsource.h" /** * SECTION:gtkcolumnview @@ -73,8 +74,11 @@ struct _GtkColumnView gboolean reorderable; gboolean in_column_resize; + gboolean in_column_reorder; int drag_pos; int drag_x; + int drag_offset; + int drag_column_x; }; struct _GtkColumnViewClass @@ -224,6 +228,9 @@ gtk_column_view_allocate_columns (GtkColumnView *self, col_size = sizes[i].natural_size; gtk_column_view_column_allocate (column, x, col_size); + if (self->in_column_reorder && i == self->drag_pos) + gtk_column_view_column_set_header_position (column, self->drag_x); + x += col_size; } @@ -602,6 +609,23 @@ gtk_column_view_in_resize_rect (GtkColumnView *self, return graphene_rect_contains_point (&rect, &(graphene_point_t) { x, y}); } +static gboolean +gtk_column_view_in_header (GtkColumnView *self, + GtkColumnViewColumn *column, + double x, + double y) +{ + GtkWidget *header; + graphene_rect_t rect; + + header = gtk_column_view_column_get_header (column); + + if (!gtk_widget_compute_bounds (header, self->header, &rect)) + return FALSE; + + return graphene_rect_contains_point (&rect, &(graphene_point_t) { x, y}); +} + static void header_drag_begin (GtkGestureDrag *gesture, double start_x, @@ -610,6 +634,8 @@ header_drag_begin (GtkGestureDrag *gesture, { int i, n; + self->drag_pos = -1; + n = g_list_model_get_n_items (G_LIST_MODEL (self->columns)); for (i = 0; !self->in_column_resize && i < n; i++) { @@ -631,6 +657,7 @@ header_drag_begin (GtkGestureDrag *gesture, gtk_column_view_column_get_allocation (column, NULL, &size); gtk_column_view_column_set_fixed_width (column, size); + self->drag_pos = i; self->drag_x = start_x - size; self->in_column_resize = TRUE; @@ -639,6 +666,20 @@ header_drag_begin (GtkGestureDrag *gesture, break; } + if (gtk_column_view_get_reorderable (self) && + gtk_column_view_in_header (self, column, start_x, start_y)) + { + int pos; + + gtk_column_view_column_get_allocation (column, &pos, NULL); + + self->drag_pos = i; + self->drag_offset = start_x - pos; + + g_object_unref (column); + break; + } + g_object_unref (column); } } @@ -649,7 +690,49 @@ header_drag_end (GtkGestureDrag *gesture, double offset_y, GtkColumnView *self) { - self->in_column_resize = FALSE; + double start_x, x; + + gtk_gesture_drag_get_start_point (gesture, &start_x, NULL); + x = start_x + offset_x; + + if (self->in_column_resize) + { + self->in_column_resize = FALSE; + } + else if (self->in_column_reorder) + { + GtkColumnViewColumn *column; + GtkWidget *header; + int i; + + column = g_list_model_get_item (G_LIST_MODEL (self->columns), self->drag_pos); + header = gtk_column_view_column_get_header (column); + gtk_style_context_remove_class (gtk_widget_get_style_context (header), "dnd"); + + for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (self->columns)); i++) + { + GtkColumnViewColumn *col = g_list_model_get_item (G_LIST_MODEL (self->columns), i); + + if (gtk_column_view_column_get_visible (col)) + { + int pos, size; + + gtk_column_view_column_get_allocation (col, &pos, &size); + if (pos <= x && x <= pos + size) + { + gtk_column_view_insert_column (self, i, column); + g_object_unref (col); + break; + } + } + + g_object_unref (col); + } + + g_object_unref (column); + + self->in_column_reorder = FALSE; + } } static void @@ -663,6 +746,25 @@ update_column_resize (GtkColumnView *self, g_object_unref (column); } +static void +update_column_reorder (GtkColumnView *self, + double x) +{ + GtkColumnViewColumn *column; + int width; + int size; + + column = g_list_model_get_item (G_LIST_MODEL (self->columns), self->drag_pos); + width = gtk_widget_get_allocated_width (GTK_WIDGET (self->header)); + gtk_column_view_column_get_allocation (column, NULL, &size); + + self->drag_x = CLAMP (x - self->drag_offset, 0, width - size); + + gtk_widget_queue_allocate (GTK_WIDGET (self)); + gtk_column_view_column_queue_resize (column); + g_object_unref (column); +} + static void header_drag_update (GtkGestureDrag *gesture, double offset_x, @@ -671,11 +773,37 @@ header_drag_update (GtkGestureDrag *gesture, { double start_x, x; + if (self->drag_pos == -1) + return; + + + if (!self->in_column_resize && !self->in_column_reorder) + { + if (gtk_drag_check_threshold (GTK_WIDGET (self), 0, 0, offset_x, 0)) + { + GtkColumnViewColumn *column; + GtkWidget *header; + + column = g_list_model_get_item (G_LIST_MODEL (self->columns), self->drag_pos); + header = gtk_column_view_column_get_header (column); + + gtk_widget_insert_after (header, self->header, gtk_widget_get_last_child (self->header)); + gtk_style_context_add_class (gtk_widget_get_style_context (header), "dnd"); + + gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED); + self->in_column_reorder = TRUE; + + g_object_unref (column); + } + } + gtk_gesture_drag_get_start_point (gesture, &start_x, NULL); x = start_x + offset_x; if (self->in_column_resize) update_column_resize (self, x); + else if (self->in_column_reorder) + update_column_reorder (self, x); } static void From c58eb9c2766af3ae04c62cb374b628df07ca0477 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 20 Dec 2019 19:24:01 -0500 Subject: [PATCH 6/7] columnview: Allow to cancel reorder with Escape The treeview does this too. --- gtk/gtkcolumnview.c | 49 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/gtk/gtkcolumnview.c b/gtk/gtkcolumnview.c index 73704328b7..4666e02b93 100644 --- a/gtk/gtkcolumnview.c +++ b/gtk/gtkcolumnview.c @@ -39,6 +39,7 @@ #include "gtkgesturedrag.h" #include "gtkeventcontrollermotion.h" #include "gtkdragsource.h" +#include "gtkeventcontrollerkey.h" /** * SECTION:gtkcolumnview @@ -79,6 +80,8 @@ struct _GtkColumnView int drag_x; int drag_offset; int drag_column_x; + + GtkGesture *drag_gesture; }; struct _GtkColumnViewClass @@ -654,6 +657,8 @@ header_drag_begin (GtkGestureDrag *gesture, int size; gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED); + if (!gtk_widget_has_focus (GTK_WIDGET (self))) + gtk_widget_grab_focus (GTK_WIDGET (self)); gtk_column_view_column_get_allocation (column, NULL, &size); gtk_column_view_column_set_fixed_width (column, size); @@ -701,14 +706,24 @@ header_drag_end (GtkGestureDrag *gesture, } else if (self->in_column_reorder) { + GdkEventSequence *sequence; GtkColumnViewColumn *column; GtkWidget *header; int i; + self->in_column_reorder = FALSE; + + if (self->drag_pos == -1) + return; + column = g_list_model_get_item (G_LIST_MODEL (self->columns), self->drag_pos); header = gtk_column_view_column_get_header (column); gtk_style_context_remove_class (gtk_widget_get_style_context (header), "dnd"); + sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture)); + if (!gtk_gesture_handles_sequence (GTK_GESTURE (gesture), sequence)) + return; + for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (self->columns)); i++) { GtkColumnViewColumn *col = g_list_model_get_item (G_LIST_MODEL (self->columns), i); @@ -730,8 +745,6 @@ header_drag_end (GtkGestureDrag *gesture, } g_object_unref (column); - - self->in_column_reorder = FALSE; } } @@ -771,12 +784,16 @@ header_drag_update (GtkGestureDrag *gesture, double offset_y, GtkColumnView *self) { + GdkEventSequence *sequence; double start_x, x; + sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture)); + if (!gtk_gesture_handles_sequence (GTK_GESTURE (gesture), sequence)) + return; + if (self->drag_pos == -1) return; - if (!self->in_column_resize && !self->in_column_reorder) { if (gtk_drag_check_threshold (GTK_WIDGET (self), 0, 0, offset_x, 0)) @@ -791,6 +808,9 @@ header_drag_update (GtkGestureDrag *gesture, gtk_style_context_add_class (gtk_widget_get_style_context (header), "dnd"); gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED); + if (!gtk_widget_has_focus (GTK_WIDGET (self))) + gtk_widget_grab_focus (GTK_WIDGET (self)); + self->in_column_reorder = TRUE; g_object_unref (column); @@ -841,6 +861,23 @@ header_motion (GtkEventControllerMotion *controller, gtk_widget_set_cursor (self->header, NULL); } +static gboolean +header_key_pressed (GtkEventControllerKey *controller, + guint keyval, + guint keycode, + GdkModifierType modifiers, + GtkColumnView *self) +{ + if (self->in_column_reorder) + { + if (keyval == GDK_KEY_Escape) + gtk_gesture_set_state (self->drag_gesture, GTK_EVENT_SEQUENCE_DENIED); + return TRUE; + } + + return FALSE; +} + static void gtk_column_view_init (GtkColumnView *self) { @@ -859,11 +896,16 @@ gtk_column_view_init (GtkColumnView *self) g_signal_connect (controller, "drag-end", G_CALLBACK (header_drag_end), self); gtk_event_controller_set_propagation_phase (controller, GTK_PHASE_CAPTURE); gtk_widget_add_controller (self->header, controller); + self->drag_gesture = GTK_GESTURE (controller); controller = gtk_event_controller_motion_new (); g_signal_connect (controller, "motion", G_CALLBACK (header_motion), self); gtk_widget_add_controller (self->header, controller); + controller = gtk_event_controller_key_new (); + g_signal_connect (controller, "key-pressed", G_CALLBACK (header_key_pressed), self); + gtk_widget_add_controller (GTK_WIDGET (self), controller); + self->sorter = gtk_column_view_sorter_new (); self->factory = gtk_column_list_item_factory_new (self); self->listview = GTK_LIST_VIEW (gtk_list_view_new_with_factory ( @@ -877,6 +919,7 @@ gtk_column_view_init (GtkColumnView *self) g_quark_from_static_string (I_("view"))); gtk_widget_set_overflow (GTK_WIDGET (self), GTK_OVERFLOW_HIDDEN); + gtk_widget_set_focusable (GTK_WIDGET (self), TRUE); self->reorderable = TRUE; } From 964d0c219afe8cdb8fe9d0e363a9b4b02a24700a Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 21 Dec 2019 00:24:55 -0500 Subject: [PATCH 7/7] columnview: Add autoscroll Autoscroll when the pointer gets close to the edge during column resizing or reordering. This is similar to what the treeview does, but it is implemented using a tick callback, and has variable speed. --- gtk/gtkcolumnview.c | 71 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/gtk/gtkcolumnview.c b/gtk/gtkcolumnview.c index 4666e02b93..7a223d17e7 100644 --- a/gtk/gtkcolumnview.c +++ b/gtk/gtkcolumnview.c @@ -82,6 +82,10 @@ struct _GtkColumnView int drag_column_x; GtkGesture *drag_gesture; + + guint autoscroll_id; + double autoscroll_x; + double autoscroll_delta; }; struct _GtkColumnViewClass @@ -590,6 +594,53 @@ gtk_column_view_class_init (GtkColumnViewClass *klass) gtk_widget_class_set_css_name (widget_class, I_("treeview")); } +static void update_column_resize (GtkColumnView *self, + double x); +static void update_column_reorder (GtkColumnView *self, + double x); + +static gboolean +autoscroll_cb (GtkWidget *widget, + GdkFrameClock *frame_clock, + gpointer data) +{ + GtkColumnView *self = data; + + gtk_adjustment_set_value (self->hadjustment, + gtk_adjustment_get_value (self->hadjustment) + self->autoscroll_delta); + + self->autoscroll_x += self->autoscroll_delta; + + if (self->in_column_resize) + update_column_resize (self, self->autoscroll_x); + else if (self->in_column_reorder) + update_column_reorder (self, self->autoscroll_x); + + return G_SOURCE_CONTINUE; +} + +static void +add_autoscroll (GtkColumnView *self, + double x, + double delta) +{ + self->autoscroll_x = x; + self->autoscroll_delta = delta; + + if (self->autoscroll_id == 0) + self->autoscroll_id = gtk_widget_add_tick_callback (GTK_WIDGET (self), autoscroll_cb, self, NULL); +} + +static void +remove_autoscroll (GtkColumnView *self) +{ + if (self->autoscroll_id != 0) + { + gtk_widget_remove_tick_callback (GTK_WIDGET (self), self->autoscroll_id); + self->autoscroll_id = 0; + } +} + #define DRAG_WIDTH 6 static gboolean @@ -700,6 +751,8 @@ header_drag_end (GtkGestureDrag *gesture, gtk_gesture_drag_get_start_point (gesture, &start_x, NULL); x = start_x + offset_x; + remove_autoscroll (self); + if (self->in_column_resize) { self->in_column_resize = FALSE; @@ -778,6 +831,8 @@ update_column_reorder (GtkColumnView *self, g_object_unref (column); } +#define SCROLL_EDGE_SIZE 15 + static void header_drag_update (GtkGestureDrag *gesture, double offset_x, @@ -824,6 +879,22 @@ header_drag_update (GtkGestureDrag *gesture, update_column_resize (self, x); else if (self->in_column_reorder) update_column_reorder (self, x); + + if (self->in_column_resize || self->in_column_reorder) + { + double value, page_size, upper; + + value = gtk_adjustment_get_value (self->hadjustment); + page_size = gtk_adjustment_get_page_size (self->hadjustment); + upper = gtk_adjustment_get_upper (self->hadjustment); + + if (x - value < SCROLL_EDGE_SIZE && value > 0) + add_autoscroll (self, x, - (SCROLL_EDGE_SIZE - (x - value))/3.0); + else if (value + page_size - x < SCROLL_EDGE_SIZE && value + page_size < upper) + add_autoscroll (self, x, (SCROLL_EDGE_SIZE - (value + page_size - x))/3.0); + else + remove_autoscroll (self); + } } static void