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 // document.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; } this._started = true; if (this.getChildren) { 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(); }); } }, 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 || {}); // 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
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); } }); }; })(); }