[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
This commit is contained in:
parent
a0be7fa455
commit
3e2a9a57a1
68
js/ui/dnd.js
68
js/ui/dnd.js
@ -14,6 +14,8 @@ const Params = imports.misc.params;
|
|||||||
const SCALE_ANIMATION_TIME = 0.25;
|
const SCALE_ANIMATION_TIME = 0.25;
|
||||||
// Time to animate to original position on cancel
|
// Time to animate to original position on cancel
|
||||||
const SNAP_BACK_ANIMATION_TIME = 0.25;
|
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 eventHandlerActor = null;
|
||||||
let currentDraggable = null;
|
let currentDraggable = null;
|
||||||
@ -41,6 +43,7 @@ function _Draggable(actor, params) {
|
|||||||
_Draggable.prototype = {
|
_Draggable.prototype = {
|
||||||
_init : function(actor, params) {
|
_init : function(actor, params) {
|
||||||
params = Params.parse(params, { manualMode: false,
|
params = Params.parse(params, { manualMode: false,
|
||||||
|
restoreOnSuccess: false,
|
||||||
dragActorMaxSize: undefined,
|
dragActorMaxSize: undefined,
|
||||||
dragActorOpacity: undefined });
|
dragActorOpacity: undefined });
|
||||||
|
|
||||||
@ -54,12 +57,13 @@ _Draggable.prototype = {
|
|||||||
}));
|
}));
|
||||||
this._onEventId = null;
|
this._onEventId = null;
|
||||||
|
|
||||||
|
this._restoreOnSuccess = params.restoreOnSuccess;
|
||||||
this._dragActorMaxSize = params.dragActorMaxSize;
|
this._dragActorMaxSize = params.dragActorMaxSize;
|
||||||
this._dragActorOpacity = params.dragActorOpacity;
|
this._dragActorOpacity = params.dragActorOpacity;
|
||||||
|
|
||||||
this._buttonDown = false; // The mouse button has been pressed and has not yet been released.
|
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._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) {
|
_onButtonPress : function (actor, event) {
|
||||||
@ -125,7 +129,7 @@ _Draggable.prototype = {
|
|||||||
this._buttonDown = false;
|
this._buttonDown = false;
|
||||||
if (this._dragInProgress) {
|
if (this._dragInProgress) {
|
||||||
return this._dragActorDropped(event);
|
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.
|
// Drag must have been cancelled with Esc.
|
||||||
this._dragComplete();
|
this._dragComplete();
|
||||||
return true;
|
return true;
|
||||||
@ -330,9 +334,14 @@ _Draggable.prototype = {
|
|||||||
(dropY - targY) / target.scale_y,
|
(dropY - targY) / target.scale_y,
|
||||||
event.get_time())) {
|
event.get_time())) {
|
||||||
// If it accepted the drop without taking the actor,
|
// If it accepted the drop without taking the actor,
|
||||||
// destroy it.
|
// handle it ourselves.
|
||||||
if (this._dragActor.get_parent() == this._dragActor.get_stage())
|
if (this._dragActor.get_parent() == this._dragActor.get_stage()) {
|
||||||
this._dragActor.destroy();
|
if (this._restoreOnSuccess) {
|
||||||
|
this._restoreDragActor(event.get_time());
|
||||||
|
return true;
|
||||||
|
} else
|
||||||
|
this._dragActor.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
this._dragInProgress = false;
|
this._dragInProgress = false;
|
||||||
this.emit('drag-end', event.get_time(), true);
|
this.emit('drag-end', event.get_time(), true);
|
||||||
@ -348,18 +357,23 @@ _Draggable.prototype = {
|
|||||||
return true;
|
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) {
|
_cancelDrag: function(eventTime) {
|
||||||
this._dragInProgress = false;
|
this._dragInProgress = false;
|
||||||
// Snap back to the actor source if the source is still around, snap back
|
let [snapBackX, snapBackY] = this._getRestoreLocation();
|
||||||
// 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
this._snapBackInProgress = true;
|
this._animationInProgress = true;
|
||||||
// No target, so snap back
|
// No target, so snap back
|
||||||
Tweener.addTween(this._dragActor,
|
Tweener.addTween(this._dragActor,
|
||||||
{ x: snapBackX,
|
{ x: snapBackX,
|
||||||
@ -369,13 +383,33 @@ _Draggable.prototype = {
|
|||||||
opacity: this._dragOrigOpacity,
|
opacity: this._dragOrigOpacity,
|
||||||
time: SNAP_BACK_ANIMATION_TIME,
|
time: SNAP_BACK_ANIMATION_TIME,
|
||||||
transition: 'easeOutQuad',
|
transition: 'easeOutQuad',
|
||||||
onComplete: this._onSnapBackComplete,
|
onComplete: this._onAnimationComplete,
|
||||||
onCompleteScope: this,
|
onCompleteScope: this,
|
||||||
onCompleteParams: [this._dragActor, eventTime]
|
onCompleteParams: [this._dragActor, eventTime]
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_onSnapBackComplete : function (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]
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_onAnimationComplete : function (dragActor, eventTime) {
|
||||||
if (this._dragOrigParent) {
|
if (this._dragOrigParent) {
|
||||||
dragActor.reparent(this._dragOrigParent);
|
dragActor.reparent(this._dragOrigParent);
|
||||||
dragActor.set_scale(this._dragOrigScale, this._dragOrigScale);
|
dragActor.set_scale(this._dragOrigScale, this._dragOrigScale);
|
||||||
@ -385,7 +419,7 @@ _Draggable.prototype = {
|
|||||||
}
|
}
|
||||||
this.emit('drag-end', eventTime, false);
|
this.emit('drag-end', eventTime, false);
|
||||||
|
|
||||||
this._snapBackInProgress = false;
|
this._animationInProgress = false;
|
||||||
if (!this._buttonDown)
|
if (!this._buttonDown)
|
||||||
this._dragComplete();
|
this._dragComplete();
|
||||||
},
|
},
|
||||||
|
@ -125,7 +125,8 @@ WindowClone.prototype = {
|
|||||||
Lang.bind(this, this._onLeave));
|
Lang.bind(this, this._onLeave));
|
||||||
|
|
||||||
this._draggable = DND.makeDraggable(this.actor,
|
this._draggable = DND.makeDraggable(this.actor,
|
||||||
{ dragActorMaxSize: WINDOW_DND_SIZE,
|
{ restoreOnSuccess: true,
|
||||||
|
dragActorMaxSize: WINDOW_DND_SIZE,
|
||||||
dragActorOpacity: DRAGGING_WINDOW_OPACITY });
|
dragActorOpacity: DRAGGING_WINDOW_OPACITY });
|
||||||
this._draggable.connect('drag-begin', Lang.bind(this, this._onDragBegin));
|
this._draggable.connect('drag-begin', Lang.bind(this, this._onDragBegin));
|
||||||
this._draggable.connect('drag-end', Lang.bind(this, this._onDragEnd));
|
this._draggable.connect('drag-end', Lang.bind(this, this._onDragEnd));
|
||||||
|
@ -1244,7 +1244,6 @@ SingleView.prototype = {
|
|||||||
this._timeoutId = 0;
|
this._timeoutId = 0;
|
||||||
}
|
}
|
||||||
this._dropGroup.lower_bottom();
|
this._dropGroup.lower_bottom();
|
||||||
actor.opacity = 255;
|
|
||||||
this._inDrag = false;
|
this._inDrag = false;
|
||||||
this._computeWorkspacePositions();
|
this._computeWorkspacePositions();
|
||||||
this._updateWorkspaceActors(true);
|
this._updateWorkspaceActors(true);
|
||||||
|
Loading…
Reference in New Issue
Block a user