[gtk/wip/otte/dnd] textview: Move drop scrolling to drop motion controller
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/dnd] textview: Move drop scrolling to drop motion controller
- Date: Sun, 1 Mar 2020 05:57:11 +0000 (UTC)
commit 875cec69c73542000798c3ac578d623d615fe143
Author: Benjamin Otte <otte redhat com>
Date: Sat Feb 29 04:37:16 2020 +0100
textview: Move drop scrolling to drop motion controller
Don't confuse the drop target with it.
gtk/gtktextview.c | 220 +++++++++++++++++++++++++++++-------------------------
1 file changed, 119 insertions(+), 101 deletions(-)
---
diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c
index 8f48e05b64..85bb10f2ea 100644
--- a/gtk/gtktextview.c
+++ b/gtk/gtktextview.c
@@ -33,6 +33,7 @@
#include "gtkbindings.h"
#include "gtkcsscolorvalueprivate.h"
#include "gtkdebug.h"
+#include "gtkdropcontrollermotion.h"
#include "gtkintl.h"
#include "gtkmain.h"
#include "gtkmarshalers.h"
@@ -661,6 +662,118 @@ G_DEFINE_TYPE_WITH_CODE (GtkTextView, gtk_text_view, GTK_TYPE_CONTAINER,
G_ADD_PRIVATE (GtkTextView)
G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL))
+static GtkTextBuffer*
+get_buffer (GtkTextView *text_view)
+{
+ if (text_view->priv->buffer == NULL)
+ {
+ GtkTextBuffer *b;
+ b = GTK_TEXT_VIEW_GET_CLASS (text_view)->create_buffer (text_view);
+ gtk_text_view_set_buffer (text_view, b);
+ g_object_unref (b);
+ }
+
+ return text_view->priv->buffer;
+}
+
+#define UPPER_OFFSET_ANCHOR 0.8
+#define LOWER_OFFSET_ANCHOR 0.2
+
+static gboolean
+check_scroll (gdouble offset, GtkAdjustment *adjustment)
+{
+ if ((offset > UPPER_OFFSET_ANCHOR &&
+ gtk_adjustment_get_value (adjustment) + gtk_adjustment_get_page_size (adjustment) <
gtk_adjustment_get_upper (adjustment)) ||
+ (offset < LOWER_OFFSET_ANCHOR &&
+ gtk_adjustment_get_value (adjustment) > gtk_adjustment_get_lower (adjustment)))
+ return TRUE;
+
+ return FALSE;
+}
+
+static int
+gtk_text_view_drop_motion_scroll_timeout (gpointer data)
+{
+ GtkTextView *text_view;
+ GtkTextViewPrivate *priv;
+ GtkTextIter newplace;
+ gdouble pointer_xoffset, pointer_yoffset;
+
+ text_view = GTK_TEXT_VIEW (data);
+ priv = text_view->priv;
+
+ gtk_text_layout_get_iter_at_pixel (priv->layout,
+ &newplace,
+ priv->dnd_x + priv->xoffset,
+ priv->dnd_y + priv->yoffset);
+
+ gtk_text_buffer_move_mark (get_buffer (text_view), priv->dnd_mark, &newplace);
+
+ pointer_xoffset = (gdouble) priv->dnd_x / text_window_get_width (priv->text_window);
+ pointer_yoffset = (gdouble) priv->dnd_y / text_window_get_height (priv->text_window);
+
+ if (check_scroll (pointer_xoffset, priv->hadjustment) ||
+ check_scroll (pointer_yoffset, priv->vadjustment))
+ {
+ /* do not make offsets surpass lower nor upper anchors, this makes
+ * scrolling speed relative to the distance of the pointer to the
+ * anchors when it moves beyond them.
+ */
+ pointer_xoffset = CLAMP (pointer_xoffset, LOWER_OFFSET_ANCHOR, UPPER_OFFSET_ANCHOR);
+ pointer_yoffset = CLAMP (pointer_yoffset, LOWER_OFFSET_ANCHOR, UPPER_OFFSET_ANCHOR);
+
+ gtk_text_view_scroll_to_mark (text_view,
+ priv->dnd_mark,
+ 0., TRUE, pointer_xoffset, pointer_yoffset);
+ }
+
+ return G_SOURCE_CONTINUE;
+}
+
+static void
+gtk_text_view_drop_scroll_motion (GtkDropControllerMotion *motion,
+ double x,
+ double y,
+ GtkTextView *self)
+{
+ GtkTextViewPrivate *priv = self->priv;
+ GdkRectangle target_rect;
+
+ target_rect = priv->text_window->allocation;
+
+ if (x < target_rect.x ||
+ y < target_rect.y ||
+ x > (target_rect.x + target_rect.width) ||
+ y > (target_rect.y + target_rect.height))
+ {
+ priv->dnd_x = priv->dnd_y = -1;
+ g_clear_handle_id (&priv->scroll_timeout, g_source_remove);
+ return;
+ }
+
+ /* DnD uses text window coords, so subtract extra widget
+ * coords that happen e.g. when displaying line numbers.
+ */
+ priv->dnd_x = x - target_rect.x;
+ priv->dnd_y = y - target_rect.y;
+
+ if (!priv->scroll_timeout)
+ {
+ priv->scroll_timeout = g_timeout_add (100, gtk_text_view_drop_motion_scroll_timeout, self);
+ g_source_set_name_by_id (priv->scroll_timeout, "[gtk] gtk_text_view_drop_motion_scroll_timeout");
+ }
+}
+
+static void
+gtk_text_view_drop_scroll_leave (GtkDropControllerMotion *motion,
+ GtkTextView *self)
+{
+ GtkTextViewPrivate *priv = self->priv;
+
+ priv->dnd_x = priv->dnd_y = -1;
+ g_clear_handle_id (&priv->scroll_timeout, g_source_remove);
+}
+
static void
add_move_binding (GtkBindingSet *binding_set,
guint keyval,
@@ -1645,6 +1758,12 @@ gtk_text_view_init (GtkTextView *text_view)
g_signal_connect (dest, "drag-drop", G_CALLBACK (gtk_text_view_drag_drop), text_view);
gtk_widget_add_controller (GTK_WIDGET (text_view), GTK_EVENT_CONTROLLER (dest));
+ controller = gtk_drop_controller_motion_new ();
+ g_signal_connect (controller, "enter", G_CALLBACK (gtk_text_view_drop_scroll_motion), text_view);
+ g_signal_connect (controller, "motion", G_CALLBACK (gtk_text_view_drop_scroll_motion), text_view);
+ g_signal_connect (controller, "leave", G_CALLBACK (gtk_text_view_drop_scroll_leave), text_view);
+ gtk_widget_add_controller (GTK_WIDGET (text_view), controller);
+
priv->virtual_cursor_x = -1;
priv->virtual_cursor_y = -1;
@@ -1949,20 +2068,6 @@ gtk_text_view_create_buffer (GtkTextView *text_view)
return gtk_text_buffer_new (NULL);
}
-static GtkTextBuffer*
-get_buffer (GtkTextView *text_view)
-{
- if (text_view->priv->buffer == NULL)
- {
- GtkTextBuffer *b;
- b = GTK_TEXT_VIEW_GET_CLASS (text_view)->create_buffer (text_view);
- gtk_text_view_set_buffer (text_view, b);
- g_object_unref (b);
- }
-
- return text_view->priv->buffer;
-}
-
/**
* gtk_text_view_get_buffer:
* @text_view: a #GtkTextView
@@ -6895,60 +7000,6 @@ selection_scan_timeout (gpointer data)
return TRUE; /* remain installed. */
}
-#define UPPER_OFFSET_ANCHOR 0.8
-#define LOWER_OFFSET_ANCHOR 0.2
-
-static gboolean
-check_scroll (gdouble offset, GtkAdjustment *adjustment)
-{
- if ((offset > UPPER_OFFSET_ANCHOR &&
- gtk_adjustment_get_value (adjustment) + gtk_adjustment_get_page_size (adjustment) <
gtk_adjustment_get_upper (adjustment)) ||
- (offset < LOWER_OFFSET_ANCHOR &&
- gtk_adjustment_get_value (adjustment) > gtk_adjustment_get_lower (adjustment)))
- return TRUE;
-
- return FALSE;
-}
-
-static gint
-drag_scan_timeout (gpointer data)
-{
- GtkTextView *text_view;
- GtkTextViewPrivate *priv;
- GtkTextIter newplace;
- gdouble pointer_xoffset, pointer_yoffset;
-
- text_view = GTK_TEXT_VIEW (data);
- priv = text_view->priv;
-
- gtk_text_layout_get_iter_at_pixel (priv->layout,
- &newplace,
- priv->dnd_x + priv->xoffset,
- priv->dnd_y + priv->yoffset);
-
- gtk_text_buffer_move_mark (get_buffer (text_view), priv->dnd_mark, &newplace);
-
- pointer_xoffset = (gdouble) priv->dnd_x / text_window_get_width (priv->text_window);
- pointer_yoffset = (gdouble) priv->dnd_y / text_window_get_height (priv->text_window);
-
- if (check_scroll (pointer_xoffset, priv->hadjustment) ||
- check_scroll (pointer_yoffset, priv->vadjustment))
- {
- /* do not make offsets surpass lower nor upper anchors, this makes
- * scrolling speed relative to the distance of the pointer to the
- * anchors when it moves beyond them.
- */
- pointer_xoffset = CLAMP (pointer_xoffset, LOWER_OFFSET_ANCHOR, UPPER_OFFSET_ANCHOR);
- pointer_yoffset = CLAMP (pointer_yoffset, LOWER_OFFSET_ANCHOR, UPPER_OFFSET_ANCHOR);
-
- gtk_text_view_scroll_to_mark (text_view,
- priv->dnd_mark,
- 0., TRUE, pointer_xoffset, pointer_yoffset);
- }
-
- return TRUE;
-}
-
static void
extend_selection (GtkTextView *text_view,
SelectionGranularity granularity,
@@ -7742,13 +7793,6 @@ gtk_text_view_drag_leave (GtkDropTarget *dest,
GtkTextViewPrivate *priv = text_view->priv;
gtk_text_mark_set_visible (priv->dnd_mark, FALSE);
-
- priv->dnd_x = priv->dnd_y = -1;
-
- if (priv->scroll_timeout != 0)
- g_source_remove (priv->scroll_timeout);
-
- priv->scroll_timeout = 0;
}
static gboolean
@@ -7762,18 +7806,9 @@ gtk_text_view_drag_motion (GtkDropTarget *dest,
GtkTextIter newplace;
GtkTextIter start;
GtkTextIter end;
- GdkRectangle target_rect;
gint bx, by;
gboolean can_accept = FALSE;
- target_rect = priv->text_window->allocation;
-
- if (x < target_rect.x ||
- y < target_rect.y ||
- x > (target_rect.x + target_rect.width) ||
- y > (target_rect.y + target_rect.height))
- return FALSE; /* outside the text window, allow parent widgets to handle event */
-
gtk_text_view_window_to_buffer_coords (text_view,
GTK_TEXT_WINDOW_WIDGET,
x, y,
@@ -7806,18 +7841,6 @@ gtk_text_view_drag_motion (GtkDropTarget *dest,
gtk_text_mark_set_visible (priv->dnd_mark, FALSE);
}
- /* DnD uses text window coords, so subtract extra widget
- * coords that happen e.g. when displaying line numbers.
- */
- priv->dnd_x = x - target_rect.x;
- priv->dnd_y = y - target_rect.y;
-
- if (!priv->scroll_timeout)
- {
- priv->scroll_timeout = g_timeout_add (100, drag_scan_timeout, text_view);
- g_source_set_name_by_id (text_view->priv->scroll_timeout, "[gtk] drag_scan_timeout");
- }
-
/* TRUE return means don't propagate the drag motion to parent
* widgets that may also be drop sites.
*/
@@ -7899,11 +7922,6 @@ gtk_text_view_drag_drop (GtkDropTarget *dest,
GtkTextIter drop_point;
GtkTextBuffer *buffer = NULL;
- if (priv->scroll_timeout != 0)
- g_source_remove (priv->scroll_timeout);
-
- priv->scroll_timeout = 0;
-
gtk_text_mark_set_visible (priv->dnd_mark, FALSE);
buffer = get_buffer (text_view);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]