Upgrade to ExtJS 4.0.2 - Released 06/09/2011
[extjs.git] / src / dd / DDProxy.js
1 /*
2
3 This file is part of Ext JS 4
4
5 Copyright (c) 2011 Sencha Inc
6
7 Contact:  http://www.sencha.com/contact
8
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.
11
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
13
14 */
15 /*
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
21  */
22
23 /**
24  * @class Ext.dd.DDProxy
25  * @extends Ext.dd.DD
26  * A DragDrop implementation that inserts an empty, bordered div into
27  * the document that follows the cursor during drag operations.  At the time of
28  * the click, the frame div is resized to the dimensions of the linked html
29  * element, and moved to the exact location of the linked element.
30  *
31  * References to the "frame" element refer to the single proxy element that
32  * was created to be dragged in place of all DDProxy elements on the
33  * page.
34  */
35 Ext.define('Ext.dd.DDProxy', {
36     extend: 'Ext.dd.DD',
37
38     statics: {
39         /**
40          * The default drag frame div id
41          * @static
42          */
43         dragElId: "ygddfdiv"
44     },
45
46     /**
47      * Creates new DDProxy.
48      * @param {String} id the id of the linked html element
49      * @param {String} sGroup the group of related DragDrop objects
50      * @param {object} config an object containing configurable attributes.
51      * Valid properties for DDProxy in addition to those in DragDrop:
52      * 
53      * - resizeFrame
54      * - centerFrame
55      * - dragElId
56      */
57     constructor: function(id, sGroup, config) {
58         if (id) {
59             this.init(id, sGroup, config);
60             this.initFrame();
61         }
62     },
63
64     /**
65      * By default we resize the drag frame to be the same size as the element
66      * we want to drag (this is to get the frame effect).  We can turn it off
67      * if we want a different behavior.
68      * @property resizeFrame
69      * @type boolean
70      */
71     resizeFrame: true,
72
73     /**
74      * By default the frame is positioned exactly where the drag element is, so
75      * we use the cursor offset provided by Ext.dd.DD.  Another option that works only if
76      * you do not have constraints on the obj is to have the drag frame centered
77      * around the cursor.  Set centerFrame to true for this effect.
78      * @property centerFrame
79      * @type boolean
80      */
81     centerFrame: false,
82
83     /**
84      * Creates the proxy element if it does not yet exist
85      * @method createFrame
86      */
87     createFrame: function() {
88         var self = this;
89         var body = document.body;
90
91         if (!body || !body.firstChild) {
92             setTimeout( function() { self.createFrame(); }, 50 );
93             return;
94         }
95
96         var div = this.getDragEl();
97
98         if (!div) {
99             div    = document.createElement("div");
100             div.id = this.dragElId;
101             var s  = div.style;
102
103             s.position   = "absolute";
104             s.visibility = "hidden";
105             s.cursor     = "move";
106             s.border     = "2px solid #aaa";
107             s.zIndex     = 999;
108
109             // appendChild can blow up IE if invoked prior to the window load event
110             // while rendering a table.  It is possible there are other scenarios
111             // that would cause this to happen as well.
112             body.insertBefore(div, body.firstChild);
113         }
114     },
115
116     /**
117      * Initialization for the drag frame element.  Must be called in the
118      * constructor of all subclasses
119      * @method initFrame
120      */
121     initFrame: function() {
122         this.createFrame();
123     },
124
125     applyConfig: function() {
126         this.callParent();
127
128         this.resizeFrame = (this.config.resizeFrame !== false);
129         this.centerFrame = (this.config.centerFrame);
130         this.setDragElId(this.config.dragElId || Ext.dd.DDProxy.dragElId);
131     },
132
133     /**
134      * Resizes the drag frame to the dimensions of the clicked object, positions
135      * it over the object, and finally displays it
136      * @method showFrame
137      * @param {int} iPageX X click position
138      * @param {int} iPageY Y click position
139      * @private
140      */
141     showFrame: function(iPageX, iPageY) {
142         var el = this.getEl();
143         var dragEl = this.getDragEl();
144         var s = dragEl.style;
145
146         this._resizeProxy();
147
148         if (this.centerFrame) {
149             this.setDelta( Math.round(parseInt(s.width,  10)/2),
150                            Math.round(parseInt(s.height, 10)/2) );
151         }
152
153         this.setDragElPos(iPageX, iPageY);
154
155         Ext.fly(dragEl).show();
156     },
157
158     /**
159      * The proxy is automatically resized to the dimensions of the linked
160      * element when a drag is initiated, unless resizeFrame is set to false
161      * @method _resizeProxy
162      * @private
163      */
164     _resizeProxy: function() {
165         if (this.resizeFrame) {
166             var el = this.getEl();
167             Ext.fly(this.getDragEl()).setSize(el.offsetWidth, el.offsetHeight);
168         }
169     },
170
171     // overrides Ext.dd.DragDrop
172     b4MouseDown: function(e) {
173         var x = e.getPageX();
174         var y = e.getPageY();
175         this.autoOffset(x, y);
176         this.setDragElPos(x, y);
177     },
178
179     // overrides Ext.dd.DragDrop
180     b4StartDrag: function(x, y) {
181         // show the drag frame
182         this.showFrame(x, y);
183     },
184
185     // overrides Ext.dd.DragDrop
186     b4EndDrag: function(e) {
187         Ext.fly(this.getDragEl()).hide();
188     },
189
190     // overrides Ext.dd.DragDrop
191     // By default we try to move the element to the last location of the frame.
192     // This is so that the default behavior mirrors that of Ext.dd.DD.
193     endDrag: function(e) {
194
195         var lel = this.getEl();
196         var del = this.getDragEl();
197
198         // Show the drag frame briefly so we can get its position
199         del.style.visibility = "";
200
201         this.beforeMove();
202         // Hide the linked element before the move to get around a Safari
203         // rendering bug.
204         lel.style.visibility = "hidden";
205         Ext.dd.DDM.moveToEl(lel, del);
206         del.style.visibility = "hidden";
207         lel.style.visibility = "";
208
209         this.afterDrag();
210     },
211
212     beforeMove : function(){
213
214     },
215
216     afterDrag : function(){
217
218     },
219
220     toString: function() {
221         return ("DDProxy " + this.id);
222     }
223
224 });
225