Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / src / util / ComponentDragger.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  * @class Ext.util.ComponentDragger
17  * @extends Ext.dd.DragTracker
18  * <p>A subclass of Ext.dd.DragTracker which handles dragging any Component.</p>
19  * <p>This is configured with a Component to be made draggable, and a config object for the
20  * {@link Ext.dd.DragTracker} class.</p>
21  * <p>A {@link #delegate} may be provided which may be either the element to use as the mousedown target
22  * or a {@link Ext.DomQuery} selector to activate multiple mousedown targets.</p>
23  */
24 Ext.define('Ext.util.ComponentDragger', {
25
26     /**
27      * @cfg {Boolean} constrain
28      * Specify as <code>true</code> to constrain the Component to within the bounds of the {@link #constrainTo} region.
29      */
30
31     /**
32      * @cfg {String/Ext.Element} delegate
33      * Optional. <p>A {@link Ext.DomQuery DomQuery} selector which identifies child elements within the Component's encapsulating
34      * Element which are the drag handles. This limits dragging to only begin when the matching elements are mousedowned.</p>
35      * <p>This may also be a specific child element within the Component's encapsulating element to use as the drag handle.</p>
36      */
37
38     /**
39      * @cfg {Boolean} constrainDelegate
40      * Specify as <code>true</code> to constrain the drag handles within the {@link #constrainTo} region.
41      */
42
43     extend: 'Ext.dd.DragTracker',
44
45     autoStart: 500,
46
47     /**
48      * Creates new ComponentDragger.
49      * @param {Object} comp The Component to provide dragging for.
50      * @param {Object} config (optional) Config object
51      */
52     constructor: function(comp, config) {
53         this.comp = comp;
54         this.initialConstrainTo = config.constrainTo;
55         this.callParent([ config ]);
56     },
57
58     onStart: function(e) {
59         var me = this,
60             comp = me.comp;
61
62         // Cache the start [X, Y] array
63         this.startPosition = comp.getPosition();
64
65         // If client Component has a ghost method to show a lightweight version of itself
66         // then use that as a drag proxy unless configured to liveDrag.
67         if (comp.ghost && !comp.liveDrag) {
68              me.proxy = comp.ghost();
69              me.dragTarget = me.proxy.header.el;
70         }
71
72         // Set the constrainTo Region before we start dragging.
73         if (me.constrain || me.constrainDelegate) {
74             me.constrainTo = me.calculateConstrainRegion();
75         }
76     },
77
78     calculateConstrainRegion: function() {
79         var me = this,
80             comp = me.comp,
81             c = me.initialConstrainTo,
82             delegateRegion,
83             elRegion,
84             shadowSize = comp.el.shadow ? comp.el.shadow.offset : 0;
85
86         // The configured constrainTo might be a Region or an element
87         if (!(c instanceof Ext.util.Region)) {
88             c =  Ext.fly(c).getViewRegion();
89         }
90
91         // Reduce the constrain region to allow for shadow
92         if (shadowSize) {
93             c.adjust(0, -shadowSize, -shadowSize, shadowSize);
94         }
95
96         // If they only want to constrain the *delegate* to within the constrain region,
97         // adjust the region to be larger based on the insets of the delegate from the outer
98         // edges of the Component.
99         if (!me.constrainDelegate) {
100             delegateRegion = Ext.fly(me.dragTarget).getRegion();
101             elRegion = me.proxy ? me.proxy.el.getRegion() : comp.el.getRegion();
102
103             c.adjust(
104                 delegateRegion.top - elRegion.top,
105                 delegateRegion.right - elRegion.right,
106                 delegateRegion.bottom - elRegion.bottom,
107                 delegateRegion.left - elRegion.left
108             );
109         }
110         return c;
111     },
112
113     // Move either the ghost Component or the target Component to its new position on drag
114     onDrag: function(e) {
115         var me = this,
116             comp = (me.proxy && !me.comp.liveDrag) ? me.proxy : me.comp,
117             offset = me.getOffset(me.constrain || me.constrainDelegate ? 'dragTarget' : null);
118
119         comp.setPosition(me.startPosition[0] + offset[0], me.startPosition[1] + offset[1]);
120     },
121
122     onEnd: function(e) {
123         if (this.proxy && !this.comp.liveDrag) {
124             this.comp.unghost();
125         }
126     }
127 });