+ the notion of stationaryCorner to the Trench logic. this value specifies which corner of a bound must remain stationary while resizing. Normally this is the topleft, but in the case of dragging out new tab groups, it actually could be another corner, which means the snapping computation is different. Fixes a couple minor resizing bugs.

This commit is contained in:
Michael Yoshitaka Erlewine 2010-07-03 16:55:54 -04:00
parent 3eaf0547a0
commit e41c23897b
4 changed files with 69 additions and 40 deletions

View File

@ -61,7 +61,8 @@ var drag = {
// isResizing - (boolean) is this a resizing instance? or (if false) dragging?
var Drag = function(item, event, isResizing) {
try {
Utils.assert('item', item && item.isAnItem);
Utils.assert('must be an item, or at least a faux item',
item && (item.isAnItem || item.isAFauxItem));
this.isResizing = isResizing || false;
this.item = item;
@ -97,8 +98,20 @@ var Drag = function(item, event, isResizing) {
};
Drag.prototype = {
// ----------
snap: function(event, ui, assumeConstantSize, keepProportional){
// ----------
// Function: snap
// Called when a drag or mousemove occurs. Set the bounds based on the mouse move first, then
// call snap and it will adjust the item's bounds if appropriate. Also triggers the display of
// trenches that it snapped to.
//
// Parameters:
// stationaryCorner - which corner is stationary? by default, the top left.
// "topleft", "bottomleft", "topright", "bottomright"
// assumeConstantSize - (boolean) whether the bounds' dimensions are sacred or not.
// keepProportional - (boolean) if assumeConstantSize is false, whether we should resize
// proportionally or not
snap: function(stationaryCorner, assumeConstantSize, keepProportional) {
var stationaryCorner = stationaryCorner || 'topleft';
var bounds = this.item.getBounds();
var update = false; // need to update
var updateX = false;
@ -107,10 +120,11 @@ Drag.prototype = {
var snappedTrenches = {};
// OH SNAP!
if ( !Keys.meta // if we aren't holding down the meta key...
&& !(this.isATabItem && this.item.overlapsWithOtherItems()) // and we aren't a tab on top of something else...
) {
newRect = Trenches.snap(bounds,assumeConstantSize,keepProportional);
if ( // if we aren't holding down the meta key...
!Keys.meta
// and we aren't a tab on top of something else...
&& !(this.isATabItem && this.item.overlapsWithOtherItems()) ) {
newRect = Trenches.snap(bounds,stationaryCorner,assumeConstantSize,keepProportional);
if (newRect) { // might be false if no changes were made
update = true;
snappedTrenches = newRect.snappedTrenches || {};
@ -119,7 +133,7 @@ Drag.prototype = {
}
// make sure the bounds are in the window.
newRect = this.snapToEdge(bounds,assumeConstantSize,keepProportional);
newRect = this.snapToEdge(bounds,stationaryCorner,assumeConstantSize,keepProportional);
if (newRect) {
update = true;
bounds = newRect;
@ -149,10 +163,13 @@ Drag.prototype = {
//
// Parameters:
// rect - (<Rect>) current bounds of the object
// stationaryCorner - which corner is stationary? by default, the top left.
// "topleft", "bottomleft", "topright", "bottomright"
// assumeConstantSize - (boolean) whether the rect's dimensions are sacred or not
// keepProportional - (boolean) if we are allowed to change the rect's size, whether the
// dimensions should scaled proportionally or not.
snapToEdge: function Drag_snapToEdge(rect, assumeConstantSize, keepProportional) {
// keepProportional - (boolean) if we are allowed to change the rect's size, whether the
// dimensions should scaled proportionally or not.
snapToEdge: function Drag_snapToEdge(rect, stationaryCorner, assumeConstantSize, keepProportional) {
var swb = this.safeWindowBounds;
var update = false;
var updateX = false;
@ -161,6 +178,8 @@ Drag.prototype = {
var snapRadius = ( Keys.meta ? 0 : Trenches.defaultRadius );
if (rect.left < swb.left + snapRadius ) {
if (stationaryCorner.indexOf('right') > -1)
rect.width = rect.right - swb.left;
rect.left = swb.left;
update = true;
updateX = true;
@ -182,6 +201,8 @@ Drag.prototype = {
delete snappedTrenches.left;
}
if (rect.top < swb.top + snapRadius) {
if (stationaryCorner.indexOf('bottom') > -1)
rect.height = rect.bottom - swb.top;
rect.top = swb.top;
update = true;
updateY = true;
@ -213,7 +234,7 @@ Drag.prototype = {
// Function: drag
// Called in response to an <Item> draggable "drag" event.
drag: function(event, ui) {
this.snap(event,ui,true);
this.snap('topleft',true);
if (this.parent && this.parent.expanded) {
var now = Utils.getMilliseconds();

View File

@ -214,7 +214,8 @@ window.Item.prototype = {
resizeInfo = new Drag(this, e, true); // true = isResizing
},
resize: function(e,ui){
resizeInfo.snap(e,ui, false, self.keepProportional);
// TODO: maybe the stationaryCorner should be topright for rtl langs?
resizeInfo.snap('topleft', false, self.keepProportional);
},
stop: function(){
self.setUserSize();

View File

@ -285,6 +285,8 @@ Trench.prototype = {
//
// Parameters:
// rect - (<Rect>) the rectangle in question
// stationaryCorner - which corner is stationary? by default, the top left.
// "topleft", "bottomleft", "topright", "bottomright"
// assumeConstantSize - (boolean) whether the rect's dimensions are sacred or not
// keepProportional - (boolean) if we are allowed to change the rect's size, whether the
// dimensions should scaled proportionally or not.
@ -292,7 +294,7 @@ Trench.prototype = {
// Returns:
// false - if rect does not overlap with this trench
// newRect - (<Rect>) an adjusted version of rect, if it is affected by this trench
rectOverlaps: function Trench_rectOverlaps(rect,assumeConstantSize,keepProportional) {
rectOverlaps: function Trench_rectOverlaps(rect,stationaryCorner,assumeConstantSize,keepProportional) {
var edgeToCheck;
if (this.type == "border") {
if (this.edge == "left")
@ -312,6 +314,8 @@ Trench.prototype = {
switch (edgeToCheck) {
case "left":
if (this.ruleOverlaps(rect.left, rect.yRange)) {
if (stationaryCorner.indexOf('right') > -1)
rect.width = rect.right - this.position;
rect.left = this.position;
return rect;
}
@ -331,6 +335,8 @@ Trench.prototype = {
break;
case "top":
if (this.ruleOverlaps(rect.top, rect.xRange)) {
if (stationaryCorner.indexOf('bottom') > -1)
rect.height = rect.bottom - this.position;
rect.top = this.position;
return rect;
}
@ -548,22 +554,25 @@ var Trenches = {
// not leaving the safe bounds of the window.
//
// Parameters:
// rect - (<Rect>) the object's current bounds
// rect - (<Rect>) the object's current bounds
// stationaryCorner - which corner is stationary? by default, the top left.
// "topleft", "bottomleft", "topright", "bottomright"
// assumeConstantSize - (boolean) whether the rect's dimensions are sacred or not
// keepProportional - (boolean) if we are allowed to change the rect's size, whether the
// dimensions should scaled proportionally or not.
// keepProportional - (boolean) if we are allowed to change the rect's size, whether the
// dimensions should scaled proportionally or not.
//
// Returns:
// (<Rect>) - the updated bounds, if they were updated
// false - if the bounds were not updated
snap: function Trenches_snap(rect,assumeConstantSize,keepProportional) {
snap: function Trenches_snap(rect,stationaryCorner,assumeConstantSize,keepProportional) {
var aT = this.activeTrenches;
// hide all the guide trenches, because the correct ones will be turned on later.
Trenches.hideGuides();
// if we're currently dragging over a drop-site, don't snap at all.
if (iQ(".acceptsDrop").length) {
Trenches.hideGuides();
if (iQ(".acceptsDrop").length)
return;
}
var updated = false;
var updatedX = false;
@ -576,7 +585,7 @@ var Trenches = {
if (!t.active)
continue;
// newRect will be a new rect, or false
var newRect = t.rectOverlaps(rect,assumeConstantSize,keepProportional);
var newRect = t.rectOverlaps(rect,stationaryCorner,assumeConstantSize,keepProportional);
if (newRect) { // if rectOverlaps returned an updated rect...
@ -607,27 +616,11 @@ var Trenches = {
}
}
let snappedIds = [ snappedTrenches[j].id for (j in snappedTrenches) ];
for (let i in this.trenches) {
let t = this.trenches[i];
// show the guide if it was used in snapping
if (snappedIds.indexOf(t.id) != -1) {
t.showGuide = true;
t.show();
}
// make sure to turn the guide off if we're no longer snapping to it
if (t.showGuide && snappedIds.indexOf(t.id) == -1) {
t.showGuide = false;
t.show();
}
}
if (updated) {
rect.snappedTrenches = snappedTrenches;
return rect;
} else {
Trenches.hideGuides();
return false;
}
},

View File

@ -418,6 +418,7 @@ window.Page = {
var item = { // a faux-Item
container: phantom,
isAFauxItem: true,
bounds: {},
getBounds: function FauxItem_getBounds() {
return this.container.bounds();
@ -447,7 +448,20 @@ window.Page = {
box.bottom = Math.max(startPos.y, e.clientY);
item.setBounds(box);
dragOutInfo.snap(e, null, false, false); // null for ui, which we don't use anyway.
// compute the stationaryCorner
var stationaryCorner = '';
if (startPos.y == box.top)
stationaryCorner += 'top';
else
stationaryCorner += 'bottom';
if (startPos.x == box.left)
stationaryCorner += 'left';
else
stationaryCorner += 'right';
dragOutInfo.snap(stationaryCorner, false, false); // null for ui, which we don't use anyway.
box = item.getBounds();
if (box.width > minMinSize && box.height > minMinSize