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.ResizeTracker
17 * @extends Ext.dd.DragTracker
18 * Private utility class for Ext.resizer.Resizer.
21 Ext.define('Ext.resizer.ResizeTracker', {
22 extend: 'Ext.dd.DragTracker',
26 // Default to no constraint
29 constructor: function(config) {
33 if (config.target.isComponent) {
34 me.el = config.target.getEl();
36 me.el = config.target;
39 this.callParent(arguments);
41 // Ensure that if we are preserving aspect ratio, the largest minimum is honoured
42 if (me.preserveRatio && me.minWidth && me.minHeight) {
43 var widthRatio = me.minWidth / me.el.getWidth(),
44 heightRatio = me.minHeight / me.el.getHeight();
46 // largest ratio of minimum:size must be preserved.
47 // So if a 400x200 pixel image has
48 // minWidth: 50, maxWidth: 50, the maxWidth will be 400 * (50/200)... that is 100
49 if (heightRatio > widthRatio) {
50 me.minWidth = me.el.getWidth() * heightRatio;
52 me.minHeight = me.el.getHeight() * widthRatio;
56 // If configured as throttled, create an instance version of resize which calls
57 // a throttled function to perform the resize operation.
59 var throttledResizeFn = Ext.Function.createThrottled(function() {
60 Ext.resizer.ResizeTracker.prototype.resize.apply(me, arguments);
63 me.resize = function(box, direction, atEnd) {
65 Ext.resizer.ResizeTracker.prototype.resize.apply(me, arguments);
67 throttledResizeFn.apply(null, arguments);
73 onBeforeStart: function(e) {
74 // record the startBox
75 this.startBox = this.el.getBox();
80 * Returns the object that will be resized on every mousemove event.
81 * If dynamic is false, this will be a proxy, otherwise it will be our actual target.
83 getDynamicTarget: function() {
87 } else if (!this.proxy) {
88 this.proxy = d.isComponent ? d.getProxy().addCls(Ext.baseCSSPrefix + 'resizable-proxy') : d.createProxy({tag: 'div', cls: Ext.baseCSSPrefix + 'resizable-proxy', id: d.id + '-rzproxy'}, Ext.getBody());
89 this.proxy.removeCls(Ext.baseCSSPrefix + 'proxy-el');
95 onStart: function(e) {
96 // returns the Ext.ResizeHandle that the user started dragging
97 this.activeResizeHandle = Ext.getCmp(this.getDragTarget().id);
99 // If we are using a proxy, ensure it is sized.
101 this.resize(this.startBox, {
108 onDrag: function(e) {
109 // dynamic resizing, update dimensions during resize
110 if (this.dynamic || this.proxy) {
111 this.updateDimensions(e);
115 updateDimensions: function(e, atEnd) {
117 region = me.activeResizeHandle.region,
118 offset = me.getOffset(me.constrainTo ? 'dragTarget' : null),
128 horizDir = offset[0] < 0 ? 'right' : 'left',
129 vertDir = offset[1] < 0 ? 'down' : 'up',
131 axis; // 1 = x, 2 = y, 3 = x and y.
135 heightAdjust = offset[1];
139 heightAdjust = -offset[1];
140 adjustY = -heightAdjust;
144 widthAdjust = offset[0];
148 widthAdjust = -offset[0];
149 adjustX = -widthAdjust;
153 heightAdjust = -offset[1];
154 adjustY = -heightAdjust;
155 widthAdjust = offset[0];
156 oppositeCorner = [box.x, box.y + box.height];
160 heightAdjust = offset[1];
161 widthAdjust = offset[0];
162 oppositeCorner = [box.x, box.y];
166 widthAdjust = -offset[0];
167 adjustX = -widthAdjust;
168 heightAdjust = offset[1];
169 oppositeCorner = [box.x + box.width, box.y];
173 heightAdjust = -offset[1];
174 adjustY = -heightAdjust;
175 widthAdjust = -offset[0];
176 adjustX = -widthAdjust;
177 oppositeCorner = [box.x + box.width, box.y + box.height];
183 width: box.width + widthAdjust,
184 height: box.height + heightAdjust,
189 // Snap value between stops according to configured increments
190 snappedWidth = Ext.Number.snap(newBox.width, me.widthIncrement);
191 snappedHeight = Ext.Number.snap(newBox.height, me.heightIncrement);
192 if (snappedWidth != newBox.width || snappedHeight != newBox.height){
195 newBox.y -= snappedHeight - newBox.height;
198 newBox.y -= snappedHeight - newBox.height;
201 newBox.x -= snappedWidth - newBox.width;
204 newBox.x -= snappedWidth - newBox.width;
207 newBox.x -= snappedWidth - newBox.width;
208 newBox.y -= snappedHeight - newBox.height;
210 newBox.width = snappedWidth;
211 newBox.height = snappedHeight;
215 if (newBox.width < me.minWidth || newBox.width > me.maxWidth) {
216 newBox.width = Ext.Number.constrain(newBox.width, me.minWidth, me.maxWidth);
218 // Re-adjust the X position if we were dragging the west side
220 newBox.x = box.x + (box.width - newBox.width);
225 if (newBox.height < me.minHeight || newBox.height > me.maxHeight) {
226 newBox.height = Ext.Number.constrain(newBox.height, me.minHeight, me.maxHeight);
228 // Re-adjust the Y position if we were dragging the north side
230 newBox.y = box.y + (box.height - newBox.height);
236 // If this is configured to preserve the aspect ratio, or they are dragging using the shift key
237 if (me.preserveRatio || e.shiftKey) {
241 ratio = me.startBox.width / me.startBox.height;
243 // Calculate aspect ratio constrained values.
244 newHeight = Math.min(Math.max(me.minHeight, newBox.width / ratio), me.maxHeight);
245 newWidth = Math.min(Math.max(me.minWidth, newBox.height * ratio), me.maxWidth);
247 // X axis: width-only change, height must obey
249 newBox.height = newHeight;
252 // Y axis: height-only change, width must obey
253 else if (axis == 2) {
254 newBox.width = newWidth;
259 // Drag ratio is the ratio of the mouse point from the opposite corner.
260 // Basically what edge we are dragging, a horizontal edge or a vertical edge.
261 dragRatio = Math.abs(oppositeCorner[0] - this.lastXY[0]) / Math.abs(oppositeCorner[1] - this.lastXY[1]);
263 // If drag ratio > aspect ratio then width is dominant and height must obey
264 if (dragRatio > ratio) {
265 newBox.height = newHeight;
267 newBox.width = newWidth;
270 // Handle dragging start coordinates
271 if (region == 'northeast') {
272 newBox.y = box.y - (newBox.height - box.height);
273 } else if (region == 'northwest') {
274 newBox.y = box.y - (newBox.height - box.height);
275 newBox.x = box.x - (newBox.width - box.width);
276 } else if (region == 'southwest') {
277 newBox.x = box.x - (newBox.width - box.width);
282 if (heightAdjust === 0) {
285 if (widthAdjust === 0) {
289 horizontal: horizDir,
294 getResizeTarget: function(atEnd) {
295 return atEnd ? this.target : this.getDynamicTarget();
298 resize: function(box, direction, atEnd) {
299 var target = this.getResizeTarget(atEnd);
300 if (target.isComponent) {
301 if (target.floating) {
302 target.setPagePosition(box.x, box.y);
304 target.setSize(box.width, box.height);
307 // update the originalTarget if this was wrapped.
308 if (this.originalTarget) {
309 this.originalTarget.setBox(box);
315 this.updateDimensions(e, true);