if (!dojo._hasResource["dojox.layout.ResizeHandle"]) { // _hasResource checks
// added by build. Do
// not use _hasResource
// directly in your
// code.
dojo._hasResource["dojox.layout.ResizeHandle"] = true;
dojo.provide("dojox.layout.ResizeHandle");
dojo.experimental("dojox.layout.ResizeHandle");
dojo.require("dijit._Widget");
dojo.require("dijit._Templated");
dojo.require("dojo.fx");
dojo.declare("dojox.layout.ResizeHandle",
[dijit._Widget, dijit._Templated], {
// summary
// The handle on the bottom-right corner of FloatingPane or
// other widgets that allows
// the widget to be resized.
// Typically not used directly.
// targetId: String
// id of the Widget OR DomNode that I will size
targetId : '',
// targetContainer: DomNode
// over-ride targetId and attch this handle directly to a
// reference of a DomNode
targetContainer : null,
// resizeAxis: String
// one of: x|y|xy limit resizing to a single axis, default to xy
// ...
resizeAxis : "xy",
// activeResize: Boolean
// if true, node will size realtime with mouse movement,
// if false, node will create virtual node, and only resize
// target on mouseUp
activeResize : false,
// activeResizeClass: String
// css class applied to virtual resize node.
activeResizeClass : 'dojoxResizeHandleClone',
// animateSizing: Boolean
// only applicable if activeResize = false. onMouseup, animate
// the node to the
// new size
animateSizing : true,
// animateMethod: String
// one of "chain" or "combine" ... visual effect only. combine
// will "scale"
// node to size, "chain" will alter width, then height
animateMethod : 'chain',
// animateDuration: Integer
// time in MS to run sizing animation. if animateMethod="chain",
// total animation
// playtime is 2*animateDuration
animateDuration : 225,
// minHeight: Integer
// smallest height in px resized node can be
minHeight : 100,
// minWidth: Integer
// smallest width in px resize node can be
minWidth : 100,
// resize handle template, fairly easy to override:
templateString : '
',
// private propteries and holders
_isSizing : false,
_connects : [],
_activeResizeNode : null,
_activeResizeLastEvent : null,
// defaults to match default resizeAxis. set resizeAxis variable
// to modify.
_resizeX : true,
_resizeY : true,
postCreate : function() {
// summary: setup our one major listener upon creation
dojo.connect(this.resizeHandle, "onmousedown", this,
"_beginSizing");
if (!this.activeResize) {
this._activeResizeNode = document.createElement('div');
dojo.addClass(this._activeResizeNode,
this.activeResizeClass);
} else {
this.animateSizing = false;
}
if (!this.minSize) {
this.minSize = {
w : this.minWidth,
h : this.minHeight
};
}
// should we modify the css for the cursor hover to n-resize
// nw-resize and w-resize?
this._resizeX = this._resizeY = false;
switch (this.resizeAxis.toLowerCase()) {
case "xy" :
this._resizeX = this._resizeY = true;
// FIXME: need logic to determine NW or NE class to
// see
// based on which [todo] corner is clicked
dojo.addClass(this.resizeHandle, "dojoxResizeNW");
break;
case "x" :
this._resizeX = true;
dojo.addClass(this.resizeHandle, "dojoxResizeW");
break;
case "y" :
this._resizeY = true;
dojo.addClass(this.resizeHandle, "dojoxResizeN");
break;
}
},
_beginSizing : function(/* Event */e) {
// summary: setup movement listeners and calculate initial
// size
if (this._isSizing) {
return false;
}
this.targetWidget = dijit.byId(this.targetId);
// FIXME: resizing widgets does weird things, disable
// virtual resizing for now:
if (this.targetWidget) {
this.activeResize = true;
}
this.targetDomNode = this.targetWidget
? this.targetWidget.domNode
: dojo.byId(this.targetId);
if (this.targetContainer) {
this.targetDomNode = this.targetContainer;
}
if (!this.targetDomNode) {
return;
}
if (!this.activeResize) {
this.targetDomNode.appendChild(this._activeResizeNode);
dojo.fadeIn({
node : this._activeResizeNode,
duration : 120,
beforeBegin : dojo.hitch(this, function() {
this._activeResizeNode.style.display = '';
})
}).play();
}
this._isSizing = true;
this.startPoint = {
'x' : e.clientX,
'y' : e.clientY
};
// FIXME: this is funky: marginBox adds height, contentBox
// ignores padding (expected, but foo!)
var mb = (this.targetWidget) ? dojo
.marginBox(this.targetDomNode) : dojo
.contentBox(this.targetDomNode);
this.startSize = {
'w' : mb.w,
'h' : mb.h
};
this._connects = [];
this._connects.push(dojo.connect(document, "onmousemove",
this, "_updateSizing"));
this._connects.push(dojo.connect(document, "onmouseup",
this, "_endSizing"));
e.preventDefault();
},
_updateSizing : function(/* Event */e) {
// summary: called when moving the ResizeHandle ...
// determines
// new size based on settings/position and sets styles.
if (this.activeResize) {
this._changeSizing(e);
} else {
var tmp = this._getNewCoords(e);
if (tmp === false) {
return;
}
dojo.style(this._activeResizeNode, "width", tmp.width
+ "px");
dojo.style(this._activeResizeNode, "height", tmp.height
+ "px");
this._activeResizeNode.style.display = '';
}
},
_getNewCoords : function(/* Event */e) {
// On IE, if you move the mouse above/to the left of the
// object being resized,
// sometimes clientX/Y aren't set, apparently. Just ignore
// the event.
try {
if (!e.clientX || !e.clientY) {
return false;
}
} catch (e) {
// sometimes you get an exception accessing above
// fields...
return false;
}
this._activeResizeLastEvent = e;
var dx = this.startPoint.x - e.clientX;
var dy = this.startPoint.y - e.clientY;
var newW = (this._resizeX)
? this.startSize.w - dx
: this.startSize.w;
var newH = (this._resizeY)
? this.startSize.h - dy
: this.startSize.h;
// minimum size check
if (this.minSize) {
// var mb = dojo.marginBox(this.targetDomNode);
if (newW < this.minSize.w) {
newW = this.minSize.w;
}
if (newH < this.minSize.h) {
newH = this.minSize.h;
}
}
return {
width : newW,
height : newH
}; // Object
},
_changeSizing : function(/* Event */e) {
// summary: apply sizing information based on information in
// (e) to attached node
var tmp = this._getNewCoords(e);
if (tmp === false) {
return;
}
if (this.targetWidget
&& typeof this.targetWidget.resize == "function") {
this.targetWidget.resize({
w : tmp.width,
h : tmp.height
});
} else {
if (this.animateSizing) {
var anim = dojo.fx[this.animateMethod]([
dojo.animateProperty({
node : this.targetDomNode,
properties : {
width : {
start : this.startSize.w,
end : tmp.width,
unit : 'px'
}
},
duration : this.animateDuration
}), dojo.animateProperty({
node : this.targetDomNode,
properties : {
height : {
start : this.startSize.h,
end : tmp.height,
unit : 'px'
}
},
duration : this.animateDuration
})]);
anim.play();
} else {
dojo.style(this.targetDomNode, "width", tmp.width
+ "px");
dojo.style(this.targetDomNode, "height", tmp.height
+ "px");
}
}
e.preventDefault();
},
_endSizing : function(/* Event */e) {
// summary: disconnect listenrs and cleanup sizing
dojo.forEach(this._connects, function(c) {
dojo.disconnect(c);
});
if (!this.activeResize) {
dojo.fadeOut({
node : this._activeResizeNode,
duration : 250,
onEnd : dojo.hitch(this, function() {
this._activeResizeNode.style.display = "none";
})
}).play();
this._changeSizing(e);
}
this._isSizing = false;
}
});
}