initial import
[roojs1] / Roo / dd / DD.js
1 /*
2  * Based on:
3  * Ext JS Library 1.1.1
4  * Copyright(c) 2006-2007, Ext JS, LLC.
5  *
6  * Originally Released Under LGPL - original licence link has changed is not relivant.
7  *
8  * Fork - LGPL
9  * <script type="text/javascript">
10  */
11
12 /**
13  * @class Roo.dd.DD
14  * A DragDrop implementation where the linked element follows the
15  * mouse cursor during a drag.
16  * @extends Roo.dd.DragDrop
17  * @constructor
18  * @param {String} id the id of the linked element
19  * @param {String} sGroup the group of related DragDrop items
20  * @param {object} config an object containing configurable attributes
21  *                Valid properties for DD:
22  *                    scroll
23  */
24 Roo.dd.DD = function(id, sGroup, config) {
25     if (id) {
26         this.init(id, sGroup, config);
27     }
28 };
29
30 Roo.extend(Roo.dd.DD, Roo.dd.DragDrop, {
31
32     /**
33      * When set to true, the utility automatically tries to scroll the browser
34      * window wehn a drag and drop element is dragged near the viewport boundary.
35      * Defaults to true.
36      * @property scroll
37      * @type boolean
38      */
39     scroll: true,
40
41     /**
42      * Sets the pointer offset to the distance between the linked element's top
43      * left corner and the location the element was clicked
44      * @method autoOffset
45      * @param {int} iPageX the X coordinate of the click
46      * @param {int} iPageY the Y coordinate of the click
47      */
48     autoOffset: function(iPageX, iPageY) {
49         var x = iPageX - this.startPageX;
50         var y = iPageY - this.startPageY;
51         this.setDelta(x, y);
52     },
53
54     /**
55      * Sets the pointer offset.  You can call this directly to force the
56      * offset to be in a particular location (e.g., pass in 0,0 to set it
57      * to the center of the object)
58      * @method setDelta
59      * @param {int} iDeltaX the distance from the left
60      * @param {int} iDeltaY the distance from the top
61      */
62     setDelta: function(iDeltaX, iDeltaY) {
63         this.deltaX = iDeltaX;
64         this.deltaY = iDeltaY;
65     },
66
67     /**
68      * Sets the drag element to the location of the mousedown or click event,
69      * maintaining the cursor location relative to the location on the element
70      * that was clicked.  Override this if you want to place the element in a
71      * location other than where the cursor is.
72      * @method setDragElPos
73      * @param {int} iPageX the X coordinate of the mousedown or drag event
74      * @param {int} iPageY the Y coordinate of the mousedown or drag event
75      */
76     setDragElPos: function(iPageX, iPageY) {
77         // the first time we do this, we are going to check to make sure
78         // the element has css positioning
79
80         var el = this.getDragEl();
81         this.alignElWithMouse(el, iPageX, iPageY);
82     },
83
84     /**
85      * Sets the element to the location of the mousedown or click event,
86      * maintaining the cursor location relative to the location on the element
87      * that was clicked.  Override this if you want to place the element in a
88      * location other than where the cursor is.
89      * @method alignElWithMouse
90      * @param {HTMLElement} el the element to move
91      * @param {int} iPageX the X coordinate of the mousedown or drag event
92      * @param {int} iPageY the Y coordinate of the mousedown or drag event
93      */
94     alignElWithMouse: function(el, iPageX, iPageY) {
95         var oCoord = this.getTargetCoord(iPageX, iPageY);
96         var fly = el.dom ? el : Roo.fly(el);
97         if (!this.deltaSetXY) {
98             var aCoord = [oCoord.x, oCoord.y];
99             fly.setXY(aCoord);
100             var newLeft = fly.getLeft(true);
101             var newTop  = fly.getTop(true);
102             this.deltaSetXY = [ newLeft - oCoord.x, newTop - oCoord.y ];
103         } else {
104             fly.setLeftTop(oCoord.x + this.deltaSetXY[0], oCoord.y + this.deltaSetXY[1]);
105         }
106
107         this.cachePosition(oCoord.x, oCoord.y);
108         this.autoScroll(oCoord.x, oCoord.y, el.offsetHeight, el.offsetWidth);
109         return oCoord;
110     },
111
112     /**
113      * Saves the most recent position so that we can reset the constraints and
114      * tick marks on-demand.  We need to know this so that we can calculate the
115      * number of pixels the element is offset from its original position.
116      * @method cachePosition
117      * @param iPageX the current x position (optional, this just makes it so we
118      * don't have to look it up again)
119      * @param iPageY the current y position (optional, this just makes it so we
120      * don't have to look it up again)
121      */
122     cachePosition: function(iPageX, iPageY) {
123         if (iPageX) {
124             this.lastPageX = iPageX;
125             this.lastPageY = iPageY;
126         } else {
127             var aCoord = Roo.lib.Dom.getXY(this.getEl());
128             this.lastPageX = aCoord[0];
129             this.lastPageY = aCoord[1];
130         }
131     },
132
133     /**
134      * Auto-scroll the window if the dragged object has been moved beyond the
135      * visible window boundary.
136      * @method autoScroll
137      * @param {int} x the drag element's x position
138      * @param {int} y the drag element's y position
139      * @param {int} h the height of the drag element
140      * @param {int} w the width of the drag element
141      * @private
142      */
143     autoScroll: function(x, y, h, w) {
144
145         if (this.scroll) {
146             // The client height
147             var clientH = Roo.lib.Dom.getViewWidth();
148
149             // The client width
150             var clientW = Roo.lib.Dom.getViewHeight();
151
152             // The amt scrolled down
153             var st = this.DDM.getScrollTop();
154
155             // The amt scrolled right
156             var sl = this.DDM.getScrollLeft();
157
158             // Location of the bottom of the element
159             var bot = h + y;
160
161             // Location of the right of the element
162             var right = w + x;
163
164             // The distance from the cursor to the bottom of the visible area,
165             // adjusted so that we don't scroll if the cursor is beyond the
166             // element drag constraints
167             var toBot = (clientH + st - y - this.deltaY);
168
169             // The distance from the cursor to the right of the visible area
170             var toRight = (clientW + sl - x - this.deltaX);
171
172
173             // How close to the edge the cursor must be before we scroll
174             // var thresh = (document.all) ? 100 : 40;
175             var thresh = 40;
176
177             // How many pixels to scroll per autoscroll op.  This helps to reduce
178             // clunky scrolling. IE is more sensitive about this ... it needs this
179             // value to be higher.
180             var scrAmt = (document.all) ? 80 : 30;
181
182             // Scroll down if we are near the bottom of the visible page and the
183             // obj extends below the crease
184             if ( bot > clientH && toBot < thresh ) {
185                 window.scrollTo(sl, st + scrAmt);
186             }
187
188             // Scroll up if the window is scrolled down and the top of the object
189             // goes above the top border
190             if ( y < st && st > 0 && y - st < thresh ) {
191                 window.scrollTo(sl, st - scrAmt);
192             }
193
194             // Scroll right if the obj is beyond the right border and the cursor is
195             // near the border.
196             if ( right > clientW && toRight < thresh ) {
197                 window.scrollTo(sl + scrAmt, st);
198             }
199
200             // Scroll left if the window has been scrolled to the right and the obj
201             // extends past the left border
202             if ( x < sl && sl > 0 && x - sl < thresh ) {
203                 window.scrollTo(sl - scrAmt, st);
204             }
205         }
206     },
207
208     /**
209      * Finds the location the element should be placed if we want to move
210      * it to where the mouse location less the click offset would place us.
211      * @method getTargetCoord
212      * @param {int} iPageX the X coordinate of the click
213      * @param {int} iPageY the Y coordinate of the click
214      * @return an object that contains the coordinates (Object.x and Object.y)
215      * @private
216      */
217     getTargetCoord: function(iPageX, iPageY) {
218
219
220         var x = iPageX - this.deltaX;
221         var y = iPageY - this.deltaY;
222
223         if (this.constrainX) {
224             if (x < this.minX) { x = this.minX; }
225             if (x > this.maxX) { x = this.maxX; }
226         }
227
228         if (this.constrainY) {
229             if (y < this.minY) { y = this.minY; }
230             if (y > this.maxY) { y = this.maxY; }
231         }
232
233         x = this.getTick(x, this.xTicks);
234         y = this.getTick(y, this.yTicks);
235
236
237         return {x:x, y:y};
238     },
239
240     /*
241      * Sets up config options specific to this class. Overrides
242      * Roo.dd.DragDrop, but all versions of this method through the
243      * inheritance chain are called
244      */
245     applyConfig: function() {
246         Roo.dd.DD.superclass.applyConfig.call(this);
247         this.scroll = (this.config.scroll !== false);
248     },
249
250     /*
251      * Event that fires prior to the onMouseDown event.  Overrides
252      * Roo.dd.DragDrop.
253      */
254     b4MouseDown: function(e) {
255         // this.resetConstraints();
256         this.autoOffset(e.getPageX(),
257                             e.getPageY());
258     },
259
260     /*
261      * Event that fires prior to the onDrag event.  Overrides
262      * Roo.dd.DragDrop.
263      */
264     b4Drag: function(e) {
265         this.setDragElPos(e.getPageX(),
266                             e.getPageY());
267     },
268
269     toString: function() {
270         return ("DD " + this.id);
271     }
272
273     //////////////////////////////////////////////////////////////////////////
274     // Debugging ygDragDrop events that can be overridden
275     //////////////////////////////////////////////////////////////////////////
276     /*
277     startDrag: function(x, y) {
278     },
279
280     onDrag: function(e) {
281     },
282
283     onDragEnter: function(e, id) {
284     },
285
286     onDragOver: function(e, id) {
287     },
288
289     onDragOut: function(e, id) {
290     },
291
292     onDragDrop: function(e, id) {
293     },
294
295     endDrag: function(e) {
296     }
297
298     */
299
300 });