[gnome-shell] [dnd] Optionally restore the drag actor



commit 3e2a9a57a1234d7095b178395ecf8ccedf050f9f
Author: Florian Müllner <fmuellner src gnome org>
Date:   Thu May 20 16:44:45 2010 +0200

    [dnd] Optionally restore the drag actor
    
    Currently, the drag and drop code assumes that on a successful drop
    the target will either consume the drag actor or that it is otherwise
    OK to destroy the actor.
    As the drag behavior for window preview was changed, dropping a preview
    on the dash now results in the preview being swallowed - to fix, add an
    option to restore the actor in case of a successful drop as well.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=619203

 js/ui/dnd.js            |   68 +++++++++++++++++++++++++++++++++++-----------
 js/ui/workspace.js      |    3 +-
 js/ui/workspacesView.js |    1 -
 3 files changed, 53 insertions(+), 19 deletions(-)
---
diff --git a/js/ui/dnd.js b/js/ui/dnd.js
index adcf6ec..d27aa49 100644
--- a/js/ui/dnd.js
+++ b/js/ui/dnd.js
@@ -14,6 +14,8 @@ const Params = imports.misc.params;
 const SCALE_ANIMATION_TIME = 0.25;
 // Time to animate to original position on cancel
 const SNAP_BACK_ANIMATION_TIME = 0.25;
+// Time to animate to original position on success
+const REVERT_ANIMATION_TIME = 0.75;
 
 let eventHandlerActor = null;
 let currentDraggable = null;
