[gtk+/wip/matthiasc/dnd-animation: 6/7] x11: Implement drag cancel animation



commit ffd6795e8bc4f608d8a2c81bcb304bdc373863d3
Author: Matthias Clasen <mclasen redhat com>
Date:   Mon Dec 7 18:28:06 2015 -0500

    x11: Implement drag cancel animation
    
    Showing the drag cancel animation can be done in the X11
    drag context implementation now that we hold the drag
    window there, and have the start coordinates.

 gdk/x11/gdkdnd-x11.c |   77 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 77 insertions(+), 0 deletions(-)
---
diff --git a/gdk/x11/gdkdnd-x11.c b/gdk/x11/gdkdnd-x11.c
index 0cc8209..ea08f47 100644
--- a/gdk/x11/gdkdnd-x11.c
+++ b/gdk/x11/gdkdnd-x11.c
@@ -186,6 +186,8 @@ static void        gdk_x11_drag_context_drop_finish (GdkDragContext  *context,
                                                      guint32          time_);
 static gboolean    gdk_x11_drag_context_drop_status (GdkDragContext  *context);
 static GdkAtom     gdk_x11_drag_context_get_selection (GdkDragContext  *context);
+static void        gdk_x11_drag_context_drop_done     (GdkDragContext  *context,
+                                                       gboolean         success);
 
 static GdkWindow *
 gdk_x11_drag_context_get_drag_window (GdkDragContext *context)
@@ -211,6 +213,7 @@ gdk_x11_drag_context_class_init (GdkX11DragContextClass *klass)
   context_class->drop_status = gdk_x11_drag_context_drop_status;
   context_class->get_selection = gdk_x11_drag_context_get_selection;
   context_class->get_drag_window = gdk_x11_drag_context_get_drag_window;
+  context_class->drop_done = gdk_x11_drag_context_drop_done;
 }
 
 static void
@@ -2465,3 +2468,77 @@ gdk_x11_drag_context_drop_status (GdkDragContext *context)
 {
   return ! GDK_X11_DRAG_CONTEXT (context)->drop_failed;
 }
+
+static double
+ease_out_cubic (double t)
+{
+  double p = t - 1;
+  return p * p * p + 1;
+}
+
+
+#define ANIM_TIME 500000 /* half a second */
+
+typedef struct _GdkDragAnim GdkDragAnim;
+struct _GdkDragAnim {
+  GdkX11DragContext *context;
+  GdkFrameClock *frame_clock;
+  gint64 start_time;
+};
+
+static void
+gdk_drag_anim_destroy (GdkDragAnim *anim)
+{
+  g_object_unref (anim->context);
+  g_slice_free (GdkDragAnim, anim);
+}
+
+static gboolean
+gdk_drag_anim_timeout (gpointer data)
+{
+  GdkDragAnim *anim = data;
+  GdkX11DragContext *context = anim->context;
+  GdkFrameClock *frame_clock = anim->frame_clock;
+  gint64 current_time;
+  double f;
+  double t;
+
+  if (!frame_clock)
+    return G_SOURCE_REMOVE;
+
+  current_time = gdk_frame_clock_get_frame_time (frame_clock);
+
+  f = (current_time - anim->start_time) / (double) ANIM_TIME;
+
+  if (f >= 1.0)
+    return G_SOURCE_REMOVE;
+
+  t = ease_out_cubic (f);
+
+  gdk_window_move (context->drag_window,
+                   context->last_x + (context->start_x - context->last_x) * t,
+                   context->last_y + (context->start_y - context->last_y) * t);
+  gdk_window_set_opacity (context->drag_window, 1.0 - f);
+
+  return G_SOURCE_CONTINUE;
+}
+
+static void
+gdk_x11_drag_context_drop_done (GdkDragContext *context,
+                                gboolean        success)
+{
+  GdkX11DragContext *x11_context = GDK_X11_DRAG_CONTEXT (context);
+  GdkDragAnim *anim;
+
+  if (success)
+    return;
+
+  anim = g_slice_new0 (GdkDragAnim);
+  anim->context = g_object_ref (x11_context);
+  anim->frame_clock = gdk_window_get_frame_clock (x11_context->drag_window);
+  anim->start_time = gdk_frame_clock_get_frame_time (anim->frame_clock);
+
+  gdk_threads_add_timeout_full (G_PRIORITY_DEFAULT, 17,
+                                gdk_drag_anim_timeout, anim,
+                                (GDestroyNotify) gdk_drag_anim_destroy);
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]