if (!dojo._hasResource["dojox.layout.FloatingPane"]) { // _hasResource checks // added by build. Do // not use _hasResource // directly in your // code. dojo._hasResource["dojox.layout.FloatingPane"] = true; dojo.provide("dojox.layout.FloatingPane"); dojo.experimental("dojox.layout.FloatingPane"); dojo.require("dojox.layout.ContentPane"); dojo.require("dijit._Templated"); dojo.require("dijit._Widget"); dojo.require("dojo.dnd.move"); dojo.require("dojox.layout.ResizeHandle"); dojo.declare("dojox.layout.FloatingPane", [dojox.layout.ContentPane, dijit._Templated], { // summary: // // Makes a dijit.ContentPane float and draggable by it's title // [similar to TitlePane] // and over-rides onClick to onDblClick for wipeIn/Out of // containerNode // provides minimize(dock) / show() and hide() methods, and // resize [almost] // closable: Boolean // allow closure of this Node closable : true, // dockable: Boolean // allow minimizing of pane true/false dockable : true, // resizable: Boolean // allow resizing of pane true/false resizable : false, // maxable: Boolean // horrible param name for "Can you maximize this floating pane" maxable : false, // resizeAxis: String // x | xy | y to limit pane's sizing direction resizeAxis : "xy", // title: String // title to put in titlebar title : "", // dockTo: DomNode || null // if null, will create private layout.Dock that scrolls with // viewport // on bottom span of viewport. dockTo : null, // duration: Integer // time is MS to spend toggling in/out node duration : 400, // animation holders for toggle _showAnim : null, _hideAnim : null, // node in the dock (if docked) _dockNode : null, // iconSrc: String // [not implemented yet] will be either icon in titlepane to // left // of Title, and/or icon show when docked in a fisheye-like dock // or maybe dockIcon would be better? iconSrc : null, contentClass : "dojoxFloatingPaneContent", templateString : null, templateString : "
\n\t
\n\t\t\n\t\t\n\t\t\t\n\t\t\n\t\t\n\t
\n\t
\n\t\t
\n\t\t
\n\t\t\n\t
\n
\n", _restoreState : {}, _allFPs : [], postCreate : function() { // summary: this.setTitle(this.title); this.inherited("postCreate", arguments); var move = new dojo.dnd.Moveable(this.domNode, { handle : this.focusNode }); // this._listener = // dojo.subscribe("/dnd/move/start",this,"bringToTop"); if (!this.dockable) { this.dockNode.style.display = "none"; } if (!this.closable) { this.closeNode.style.display = "none"; } if (!this.maxable) { this.maxNode.style.display = "none"; this.restoreNode.style.display = "none"; } if (!this.resizable) { this.resizeHandle.style.display = "none"; } else { var foo = dojo.marginBox(this.domNode); this.domNode.style.width = foo.w + "px"; } this._allFPs.push(this); }, startup : function() { this.inherited("startup", arguments); if (this.resizable) { if (dojo.isIE) { this.canvas.style.overflow = "auto"; } else { this.containerNode.style.overflow = "auto"; } var tmp = new dojox.layout.ResizeHandle({ // targetContainer: this.containerNode, targetId : this.id, resizeAxis : this.resizeAxis }, this.resizeHandle); } if (this.dockable) { // FIXME: argh. tmpName = this.dockTo; if (this.dockTo) { this.dockTo = dijit.byId(this.dockTo); } else { this.dockTo = dijit.byId('dojoxGlobalFloatingDock'); } if (!this.dockTo) { // we need to make our dock node, and position it // against // .dojoxDockDefault .. this is a lot. either // dockto="node" // and fail if node doesn't exist or make the global // one // once, and use it on empty OR invalid dockTo="" // node? if (tmpName) { var tmpId = tmpName; var tmpNode = dojo.byId(tmpName); } else { var tmpNode = document.createElement('div'); dojo.body().appendChild(tmpNode); dojo.addClass(tmpNode, "dojoxFloatingDockDefault"); var tmpId = 'dojoxGlobalFloatingDock'; } this.dockTo = new dojox.layout.Dock({ id : tmpId, autoPosition : "south" }, tmpNode); this.dockTo.startup(); } if ((this.domNode.style.display == "none") || (this.domNode.style.visibility == "hidden")) { // If the FP is created dockable and non-visible, // start up docked. this.minimize(); } } this.connect(this.focusNode, "onmousedown", "bringToTop"); this.connect(this.domNode, "onmousedown", "bringToTop"); }, setTitle : function(/* String */title) { // summary: Update the string in the titleNode this.titleNode.innerHTML = title; }, close : function() { // summary: close and destroy this widget if (!this.closable) { return; } dojo.unsubscribe(this._listener); this.hide(dojo.hitch(this, "destroy")); }, hide : function(/* Function? */callback) { // summary: close but do not destroy this widget dojo.fadeOut({ node : this.domNode, duration : this.duration, onEnd : dojo.hitch(this, function() { this.domNode.style.display = "none"; this.domNode.style.visibility = "hidden"; if (this.dockTo) { this.dockTo._positionDock(null); } if (callback) { callback(); } }) }).play(); }, show : function(/* Function? */callback) { // summary: show the FloatingPane var anim = dojo.fadeIn({ node : this.domNode, duration : this.duration, beforeBegin : dojo.hitch(this, function() { this.domNode.style.display = ""; this.domNode.style.visibility = "visible"; this.dockTo._positionDock(null); if (this.dockTo) { this.dockTo._positionDock(null); } if (typeof callback == "function") { callback(); } this._isDocked = false; if (this._dockNode) { this._dockNode.destroy(); this._dockNode = null; } }) }).play(); this.resize(dojo.coords(this.domNode)); }, minimize : function() { // summary: hide and dock the FloatingPane if (!this._isDocked) { this.hide(dojo.hitch(this, "_dock")); } }, maximize : function() { // summary: Make this floatingpane fullscreen (viewport) if (this._maximized) { return; } this._naturalState = dojo.coords(this.domNode); if (this._isDocked) { this.show(); setTimeout(dojo.hitch(this, "maximize"), this.duration); } dojo.addClass(this.focusNode, "floatingPaneMaximized"); this.resize(dijit.getViewport()); this._maximized = true; }, _restore : function() { if (this._maximized) { this.resize(this._naturalState); dojo.removeClass(this.focusNode, "floatingPaneMaximized"); this._maximized = false; } }, _dock : function() { if (!this._isDocked) { this._dockNode = this.dockTo.addNode(this); this._isDocked = true; } }, resize : function(/* Object */dim) { // summary: size the widget and place accordingly this._currentState = dim; var dns = this.domNode.style; dns.top = dim.t + "px"; dns.left = dim.l + "px"; dns.width = dim.w + "px"; this.canvas.style.width = dim.w + "px"; dns.height = dim.h + "px"; this.canvas.style.height = (dim.h - this.focusNode.offsetHeight) + "px"; }, _startZ : 100, bringToTop : function() { // summary: bring this FloatingPane above all other panes var windows = dojo.filter(this._allFPs, function(i) { return i !== this; }, this); windows.sort(function(a, b) { return a.domNode.style.zIndex - b.domNode.style.zIndex; }); windows.push(this); dojo.forEach(windows, function(w, x) { w.domNode.style.zIndex = (this._startZ + x * 2); dojo.removeClass(w.domNode, "dojoxFloatingPaneFg"); }, this); dojo.addClass(this.domNode, "dojoxFloatingPaneFg"); }, destroy : function() { // summary: Destroy this FloatingPane completely this._allFPs.splice(dojo.indexOf(this._allFPs, this), 1); this.inherited("destroy", arguments); } }); dojo.declare("dojox.layout.Dock", [dijit._Widget, dijit._Templated], { // summary: // a widget that attaches to a node and keeps track of incoming / // outgoing FloatingPanes // and handles layout templateString : '
', // private _docked: array of panes currently in our dock _docked : [], _inPositioning : false, autoPosition : false, addNode : function(refNode) { // summary: instert a dockNode refernce into the dock var div = document.createElement('li'); this.containerNode.appendChild(div); var node = new dojox.layout._DockNode({ title : refNode.title, paneRef : refNode }, div); node.startup(); return node; }, startup : function() { // summary: attaches some event listeners if (this.id == "dojoxGlobalFloatingDock" || this.isFixedDock) { // attach window.onScroll, and a position like in // presentation/dialog dojo.connect(window, 'onresize', this, "_positionDock"); dojo.connect(window, 'onscroll', this, "_positionDock"); if (dojo.isIE) { dojo.connect(this.domNode, 'onresize', this, "_positionDock"); } } this._positionDock(null); this.inherited("startup", arguments); }, _positionDock : function(/* Event? */e) { if (!this._inPositioning) { if (this.autoPosition == "south") { // Give some time for scrollbars to appear/disappear setTimeout(dojo.hitch(this, function() { this._inPositiononing = true; var viewport = dijit.getViewport(); var s = this.domNode.style; s.left = viewport.l + "px"; s.width = (viewport.w - 2) + "px"; s.top = (viewport.h + viewport.t) - this.domNode.offsetHeight + "px"; this._inPositioning = false; }), 500); } } } }); dojo.declare("dojox.layout._DockNode", [dijit._Widget, dijit._Templated], { // summary: // dojox.layout._DockNode is a private widget used to keep track of // which pane is docked. // title: String // shown in dock icon. should read parent iconSrc? title : "", // paneRef: Widget // reference to the FloatingPane we reprasent in any given dock paneRef : null, templateString : '
  • ' + '' + '${title}' + '
  • ', restore : function() { // summary: remove this dock item from parent dock, and call show() // on reffed floatingpane this.paneRef.show(); this.paneRef.bringToTop(); this.destroy(); } }); }