@@ -41,6 +43,7 @@ function _Draggable(actor, params) {
 _Draggable.prototype = {
     _init : function(actor, params) {
         params = Params.parse(params, { manualMode: false,
+                                        restoreOnSuccess: false,
                                         dragActorMaxSize: undefined,
                                         dragActorOpacity: undefined });
 
@@ -54,12 +57,13 @@ _Draggable.prototype = {
         }));
         this._onEventId = null;
 
+        this._restoreOnSuccess = params.restoreOnSuccess;
         this._dragActorMaxSize = params.dragActorMaxSize;
         this._dragActorOpacity = params.dragActorOpacity;
 
         this._buttonDown = false; // The mouse button has been pressed and has not yet been released.
         this._dragInProgress = false; // The drag has been started, and has not been dropped or cancelled yet.
-        this._snapBackInProgress = false; // The drag has been cancelled and the item is in the process of snapping back.
+        this._animationInProgress = false; // The drag is over and the item is in the process of animating to its original position (snapping back or reverting).
     },
 
     _onButtonPress : function (actor, event) {
@@ -125,7 +129,7 @@ _Draggable.prototype = {
             this._buttonDown = false;
             if (this._dragInProgress) {
                 return this._dragActorDropped(event);
-            } else if (this._dragActor != null && !this._snapBackInProgress) {
+            } else if (this._dragActor != null && !this._animationInProgress) {
                 // Drag must have been cancelled with Esc.
                 this._dragComplete();
                 return true;
@@ -330,9 +334,14 @@ _Draggable.prototype = {
                                                 (dropY - targY) / target.scale_y,
                                                 event.get_time())) {
                     // If it accepted the drop without taking the actor,
-                    // destroy it.
-                    if (this._dragActor.get_parent() == this._dragActor.get_stage())
-                        this._dragActor.destroy();
+                    // handle it ourselves.
+                    if (this._dragActor.get_parent() == this._dragActor.get_stage()) {
+                        if (this._restoreOnSuccess) {
+                            this._restoreDragActor(event.get_time());
+                            return true;
+                        } else
+                            this._dragActor.destroy();
+                    }
 
                     this._dragInProgress = false;
                     this.emit('drag-end', event.get_time(), true);
@@ -348,18 +357,23 @@ _Draggable.prototype = {
         return true;
     },
 
+    // Get position of the drag actor's source if the source is still around,
+    // or return the original location if the actor itself was being dragged
+    // or the source is no longer around.
+    _getRestoreLocation: function() {
+        let locX = this._snapBackX;
+        let locY = this._snapBackY;
+
+        if (this._dragActorSource && this._dragActorSource.visible)
+            [locX, locY] = this._dragActorSource.get_transformed_position();
+        return [locX, locY];
+    },
+
     _cancelDrag: function(eventTime) {
         this._dragInProgress = false;
-        // Snap back to the actor source if the source is still around, snap back 
-        // to the original location if the actor itself was being dragged or the
-        // source is no longer around.
-        let snapBackX = this._snapBackX;
-        let snapBackY = this._snapBackY;
-        if (this._dragActorSource && this._dragActorSource.visible) {
-            [snapBackX, snapBackY] = this._dragActorSource.get_transformed_position();
-        }
+        let [snapBackX, snapBackY] = this._getRestoreLocation();
 
-        this._snapBackInProgress = true;
+        this._animationInProgress = true;
         // No target, so snap back
         Tweener.addTween(this._dragActor,
                          { x: snapBackX,
@@ -369,13 +383,33 @@ _Draggable.prototype = {
                            opacity: this._dragOrigOpacity,
                            time: SNAP_BACK_ANIMATION_TIME,
                            transition: 'easeOutQuad',
-                           onComplete: this._onSnapBackComplete,
+                           onComplete: this._onAnimationComplete,
+                           onCompleteScope: this,
+                           onCompleteParams: [this._dragActor, eventTime]
+                         });
+    },
+
+    _restoreDragActor: function(eventTime) {
+        this._dragInProgress = false;
+        [restoreX, restoreY] = this._getRestoreLocation();
+
+        // fade the actor back in at its original location
+        this._dragActor.set_position(restoreX, restoreY);
+        this._dragActor.set_scale(this._snapBackScale, this._snapBackScale);
+        this._dragActor.opacity = 0;
+
+        this._animationInProgress = true;
+        Tweener.addTween(this._dragActor,
+                         { opacity: this._dragOrigOpacity,
+                           time: REVERT_ANIMATION_TIME,
+                           transition: 'easeOutQuad',
+                           onComplete: this._onAnimationComplete,
                            onCompleteScope: this,
                            onCompleteParams: [this._dragActor, eventTime]
                          });
     },
 
-    _onSnapBackComplete : function (dragActor, eventTime) {
+    _onAnimationComplete : function (dragActor, eventTime) {
         if (this._dragOrigParent) {
             dragActor.reparent(this._dragOrigParent);
             dragActor.set_scale(this._dragOrigScale, this._dragOrigScale);
@@ -385,7 +419,7 @@ _Draggable.prototype = {
         }
         this.emit('drag-end', eventTime, false);
 
-        this._snapBackInProgress = false;
+        this._animationInProgress = false;
         if (!this._buttonDown)
             this._dragComplete();
     },
diff --git a/js/ui/workspace.js b/js/ui/workspace.js
index 21bd5b6..060d2a0 100644
--- a/js/ui/workspace.js
+++ b/js/ui/workspace.js
@@ -125,7 +125,8 @@ WindowClone.prototype = {
                            Lang.bind(this, this._onLeave));
 
         this._draggable = DND.makeDraggable(this.actor,
-                                            { dragActorMaxSize: WINDOW_DND_SIZE,
+                                            { restoreOnSuccess: true,
+                                              dragActorMaxSize: WINDOW_DND_SIZE,
                                               dragActorOpacity: DRAGGING_WINDOW_OPACITY });
         this._draggable.connect('drag-begin', Lang.bind(this, this._onDragBegin));
         this._draggable.connect('drag-end', Lang.bind(this, this._onDragEnd));
diff --git a/js/ui/workspacesView.js b/js/ui/workspacesView.js
index f947da3..cf8882b 100644
--- a/js/ui/workspacesView.js
+++ b/js/ui/workspacesView.js
@@ -1244,7 +1244,6 @@ SingleView.prototype = {
             this._timeoutId = 0;
         }
         this._dropGroup.lower_bottom();
-        actor.opacity = 255;
         this._inDrag = false;
         this._computeWorkspacePositions();
         this._updateWorkspaceActors(true);



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