diff options
Diffstat (limited to 'js/dojo/dojox/layout/ExpandoPane.js')
| -rw-r--r-- | js/dojo/dojox/layout/ExpandoPane.js | 291 |
1 files changed, 291 insertions, 0 deletions
diff --git a/js/dojo/dojox/layout/ExpandoPane.js b/js/dojo/dojox/layout/ExpandoPane.js new file mode 100644 index 0000000..e370bf2 --- /dev/null +++ b/js/dojo/dojox/layout/ExpandoPane.js @@ -0,0 +1,291 @@ +//>>built +require({cache:{ +'url:dojox/layout/resources/ExpandoPane.html':"<div class=\"dojoxExpandoPane\">\n\t<div dojoAttachPoint=\"titleWrapper\" class=\"dojoxExpandoTitle\">\n\t\t<div class=\"dojoxExpandoIcon\" dojoAttachPoint=\"iconNode\" dojoAttachEvent=\"onclick:toggle\"><span class=\"a11yNode\">X</span></div>\t\t\t\n\t\t<span class=\"dojoxExpandoTitleNode\" dojoAttachPoint=\"titleNode\">${title}</span>\n\t</div>\n\t<div class=\"dojoxExpandoWrapper\" dojoAttachPoint=\"cwrapper\" dojoAttachEvent=\"ondblclick:_trap\">\n\t\t<div class=\"dojoxExpandoContent\" dojoAttachPoint=\"containerNode\"></div>\n\t</div>\n</div>\n"}}); +define("dojox/layout/ExpandoPane", ["dojo/_base/kernel","dojo/_base/lang","dojo/_base/declare","dojo/_base/array", + "dojo/_base/connect","dojo/_base/event","dojo/_base/fx","dojo/dom-style", + "dojo/dom-class","dojo/dom-geometry","dojo/text!./resources/ExpandoPane.html", + "dijit/layout/ContentPane","dijit/_TemplatedMixin","dijit/_Contained","dijit/_Container"], + function(kernel,lang,declare,arrayUtil,connectUtil,eventUtil,baseFx,domStyle,domClass,domGeom, + template,ContentPane,TemplatedMixin,Contained,Container) { +/*===== +var ContentPane = dijit.layout.ContentPane; +var TemplatedMixin = dijit._TemplatedMixin; +var Contained = dijit._Contained; +var Container = dijit._Container; + =====*/ +kernel.experimental("dojox.layout.ExpandoPane"); // just to show it can be done? + +return declare("dojox.layout.ExpandoPane", [ContentPane, TemplatedMixin, Contained, Container],{ + // summary: An experimental collapsing-pane for dijit.layout.BorderContainer + // + // description: + // Works just like a ContentPane inside of a borderContainer. Will expand/collapse on + // command, and supports having Layout Children as direct descendants + // + + //maxHeight: "", + //maxWidth: "", + //splitter: false, + attributeMap: lang.delegate(ContentPane.prototype.attributeMap, { + title: { node: "titleNode", type: "innerHTML" } + }), + + templateString: template, + + // easeOut: String|Function + // easing function used to hide pane + easeOut: "dojo._DefaultEasing", // FIXME: This won't work with globalless AMD + + // easeIn: String|Function + // easing function use to show pane + easeIn: "dojo._DefaultEasing", // FIXME: This won't work with globalless AMD + + // duration: Integer + // duration to run show/hide animations + duration: 420, + + // startExpanded: Boolean + // Does this widget start in an open (true) or closed (false) state + startExpanded: true, + + // previewOpacity: Float + // A value from 0 .. 1 indicating the opacity to use on the container + // when only showing a preview + previewOpacity: 0.75, + + // previewOnDblClick: Boolean + // If true, will override the default behavior of a double-click calling a full toggle. + // If false, a double-click will cause the preview to popup + previewOnDblClick: false, + + baseClass: "dijitExpandoPane", + + postCreate: function(){ + this.inherited(arguments); + this._animConnects = []; + + this._isHorizontal = true; + + if(lang.isString(this.easeOut)){ + this.easeOut = lang.getObject(this.easeOut); + } + if(lang.isString(this.easeIn)){ + this.easeIn = lang.getObject(this.easeIn); + } + + var thisClass = "", rtl = !this.isLeftToRight(); + if(this.region){ + switch(this.region){ + case "trailing" : + case "right" : + thisClass = rtl ? "Left" : "Right"; + break; + case "leading" : + case "left" : + thisClass = rtl ? "Right" : "Left"; + break; + case "top" : + thisClass = "Top"; + break; + case "bottom" : + thisClass = "Bottom"; + break; + } + domClass.add(this.domNode, "dojoxExpando" + thisClass); + domClass.add(this.iconNode, "dojoxExpandoIcon" + thisClass); + this._isHorizontal = /top|bottom/.test(this.region); + } + domStyle.set(this.domNode, { + overflow: "hidden", + padding:0 + }); + + this.connect(this.domNode, "ondblclick", this.previewOnDblClick ? "preview" : "toggle"); + + if(this.previewOnDblClick){ + this.connect(this.getParent(), "_layoutChildren", lang.hitch(this, function(){ + this._isonlypreview = false; + })); + } + + }, + + _startupSizes: function(){ + + this._container = this.getParent(); + this._closedSize = this._titleHeight = domGeom.getMarginBox(this.titleWrapper).h; + + if(this.splitter){ + // find our splitter and tie into it's drag logic + var myid = this.id; + arrayUtil.forEach(dijit.registry.toArray(), function(w){ + if(w && w.child && w.child.id == myid){ + this.connect(w,"_stopDrag","_afterResize"); + } + }, this); + } + + this._currentSize = domGeom.getContentBox(this.domNode); // TODO: can compute this from passed in value to resize(), see _LayoutWidget for example + this._showSize = this._currentSize[(this._isHorizontal ? "h" : "w")]; + this._setupAnims(); + + if(this.startExpanded){ + this._showing = true; + }else{ + this._showing = false; + this._hideWrapper(); + this._hideAnim.gotoPercent(99,true); + } + + this._hasSizes = true; + }, + + _afterResize: function(e){ + var tmp = this._currentSize; // the old size + this._currentSize = domGeom.getMarginBox(this.domNode); // the new size + var n = this._currentSize[(this._isHorizontal ? "h" : "w")] + if(n > this._titleHeight){ + if(!this._showing){ + this._showing = !this._showing; + this._showEnd(); + } + this._showSize = n; + this._setupAnims(); + }else{ + this._showSize = tmp[(this._isHorizontal ? "h" : "w")]; + this._showing = false; + this._hideWrapper(); + this._hideAnim.gotoPercent(89,true); + } + + }, + + _setupAnims: function(){ + // summary: Create the show and hide animations + arrayUtil.forEach(this._animConnects, connectUtil.disconnect); + + var _common = { + node:this.domNode, + duration:this.duration + }, + isHorizontal = this._isHorizontal, + showProps = {}, + hideProps = {}, + dimension = isHorizontal ? "height" : "width" + ; + + showProps[dimension] = { + end: this._showSize + }; + hideProps[dimension] = { + end: this._closedSize + }; + + this._showAnim = baseFx.animateProperty(lang.mixin(_common,{ + easing:this.easeIn, + properties: showProps + })); + this._hideAnim = baseFx.animateProperty(lang.mixin(_common,{ + easing:this.easeOut, + properties: hideProps + })); + + this._animConnects = [ + connectUtil.connect(this._showAnim, "onEnd", this, "_showEnd"), + connectUtil.connect(this._hideAnim, "onEnd", this, "_hideEnd") + ]; + }, + + preview: function(){ + // summary: Expand this pane in preview mode (does not affect surrounding layout) + + if(!this._showing){ + this._isonlypreview = !this._isonlypreview; + } + this.toggle(); + }, + + toggle: function(){ + // summary: Toggle this pane's visibility + if(this._showing){ + this._hideWrapper(); + this._showAnim && this._showAnim.stop(); + this._hideAnim.play(); + }else{ + this._hideAnim && this._hideAnim.stop(); + this._showAnim.play(); + } + this._showing = !this._showing; + }, + + _hideWrapper: function(){ + // summary: Set the Expando state to "closed" + domClass.add(this.domNode, "dojoxExpandoClosed"); + + domStyle.set(this.cwrapper,{ + visibility: "hidden", + opacity: "0", + overflow: "hidden" + }); + }, + + _showEnd: function(){ + // summary: Common animation onEnd code - "unclose" + domStyle.set(this.cwrapper, { + opacity: 0, + visibility:"visible" + }); + baseFx.anim(this.cwrapper, { + opacity: this._isonlypreview ? this.previewOpacity : 1 + }, 227); + domClass.remove(this.domNode, "dojoxExpandoClosed"); + if(!this._isonlypreview){ + setTimeout(lang.hitch(this._container, "layout"), 15); + }else{ + this._previewShowing = true; + this.resize(); + } + }, + + _hideEnd: function(){ + // summary: Callback for the hide animation - "close" + + // every time we hide, reset the "only preview" state + if(!this._isonlypreview){ + setTimeout(lang.hitch(this._container, "layout"), 25); + }else{ + this._previewShowing = false; + } + this._isonlypreview = false; + + }, + + resize: function(/* Object? */newSize){ + // summary: + // we aren't a layout widget, but need to act like one: + // newSize: Object + // The size object to resize to + + if(!this._hasSizes){ this._startupSizes(newSize); } + + // compute size of container (ie, size left over after title bar) + var currentSize = domGeom.getMarginBox(this.domNode); + this._contentBox = { + w: newSize && "w" in newSize ? newSize.w : currentSize.w, + h: (newSize && "h" in newSize ? newSize.h : currentSize.h) - this._titleHeight + }; + domStyle.set(this.containerNode, "height", this._contentBox.h + "px"); + + if(newSize){ + domGeom.setMarginBox(this.domNode, newSize); + } + + this._layoutChildren(); + }, + + _trap: function(e){ + // summary: Trap stray events + eventUtil.stop(e); + } +}); +}); |
