mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-14 04:31:09 +00:00
text: Port to GtkDropTarget
This commit is contained in:
parent
025eee112c
commit
6e602e052b
201
gtk/gtktext.c
201
gtk/gtktext.c
@ -68,6 +68,7 @@
|
||||
#include "gtknative.h"
|
||||
#include "gtkactionmuxerprivate.h"
|
||||
#include "gtkdragsource.h"
|
||||
#include "gtkdragdest.h"
|
||||
|
||||
#include "a11y/gtktextaccessible.h"
|
||||
|
||||
@ -332,19 +333,16 @@ static void gtk_text_state_flags_changed (GtkWidget *widget,
|
||||
GtkStateFlags previous_state);
|
||||
static void gtk_text_root (GtkWidget *widget);
|
||||
|
||||
static gboolean gtk_text_drag_drop (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
static gboolean gtk_text_drag_drop (GtkDropTarget *dest,
|
||||
int x,
|
||||
int y);
|
||||
static gboolean gtk_text_drag_motion (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
int y,
|
||||
GtkText *text);
|
||||
static gboolean gtk_text_drag_motion (GtkDropTarget *dest,
|
||||
int x,
|
||||
int y);
|
||||
static void gtk_text_drag_leave (GtkWidget *widget,
|
||||
GdkDrop *drop);
|
||||
static void gtk_text_drag_data_received (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
GtkSelectionData *selection_data);
|
||||
int y,
|
||||
GtkText *text);
|
||||
static void gtk_text_drag_leave (GtkDropTarget *dest,
|
||||
GtkText *text);
|
||||
|
||||
|
||||
/* GtkEditable method implementations
|
||||
@ -726,10 +724,6 @@ gtk_text_class_init (GtkTextClass *class)
|
||||
widget_class->root = gtk_text_root;
|
||||
widget_class->mnemonic_activate = gtk_text_mnemonic_activate;
|
||||
widget_class->popup_menu = gtk_text_popup_menu;
|
||||
widget_class->drag_drop = gtk_text_drag_drop;
|
||||
widget_class->drag_motion = gtk_text_drag_motion;
|
||||
widget_class->drag_leave = gtk_text_drag_leave;
|
||||
widget_class->drag_data_received = gtk_text_drag_data_received;
|
||||
|
||||
class->move_cursor = gtk_text_move_cursor;
|
||||
class->insert_at_cursor = gtk_text_insert_at_cursor;
|
||||
@ -1710,6 +1704,8 @@ gtk_text_init (GtkText *self)
|
||||
GtkGesture *gesture;
|
||||
GtkEventController *controller;
|
||||
int i;
|
||||
GtkDropTarget *dest;
|
||||
GdkContentFormats *formats;
|
||||
|
||||
gtk_widget_set_can_focus (GTK_WIDGET (self), TRUE);
|
||||
gtk_widget_set_overflow (GTK_WIDGET (self), GTK_OVERFLOW_HIDDEN);
|
||||
@ -1730,9 +1726,14 @@ gtk_text_init (GtkText *self)
|
||||
priv->selection_content = g_object_new (GTK_TYPE_TEXT_CONTENT, NULL);
|
||||
GTK_TEXT_CONTENT (priv->selection_content)->self = self;
|
||||
|
||||
gtk_drag_dest_set (GTK_WIDGET (self), 0, NULL,
|
||||
GDK_ACTION_COPY | GDK_ACTION_MOVE);
|
||||
gtk_drag_dest_add_text_targets (GTK_WIDGET (self));
|
||||
formats = gdk_content_formats_new (NULL, 0);
|
||||
formats = gtk_content_formats_add_text_targets (formats);
|
||||
dest = gtk_drop_target_new (0, formats, GDK_ACTION_COPY | GDK_ACTION_MOVE);
|
||||
g_signal_connect (dest, "drag-motion", G_CALLBACK (gtk_text_drag_motion), self);
|
||||
g_signal_connect (dest, "drag-leave", G_CALLBACK (gtk_text_drag_leave), self);
|
||||
g_signal_connect (dest, "drag-drop", G_CALLBACK (gtk_text_drag_drop), self);
|
||||
gdk_content_formats_unref (formats);
|
||||
gtk_drop_target_attach (dest, GTK_WIDGET (self));
|
||||
|
||||
/* This object is completely private. No external entity can gain a reference
|
||||
* to it; so we create it here and destroy it in finalize().
|
||||
@ -6106,90 +6107,17 @@ gtk_text_selection_bubble_popup_set (GtkText *self)
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_drag_leave (GtkWidget *widget,
|
||||
GdkDrop *drop)
|
||||
gtk_text_drag_leave (GtkDropTarget *dest,
|
||||
GtkText *self)
|
||||
{
|
||||
GtkText *self = GTK_TEXT (widget);
|
||||
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
|
||||
GtkWidget *widget = GTK_WIDGET (self);
|
||||
|
||||
gtk_drag_unhighlight (widget);
|
||||
priv->dnd_position = -1;
|
||||
gtk_widget_queue_draw (widget);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_text_drag_drop (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
GtkText *self = GTK_TEXT (widget);
|
||||
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
|
||||
GdkAtom target = NULL;
|
||||
|
||||
if (priv->editable)
|
||||
target = gtk_drag_dest_find_target (widget, drop, NULL);
|
||||
|
||||
if (target != NULL)
|
||||
{
|
||||
priv->drop_position = gtk_text_find_position (self, x + priv->scroll_offset);
|
||||
gtk_drag_get_data (widget, drop, target);
|
||||
}
|
||||
else
|
||||
gdk_drop_finish (drop, 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_text_drag_motion (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
GtkText *self = GTK_TEXT (widget);
|
||||
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
|
||||
GdkDragAction suggested_action;
|
||||
int new_position, old_position;
|
||||
|
||||
old_position = priv->dnd_position;
|
||||
new_position = gtk_text_find_position (self, x + priv->scroll_offset);
|
||||
|
||||
if (priv->editable &&
|
||||
gtk_drag_dest_find_target (widget, drop, NULL) != NULL)
|
||||
{
|
||||
suggested_action = GDK_ACTION_COPY | GDK_ACTION_MOVE;
|
||||
|
||||
if (priv->selection_bound == priv->current_pos ||
|
||||
new_position < priv->selection_bound ||
|
||||
new_position > priv->current_pos)
|
||||
{
|
||||
priv->dnd_position = new_position;
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->dnd_position = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Entry not editable, or no text */
|
||||
suggested_action = 0;
|
||||
priv->dnd_position = -1;
|
||||
}
|
||||
|
||||
gdk_drop_status (drop, suggested_action);
|
||||
if (suggested_action == 0)
|
||||
gtk_drag_unhighlight (widget);
|
||||
else
|
||||
gtk_drag_highlight (widget);
|
||||
|
||||
if (priv->dnd_position != old_position)
|
||||
gtk_widget_queue_draw (widget);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GdkDragAction
|
||||
gtk_text_get_action (GtkText *self,
|
||||
GdkDrop *drop)
|
||||
@ -6218,19 +6146,20 @@ gtk_text_get_action (GtkText *self,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_drag_data_received (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
GtkSelectionData *selection_data)
|
||||
got_text (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GtkText *self = GTK_TEXT (widget);
|
||||
GdkDrop *drop = GDK_DROP (source);
|
||||
GtkText *self = GTK_TEXT (data);
|
||||
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
|
||||
GdkDragAction action;
|
||||
char *str;
|
||||
GdkDragAction action;
|
||||
|
||||
str = (char *) gtk_selection_data_get_text (selection_data);
|
||||
str = gdk_drop_read_text_finish (drop, result, NULL);
|
||||
action = gtk_text_get_action (self, drop);
|
||||
|
||||
if (action && str && priv->editable)
|
||||
if (action && str)
|
||||
{
|
||||
int length = -1;
|
||||
int pos;
|
||||
@ -6265,6 +6194,76 @@ gtk_text_drag_data_received (GtkWidget *widget,
|
||||
g_free (str);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_text_drag_drop (GtkDropTarget *dest,
|
||||
int x,
|
||||
int y,
|
||||
GtkText *self)
|
||||
{
|
||||
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
|
||||
GdkDrop *drop = gtk_drop_target_get_drop (dest);
|
||||
|
||||
if (priv->editable && gdk_drop_has_value (drop, G_TYPE_STRING))
|
||||
{
|
||||
priv->drop_position = gtk_text_find_position (self, x + priv->scroll_offset);
|
||||
gdk_drop_read_text_async (drop, NULL, got_text, self);
|
||||
}
|
||||
else
|
||||
gdk_drop_finish (drop, 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_text_drag_motion (GtkDropTarget *dest,
|
||||
int x,
|
||||
int y,
|
||||
GtkText *self)
|
||||
{
|
||||
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
|
||||
GdkDrop *drop = gtk_drop_target_get_drop (dest);
|
||||
GtkWidget *widget = GTK_WIDGET (self);
|
||||
GdkDragAction suggested_action;
|
||||
int new_position, old_position;
|
||||
|
||||
old_position = priv->dnd_position;
|
||||
new_position = gtk_text_find_position (self, x + priv->scroll_offset);
|
||||
|
||||
if (priv->editable &&
|
||||
gtk_drop_target_find_mimetype (dest) != NULL)
|
||||
{
|
||||
suggested_action = GDK_ACTION_COPY | GDK_ACTION_MOVE;
|
||||
|
||||
if (priv->selection_bound == priv->current_pos ||
|
||||
new_position < priv->selection_bound ||
|
||||
new_position > priv->current_pos)
|
||||
{
|
||||
priv->dnd_position = new_position;
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->dnd_position = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Entry not editable, or no text */
|
||||
suggested_action = 0;
|
||||
priv->dnd_position = -1;
|
||||
}
|
||||
|
||||
gdk_drop_status (drop, suggested_action);
|
||||
if (suggested_action == 0)
|
||||
gtk_drag_unhighlight (widget);
|
||||
else
|
||||
gtk_drag_highlight (widget);
|
||||
|
||||
if (priv->dnd_position != old_position)
|
||||
gtk_widget_queue_draw (widget);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* We display the cursor when
|
||||
*
|
||||
* - the selection is empty, AND
|
||||
|
Loading…
Reference in New Issue
Block a user