[gtk+] gtkdnd: Use a more modern spring back animation for cancelled drags
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] gtkdnd: Use a more modern spring back animation for cancelled drags
- Date: Wed, 14 Aug 2013 11:15:50 +0000 (UTC)
commit e80d1f0523d8e47deff687b3aa6877a152507d0d
Author: Jasper St. Pierre <jstpierre mecheye net>
Date: Wed Aug 7 03:24:01 2013 -0400
gtkdnd: Use a more modern spring back animation for cancelled drags
https://bugzilla.gnome.org/show_bug.cgi?id=705605
gtk/gtkdnd.c | 98 ++++++++++++++++++++++++++++------------------------------
1 files changed, 47 insertions(+), 51 deletions(-)
---
diff --git a/gtk/gtkdnd.c b/gtk/gtkdnd.c
index dab4dfc..21ca429 100644
--- a/gtk/gtkdnd.c
+++ b/gtk/gtkdnd.c
@@ -159,16 +159,12 @@ struct _GtkDragDestInfo
#define DROP_ABORT_TIME 300000
-#define ANIM_STEP_TIME 50
-#define ANIM_STEP_LENGTH 50
-#define ANIM_MIN_STEPS 5
-#define ANIM_MAX_STEPS 10
+#define ANIM_TIME (0.5 * 1000 * 1000) /* half a second */
struct _GtkDragAnim
{
GtkDragSourceInfo *info;
- gint step;
- gint n_steps;
+ gint64 start_time;
};
typedef gboolean (* GtkDragDestCallback) (GtkWidget *widget,
@@ -259,7 +255,10 @@ static void gtk_drag_selection_get (GtkWidget *widget,
guint sel_info,
guint32 time,
gpointer data);
-static gboolean gtk_drag_anim_timeout (gpointer data);
+static void gtk_drag_anim_destroy (GtkDragAnim *anim);
+static gboolean gtk_drag_anim_tick (GtkWidget *widget,
+ GdkFrameClock *frame_clock,
+ gpointer data);
static void gtk_drag_remove_icon (GtkDragSourceInfo *info);
static void gtk_drag_source_info_destroy (GtkDragSourceInfo *info);
static void gtk_drag_add_update_idle (GtkDragSourceInfo *info);
@@ -3727,11 +3726,7 @@ gtk_drag_drop_finished (GtkDragSourceInfo *info,
{
GtkDragAnim *anim = g_slice_new0 (GtkDragAnim);
anim->info = info;
- anim->step = 0;
-
- anim->n_steps = MAX (info->cur_x - info->start_x,
- info->cur_y - info->start_y) / ANIM_STEP_LENGTH;
- anim->n_steps = CLAMP (anim->n_steps, ANIM_MIN_STEPS, ANIM_MAX_STEPS);
+ anim->start_time = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (info->widget));
info->cur_screen = gtk_widget_get_screen (info->widget);
@@ -3745,7 +3740,7 @@ gtk_drag_drop_finished (GtkDragSourceInfo *info,
* to respond really late, we still are OK.
*/
gtk_drag_clear_source_info (info->context);
- gdk_threads_add_timeout (ANIM_STEP_TIME, gtk_drag_anim_timeout, anim);
+ gtk_widget_add_tick_callback (info->widget, gtk_drag_anim_tick, anim, (GDestroyNotify)
gtk_drag_anim_destroy);
}
}
}
@@ -3957,47 +3952,48 @@ gtk_drag_selection_get (GtkWidget *widget,
}
}
-static gboolean
-gtk_drag_anim_timeout (gpointer data)
+/* From clutter-easing.c, based on Robert Penner's
+ * infamous easing equations, MIT license.
+ */
+static double
+ease_out_cubic (double t)
{
- GtkDragAnim *anim;
- GtkDragSourceInfo *info;
- gint x, y;
- gboolean retval;
-
- anim = data;
- info = anim->info;
-
- if (anim->step == anim->n_steps)
- {
- gtk_drag_source_info_destroy (anim->info);
- g_slice_free (GtkDragAnim, anim);
-
- retval = FALSE;
- }
- else
- {
- x = (info->start_x * (anim->step + 1) +
- info->cur_x * (anim->n_steps - anim->step - 1)) / anim->n_steps;
- y = (info->start_y * (anim->step + 1) +
- info->cur_y * (anim->n_steps - anim->step - 1)) / anim->n_steps;
- if (info->icon_window)
- {
- GtkWidget *icon_window;
- gint hot_x, hot_y;
-
- gtk_drag_get_icon (info, &icon_window, &hot_x, &hot_y);
- gtk_window_move (GTK_WINDOW (icon_window),
- x - hot_x,
- y - hot_y);
- }
-
- anim->step++;
+ double p = t - 1;
+ return p * p * p + 1;
+}
- retval = TRUE;
- }
+static void
+gtk_drag_anim_destroy (GtkDragAnim *anim)
+{
+ gtk_drag_source_info_destroy (anim->info);
+ g_slice_free (GtkDragAnim, anim);
+}
- return retval;
+static gboolean
+gtk_drag_anim_tick (GtkWidget *widget,
+ GdkFrameClock *frame_clock,
+ gpointer data)
+{
+ GtkWidget *icon_window;
+ GtkDragAnim *anim = data;
+ GtkDragSourceInfo *info = anim->info;
+ gint64 current_time = gdk_frame_clock_get_frame_time (frame_clock);
+ int hot_x, hot_y;
+ double f = (current_time - anim->start_time) / (double) ANIM_TIME;
+ double t;
+
+ if (f >= 1.0)
+ return G_SOURCE_REMOVE;
+
+ t = ease_out_cubic (f);
+
+ gtk_drag_get_icon (info, &icon_window, &hot_x, &hot_y);
+ gtk_window_move (GTK_WINDOW (icon_window),
+ (info->cur_x + (info->start_x - info->cur_x) * t) - hot_x,
+ (info->cur_y + (info->start_y - info->cur_y) * t) - hot_y);
+ gtk_widget_set_opacity (icon_window, (1.0 - f));
+
+ return G_SOURCE_CONTINUE;
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]