New file |
0,0 → 1,239 |
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: '<div dojoAttachPoint="resizeHandle" class="dojoxResizeHandle"><div></div></div>', |
|
// 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; |
} |
|
}); |
|
} |