[gnome-shell] [DND] Allow setting drag actor max size and opacity
- From: Owen Taylor <otaylor src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell] [DND] Allow setting drag actor max size and opacity
- Date: Tue, 23 Mar 2010 15:32:53 +0000 (UTC)
commit 94472ba9fafeddf09eceaf7751606b56d1bbabca
Author: Owen W. Taylor <otaylor fishsoup net>
Date: Mon Mar 22 16:29:13 2010 -0400
[DND] Allow setting drag actor max size and opacity
Add parameters to DND.makeDraggable:
dragActorMaxSize: Maximum size for actor drag icon
dragActorOpacity: Opacity of actor during drag
https://bugzilla.gnome.org/show_bug.cgi?id=613367
js/ui/dnd.js | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 68 insertions(+), 5 deletions(-)
---
diff --git a/js/ui/dnd.js b/js/ui/dnd.js
index f64dc75..8bf28df 100644
--- a/js/ui/dnd.js
+++ b/js/ui/dnd.js
@@ -8,6 +8,9 @@ const Tweener = imports.ui.tweener;
const Params = imports.misc.params;
+// Time to scale down to maxDragActorSize
+const SCALE_ANIMATION_TIME = 0.25;
+// Time to animate to original position on cancel
const SNAP_BACK_ANIMATION_TIME = 0.25;
let eventHandlerActor = null;
@@ -35,7 +38,9 @@ function _Draggable(actor, params) {
_Draggable.prototype = {
_init : function(actor, params) {
- params = Params.parse(params, { manualMode: false });
+ params = Params.parse(params, { manualMode: false,
+ dragActorMaxSize: undefined,
+ dragActorOpacity: undefined });
this.actor = actor;
if (!params.manualMode)
@@ -47,6 +52,9 @@ _Draggable.prototype = {
}));
this._onEventId = null;
+ 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.
@@ -148,8 +156,8 @@ _Draggable.prototype = {
this._ungrabActor();
this._grabEvents();
- this._dragStartX = stageX;
- this._dragStartY = stageY;
+ this._dragX = this._dragStartX = stageX;
+ this._dragY = this._dragStartY = stageY;
if (this.actor._delegate && this.actor._delegate.getDragActor) {
this._dragActor = this.actor._delegate.getDragActor(this._dragStartX, this._dragStartY);
@@ -200,6 +208,45 @@ _Draggable.prototype = {
this._dragActor.reparent(this.actor.get_stage());
this._dragActor.raise_top();
+
+ this._dragOrigOpacity = this._dragActor.opacity;
+ if (this._dragActorOpacity != undefined)
+ this._dragActor.opacity = this._dragActorOpacity;
+
+ this._snapBackX = this._dragStartX + this._dragOffsetX;
+ this._snapBackY = this._dragStartY + this._dragOffsetY;
+ this._snapBackScale = this._dragActor.scale_x;
+
+ if (this._dragActorMaxSize != undefined) {
+ let [scaledWidth, scaledHeight] = this._dragActor.get_transformed_size();
+ let currentSize = Math.max(scaledWidth, scaledHeight);
+ if (currentSize > this._dragActorMaxSize) {
+ let scale = this._dragActorMaxSize / currentSize;
+ let origScale = this._dragActor.scale_x;
+ let origDragOffsetX = this._dragOffsetX;
+ let origDragOffsetY = this._dragOffsetY;
+
+ // The position of the actor changes as we scale
+ // around the drag position, but we can't just tween
+ // to the final position because that tween would
+ // fight with updates as the user continues dragging
+ // the mouse; instead we do the position computations in
+ // an onUpdate() function.
+ Tweener.addTween(this._dragActor,
+ { scale_x: scale * origScale,
+ scale_y: scale * origScale,
+ time: SCALE_ANIMATION_TIME,
+ transition: "easeOutQuad",
+ onUpdate: function() {
+ let currentScale = this._dragActor.scale_x / origScale;
+ this._dragOffsetX = currentScale * origDragOffsetX;
+ this._dragOffsetY = currentScale * origDragOffsetY;
+ this._dragActor.set_position(this._dragX + this._dragOffsetX,
+ this._dragY + this._dragOffsetY);
+ },
+ onUpdateScope: this });
+ }
+ }
},
_maybeStartDrag: function(event) {
@@ -218,6 +265,8 @@ _Draggable.prototype = {
_updateDragPosition : function (event) {
let [stageX, stageY] = event.get_coords();
+ this._dragX = stageX;
+ this._dragY = stageY;
// If we are dragging, update the position
if (this._dragActor) {
@@ -286,8 +335,8 @@ _Draggable.prototype = {
// 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._dragStartX + this._dragOffsetX;
- let snapBackY = this._dragStartY + this._dragOffsetY;
+ let snapBackX = this._snapBackX;
+ let snapBackY = this._snapBackY;
if (this._dragActorSource && this._dragActorSource.visible) {
[snapBackX, snapBackY] = this._dragActorSource.get_transformed_position();
}
@@ -297,6 +346,9 @@ _Draggable.prototype = {
Tweener.addTween(this._dragActor,
{ x: snapBackX,
y: snapBackY,
+ scale_x: this._snapBackScale,
+ scale_y: this._snapBackScale,
+ opacity: this._dragOrigOpacity,
time: SNAP_BACK_ANIMATION_TIME,
transition: "easeOutQuad",
onComplete: this._onSnapBackComplete,
@@ -338,6 +390,17 @@ Signals.addSignalMethods(_Draggable.prototype);
*
* If %manualMode is %true in @params, do not automatically start
* drag and drop on click
+ *
+ * If %dragActorMaxSize is present in @params, the drag actor will
+ * be scaled down to be no larger than that size in pixels.
+ *
+ * If %dragActorOpacity is present in @params, the drag actor will
+ * will be set to have that opacity during the drag.
+ *
+ * Note that when the drag actor is the source actor and the drop
+ * succeeds, the actor scale and opacity aren't reset; if the drop
+ * target wants to reuse the actor, it's up to the drop target to
+ * reset these values.
*/
function makeDraggable(actor, params) {
return new _Draggable(actor, params);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]