[mutter/wip/dnd-surface2: 10/18] backend: Add "DnD failed" animation
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/dnd-surface2: 10/18] backend: Add "DnD failed" animation
- Date: Tue, 30 Sep 2014 15:35:59 +0000 (UTC)
commit 79fdbbfe1a8b91a609fb482b268b2bdc59329afc
Author: Carlos Garnacho <carlosg gnome org>
Date: Tue Sep 30 16:53:21 2014 +0200
backend: Add "DnD failed" animation
This is currently handled by the MetaStage, when DnD is hinted to be
failed, the current overlay will be copied and used on the snap back/
fade out animation, after the animation is finished, the extra overlay
will be freed.
src/backends/meta-stage.c | 102 +++++++++++++++++++++++++++++++++++++++++++++
src/backends/meta-stage.h | 5 ++
2 files changed, 107 insertions(+), 0 deletions(-)
---
diff --git a/src/backends/meta-stage.c b/src/backends/meta-stage.c
index 72c5091..109778f 100644
--- a/src/backends/meta-stage.c
+++ b/src/backends/meta-stage.c
@@ -28,6 +28,8 @@
#include <meta/meta-backend.h>
#include <meta/util.h>
+#define DRAG_FAILED_MSECS 500
+
typedef struct {
gboolean enabled;
@@ -39,9 +41,20 @@ typedef struct {
gboolean previous_is_valid;
} MetaOverlay;
+typedef struct {
+ MetaStage *stage;
+ MetaOverlay overlay;
+ ClutterTimeline *timeline;
+ int orig_x;
+ int orig_y;
+ int dest_x;
+ int dest_y;
+} MetaDragFailedAnimation;
+
struct _MetaStagePrivate {
MetaOverlay dnd_overlay;
MetaOverlay cursor_overlay;
+ GList *drag_failed_animations;
};
typedef struct _MetaStagePrivate MetaStagePrivate;
@@ -131,9 +144,17 @@ meta_stage_paint (ClutterActor *actor)
{
MetaStage *stage = META_STAGE (actor);
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
+ MetaDragFailedAnimation *animation;
+ GList *l;
CLUTTER_ACTOR_CLASS (meta_stage_parent_class)->paint (actor);
+ for (l = priv->drag_failed_animations; l; l = l->next)
+ {
+ animation = l->data;
+ meta_overlay_paint (&animation->overlay);
+ }
+
meta_overlay_paint (&priv->dnd_overlay);
meta_overlay_paint (&priv->cursor_overlay);
}
@@ -221,3 +242,84 @@ meta_stage_set_cursor (MetaStage *stage,
meta_overlay_set (&priv->cursor_overlay, texture, rect);
queue_redraw_for_overlay (stage, &priv->cursor_overlay);
}
+
+static void
+drag_failed_animation_frame_cb (ClutterTimeline *timeline,
+ guint pos,
+ gpointer user_data)
+{
+ MetaDragFailedAnimation *data = user_data;
+ gdouble progress = clutter_timeline_get_progress (timeline);
+ CoglColor color;
+
+ cogl_color_init_from_4f (&color, 0, 0, 0, 1 - progress);
+ cogl_pipeline_set_layer_combine_constant (data->overlay.pipeline, 0, &color);
+
+ data->overlay.current_rect.x = data->orig_x + ((data->dest_x - data->orig_x) * progress);
+ data->overlay.current_rect.y = data->orig_y + ((data->dest_y - data->orig_y) * progress);
+ queue_redraw_for_overlay (data->stage, &data->overlay);
+}
+
+static void
+meta_drag_failed_animation_free (MetaDragFailedAnimation *data)
+{
+ MetaStage *stage = data->stage;
+ MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
+
+ priv->drag_failed_animations =
+ g_list_remove (priv->drag_failed_animations, data);
+
+ g_object_unref (data->timeline);
+ meta_overlay_free (&data->overlay);
+ g_slice_free (MetaDragFailedAnimation, data);
+}
+
+static MetaDragFailedAnimation *
+meta_drag_failed_animation_new (MetaStage *stage,
+ int dest_x,
+ int dest_y)
+{
+ MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
+ MetaDragFailedAnimation *data;
+
+ data = g_slice_new0 (MetaDragFailedAnimation);
+ data->stage = stage;
+ data->orig_x = priv->dnd_overlay.current_rect.x;
+ data->orig_y = priv->dnd_overlay.current_rect.y;
+ data->dest_x = dest_x;
+ data->dest_y = dest_y;
+
+ meta_overlay_copy (&priv->dnd_overlay, &data->overlay);
+
+ data->timeline = clutter_timeline_new (DRAG_FAILED_MSECS);
+ clutter_timeline_set_progress_mode (data->timeline, CLUTTER_EASE_OUT_CUBIC);
+ g_signal_connect (data->timeline, "new-frame",
+ G_CALLBACK (drag_failed_animation_frame_cb), data);
+ g_signal_connect_swapped (data->timeline, "completed",
+ G_CALLBACK (meta_drag_failed_animation_free), data);
+
+ priv->drag_failed_animations =
+ g_list_prepend (priv->drag_failed_animations, data);
+
+ cogl_pipeline_set_layer_combine (data->overlay.pipeline, 0,
+ "RGBA = MODULATE (TEXTURE, CONSTANT[A])",
+ NULL);
+ return data;
+}
+
+void
+meta_stage_dnd_failed (MetaStage *stage,
+ int dest_x,
+ int dest_y)
+{
+ MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
+ MetaDragFailedAnimation *data;
+
+ g_assert (meta_is_wayland_compositor ());
+
+ if (!priv->dnd_overlay.enabled)
+ return;
+
+ data = meta_drag_failed_animation_new (stage, dest_x, dest_y);
+ clutter_timeline_start (data->timeline);
+}
diff --git a/src/backends/meta-stage.h b/src/backends/meta-stage.h
index 572530d..6e7d0df 100644
--- a/src/backends/meta-stage.h
+++ b/src/backends/meta-stage.h
@@ -58,6 +58,11 @@ void meta_stage_set_dnd_surface (MetaStage *stage,
void meta_stage_set_cursor (MetaStage *stage,
CoglTexture *texture,
MetaRectangle *rect);
+
+void meta_stage_dnd_failed (MetaStage *stage,
+ int dest_x,
+ int dest_y);
+
G_END_DECLS
#endif /* META_STAGE_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]