1 /* See license.txt for terms of usage */
  2 
  3 define([
  4     "firebug/lib/object",
  5     "firebug/firebug",
  6     "firebug/lib/events",
  7 ],
  8 function(Obj, Firebug, Events) {
  9 
 10 // ********************************************************************************************* //
 11 
 12 /**
 13  *
 14  * @param {Object} element
 15  * @param {Object} handle
 16  * @param {Object} callbacks: onDragStart, onDragOver, onDragLeave, onDrop
 17  */
 18 function Tracker(handle, callbacks)
 19 {
 20     this.element = handle;
 21     this.handle = handle;
 22     this.callbacks = callbacks;
 23 
 24     this.cursorStartPos = null;
 25     this.cursorLastPos = null;
 26     //this.elementStartPos = null;
 27     this.dragging = false;
 28 
 29     // Start listening
 30     this.onDragStart = Obj.bind(this.onDragStart, this);
 31     this.onDragOver = Obj.bind(this.onDragOver, this);
 32     this.onDrop = Obj.bind(this.onDrop, this);
 33 
 34     Events.addEventListener(this.element, "mousedown", this.onDragStart, false);
 35     this.active = true;
 36 }
 37 
 38 Tracker.prototype =
 39 {
 40     onDragStart: function(event)
 41     {
 42         if (this.dragging)
 43             return;
 44 
 45         if (this.callbacks.onDragStart)
 46             this.callbacks.onDragStart(this);
 47 
 48         this.dragging = true;
 49         this.cursorStartPos = absoluteCursorPostion(event);
 50         this.cursorLastPos = this.cursorStartPos;
 51         //this.elementStartPos = new Position(
 52         //    parseInt(this.element.style.left),
 53         //    parseInt(this.element.style.top));
 54 
 55         Events.addEventListener(this.element.ownerDocument, "mousemove", this.onDragOver, false);
 56         Events.addEventListener(this.element.ownerDocument, "mouseup", this.onDrop, false);
 57 
 58         Events.cancelEvent(e);
 59     },
 60 
 61     onDragOver: function(event)
 62     {
 63         if (!this.dragging)
 64             return;
 65 
 66         Events.cancelEvent(event);
 67 
 68         var newPos = absoluteCursorPostion(event);
 69         //newPos = newPos.Add(this.elementStartPos);
 70         var newPos = newPos.Subtract(this.cursorStartPos);
 71         //newPos = newPos.Bound(lowerBound, upperBound);
 72         //newPos.Apply(this.element);
 73 
 74         // Only fire event if the position has beeb changed.
 75         if (this.cursorLastPos.x == newPos.x && this.cursorLastPos.y == newPos.y)
 76             return;
 77 
 78         this.cursorLastPos = newPos;
 79 
 80         if (this.callbacks.onDragOver != null)
 81             this.callbacks.onDragOver(newPos, this);
 82     },
 83 
 84     onDrop: function(event)
 85     {
 86         if (!this.dragging)
 87             return;
 88 
 89         Events.cancelEvent(event);
 90 
 91         this.dragStop();
 92     },
 93 
 94     dragStop: function()
 95     {
 96         if (!this.dragging)
 97             return;
 98 
 99         Events.removeEventListener(this.element.ownerDocument, "mousemove", this.onDragOver, false);
100         Events.removeEventListener(this.element.ownerDocument, "mouseup", this.onDrop, false);
101 
102         this.cursorStartPos = null;
103         this.cursorLastPos = null;
104         //this.elementStartPos = null;
105 
106         if (this.callbacks.onDrop != null)
107             this.callbacks.onDrop(this);
108 
109         this.dragging = false;
110     },
111 
112     destroy: function()
113     {
114         Events.removeEventListener(this.element, "mousedown", this.onDragStart, false);
115         this.active = false;
116 
117         if (this.dragging)
118             this.dragStop();
119     }
120 }
121 
122 // ********************************************************************************************* //
123 
124 function Position(x, y)
125 {
126     this.x = x;
127     this.y = y;
128 
129     this.Add = function(val)
130     {
131         var newPos = new Position(this.x, this.y);
132         if (val != null)
133         {
134             if(!isNaN(val.x))
135                 newPos.x += val.x;
136             if(!isNaN(val.y))
137                 newPos.y += val.y
138         }
139         return newPos;
140     }
141 
142     this.Subtract = function(val)
143     {
144         var newPos = new Position(this.x, this.y);
145         if (val != null)
146         {
147             if(!isNaN(val.x))
148                 newPos.x -= val.x;
149             if(!isNaN(val.y))
150                 newPos.y -= val.y
151         }
152         return newPos;
153     }
154 
155     this.Bound = function(lower, upper)
156     {
157         var newPos = this.Max(lower);
158         return newPos.Min(upper);
159     }
160 
161     this.Check = function()
162     {
163         var newPos = new Position(this.x, this.y);
164         if (isNaN(newPos.x))
165             newPos.x = 0;
166 
167         if (isNaN(newPos.y))
168             newPos.y = 0;
169 
170         return newPos;
171     }
172 
173     this.Apply = function(element)
174     {
175         if (typeof(element) == "string")
176             element = document.getElementById(element);
177 
178         if (!element)
179             return;
180 
181         if(!isNaN(this.x))
182             element.style.left = this.x + "px";
183 
184         if(!isNaN(this.y))
185             element.style.top = this.y + "px";
186     }
187 }
188 
189 // ********************************************************************************************* //
190 
191 function absoluteCursorPostion(e)
192 {
193     if (isNaN(window.scrollX))
194     {
195         return new Position(e.clientX + document.documentElement.scrollLeft
196             + document.body.scrollLeft, e.clientY + document.documentElement.scrollTop
197             + document.body.scrollTop);
198     }
199     else
200     {
201         return new Position(e.clientX + window.scrollX, e.clientY + window.scrollY);
202     }
203 }
204 
205 // ********************************************************************************************* //
206 
207 var DragDrop = {};
208 DragDrop.Tracker = Tracker;
209 
210 // ********************************************************************************************* //
211 // Registration in Firebug namespace
212 
213 return DragDrop;
214 
215 // ********************************************************************************************* //
216 });
217