3 This file is part of Ext JS 4
5 Copyright (c) 2011 Sencha Inc
7 Contact: http://www.sencha.com/contact
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
16 * This is a derivative of the similarly named class in the YUI Library.
17 * The original license:
18 * Copyright (c) 2006, Yahoo! Inc. All rights reserved.
19 * Code licensed under the BSD License:
20 * http://developer.yahoo.net/yui/license.txt
26 * A DragDrop implementation where the linked element follows the
27 * mouse cursor during a drag.
28 * @extends Ext.dd.DragDrop
30 Ext.define('Ext.dd.DD', {
31 extend: 'Ext.dd.DragDrop',
32 requires: ['Ext.dd.DragDropManager'],
35 * Creates new DD instance.
36 * @param {String} id the id of the linked element
37 * @param {String} sGroup the group of related DragDrop items
38 * @param {Object} config an object containing configurable attributes.
39 * Valid properties for DD: scroll
41 constructor: function(id, sGroup, config) {
43 this.init(id, sGroup, config);
48 * When set to true, the utility automatically tries to scroll the browser
49 * window when a drag and drop element is dragged near the viewport boundary.
57 * Sets the pointer offset to the distance between the linked element's top
58 * left corner and the location the element was clicked
60 * @param {Number} iPageX the X coordinate of the click
61 * @param {Number} iPageY the Y coordinate of the click
63 autoOffset: function(iPageX, iPageY) {
64 var x = iPageX - this.startPageX;
65 var y = iPageY - this.startPageY;
70 * Sets the pointer offset. You can call this directly to force the
71 * offset to be in a particular location (e.g., pass in 0,0 to set it
72 * to the center of the object)
74 * @param {Number} iDeltaX the distance from the left
75 * @param {Number} iDeltaY the distance from the top
77 setDelta: function(iDeltaX, iDeltaY) {
78 this.deltaX = iDeltaX;
79 this.deltaY = iDeltaY;
83 * Sets the drag element to the location of the mousedown or click event,
84 * maintaining the cursor location relative to the location on the element
85 * that was clicked. Override this if you want to place the element in a
86 * location other than where the cursor is.
87 * @method setDragElPos
88 * @param {Number} iPageX the X coordinate of the mousedown or drag event
89 * @param {Number} iPageY the Y coordinate of the mousedown or drag event
91 setDragElPos: function(iPageX, iPageY) {
92 // the first time we do this, we are going to check to make sure
93 // the element has css positioning
95 var el = this.getDragEl();
96 this.alignElWithMouse(el, iPageX, iPageY);
100 * Sets the element to the location of the mousedown or click event,
101 * maintaining the cursor location relative to the location on the element
102 * that was clicked. Override this if you want to place the element in a
103 * location other than where the cursor is.
104 * @method alignElWithMouse
105 * @param {HTMLElement} el the element to move
106 * @param {Number} iPageX the X coordinate of the mousedown or drag event
107 * @param {Number} iPageY the Y coordinate of the mousedown or drag event
109 alignElWithMouse: function(el, iPageX, iPageY) {
110 var oCoord = this.getTargetCoord(iPageX, iPageY),
111 fly = el.dom ? el : Ext.fly(el, '_dd'),
112 elSize = fly.getSize(),
116 if (!this.deltaSetXY) {
117 vpSize = this.cachedViewportSize = { width: EL.getDocumentWidth(), height: EL.getDocumentHeight() };
119 Math.max(0, Math.min(oCoord.x, vpSize.width - elSize.width)),
120 Math.max(0, Math.min(oCoord.y, vpSize.height - elSize.height))
123 var newLeft = fly.getLeft(true);
124 var newTop = fly.getTop(true);
125 this.deltaSetXY = [newLeft - oCoord.x, newTop - oCoord.y];
127 vpSize = this.cachedViewportSize;
129 Math.max(0, Math.min(oCoord.x + this.deltaSetXY[0], vpSize.width - elSize.width)),
130 Math.max(0, Math.min(oCoord.y + this.deltaSetXY[1], vpSize.height - elSize.height))
134 this.cachePosition(oCoord.x, oCoord.y);
135 this.autoScroll(oCoord.x, oCoord.y, el.offsetHeight, el.offsetWidth);
140 * Saves the most recent position so that we can reset the constraints and
141 * tick marks on-demand. We need to know this so that we can calculate the
142 * number of pixels the element is offset from its original position.
143 * @method cachePosition
144 * @param {Number} iPageX (optional) the current x position (this just makes it so we
145 * don't have to look it up again)
146 * @param {Number} iPageY (optional) the current y position (this just makes it so we
147 * don't have to look it up again)
149 cachePosition: function(iPageX, iPageY) {
151 this.lastPageX = iPageX;
152 this.lastPageY = iPageY;
154 var aCoord = Ext.Element.getXY(this.getEl());
155 this.lastPageX = aCoord[0];
156 this.lastPageY = aCoord[1];
161 * Auto-scroll the window if the dragged object has been moved beyond the
162 * visible window boundary.
164 * @param {Number} x the drag element's x position
165 * @param {Number} y the drag element's y position
166 * @param {Number} h the height of the drag element
167 * @param {Number} w the width of the drag element
170 autoScroll: function(x, y, h, w) {
174 var clientH = Ext.Element.getViewHeight();
177 var clientW = Ext.Element.getViewWidth();
179 // The amt scrolled down
180 var st = this.DDMInstance.getScrollTop();
182 // The amt scrolled right
183 var sl = this.DDMInstance.getScrollLeft();
185 // Location of the bottom of the element
188 // Location of the right of the element
191 // The distance from the cursor to the bottom of the visible area,
192 // adjusted so that we don't scroll if the cursor is beyond the
193 // element drag constraints
194 var toBot = (clientH + st - y - this.deltaY);
196 // The distance from the cursor to the right of the visible area
197 var toRight = (clientW + sl - x - this.deltaX);
200 // How close to the edge the cursor must be before we scroll
201 // var thresh = (document.all) ? 100 : 40;
204 // How many pixels to scroll per autoscroll op. This helps to reduce
205 // clunky scrolling. IE is more sensitive about this ... it needs this
206 // value to be higher.
207 var scrAmt = (document.all) ? 80 : 30;
209 // Scroll down if we are near the bottom of the visible page and the
210 // obj extends below the crease
211 if ( bot > clientH && toBot < thresh ) {
212 window.scrollTo(sl, st + scrAmt);
215 // Scroll up if the window is scrolled down and the top of the object
216 // goes above the top border
217 if ( y < st && st > 0 && y - st < thresh ) {
218 window.scrollTo(sl, st - scrAmt);
221 // Scroll right if the obj is beyond the right border and the cursor is
223 if ( right > clientW && toRight < thresh ) {
224 window.scrollTo(sl + scrAmt, st);
227 // Scroll left if the window has been scrolled to the right and the obj
228 // extends past the left border
229 if ( x < sl && sl > 0 && x - sl < thresh ) {
230 window.scrollTo(sl - scrAmt, st);
236 * Finds the location the element should be placed if we want to move
237 * it to where the mouse location less the click offset would place us.
238 * @method getTargetCoord
239 * @param {Number} iPageX the X coordinate of the click
240 * @param {Number} iPageY the Y coordinate of the click
241 * @return an object that contains the coordinates (Object.x and Object.y)
244 getTargetCoord: function(iPageX, iPageY) {
245 var x = iPageX - this.deltaX;
246 var y = iPageY - this.deltaY;
248 if (this.constrainX) {
257 if (this.constrainY) {
266 x = this.getTick(x, this.xTicks);
267 y = this.getTick(y, this.yTicks);
274 * Sets up config options specific to this class. Overrides
275 * Ext.dd.DragDrop, but all versions of this method through the
276 * inheritance chain are called
278 applyConfig: function() {
280 this.scroll = (this.config.scroll !== false);
284 * Event that fires prior to the onMouseDown event. Overrides
287 b4MouseDown: function(e) {
288 // this.resetConstraints();
289 this.autoOffset(e.getPageX(), e.getPageY());
293 * Event that fires prior to the onDrag event. Overrides
296 b4Drag: function(e) {
297 this.setDragElPos(e.getPageX(), e.getPageY());
300 toString: function() {
301 return ("DD " + this.id);
304 //////////////////////////////////////////////////////////////////////////
305 // Debugging ygDragDrop events that can be overridden
306 //////////////////////////////////////////////////////////////////////////
308 startDrag: function(x, y) {
311 onDrag: function(e) {
314 onDragEnter: function(e, id) {
317 onDragOver: function(e, id) {
320 onDragOut: function(e, id) {
323 onDragDrop: function(e, id) {
326 endDrag: function(e) {