forked from AuroraMiddleware/gtk
textview: Move drop scrolling to drop motion controller
Don't confuse the drop target with it.
This commit is contained in:
parent
fdb39b095b
commit
b799bc5ce1
@ -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;
|
||||
|
||||
@ -1950,20 +2069,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
|
||||
@ -6896,60 +7001,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,
|
||||
@ -7743,13 +7794,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
|
||||
@ -7763,18 +7807,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,
|
||||
@ -7807,18 +7842,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.
|
||||
*/
|
||||
@ -7900,11 +7923,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);
|
||||
|
Loading…
Reference in New Issue
Block a user