131 lines
4.4 KiB
JavaScript
131 lines
4.4 KiB
JavaScript
|
if(!dojo._hasResource["dojo.dnd.Moveable"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||
|
dojo._hasResource["dojo.dnd.Moveable"] = true;
|
||
|
dojo.provide("dojo.dnd.Moveable");
|
||
|
|
||
|
dojo.require("dojo.dnd.Mover");
|
||
|
|
||
|
dojo.declare("dojo.dnd.Moveable", null, {
|
||
|
// object attributes (for markup)
|
||
|
handle: "",
|
||
|
delay: 0,
|
||
|
skip: false,
|
||
|
|
||
|
constructor: function(node, params){
|
||
|
// summary: an object, which makes a node moveable
|
||
|
// node: Node: a node (or node's id) to be moved
|
||
|
// params: Object: an optional object with additional parameters;
|
||
|
// following parameters are recognized:
|
||
|
// handle: Node: a node (or node's id), which is used as a mouse handle
|
||
|
// if omitted, the node itself is used as a handle
|
||
|
// delay: Number: delay move by this number of pixels
|
||
|
// skip: Boolean: skip move of form elements
|
||
|
// mover: Object: a constructor of custom Mover
|
||
|
this.node = dojo.byId(node);
|
||
|
if(!params){ params = {}; }
|
||
|
this.handle = params.handle ? dojo.byId(params.handle) : null;
|
||
|
if(!this.handle){ this.handle = this.node; }
|
||
|
this.delay = params.delay > 0 ? params.delay : 0;
|
||
|
this.skip = params.skip;
|
||
|
this.mover = params.mover ? params.mover : dojo.dnd.Mover;
|
||
|
this.events = [
|
||
|
dojo.connect(this.handle, "onmousedown", this, "onMouseDown"),
|
||
|
// cancel text selection and text dragging
|
||
|
dojo.connect(this.handle, "ondragstart", this, "onSelectStart"),
|
||
|
dojo.connect(this.handle, "onselectstart", this, "onSelectStart")
|
||
|
];
|
||
|
},
|
||
|
|
||
|
// markup methods
|
||
|
markupFactory: function(params, node){
|
||
|
return new dojo.dnd.Moveable(node, params);
|
||
|
},
|
||
|
|
||
|
// methods
|
||
|
destroy: function(){
|
||
|
// summary: stops watching for possible move, deletes all references, so the object can be garbage-collected
|
||
|
dojo.forEach(this.events, dojo.disconnect);
|
||
|
this.events = this.node = this.handle = null;
|
||
|
},
|
||
|
|
||
|
// mouse event processors
|
||
|
onMouseDown: function(e){
|
||
|
// summary: event processor for onmousedown, creates a Mover for the node
|
||
|
// e: Event: mouse event
|
||
|
if(this.skip && dojo.dnd.isFormElement(e)){ return; }
|
||
|
if(this.delay){
|
||
|
this.events.push(dojo.connect(this.handle, "onmousemove", this, "onMouseMove"));
|
||
|
this.events.push(dojo.connect(this.handle, "onmouseup", this, "onMouseUp"));
|
||
|
this._lastX = e.pageX;
|
||
|
this._lastY = e.pageY;
|
||
|
}else{
|
||
|
new this.mover(this.node, e, this);
|
||
|
}
|
||
|
dojo.stopEvent(e);
|
||
|
},
|
||
|
onMouseMove: function(e){
|
||
|
// summary: event processor for onmousemove, used only for delayed drags
|
||
|
// e: Event: mouse event
|
||
|
if(Math.abs(e.pageX - this._lastX) > this.delay || Math.abs(e.pageY - this._lastY) > this.delay){
|
||
|
this.onMouseUp(e);
|
||
|
new this.mover(this.node, e, this);
|
||
|
}
|
||
|
dojo.stopEvent(e);
|
||
|
},
|
||
|
onMouseUp: function(e){
|
||
|
// summary: event processor for onmouseup, used only for delayed delayed drags
|
||
|
// e: Event: mouse event
|
||
|
dojo.disconnect(this.events.pop());
|
||
|
dojo.disconnect(this.events.pop());
|
||
|
},
|
||
|
onSelectStart: function(e){
|
||
|
// summary: event processor for onselectevent and ondragevent
|
||
|
// e: Event: mouse event
|
||
|
if(!this.skip || !dojo.dnd.isFormElement(e)){
|
||
|
dojo.stopEvent(e);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
// local events
|
||
|
onMoveStart: function(/* dojo.dnd.Mover */ mover){
|
||
|
// summary: called before every move operation
|
||
|
dojo.publish("/dnd/move/start", [mover]);
|
||
|
dojo.addClass(dojo.body(), "dojoMove");
|
||
|
dojo.addClass(this.node, "dojoMoveItem");
|
||
|
},
|
||
|
onMoveStop: function(/* dojo.dnd.Mover */ mover){
|
||
|
// summary: called after every move operation
|
||
|
dojo.publish("/dnd/move/stop", [mover]);
|
||
|
dojo.removeClass(dojo.body(), "dojoMove");
|
||
|
dojo.removeClass(this.node, "dojoMoveItem");
|
||
|
},
|
||
|
onFirstMove: function(/* dojo.dnd.Mover */ mover){
|
||
|
// summary: called during the very first move notification,
|
||
|
// can be used to initialize coordinates, can be overwritten.
|
||
|
|
||
|
// default implementation does nothing
|
||
|
},
|
||
|
onMove: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){
|
||
|
// summary: called during every move notification,
|
||
|
// should actually move the node, can be overwritten.
|
||
|
this.onMoving(mover, leftTop);
|
||
|
var s = mover.node.style;
|
||
|
s.left = leftTop.l + "px";
|
||
|
s.top = leftTop.t + "px";
|
||
|
this.onMoved(mover, leftTop);
|
||
|
},
|
||
|
onMoving: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){
|
||
|
// summary: called before every incremental move,
|
||
|
// can be overwritten.
|
||
|
|
||
|
// default implementation does nothing
|
||
|
},
|
||
|
onMoved: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){
|
||
|
// summary: called after every incremental move,
|
||
|
// can be overwritten.
|
||
|
|
||
|
// default implementation does nothing
|
||
|
}
|
||
|
});
|
||
|
|
||
|
}
|