Add API to programmatically initiate a drag
For some use cases we have other behavior on mouse press and want to manually control when a drag starts. Split out the drag initiation code into startDrag.
This commit is contained in:
parent
3e54087e42
commit
1a834f7d8b
72
js/ui/dnd.js
72
js/ui/dnd.js
@ -8,15 +8,17 @@ const Tweener = imports.ui.tweener;
|
|||||||
|
|
||||||
const SNAP_BACK_ANIMATION_TIME = 0.25;
|
const SNAP_BACK_ANIMATION_TIME = 0.25;
|
||||||
|
|
||||||
function _Draggable(actor) {
|
function _Draggable(actor, manualMode) {
|
||||||
this._init(actor);
|
this._init(actor, manualMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
_Draggable.prototype = {
|
_Draggable.prototype = {
|
||||||
_init : function(actor) {
|
_init : function(actor, manualMode) {
|
||||||
this.actor = actor;
|
this.actor = actor;
|
||||||
|
if (!manualMode)
|
||||||
this.actor.connect('button-press-event',
|
this.actor.connect('button-press-event',
|
||||||
Lang.bind(this, this._onButtonPress));
|
Lang.bind(this, this._onButtonPress));
|
||||||
|
this._haveSourceGrab = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
_onButtonPress : function (actor, event) {
|
_onButtonPress : function (actor, event) {
|
||||||
@ -25,6 +27,7 @@ _Draggable.prototype = {
|
|||||||
if (Tweener.getTweenCount(actor))
|
if (Tweener.getTweenCount(actor))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
this._haveSourceGrab = true;
|
||||||
this._grabActor(actor);
|
this._grabActor(actor);
|
||||||
|
|
||||||
let [stageX, stageY] = event.get_coords();
|
let [stageX, stageY] = event.get_coords();
|
||||||
@ -66,16 +69,22 @@ _Draggable.prototype = {
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
_onMotion : function (actor, event) {
|
/**
|
||||||
let [stageX, stageY] = event.get_coords();
|
* startDrag:
|
||||||
|
* @actor: Origin actor for drag and drop
|
||||||
|
* @stageX: X coordinate of event
|
||||||
|
* @stageY: Y coordinate of event
|
||||||
|
* @time: Event timestamp
|
||||||
|
*
|
||||||
|
* Directly initiate a drag and drop operation from the given actor.
|
||||||
|
* This function is useful to call if you've specified manualMode
|
||||||
|
* for the draggable.
|
||||||
|
*/
|
||||||
|
startDrag: function (actor, stageX, stageY, time) {
|
||||||
|
this.emit('drag-begin', time);
|
||||||
|
|
||||||
// If we haven't begun a drag, see if the user has moved the
|
this._dragStartX = stageX;
|
||||||
// mouse enough to trigger a drag
|
this._dragStartY = stageY;
|
||||||
let threshold = Gtk.Settings.get_default().gtk_dnd_drag_threshold;
|
|
||||||
if (!this._dragActor &&
|
|
||||||
(Math.abs(stageX - this._dragStartX) > threshold ||
|
|
||||||
Math.abs(stageY - this._dragStartY) > threshold)) {
|
|
||||||
this.emit('drag-begin', event.get_time());
|
|
||||||
|
|
||||||
if (this.actor._delegate && this.actor._delegate.getDragActor) {
|
if (this.actor._delegate && this.actor._delegate.getDragActor) {
|
||||||
this._dragActor = this.actor._delegate.getDragActor(this._dragStartX, this._dragStartY);
|
this._dragActor = this.actor._delegate.getDragActor(this._dragStartX, this._dragStartY);
|
||||||
@ -89,16 +98,24 @@ _Draggable.prototype = {
|
|||||||
// around the pointer
|
// around the pointer
|
||||||
let [sourceX, sourceY] = this._dragActorSource.get_transformed_position();
|
let [sourceX, sourceY] = this._dragActorSource.get_transformed_position();
|
||||||
let [sourceWidth, sourceHeight] = this._dragActorSource.get_transformed_size();
|
let [sourceWidth, sourceHeight] = this._dragActorSource.get_transformed_size();
|
||||||
|
let x, y;
|
||||||
if (stageX > sourceX && stageX <= sourceX + sourceWidth &&
|
if (stageX > sourceX && stageX <= sourceX + sourceWidth &&
|
||||||
stageY > sourceY && stageY <= sourceY + sourceHeight)
|
stageY > sourceY && stageY <= sourceY + sourceHeight) {
|
||||||
this._dragActor.set_position(sourceX, sourceY);
|
x = sourceX;
|
||||||
else
|
y = sourceY;
|
||||||
this._dragActor.set_position(stageX - this._dragActor.width / 2, stageY - this._dragActor.height / 2);
|
} else {
|
||||||
|
x = stageX - this._dragActor.width / 2;
|
||||||
|
y = stageY - this._dragActor.height / 2;
|
||||||
|
}
|
||||||
|
this._dragActor.set_position(x, y);
|
||||||
} else {
|
} else {
|
||||||
this._dragActorSource = this.actor;
|
this._dragActorSource = this.actor;
|
||||||
}
|
}
|
||||||
this._dragOrigParent = undefined;
|
this._dragOrigParent = undefined;
|
||||||
|
if (this._haveSourceGrab) {
|
||||||
|
this._haveSourceGrab = false;
|
||||||
this._ungrabActor(actor);
|
this._ungrabActor(actor);
|
||||||
|
}
|
||||||
this._grabActor(this._dragActor);
|
this._grabActor(this._dragActor);
|
||||||
|
|
||||||
this._dragOffsetX = this._dragActor.x - this._dragStartX;
|
this._dragOffsetX = this._dragActor.x - this._dragStartX;
|
||||||
@ -124,6 +141,18 @@ _Draggable.prototype = {
|
|||||||
|
|
||||||
this._dragActor.reparent(actor.get_stage());
|
this._dragActor.reparent(actor.get_stage());
|
||||||
this._dragActor.raise_top();
|
this._dragActor.raise_top();
|
||||||
|
},
|
||||||
|
|
||||||
|
_onMotion : function (actor, event) {
|
||||||
|
let [stageX, stageY] = event.get_coords();
|
||||||
|
|
||||||
|
// If we haven't begun a drag, see if the user has moved the
|
||||||
|
// mouse enough to trigger a drag
|
||||||
|
let threshold = Gtk.Settings.get_default().gtk_dnd_drag_threshold;
|
||||||
|
if (!this._dragActor &&
|
||||||
|
(Math.abs(stageX - this._dragStartX) > threshold ||
|
||||||
|
Math.abs(stageY - this._dragStartY) > threshold)) {
|
||||||
|
this.startDrag(actor, stageX, stageY, event.get_time());
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we are dragging, update the position
|
// If we are dragging, update the position
|
||||||
@ -225,6 +254,13 @@ _Draggable.prototype = {
|
|||||||
|
|
||||||
Signals.addSignalMethods(_Draggable.prototype);
|
Signals.addSignalMethods(_Draggable.prototype);
|
||||||
|
|
||||||
function makeDraggable(actor) {
|
/**
|
||||||
return new _Draggable(actor);
|
* makeDraggable:
|
||||||
|
* @actor: Source actor
|
||||||
|
* @manualMode: If given, do not automatically start drag and drop on click
|
||||||
|
*
|
||||||
|
* Create an object which controls drag and drop for the given actor.
|
||||||
|
*/
|
||||||
|
function makeDraggable(actor, manualMode) {
|
||||||
|
return new _Draggable(actor, manualMode);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user