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