diff options
Diffstat (limited to 'includes/js/dijit/layout/_LayoutWidget.js')
-rw-r--r-- | includes/js/dijit/layout/_LayoutWidget.js | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/includes/js/dijit/layout/_LayoutWidget.js b/includes/js/dijit/layout/_LayoutWidget.js new file mode 100644 index 0000000..3877802 --- /dev/null +++ b/includes/js/dijit/layout/_LayoutWidget.js @@ -0,0 +1,188 @@ +if(!dojo._hasResource["dijit.layout._LayoutWidget"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit.layout._LayoutWidget"] = true; +dojo.provide("dijit.layout._LayoutWidget"); + +dojo.require("dijit._Widget"); +dojo.require("dijit._Container"); + +dojo.declare("dijit.layout._LayoutWidget", + [dijit._Widget, dijit._Container, dijit._Contained], + { + // summary + // Mixin for widgets that contain a list of children like SplitContainer. + // Widgets which mixin this code must define layout() to lay out the children + + isLayoutContainer: true, + + postCreate: function(){ + dojo.addClass(this.domNode, "dijitContainer"); + }, + + startup: function(){ + // summary: + // Called after all the widgets have been instantiated and their + // dom nodes have been inserted somewhere under dojo.doc.body. + // + // Widgets should override this method to do any initialization + // dependent on other widgets existing, and then call + // this superclass method to finish things off. + // + // startup() in subclasses shouldn't do anything + // size related because the size of the widget hasn't been set yet. + + if(this._started){ return; } + + dojo.forEach(this.getChildren(), function(child){ child.startup(); }); + + // If I am a top level widget + if(!this.getParent || !this.getParent()){ + // Do recursive sizing and layout of all my descendants + // (passing in no argument to resize means that it has to glean the size itself) + this.resize(); + + // since my parent isn't a layout container, and my style is width=height=100% (or something similar), + // then I need to watch when the window resizes, and size myself accordingly + // (passing in no argument to resize means that it has to glean the size itself) + this.connect(window, 'onresize', function(){this.resize();}); + } + + this.inherited(arguments); + }, + + resize: function(args){ + // summary: + // Explicitly set this widget's size (in pixels), + // and then call layout() to resize contents (and maybe adjust child widgets) + // + // args: Object? + // {w: int, h: int, l: int, t: int} + + var node = this.domNode; + + // set margin box size, unless it wasn't specified, in which case use current size + if(args){ + dojo.marginBox(node, args); + + // set offset of the node + if(args.t){ node.style.top = args.t + "px"; } + if(args.l){ node.style.left = args.l + "px"; } + } + // If either height or width wasn't specified by the user, then query node for it. + // But note that setting the margin box and then immediately querying dimensions may return + // inaccurate results, so try not to depend on it. + var mb = dojo.mixin(dojo.marginBox(node), args||{}); + +// console.log(this, ": setting size to ", mb); + + // Save the size of my content box. + this._contentBox = dijit.layout.marginBox2contentBox(node, mb); + + // Callback for widget to adjust size of it's children + this.layout(); + }, + + layout: function(){ + // summary + // Widgets override this method to size & position their contents/children. + // When this is called this._contentBox is guaranteed to be set (see resize()). + // + // This is called after startup(), and also when the widget's size has been + // changed. + } + } +); + +dijit.layout.marginBox2contentBox = function(/*DomNode*/ node, /*Object*/ mb){ + // summary: + // Given the margin-box size of a node, return it's content box size. + // Functions like dojo.contentBox() but is more reliable since it doesn't have + // to wait for the browser to compute sizes. + var cs = dojo.getComputedStyle(node); + var me=dojo._getMarginExtents(node, cs); + var pb=dojo._getPadBorderExtents(node, cs); + return { + l: dojo._toPixelValue(node, cs.paddingLeft), + t: dojo._toPixelValue(node, cs.paddingTop), + w: mb.w - (me.w + pb.w), + h: mb.h - (me.h + pb.h) + }; +}; + +(function(){ + var capitalize = function(word){ + return word.substring(0,1).toUpperCase() + word.substring(1); + }; + + var size = function(widget, dim){ + // size the child + widget.resize ? widget.resize(dim) : dojo.marginBox(widget.domNode, dim); + + // record child's size, but favor our own numbers when we have them. + // the browser lies sometimes + dojo.mixin(widget, dojo.marginBox(widget.domNode)); + dojo.mixin(widget, dim); + }; + + dijit.layout.layoutChildren = function(/*DomNode*/ container, /*Object*/ dim, /*Object[]*/ children){ + /** + * summary + * Layout a bunch of child dom nodes within a parent dom node + * container: + * parent node + * dim: + * {l, t, w, h} object specifying dimensions of container into which to place children + * children: + * an array like [ {domNode: foo, layoutAlign: "bottom" }, {domNode: bar, layoutAlign: "client"} ] + */ + + // copy dim because we are going to modify it + dim = dojo.mixin({}, dim); + + dojo.addClass(container, "dijitLayoutContainer"); + + // Move "client" elements to the end of the array for layout. a11y dictates that the author + // needs to be able to put them in the document in tab-order, but this algorithm requires that + // client be last. + children = dojo.filter(children, function(item){ return item.layoutAlign != "client"; }) + .concat(dojo.filter(children, function(item){ return item.layoutAlign == "client"; })); + + // set positions/sizes + dojo.forEach(children, function(child){ + var elm = child.domNode, + pos = child.layoutAlign; + + // set elem to upper left corner of unused space; may move it later + var elmStyle = elm.style; + elmStyle.left = dim.l+"px"; + elmStyle.top = dim.t+"px"; + elmStyle.bottom = elmStyle.right = "auto"; + + dojo.addClass(elm, "dijitAlign" + capitalize(pos)); + + // set size && adjust record of remaining space. + // note that setting the width of a <div> may affect it's height. + if(pos=="top" || pos=="bottom"){ + size(child, { w: dim.w }); + dim.h -= child.h; + if(pos=="top"){ + dim.t += child.h; + }else{ + elmStyle.top = dim.t + dim.h + "px"; + } + }else if(pos=="left" || pos=="right"){ + size(child, { h: dim.h }); + dim.w -= child.w; + if(pos=="left"){ + dim.l += child.w; + }else{ + elmStyle.left = dim.l + dim.w + "px"; + } + }else if(pos=="client"){ + size(child, dim); + } + }); + }; + +})(); + +} |