summaryrefslogtreecommitdiff
path: root/gtk/gtkcalendar.c
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2020-01-11 06:09:58 +0000
committerMatthias Clasen <mclasen@redhat.com>2020-01-11 06:09:58 +0000
commitf5daecf353714d2d7d1dd202a476922d22c895e7 (patch)
tree55c458c40e95d7981cd8cad5941f705efbf10bf4 /gtk/gtkcalendar.c
parent186b783f9d3d39b37f61defcf2be4b020e90e6f8 (diff)
parentb76940bab5b82914617424a1063c6942e4ad143d (diff)
downloadgtk+-f5daecf353714d2d7d1dd202a476922d22c895e7.tar.gz
Merge branch 'dnd-gestures-2' into 'master'
Add new dnd api See merge request GNOME/gtk!1278
Diffstat (limited to 'gtk/gtkcalendar.c')
-rw-r--r--gtk/gtkcalendar.c241
1 files changed, 118 insertions, 123 deletions
diff --git a/gtk/gtkcalendar.c b/gtk/gtkcalendar.c
index c1e96c0028..e3862a3bfc 100644
--- a/gtk/gtkcalendar.c
+++ b/gtk/gtkcalendar.c
@@ -72,7 +72,6 @@
#endif
#include "gtkcalendar.h"
-#include "gtkdnd.h"
#include "gtkdragdest.h"
#include "gtkintl.h"
#include "gtkmain.h"
@@ -87,6 +86,10 @@
#include "gtkgesturedrag.h"
#include "gtkeventcontrollerscroll.h"
#include "gtkeventcontrollerkey.h"
+#include "gtkdragsource.h"
+#include "gtknative.h"
+#include "gtkicontheme.h"
+#include "gtkdragicon.h"
#define TIMEOUT_INITIAL 500
#define TIMEOUT_REPEAT 50
@@ -248,7 +251,6 @@ struct _GtkCalendarPrivate
guint need_timer : 1;
guint in_drag : 1;
- guint drag_highlight : 1;
guint32 timer;
gint click_child;
@@ -329,22 +331,17 @@ static gboolean gtk_calendar_query_tooltip (GtkWidget *widget,
gboolean keyboard_mode,
GtkTooltip *tooltip);
-static void gtk_calendar_drag_data_get (GtkWidget *widget,
- GdkDrag *drag,
- GtkSelectionData *selection_data);
-static void gtk_calendar_drag_data_received (GtkWidget *widget,
+static gboolean gtk_calendar_drag_accept (GtkDropTarget *dest,
GdkDrop *drop,
- GtkSelectionData *selection_data);
-static gboolean gtk_calendar_drag_motion (GtkWidget *widget,
+ GtkCalendar *calendar);
+static void gtk_calendar_drag_leave (GtkDropTarget *dest,
GdkDrop *drop,
- gint x,
- gint y);
-static void gtk_calendar_drag_leave (GtkWidget *widget,
- GdkDrop *drop);
-static gboolean gtk_calendar_drag_drop (GtkWidget *widget,
+ GtkCalendar *calendar);
+static gboolean gtk_calendar_drag_drop (GtkDropTarget *dest,
GdkDrop *drop,
- gint x,
- gint y);
+ int x,
+ int y,
+ GtkCalendar *calendar);
static void calendar_start_spinning (GtkCalendar *calendar,
@@ -392,12 +389,6 @@ gtk_calendar_class_init (GtkCalendarClass *class)
widget_class->grab_notify = gtk_calendar_grab_notify;
widget_class->query_tooltip = gtk_calendar_query_tooltip;
- widget_class->drag_data_get = gtk_calendar_drag_data_get;
- widget_class->drag_motion = gtk_calendar_drag_motion;
- widget_class->drag_leave = gtk_calendar_drag_leave;
- widget_class->drag_drop = gtk_calendar_drag_drop;
- widget_class->drag_data_received = gtk_calendar_drag_data_received;
-
/**
* GtkCalendar:year:
*
@@ -675,6 +666,8 @@ gtk_calendar_init (GtkCalendar *calendar)
#else
gchar *week_start;
#endif
+ GdkContentFormats *formats;
+ GtkDropTarget *dest;
gtk_widget_set_can_focus (widget, TRUE);
@@ -792,11 +785,17 @@ gtk_calendar_init (GtkCalendar *calendar)
priv->click_child = -1;
priv->in_drag = 0;
- priv->drag_highlight = 0;
- gtk_drag_dest_set (widget, 0, NULL, GDK_ACTION_COPY);
- gtk_drag_dest_add_text_targets (widget);
+ formats = gdk_content_formats_new_for_gtype (G_TYPE_STRING);
+ dest = gtk_drop_target_new (formats, GDK_ACTION_COPY);
+ gdk_content_formats_unref (formats);
+
+ g_signal_connect (dest, "accept", G_CALLBACK (gtk_calendar_drag_accept), calendar);
+ g_signal_connect (dest, "drag-leave", G_CALLBACK (gtk_calendar_drag_leave), calendar);
+ g_signal_connect (dest, "drag-drop", G_CALLBACK (gtk_calendar_drag_drop), calendar);
+ gtk_widget_add_controller (widget, GTK_EVENT_CONTROLLER (dest));
+
priv->year_before = 0;
/* Translate to calendar:YM if you want years to be displayed
@@ -2661,6 +2660,27 @@ gtk_calendar_drag_begin (GtkGestureDrag *gesture,
priv->in_drag = TRUE;
}
+static GdkContentProvider *
+get_calendar_content (GtkCalendar *calendar)
+{
+ GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
+ GDate *date;
+ gchar str[128];
+ GValue value = G_VALUE_INIT;
+ GdkContentProvider *content;
+
+ date = g_date_new_dmy (priv->selected_day, priv->month + 1, priv->year);
+ g_date_strftime (str, 127, "%x", date);
+ g_free (date);
+
+ g_value_init (&value, G_TYPE_STRING);
+ g_value_set_string (&value, str);
+ content = gdk_content_provider_new_for_value (&value);
+ g_value_unset (&value);
+
+ return content;
+}
+
static void
gtk_calendar_drag_update (GtkGestureDrag *gesture,
double x,
@@ -2671,8 +2691,12 @@ gtk_calendar_drag_update (GtkGestureDrag *gesture,
GtkCalendar *calendar = GTK_CALENDAR (widget);
GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
gdouble start_x, start_y;
+ GdkContentProvider *content;
+ GdkDevice *device;
GdkDrag *drag;
- GdkContentFormats *targets;
+ GtkIconTheme *theme;
+ GdkPaintable *paintable;
+ GdkSurface *surface;
if (!priv->in_drag)
return;
@@ -2682,19 +2706,22 @@ gtk_calendar_drag_update (GtkGestureDrag *gesture,
gtk_gesture_drag_get_start_point (gesture, &start_x, &start_y);
- gtk_event_controller_reset (GTK_EVENT_CONTROLLER (gesture));
+ surface = gtk_native_get_surface (gtk_widget_get_native (widget));
+ device = gtk_gesture_get_device (GTK_GESTURE (gesture));
- targets = gdk_content_formats_new (NULL, 0);
- targets = gtk_content_formats_add_text_targets (targets);
- drag = gtk_drag_begin (widget,
- gtk_gesture_get_device (GTK_GESTURE (gesture)),
- targets, GDK_ACTION_COPY,
- start_x, start_y);
+ content = get_calendar_content (calendar);
- priv->in_drag = 0;
- gdk_content_formats_unref (targets);
+ drag = gdk_drag_begin (surface, device, content, GDK_ACTION_COPY, start_x, start_y);
+
+ theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (widget));
+ paintable = gtk_icon_theme_load_icon (theme, "text-x-generic", 32, 0, NULL);
+ gtk_drag_icon_set_from_paintable (drag, paintable, 0, 0);
+ g_clear_object (&paintable);
+
+ g_object_unref (content);
+ g_object_unref (drag);
- gtk_drag_set_icon_default (drag);
+ priv->in_drag = 0;
}
static gboolean
@@ -2914,24 +2941,6 @@ gtk_calendar_grab_notify (GtkWidget *widget,
* Drag and Drop *
****************************************/
-static void
-gtk_calendar_drag_data_get (GtkWidget *widget,
- GdkDrag *drag,
- GtkSelectionData *selection_data)
-{
- GtkCalendar *calendar = GTK_CALENDAR (widget);
- GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
- GDate *date;
- gchar str[128];
- gsize len;
-
- date = g_date_new_dmy (priv->selected_day, priv->month + 1, priv->year);
- len = g_date_strftime (str, 127, "%x", date);
- gtk_selection_data_set_text (selection_data, str, len);
-
- g_free (date);
-}
-
/* Get/set whether drag_motion requested the drag data and
* drag_data_received should thus not actually insert the data,
* since the data doesn’t result from a drop.
@@ -2953,87 +2962,33 @@ get_status_pending (GdkDrop *drop)
}
static void
-gtk_calendar_drag_leave (GtkWidget *widget,
- GdkDrop *drop)
-{
- GtkCalendar *calendar = GTK_CALENDAR (widget);
- GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
-
- priv->drag_highlight = 0;
- gtk_drag_unhighlight (widget);
-}
-
-static gboolean
-gtk_calendar_drag_motion (GtkWidget *widget,
- GdkDrop *drop,
- gint x,
- gint y)
-{
- GtkCalendar *calendar = GTK_CALENDAR (widget);
- GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
- GdkAtom target;
-
- if (!priv->drag_highlight)
- {
- priv->drag_highlight = 1;
- gtk_drag_highlight (widget);
- }
-
- target = gtk_drag_dest_find_target (widget, drop, NULL);
- if (target == NULL || gdk_drop_get_actions (drop) == 0)
- gdk_drop_status (drop, 0);
- else if (get_status_pending (drop) == 0)
- {
- set_status_pending (drop, gdk_drop_get_actions (drop));
- gtk_drag_get_data (widget, drop, target);
- }
-
- return TRUE;
-}
-
-static gboolean
-gtk_calendar_drag_drop (GtkWidget *widget,
- GdkDrop *drop,
- gint x,
- gint y)
+gtk_calendar_drag_leave (GtkDropTarget *dest,
+ GdkDrop *drop,
+ GtkCalendar *calendar)
{
- GdkAtom target;
-
- target = gtk_drag_dest_find_target (widget, drop, NULL);
- if (target != NULL)
- {
- gtk_drag_get_data (widget, drop, target);
- return TRUE;
- }
-
- return FALSE;
}
static void
-gtk_calendar_drag_data_received (GtkWidget *widget,
- GdkDrop *drop,
- GtkSelectionData *selection_data)
+got_text (GObject *source,
+ GAsyncResult *result,
+ gpointer data)
{
- GtkCalendar *calendar = GTK_CALENDAR (widget);
+ GtkDropTarget *dest = GTK_DROP_TARGET (data);
+ GtkCalendar *calendar = GTK_CALENDAR (gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest)));
GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
+ GdkDrop *drop = GDK_DROP (source);
guint day, month, year;
gchar *str;
GDate *date;
GdkDragAction suggested_action;
suggested_action = get_status_pending (drop);
+ set_status_pending (drop, 0);
+
+ str = gdk_drop_read_text_finish (drop, result, NULL);
if (suggested_action)
{
- set_status_pending (drop, 0);
-
- /* We are getting this data due to a request in drag_motion,
- * rather than due to a request in drag_drop, so we are just
- * supposed to call drag_status, not actually paste in the
- * data.
- */
- str = (gchar*) gtk_selection_data_get_text (selection_data);
-
if (str)
{
date = g_date_new ();
@@ -3045,14 +3000,13 @@ gtk_calendar_drag_data_received (GtkWidget *widget,
}
else
suggested_action = 0;
-
gdk_drop_status (drop, suggested_action);
-
+ if (suggested_action == 0)
+ gtk_drop_target_deny_drop (dest, drop);
return;
}
date = g_date_new ();
- str = (gchar*) gtk_selection_data_get_text (selection_data);
if (str)
{
g_date_set_parse (date, str);
@@ -3064,6 +3018,7 @@ gtk_calendar_drag_data_received (GtkWidget *widget,
g_warning ("Received invalid date data");
g_date_free (date);
gdk_drop_finish (drop, 0);
+ gtk_drop_target_deny_drop (dest, drop);
return;
}
@@ -3074,7 +3029,6 @@ gtk_calendar_drag_data_received (GtkWidget *widget,
gdk_drop_finish (drop, suggested_action);
-
g_object_freeze_notify (G_OBJECT (calendar));
if (!(priv->display_flags & GTK_CALENDAR_NO_MONTH_CHANGE)
&& (priv->display_flags & GTK_CALENDAR_SHOW_HEADING))
@@ -3083,6 +3037,47 @@ gtk_calendar_drag_data_received (GtkWidget *widget,
g_object_thaw_notify (G_OBJECT (calendar));
}
+static gboolean
+gtk_calendar_drag_accept (GtkDropTarget *dest,
+ GdkDrop *drop,
+ GtkCalendar *calendar)
+{
+ GdkAtom target;
+
+ target = gtk_drop_target_find_mimetype (dest);
+ if (!target || gdk_drop_get_actions (drop) == 0)
+ {
+ gdk_drop_status (drop, 0);
+ return FALSE;
+ }
+ else if (get_status_pending (drop) == 0)
+ {
+ set_status_pending (drop, gdk_drop_get_actions (drop));
+ gdk_drop_read_text_async (drop, NULL, got_text, dest);
+ }
+ return TRUE;
+}
+
+static gboolean
+gtk_calendar_drag_drop (GtkDropTarget *dest,
+ GdkDrop *drop,
+ int x,
+ int y,
+ GtkCalendar *calendar)
+{
+ GdkAtom target;
+
+ target = gtk_drop_target_find_mimetype (dest);
+ if (target != NULL)
+ {
+ set_status_pending (drop, 0);
+ gdk_drop_read_text_async (drop, NULL, got_text, dest);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
/****************************************
* Public API *