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 * @class Ext.resizer.SplitterTracker
17 * @extends Ext.dd.DragTracker
18 * Private utility class for Ext.Splitter.
21 Ext.define('Ext.resizer.SplitterTracker', {
22 extend: 'Ext.dd.DragTracker',
23 requires: ['Ext.util.Region'],
26 overlayCls: Ext.baseCSSPrefix + 'resizable-overlay',
28 getPrevCmp: function() {
29 var splitter = this.getSplitter();
30 return splitter.previousSibling();
33 getNextCmp: function() {
34 var splitter = this.getSplitter();
35 return splitter.nextSibling();
38 // ensure the tracker is enabled, store boxes of previous and next
39 // components and calculate the constrain region
40 onBeforeStart: function(e) {
42 prevCmp = me.getPrevCmp(),
43 nextCmp = me.getNextCmp(),
44 collapseEl = me.getSplitter().collapseEl,
47 if (collapseEl && (e.getTarget() === me.getSplitter().collapseEl.dom)) {
51 // SplitterTracker is disabled if any of its adjacents are collapsed.
52 if (nextCmp.collapsed || prevCmp.collapsed) {
56 overlay = me.overlay = Ext.getBody().createChild({
60 overlay.unselectable();
61 overlay.setSize(Ext.Element.getViewWidth(true), Ext.Element.getViewHeight(true));
64 // store boxes of previous and next
65 me.prevBox = prevCmp.getEl().getBox();
66 me.nextBox = nextCmp.getEl().getBox();
67 me.constrainTo = me.calculateConstrainRegion();
70 // We move the splitter el. Add the proxy class.
71 onStart: function(e) {
72 var splitter = this.getSplitter();
73 splitter.addCls(splitter.baseCls + '-active');
76 // calculate the constrain Region in which the splitter el may be moved.
77 calculateConstrainRegion: function() {
79 splitter = me.getSplitter(),
80 splitWidth = splitter.getWidth(),
81 defaultMin = splitter.defaultSplitMin,
82 orient = splitter.orientation,
84 prevCmp = me.getPrevCmp(),
86 nextCmp = me.getNextCmp(),
87 // prev and nextConstrainRegions are the maximumBoxes minus the
88 // minimumBoxes. The result is always the intersection
89 // of these two boxes.
90 prevConstrainRegion, nextConstrainRegion;
92 // vertical splitters, so resizing left to right
93 if (orient === 'vertical') {
95 // Region constructor accepts (top, right, bottom, left)
96 // anchored/calculated from the left
97 prevConstrainRegion = Ext.create('Ext.util.Region',
99 // Right boundary is x + maxWidth if there IS a maxWidth.
100 // Otherwise it is calculated based upon the minWidth of the next Component
101 (prevCmp.maxWidth ? prevBox.x + prevCmp.maxWidth : nextBox.right - (nextCmp.minWidth || defaultMin)) + splitWidth,
103 prevBox.x + (prevCmp.minWidth || defaultMin)
105 // anchored/calculated from the right
106 nextConstrainRegion = Ext.create('Ext.util.Region',
108 nextBox.right - (nextCmp.minWidth || defaultMin),
110 // Left boundary is right - maxWidth if there IS a maxWidth.
111 // Otherwise it is calculated based upon the minWidth of the previous Component
112 (nextCmp.maxWidth ? nextBox.right - nextCmp.maxWidth : prevBox.x + (prevBox.minWidth || defaultMin)) - splitWidth
115 // anchored/calculated from the top
116 prevConstrainRegion = Ext.create('Ext.util.Region',
117 prevBox.y + (prevCmp.minHeight || defaultMin),
119 // Bottom boundary is y + maxHeight if there IS a maxHeight.
120 // Otherwise it is calculated based upon the minWidth of the next Component
121 (prevCmp.maxHeight ? prevBox.y + prevCmp.maxHeight : nextBox.bottom - (nextCmp.minHeight || defaultMin)) + splitWidth,
124 // anchored/calculated from the bottom
125 nextConstrainRegion = Ext.create('Ext.util.Region',
126 // Top boundary is bottom - maxHeight if there IS a maxHeight.
127 // Otherwise it is calculated based upon the minHeight of the previous Component
128 (nextCmp.maxHeight ? nextBox.bottom - nextCmp.maxHeight : prevBox.y + (prevCmp.minHeight || defaultMin)) - splitWidth,
130 nextBox.bottom - (nextCmp.minHeight || defaultMin),
135 // intersection of the two regions to provide region draggable
136 return prevConstrainRegion.intersect(nextConstrainRegion);
139 // Performs the actual resizing of the previous and next components
140 performResize: function(e) {
142 offset = me.getOffset('dragTarget'),
143 splitter = me.getSplitter(),
144 orient = splitter.orientation,
145 prevCmp = me.getPrevCmp(),
146 nextCmp = me.getNextCmp(),
147 owner = splitter.ownerCt,
148 layout = owner.getLayout();
150 // Inhibit automatic container layout caused by setSize calls below.
151 owner.suspendLayout = true;
153 if (orient === 'vertical') {
155 if (!prevCmp.maintainFlex) {
157 prevCmp.setSize(me.prevBox.width + offset[0], prevCmp.getHeight());
161 if (!nextCmp.maintainFlex) {
163 nextCmp.setSize(me.nextBox.width - offset[0], nextCmp.getHeight());
169 if (!prevCmp.maintainFlex) {
171 prevCmp.setSize(prevCmp.getWidth(), me.prevBox.height + offset[1]);
175 if (!nextCmp.maintainFlex) {
177 nextCmp.setSize(prevCmp.getWidth(), me.nextBox.height - offset[1]);
181 delete owner.suspendLayout;
185 // Cleans up the overlay (if we have one) and calls the base. This cannot be done in
186 // onEnd, because onEnd is only called if a drag is detected but the overlay is created
187 // regardless (by onBeforeStart).
188 endDrag: function () {
196 me.callParent(arguments); // this calls onEnd
199 // perform the resize and remove the proxy class from the splitter el
202 splitter = me.getSplitter();
204 splitter.removeCls(splitter.baseCls + '-active');
208 // Track the proxy and set the proper XY coordinates
209 // while constraining the drag
210 onDrag: function(e) {
212 offset = me.getOffset('dragTarget'),
213 splitter = me.getSplitter(),
214 splitEl = splitter.getEl(),
215 orient = splitter.orientation;
217 if (orient === "vertical") {
218 splitEl.setX(me.startRegion.left + offset[0]);
220 splitEl.setY(me.startRegion.top + offset[1]);
224 getSplitter: function() {
225 return Ext.getCmp(this.getDragCt().id);