aboutsummaryrefslogtreecommitdiffstats
path: root/js/lib_drag.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/lib_drag.js')
-rw-r--r--js/lib_drag.js350
1 files changed, 350 insertions, 0 deletions
diff --git a/js/lib_drag.js b/js/lib_drag.js
new file mode 100644
index 00000000000..bc6a8610500
--- /dev/null
+++ b/js/lib_drag.js
@@ -0,0 +1,350 @@
+/**
+* Javascript Drag&Drop - Modified for ownCloud
+*
+* @author Robin Appelman
+* @copyright 2010 Robin Appelman icewind1991@gmail.com
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+
+position=function(x,y){
+ if(x)this.x=x;
+ if(y)this.y=y;
+ return this;
+}
+position.prototype={
+ x:0,
+ y:0,
+ add:function(pos2){
+ return new position(this.x+pos2.x,this.y+pos2.y);
+ },
+ substract:function(pos2){
+ return new position(this.x-pos2.x,this.y-pos2.y);
+ },toString:function(){
+ return 'x:'+this.x+',y:'+this.y;
+ },inside:function(pos2){
+ return Math.abs(this.x)<Math.abs(pos2.x) && Math.abs(this.y)<Math.abs(pos2.y) && Math.sign(this.x)==Math.sign(pos2.x) && Math.sign(this.y)==Math.sign(pos2.y);
+ },outside:function(pos2){
+ return !this.inside(pos2);
+ }
+}
+
+Node.prototype.drag=new Object
+/**
+ * is the node dragable
+ */
+Node.prototype.drag.dragable=false;
+/**
+ * Are we currently dragging the node
+ */
+Node.prototype.drag.active=false;
+/**
+ * Create a clone to drag around
+ */
+Node.prototype.drag.clone=true;
+/**
+ * The node we (visually drag around)
+ */
+Node.prototype.drag.node=false;
+/**
+ * can we drop nodes on this
+ */
+Node.prototype.drag.isDropTarget=false;
+/**
+ * our current drop target
+ */
+Node.prototype.drag.dropTarget=null;
+/**
+ * can we drop this node now
+ */
+Node.prototype.drag.dropable=false;
+/**
+ * function called when we are being dropped on a node
+ * @return bool
+ */
+Node.prototype.drag.onDrop=function(node){};
+/**
+ * function called when an node is dropped on us
+ * @param Node node
+ * @return bool
+ */
+Node.prototype.drag.onDropOn=function(node){};
+/**
+ * where did we start the drag
+ */
+Node.prototype.drag.startPosition=new position();
+/**
+ * where are we now
+ */
+Node.prototype.drag.position=new position();
+/**
+ * how big are we
+ */
+Node.prototype.drag.size=new position();
+/**
+ * where is the mouse
+ */
+Node.prototype.drag.mousePosition=new position();
+/**
+ * where is the mouse relative to our node
+ */
+Node.prototype.drag.mouseOffset=new position();
+
+document.drag=new Object();
+/**
+ * is there currently something dragged
+ */
+document.drag.active=false;
+/**
+ * what is currently being dragged
+ */
+document.drag.node=null;
+document.drag.dropTargets=Array();
+/**
+ * start the dragging. (onmousedown)
+ * @param Event event
+ */
+Node.prototype.drag.start=function(event){
+ if(!event)var event=window.event;
+ if(!this.drag.active && this.drag.dragable){
+ document.drag.active=true;
+ document.drag.node=this;
+ this.drag.active=true;
+ this.drag.position=this.getPosition();
+ this.drag.startPosition=this.getPosition();
+ this.drag.mousePosition=getMousePosition(event);
+ this.drag.mouseOffset=this.drag.mousePosition.substract(this.drag.position);
+ }
+}
+
+/**
+ * update the dragging. (onmousemove)
+ * @param Event event
+ */
+Node.prototype.drag.update=function(event){
+ if(!event)var event=window.event;
+ if(this.drag.active && this.drag.dragable){
+ this.drag.mousePosition=getMousePosition(event);
+ this.drag.position=this.drag.mousePosition.substract(this.drag.mouseOffset);
+ if(this.drag.clone && !this.drag.node){
+ this.drag.node=this.cloneNode(true);
+ this.drag.node.className='dragClone';
+ if(this.drag.node.hasAttribute('id')){
+ this.drag.node.setAttribute('id',this.drag.node.getAttribute('id')+'_dragClone');
+ }
+ document.getElementsByTagName('body').item(0).appendChild(this.drag.node);
+ }else if(!this.drag.node){
+ this.drag.node=this;
+ this.drag.node.style.position='absolute';
+ }
+ this.drag.node.style.left=this.drag.position.x+'px';
+ this.drag.node.style.top=this.drag.position.y+'px';
+ }
+ return true;
+}
+
+/**
+ * stop the dragging/drop. (onmouseup)
+ * @param Event event
+ * @return bool
+ */
+Node.prototype.drag.stop=function(event){
+ if(!event)var event=window.event;
+ if(this.drag.active && this.drag.dragable){
+ this.drag.active=false;
+ this.drag.mousePosition=getMousePosition(event);
+ this.drag.position=this.drag.mousePosition.substract(this.drag.mouseOffset);
+ if(this.drag.node){
+ this.drag.node.style.left=this.drag.position.x;
+ this.drag.node.style.top=this.drag.position.y;
+ }
+ var target;
+ this.drag.dropTarget=null;
+ this.drag.dropable=false;
+ for(var i=0;i<document.drag.dropTargets.length;i++){
+ target=document.drag.dropTargets[i];
+ target.drag.checkDropTarget.call(target,event);
+ }
+ if(this.drag.dropable && this.drag.dropTarget){
+ if(this.drag.onDrop){
+ this.drag.onDrop.call(this,event,this.drag.dropTarget);
+ this.triggerEvent.call(this,'ondrop',event,this.drag.dropTarget);
+ }
+ if(this.drag.dropTarget.drag.onDropOn){
+ this.drag.dropTarget.drag.onDropOn.call(this.drag.dropTarget,event,this);
+ this.drag.dropTarget.triggerEvent.call(this.drag.dropTarget,'ondropon',event,this);
+ }
+ }
+ if(this.drag.clone && this.drag.node){
+ this.drag.node.parentNode.removeChild(this.drag.node);
+ this.drag.node=null;
+ }
+ document.drag.active=false;
+ document.drag.node=null;
+ }
+}
+
+/**
+ * is there currently something being dragged over us
+ * @param Event event
+ */
+Node.prototype.drag.checkDropTarget=function(event){
+ if(this.drag.isDropTarget & document.drag.active){
+ mousePos=getMousePosition(event);
+ this.drag.position=this.getPosition();
+ this.drag.size=this.getSize(true);
+ var offSet=mousePos.substract(this.drag.position);
+ if(offSet.inside(this.drag.size)){
+ document.drag.node.drag.dropTarget=this;
+ document.drag.node.drag.dropable=true;
+ setDebug('ontarget');
+ }
+ }
+}
+
+/**
+ * called when the mouse is leaving a drop target
+ * @param Event event
+ */
+Node.prototype.drag.leaveDropTarget=function(event){
+ if(this.drag.isDropTarget & document.drag.active){
+ document.drag.node.drag.dropTarget=null;
+ document.drag.node.drag.dropable=false;
+ setDebug('offtarget');
+ }
+}
+/**
+ * initiate the node as drop target
+ */
+Node.prototype.drag.initDropTarget=function(){
+ this.drag.isDropTarget=true;
+ document.drag.dropTargets.push(this);
+}
+Node.prototype.makeDropTarget=function(){
+ this.drag.initDropTarget.call(this);
+}
+
+/**
+ * initiate the node as draggable
+ */
+Node.prototype.drag.init=function(){
+ this.drag.dragable=true;
+ this.drag.size.x=this.getStyle('width');
+ this.drag.size.y=this.getStyle('height');
+ this.addEvent('onmousedown',new callBack(this.drag.start,this));
+}
+Node.prototype.makeDraggable=function(){
+ this.drag.init.call(this);
+}
+
+/**
+ * update the dragging. (onmousemove)
+ * @param Event event
+ */
+document.drag.update=function(event){
+ var target;
+ if(document.drag.active && document.drag.node){
+ document.drag.node.drag.update.call(document.drag.node,event);
+ }
+ return false;
+}
+
+/**
+ * update the dragging. (onmousemove)
+ * @param Event event
+ */
+document.drag.stop=function(event){
+ if(document.drag.active && document.drag.node){
+ document.drag.node.drag.stop.call(document.drag.node,event);
+ }
+ return false;
+}
+document.events.add(document,'onmousemove',document.drag.update);
+document.events.add(document,'onmouseup',document.drag.stop);
+
+function getMousePosition(event){
+ var pos=new position();
+ if(!event)var event = window.event;
+ if(event.pageX||event.pageY){
+ pos.x=event.pageX;
+ pos.y=event.pageY;
+ }
+ else if(event.clientX||event.clientY){
+ pos.x=event.clientX+document.body.scrollLeft+document.documentElement.scrollLeft;
+ pos.y=event.clientY+document.body.scrollTop+document.documentElement.scrollTop;
+ }
+ return pos;
+}
+
+/**
+ * get our position
+ **/
+Node.prototype.getPosition=function(){
+ var pos=new position();
+ element=this;
+ do{
+ pos.y+=element.offsetTop;
+ pos.x+=element.offsetLeft;
+ }while(element=element.offsetParent);
+ return pos;
+}
+
+/**
+ * get our size
+* @param bool full (also include padding and border)
+ **/
+Node.prototype.getSize=function(full){
+ var pos=new position();
+ pos.y= parseInt(this.getStyle('height'));
+ pos.x= parseInt(this.getStyle('width'));
+ if(full){
+ var extraY=['border-size','padding-top','padding-bottom','border-size'];
+ var extraX=['border-size','padding-left','padding-right','border-size'];
+ var tmp;
+ for(var i=0;i<extraY.length;i++){
+ tmp=parseInt(this.getStyle(extraY[i]));
+ if(tmp){
+ pos.y+=tmp;
+ }
+ }
+ for(var i=0;i<extraX.length;i++){
+ tmp=parseInt(this.getStyle(extraX[i]));
+ if(tmp){
+ pos.x+=tmp;
+ }
+ }
+ }
+ return pos;
+}
+
+function mouseTest(event){
+ var pos=getMousePosition(event);
+ setDebug(pos.toString());
+}
+
+function testDrag(){
+ var node=document.getElementById('debug');
+// document.addEvent('onclick',getOffSet,[node]);
+ node.makeDropTarget();
+}
+
+function getOffSet(node,event){
+ var nodePos=node.getPosition();
+ var mousePos=getMousePosition(event);
+ return mousePos.substract(nodePos);
+}
+
+
+// OC_onload.add(testDrag); \ No newline at end of file