forked from AuroraMiddleware/gtk
gtkdnd: Use a more modern spring back animation for cancelled drags
https://bugzilla.gnome.org/show_bug.cgi?id=705605
This commit is contained in:
parent
2b2162dd5f
commit
e80d1f0523
80
gtk/gtkdnd.c
80
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;
|
||||
double p = t - 1;
|
||||
return p * p * p + 1;
|
||||
}
|
||||
|
||||
anim = data;
|
||||
info = anim->info;
|
||||
|
||||
if (anim->step == anim->n_steps)
|
||||
static void
|
||||
gtk_drag_anim_destroy (GtkDragAnim *anim)
|
||||
{
|
||||
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)
|
||||
|
||||
static gboolean
|
||||
gtk_drag_anim_tick (GtkWidget *widget,
|
||||
GdkFrameClock *frame_clock,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *icon_window;
|
||||
gint hot_x, hot_y;
|
||||
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),
|
||||
x - hot_x,
|
||||
y - hot_y);
|
||||
}
|
||||
(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));
|
||||
|
||||
anim->step++;
|
||||
|
||||
retval = TRUE;
|
||||
}
|
||||
|
||||
return retval;
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user