2 * @class Ext.resizer.SplitterTracker
3 * @extends Ext.dd.DragTracker
4 * Private utility class for Ext.Splitter.
7 Ext.define('Ext.resizer.SplitterTracker', {
8 extend: 'Ext.dd.DragTracker',
9 requires: ['Ext.util.Region'],
12 getPrevCmp: function() {
13 var splitter = this.getSplitter();
14 return splitter.previousSibling();
17 getNextCmp: function() {
18 var splitter = this.getSplitter();
19 return splitter.nextSibling();
22 // ensure the tracker is enabled, store boxes of previous and next
23 // components and calculate the constrain region
24 onBeforeStart: function(e) {
25 var prevCmp = this.getPrevCmp(),
26 nextCmp = this.getNextCmp();
28 // SplitterTracker is disabled if any of its adjacents are collapsed.
29 if (nextCmp.collapsed || prevCmp.collapsed) {
32 // store boxes of previous and next
33 this.prevBox = prevCmp.getEl().getBox();
34 this.nextBox = nextCmp.getEl().getBox();
35 this.constrainTo = this.calculateConstrainRegion();
38 // We move the splitter el. Add the proxy class.
39 onStart: function(e) {
40 var splitter = this.getSplitter();
41 splitter.addCls(splitter.baseCls + '-active');
44 // calculate the constrain Region in which the splitter el may be moved.
45 calculateConstrainRegion: function() {
46 var splitter = this.getSplitter(),
49 splitWidth = splitter.getWidth(),
50 defaultMin = splitter.defaultSplitMin,
51 orient = splitter.orientation,
52 prevBox = this.prevBox,
53 prevCmp = this.getPrevCmp(),
54 nextBox = this.nextBox,
55 nextCmp = this.getNextCmp(),
56 // prev and nextConstrainRegions are the maximumBoxes minus the
57 // minimumBoxes. The result is always the intersection
58 // of these two boxes.
59 prevConstrainRegion, nextConstrainRegion;
61 // vertical splitters, so resizing left to right
62 if (orient === 'vertical') {
64 // Region constructor accepts (top, right, bottom, left)
65 // anchored/calculated from the left
66 prevConstrainRegion = Ext.create('Ext.util.Region',
68 // Right boundary is x + maxWidth if there IS a maxWidth.
69 // Otherwise it is calculated based upon the minWidth of the next Component
70 (prevCmp.maxWidth ? prevBox.x + prevCmp.maxWidth : nextBox.right - (nextCmp.minWidth || defaultMin)) + splitWidth,
72 prevBox.x + (prevCmp.minWidth || defaultMin)
74 // anchored/calculated from the right
75 nextConstrainRegion = Ext.create('Ext.util.Region',
77 nextBox.right - (nextCmp.minWidth || defaultMin),
79 // Left boundary is right - maxWidth if there IS a maxWidth.
80 // Otherwise it is calculated based upon the minWidth of the previous Component
81 (nextCmp.maxWidth ? nextBox.right - nextCmp.maxWidth : prevBox.x + (prevBox.minWidth || defaultMin)) - splitWidth
84 // anchored/calculated from the top
85 prevConstrainRegion = Ext.create('Ext.util.Region',
86 prevBox.y + (prevCmp.minHeight || defaultMin),
88 // Bottom boundary is y + maxHeight if there IS a maxHeight.
89 // Otherwise it is calculated based upon the minWidth of the next Component
90 (prevCmp.maxHeight ? prevBox.y + prevCmp.maxHeight : nextBox.bottom - (nextCmp.minHeight || defaultMin)) + splitWidth,
93 // anchored/calculated from the bottom
94 nextConstrainRegion = Ext.create('Ext.util.Region',
95 // Top boundary is bottom - maxHeight if there IS a maxHeight.
96 // Otherwise it is calculated based upon the minHeight of the previous Component
97 (nextCmp.maxHeight ? nextBox.bottom - nextCmp.maxHeight : prevBox.y + (prevCmp.minHeight || defaultMin)) - splitWidth,
99 nextBox.bottom - (nextCmp.minHeight || defaultMin),
104 // intersection of the two regions to provide region draggable
105 return prevConstrainRegion.intersect(nextConstrainRegion);
108 // Performs the actual resizing of the previous and next components
109 performResize: function(e) {
110 var offset = this.getOffset('dragTarget'),
111 splitter = this.getSplitter(),
112 orient = splitter.orientation,
113 prevCmp = this.getPrevCmp(),
114 nextCmp = this.getNextCmp(),
115 owner = splitter.ownerCt,
116 layout = owner.getLayout();
118 // Inhibit automatic container layout caused by setSize calls below.
119 owner.suspendLayout = true;
121 if (orient === 'vertical') {
123 if (!prevCmp.maintainFlex) {
125 prevCmp.setSize(this.prevBox.width + offset[0], prevCmp.getHeight());
129 if (!nextCmp.maintainFlex) {
131 nextCmp.setSize(this.nextBox.width - offset[0], nextCmp.getHeight());
137 if (!prevCmp.maintainFlex) {
139 prevCmp.setSize(prevCmp.getWidth(), this.prevBox.height + offset[1]);
143 if (!nextCmp.maintainFlex) {
145 nextCmp.setSize(prevCmp.getWidth(), this.nextBox.height - offset[1]);
149 delete owner.suspendLayout;
153 // perform the resize and remove the proxy class from the splitter el
155 var splitter = this.getSplitter();
156 splitter.removeCls(splitter.baseCls + '-active');
157 this.performResize();
160 // Track the proxy and set the proper XY coordinates
161 // while constraining the drag
162 onDrag: function(e) {
163 var offset = this.getOffset('dragTarget'),
164 splitter = this.getSplitter(),
165 splitEl = splitter.getEl(),
166 orient = splitter.orientation;
168 if (orient === "vertical") {
169 splitEl.setX(this.startRegion.left + offset[0]);
171 splitEl.setY(this.startRegion.top + offset[1]);
175 getSplitter: function() {
176 return Ext.getCmp(this.getDragCt().id);