linuxwindowsinboxwhatsappicloudtweetdeckhipchattelegramhangoutsslackgmailskypefacebook-workplaceoutlookemailmicrosoft-teamsdiscordmessengercustom-servicesmacos
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
338 lines
11 KiB
338 lines
11 KiB
9 years ago
|
/**
|
||
|
* Private utility class for Ext.resizer.Resizer.
|
||
|
* @private
|
||
|
*/
|
||
|
Ext.define('Ext.resizer.ResizeTracker', {
|
||
|
extend: 'Ext.dd.DragTracker',
|
||
|
dynamic: true,
|
||
|
preserveRatio: false,
|
||
|
|
||
|
// Default to no constraint
|
||
|
constrainTo: null,
|
||
|
|
||
|
proxyCls: Ext.baseCSSPrefix + 'resizable-proxy',
|
||
|
|
||
|
constructor: function(config) {
|
||
|
var me = this,
|
||
|
widthRatio, heightRatio,
|
||
|
throttledResizeFn;
|
||
|
|
||
|
if (!config.el) {
|
||
|
if (config.target.isComponent) {
|
||
|
me.el = config.target.getEl();
|
||
|
} else {
|
||
|
me.el = config.target;
|
||
|
}
|
||
|
}
|
||
|
this.callParent(arguments);
|
||
|
|
||
|
// Ensure that if we are preserving aspect ratio, the largest minimum is honoured
|
||
|
if (me.preserveRatio && me.minWidth && me.minHeight) {
|
||
|
widthRatio = me.minWidth / me.el.getWidth();
|
||
|
heightRatio = me.minHeight / me.el.getHeight();
|
||
|
|
||
|
// largest ratio of minimum:size must be preserved.
|
||
|
// So if a 400x200 pixel image has
|
||
|
// minWidth: 50, maxWidth: 50, the maxWidth will be 400 * (50/200)... that is 100
|
||
|
if (heightRatio > widthRatio) {
|
||
|
me.minWidth = me.el.getWidth() * heightRatio;
|
||
|
} else {
|
||
|
me.minHeight = me.el.getHeight() * widthRatio;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// If configured as throttled, create an instance version of resize which calls
|
||
|
// a throttled function to perform the resize operation.
|
||
|
if (me.throttle) {
|
||
|
throttledResizeFn = Ext.Function.createThrottled(function() {
|
||
|
Ext.resizer.ResizeTracker.prototype.resize.apply(me, arguments);
|
||
|
}, me.throttle);
|
||
|
|
||
|
me.resize = function(box, direction, atEnd) {
|
||
|
if (atEnd) {
|
||
|
Ext.resizer.ResizeTracker.prototype.resize.apply(me, arguments);
|
||
|
} else {
|
||
|
throttledResizeFn.apply(null, arguments);
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
},
|
||
|
|
||
|
onBeforeStart: function(e) {
|
||
|
// record the startBox
|
||
|
this.startBox = this.target.getBox();
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
* Returns the object that will be resized instead of the true target on every mousemove event.
|
||
|
* If dynamic is false, this will be a proxy, otherwise it will be null target.
|
||
|
*/
|
||
|
getProxy: function() {
|
||
|
var me = this;
|
||
|
|
||
|
if (!me.dynamic && !me.proxy) {
|
||
|
me.proxy = me.createProxy(me.target || me.el);
|
||
|
|
||
|
// Only hide proxy at end if we create one dynamically
|
||
|
// When a wrapped resizer is used it passes the wrapping el in as the proxy.
|
||
|
me.hideProxy = true;
|
||
|
}
|
||
|
if (me.proxy) {
|
||
|
me.proxy.show();
|
||
|
return me.proxy;
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Create a proxy for this resizer
|
||
|
* @param {Ext.Component/Ext.dom.Element} target The target
|
||
|
* @return {Ext.dom.Element} A proxy element
|
||
|
*/
|
||
|
createProxy: function(target){
|
||
|
var proxy,
|
||
|
cls = this.proxyCls;
|
||
|
|
||
|
if (target.isComponent) {
|
||
|
proxy = target.getProxy().addCls(cls);
|
||
|
} else {
|
||
|
proxy = target.createProxy({
|
||
|
tag: 'div',
|
||
|
role: 'presentation',
|
||
|
cls: cls,
|
||
|
id: target.id + '-rzproxy'
|
||
|
}, Ext.getBody());
|
||
|
}
|
||
|
proxy.removeCls(Ext.baseCSSPrefix + 'proxy-el');
|
||
|
return proxy;
|
||
|
},
|
||
|
|
||
|
onStart: function(e) {
|
||
|
// returns the Ext.ResizeHandle that the user started dragging
|
||
|
this.activeResizeHandle = Ext.get(this.getDragTarget().id);
|
||
|
|
||
|
// If we are using a proxy, ensure it is sized.
|
||
|
if (!this.dynamic) {
|
||
|
this.resize(this.startBox);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
onDrag: function(e) {
|
||
|
// dynamic resizing, update dimensions during resize
|
||
|
if (this.dynamic || this.proxy) {
|
||
|
this.updateDimensions(e);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
updateDimensions: function(e, atEnd) {
|
||
|
var me = this,
|
||
|
region = me.activeResizeHandle.region,
|
||
|
offset = me.getOffset(me.constrainTo ? 'dragTarget' : null),
|
||
|
box = me.startBox,
|
||
|
ratio,
|
||
|
widthAdjust = 0,
|
||
|
heightAdjust = 0,
|
||
|
snappedWidth,
|
||
|
snappedHeight,
|
||
|
adjustX = 0,
|
||
|
adjustY = 0,
|
||
|
dragRatio,
|
||
|
oppositeCorner,
|
||
|
axis, // 1 = x, 2 = y, 3 = x and y.
|
||
|
newBox,
|
||
|
newHeight, newWidth;
|
||
|
|
||
|
region = me.convertRegionName(region);
|
||
|
|
||
|
switch (region) {
|
||
|
case 'south':
|
||
|
heightAdjust = offset[1];
|
||
|
axis = 2;
|
||
|
break;
|
||
|
case 'north':
|
||
|
heightAdjust = -offset[1];
|
||
|
adjustY = -heightAdjust;
|
||
|
axis = 2;
|
||
|
break;
|
||
|
case 'east':
|
||
|
widthAdjust = offset[0];
|
||
|
axis = 1;
|
||
|
break;
|
||
|
case 'west':
|
||
|
widthAdjust = -offset[0];
|
||
|
adjustX = -widthAdjust;
|
||
|
axis = 1;
|
||
|
break;
|
||
|
case 'northeast':
|
||
|
heightAdjust = -offset[1];
|
||
|
adjustY = -heightAdjust;
|
||
|
widthAdjust = offset[0];
|
||
|
oppositeCorner = [box.x, box.y + box.height];
|
||
|
axis = 3;
|
||
|
break;
|
||
|
case 'southeast':
|
||
|
heightAdjust = offset[1];
|
||
|
widthAdjust = offset[0];
|
||
|
oppositeCorner = [box.x, box.y];
|
||
|
axis = 3;
|
||
|
break;
|
||
|
case 'southwest':
|
||
|
widthAdjust = -offset[0];
|
||
|
adjustX = -widthAdjust;
|
||
|
heightAdjust = offset[1];
|
||
|
oppositeCorner = [box.x + box.width, box.y];
|
||
|
axis = 3;
|
||
|
break;
|
||
|
case 'northwest':
|
||
|
heightAdjust = -offset[1];
|
||
|
adjustY = -heightAdjust;
|
||
|
widthAdjust = -offset[0];
|
||
|
adjustX = -widthAdjust;
|
||
|
oppositeCorner = [box.x + box.width, box.y + box.height];
|
||
|
axis = 3;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
newBox = {
|
||
|
width: box.width + widthAdjust,
|
||
|
height: box.height + heightAdjust,
|
||
|
x: box.x + adjustX,
|
||
|
y: box.y + adjustY
|
||
|
};
|
||
|
|
||
|
// Snap value between stops according to configured increments
|
||
|
snappedWidth = Ext.Number.snap(newBox.width, me.widthIncrement);
|
||
|
snappedHeight = Ext.Number.snap(newBox.height, me.heightIncrement);
|
||
|
if (snappedWidth !== newBox.width || snappedHeight !== newBox.height){
|
||
|
switch (region) {
|
||
|
case 'northeast':
|
||
|
newBox.y -= snappedHeight - newBox.height;
|
||
|
break;
|
||
|
case 'north':
|
||
|
newBox.y -= snappedHeight - newBox.height;
|
||
|
break;
|
||
|
case 'southwest':
|
||
|
newBox.x -= snappedWidth - newBox.width;
|
||
|
break;
|
||
|
case 'west':
|
||
|
newBox.x -= snappedWidth - newBox.width;
|
||
|
break;
|
||
|
case 'northwest':
|
||
|
newBox.x -= snappedWidth - newBox.width;
|
||
|
newBox.y -= snappedHeight - newBox.height;
|
||
|
}
|
||
|
newBox.width = snappedWidth;
|
||
|
newBox.height = snappedHeight;
|
||
|
}
|
||
|
|
||
|
// out of bounds
|
||
|
if (newBox.width < me.minWidth || newBox.width > me.maxWidth) {
|
||
|
newBox.width = Ext.Number.constrain(newBox.width, me.minWidth, me.maxWidth);
|
||
|
|
||
|
// Re-adjust the X position if we were dragging the west side
|
||
|
if (adjustX) {
|
||
|
newBox.x = box.x + (box.width - newBox.width);
|
||
|
}
|
||
|
} else {
|
||
|
me.lastX = newBox.x;
|
||
|
}
|
||
|
if (newBox.height < me.minHeight || newBox.height > me.maxHeight) {
|
||
|
newBox.height = Ext.Number.constrain(newBox.height, me.minHeight, me.maxHeight);
|
||
|
|
||
|
// Re-adjust the Y position if we were dragging the north side
|
||
|
if (adjustY) {
|
||
|
newBox.y = box.y + (box.height - newBox.height);
|
||
|
}
|
||
|
} else {
|
||
|
me.lastY = newBox.y;
|
||
|
}
|
||
|
|
||
|
// If this is configured to preserve the aspect ratio, or they are dragging using the shift key
|
||
|
if (me.preserveRatio || e.shiftKey) {
|
||
|
ratio = me.startBox.width / me.startBox.height;
|
||
|
|
||
|
// Calculate aspect ratio constrained values.
|
||
|
newHeight = Math.min(Math.max(me.minHeight, newBox.width / ratio), me.maxHeight);
|
||
|
newWidth = Math.min(Math.max(me.minWidth, newBox.height * ratio), me.maxWidth);
|
||
|
|
||
|
// X axis: width-only change, height must obey
|
||
|
if (axis === 1) {
|
||
|
newBox.height = newHeight;
|
||
|
}
|
||
|
|
||
|
// Y axis: height-only change, width must obey
|
||
|
else if (axis === 2) {
|
||
|
newBox.width = newWidth;
|
||
|
}
|
||
|
|
||
|
// Corner drag.
|
||
|
else {
|
||
|
// Drag ratio is the ratio of the mouse point from the opposite corner.
|
||
|
// Basically what edge we are dragging, a horizontal edge or a vertical edge.
|
||
|
dragRatio = Math.abs(oppositeCorner[0] - this.lastXY[0]) / Math.abs(oppositeCorner[1] - this.lastXY[1]);
|
||
|
|
||
|
// If drag ratio > aspect ratio then width is dominant and height must obey
|
||
|
if (dragRatio > ratio) {
|
||
|
newBox.height = newHeight;
|
||
|
} else {
|
||
|
newBox.width = newWidth;
|
||
|
}
|
||
|
|
||
|
// Handle dragging start coordinates
|
||
|
if (region === 'northeast') {
|
||
|
newBox.y = box.y - (newBox.height - box.height);
|
||
|
} else if (region === 'northwest') {
|
||
|
newBox.y = box.y - (newBox.height - box.height);
|
||
|
newBox.x = box.x - (newBox.width - box.width);
|
||
|
} else if (region === 'southwest') {
|
||
|
newBox.x = box.x - (newBox.width - box.width);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Keep track of whether position needs changing
|
||
|
me.setPosition = newBox.x !== me.startBox.x || newBox.y !== me.startBox.y;
|
||
|
me.resize(newBox, atEnd);
|
||
|
},
|
||
|
|
||
|
resize: function(box, atEnd) {
|
||
|
var me = this,
|
||
|
target,
|
||
|
setPosition = me.setPosition;
|
||
|
|
||
|
// We are live resizing the target, or at the end: Size the target
|
||
|
if (me.dynamic || (!me.dynamic && atEnd)) {
|
||
|
// Resize the target
|
||
|
if (setPosition) {
|
||
|
me.target.setBox(box);
|
||
|
} else {
|
||
|
me.target.setSize(box.width, box.height);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
// In the middle of a resize - just resize the proxy
|
||
|
if (!atEnd) {
|
||
|
target = me.getProxy();
|
||
|
if (target && target !== me.target) {
|
||
|
if (setPosition || me.hideProxy) {
|
||
|
target.setBox(box);
|
||
|
} else {
|
||
|
target.setSize(box.width, box.height);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
onEnd: function(e) {
|
||
|
this.updateDimensions(e, true);
|
||
|
if (this.proxy && this.hideProxy) {
|
||
|
this.proxy.hide();
|
||
|
}
|
||
|
},
|
||
|
|
||
|
convertRegionName: function(name) {
|
||
|
return name;
|
||
|
}
|
||
|
});
|