[gtk/prop-list: 33/33] columnview: Interactive column resizing
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/prop-list: 33/33] columnview: Interactive column resizing
- Date: Fri, 20 Dec 2019 19:40:19 +0000 (UTC)
commit a78eef4ab25f4c0b1850f9fe60b1b1597ee41cf8
Author: Matthias Clasen <mclasen redhat com>
Date: Fri Dec 20 12:17:45 2019 -0500
columnview: Interactive column resizing
This copies just enough of the treeview code to
get columns moving.
gtk/gtkcolumnview.c | 106 +++++++++++++++++++++++++++++++++++++++
gtk/gtkcolumnviewcolumn.c | 25 +++++++--
gtk/gtkcolumnviewcolumnprivate.h | 4 ++
3 files changed, 131 insertions(+), 4 deletions(-)
---
diff --git a/gtk/gtkcolumnview.c b/gtk/gtkcolumnview.c
index 3ca4d5be6b..4dab5b4d21 100644
--- a/gtk/gtkcolumnview.c
+++ b/gtk/gtkcolumnview.c
@@ -36,6 +36,8 @@
#include "gtkwidgetprivate.h"
#include "gtksizerequest.h"
#include "gtkadjustment.h"
+#include "gtkgesturedrag.h"
+#include "gtkeventcontrollermotion.h"
/**
* SECTION:gtkcolumnview
@@ -67,6 +69,10 @@ struct _GtkColumnView
GtkSorter *sorter;
GtkAdjustment *hadjustment;
+
+ gboolean in_column_resize;
+ int drag_pos;
+ int drag_start_width;
};
struct _GtkColumnViewClass
@@ -531,9 +537,98 @@ gtk_column_view_class_init (GtkColumnViewClass *klass)
gtk_widget_class_set_css_name (widget_class, I_("treeview"));
}
+static void
+header_drag_begin (GtkGestureDrag *gesture,
+ double start_x,
+ double start_y,
+ GtkColumnView *self)
+{
+ int i;
+
+ for (i = 0; !self->in_column_resize && i < g_list_model_get_n_items (G_LIST_MODEL (self->columns)); i++)
+ {
+ GtkColumnViewColumn *column = g_list_model_get_item (G_LIST_MODEL (self->columns), i);
+
+ if (gtk_column_view_column_get_resizable (column) &&
+ gtk_column_view_column_get_visible (column) &&
+ gtk_column_view_column_in_resize_rect (column, start_x, start_y))
+ {
+ int size;
+
+ gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
+
+ gtk_column_view_column_get_allocation (column, NULL, &size);
+ gtk_column_view_column_set_fixed_width (column, size);
+ self->drag_pos = i;
+ self->drag_start_width = size;
+ self->in_column_resize = TRUE;
+ }
+
+ g_clear_object (&column);
+ }
+}
+
+static void
+header_drag_end (GtkGestureDrag *gesture,
+ double offset_x,
+ double offset_y,
+ GtkColumnView *self)
+{
+ self->in_column_resize = FALSE;
+}
+
+static void
+header_drag_update (GtkGestureDrag *gesture,
+ double offset_x,
+ double offset_y,
+ GtkColumnView *self)
+{
+ if (self->in_column_resize)
+ {
+ GtkColumnViewColumn *column;
+ int new_width;
+
+ new_width = MAX (self->drag_start_width + offset_x, 0);
+
+ column = g_list_model_get_item (G_LIST_MODEL (self->columns), self->drag_pos);
+ gtk_column_view_column_set_fixed_width (column, new_width);
+ g_object_unref (column);
+ }
+}
+
+static void
+header_motion (GtkEventControllerMotion *controller,
+ double x,
+ double y,
+ GtkColumnView *self)
+{
+ gboolean cursor_set = FALSE;
+ int i;
+
+ for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (self->columns)); i++)
+ {
+ GtkColumnViewColumn *column = g_list_model_get_item (G_LIST_MODEL (self->columns), i);
+
+ if (gtk_column_view_column_get_resizable (column) &&
+ gtk_column_view_column_get_visible (column) &&
+ gtk_column_view_column_in_resize_rect (column, x, y))
+ {
+ gtk_widget_set_cursor_from_name (self->header, "col-resize");
+ cursor_set = TRUE;
+ }
+
+ g_object_unref (column);
+ }
+
+ if (!cursor_set)
+ gtk_widget_set_cursor (self->header, NULL);
+}
+
static void
gtk_column_view_init (GtkColumnView *self)
{
+ GtkEventController *controller;
+
self->columns = g_list_store_new (GTK_TYPE_COLUMN_VIEW_COLUMN);
self->header = gtk_list_item_widget_new (NULL, "header");
@@ -541,6 +636,17 @@ gtk_column_view_init (GtkColumnView *self)
gtk_widget_set_layout_manager (self->header, gtk_column_view_layout_new (self));
gtk_widget_set_parent (self->header, GTK_WIDGET (self));
+ controller = GTK_EVENT_CONTROLLER (gtk_gesture_drag_new ());
+ g_signal_connect (controller, "drag-begin", G_CALLBACK (header_drag_begin), self);
+ g_signal_connect (controller, "drag-update", G_CALLBACK (header_drag_update), 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);
+
+ controller = gtk_event_controller_motion_new ();
+ g_signal_connect (controller, "motion", G_CALLBACK (header_motion), self);
+ gtk_widget_add_controller (self->header, 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 (
diff --git a/gtk/gtkcolumnviewcolumn.c b/gtk/gtkcolumnviewcolumn.c
index 26b12d456c..bcd73bd733 100644
--- a/gtk/gtkcolumnviewcolumn.c
+++ b/gtk/gtkcolumnviewcolumn.c
@@ -810,7 +810,6 @@ 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);
@@ -827,13 +826,13 @@ gtk_column_view_column_set_fixed_width (GtkColumnViewColumn *self,
if (overflow != gtk_widget_get_overflow (GTK_WIDGET (self->header)))
{
+ GtkColumnViewCell *cell;
+
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_widget_set_overflow (GTK_WIDGET (cell), overflow);
}
gtk_column_view_column_queue_resize (self);
@@ -848,3 +847,21 @@ gtk_column_view_column_get_fixed_width (GtkColumnViewColumn *self)
return self->fixed_width;
}
+
+#define DRAG_WIDTH 6
+
+gboolean
+gtk_column_view_column_in_resize_rect (GtkColumnViewColumn *self,
+ double x,
+ double y)
+{
+ graphene_rect_t rect;
+
+ if (!gtk_widget_compute_bounds (self->header, GTK_WIDGET (self->view), &rect))
+ return FALSE;
+
+ rect.origin.x += rect.size.width - DRAG_WIDTH / 2;
+ rect.size.width = DRAG_WIDTH;
+
+ return graphene_rect_contains_point (&rect, &(graphene_point_t) { x, y});
+}
diff --git a/gtk/gtkcolumnviewcolumnprivate.h b/gtk/gtkcolumnviewcolumnprivate.h
index fe46663e63..a4b588252f 100644
--- a/gtk/gtkcolumnviewcolumnprivate.h
+++ b/gtk/gtkcolumnviewcolumnprivate.h
@@ -47,4 +47,8 @@ void gtk_column_view_column_get_allocation (GtkColu
void gtk_column_view_column_notify_sort (GtkColumnViewColumn *self);
+gboolean gtk_column_view_column_in_resize_rect (GtkColumnViewColumn *self,
+ double x,
+ double y);
+
#endif /* __GTK_COLUMN_VIEW_COLUMN_PRIVATE_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]