define("dijit/layout/_LayoutWidget", [ "dojo/_base/lang", // lang.mixin "../_Widget", "../_Container", "../_Contained", "dojo/_base/declare", // declare "dojo/dom-class", // domClass.add domClass.remove "dojo/dom-geometry", // domGeometry.marginBox "dojo/dom-style", // domStyle.getComputedStyle "dojo/_base/sniff", // has("ie") "dojo/_base/window" // win.global ], function(lang, _Widget, _Container, _Contained, declare, domClass, domGeometry, domStyle, has, win){ /*===== var _Widget = dijit._Widget; var _Container = dijit._Container; var _Contained = dijit._Contained; =====*/ // module: // dijit/layout/_LayoutWidget // summary: // _LayoutWidget Base class for a _Container widget which is responsible for laying out its children. // Widgets which mixin this code must define layout() to manage placement and sizing of the children. return declare("dijit.layout._LayoutWidget", [_Widget, _Container, _Contained], { // summary: // Base class for a _Container widget which is responsible for laying out its children. // Widgets which mixin this code must define layout() to manage placement and sizing of the children. // baseClass: [protected extension] String // This class name is applied to the widget's domNode // and also may be used to generate names for sub nodes, // for example dijitTabContainer-content. baseClass: "dijitLayoutContainer", // isLayoutContainer: [protected] Boolean // Indicates that this widget is going to call resize() on its // children widgets, setting their size, when they become visible. isLayoutContainer: true, buildRendering: function(){ this.inherited(arguments); domClass.add(this.domNode, "dijitContainer"); }, startup: function(){ // summary: // Called after all the widgets have been instantiated and their // dom nodes have been inserted somewhere under win.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; } // Need to call inherited first - so that child widgets get started // up correctly this.inherited(arguments); // If I am a not being controlled by a parent layout widget... var parent = this.getParent && this.getParent(); if(!(parent && parent.isLayoutContainer)){ // 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 *may be* width=height=100% // or something similar (either set directly or via a CSS class), // monitor when viewport size changes so that I can re-layout. this.connect(win.global, 'onresize', function(){ // Using function(){} closure to ensure no arguments passed to resize(). this.resize(); }); } }, resize: function(changeSize, resultSize){ // summary: // Call this to resize a widget, or after its size has changed. // description: // Change size mode: // When changeSize is specified, changes the marginBox of this widget // and forces it to relayout its contents accordingly. // changeSize may specify height, width, or both. // // If resultSize is specified it indicates the size the widget will // become after changeSize has been applied. // // Notification mode: // When changeSize is null, indicates that the caller has already changed // the size of the widget, or perhaps it changed because the browser // window was resized. Tells widget to relayout its contents accordingly. // // If resultSize is also specified it indicates the size the widget has // become. // // In either mode, this method also: // 1. Sets this._borderBox and this._contentBox to the new size of // the widget. Queries the current domNode size if necessary. // 2. Calls layout() to resize contents (and maybe adjust child widgets). // // changeSize: Object? // Sets the widget to this margin-box size and position. // May include any/all of the following properties: // | {w: int, h: int, l: int, t: int} // // resultSize: Object? // The margin-box size of this widget after applying changeSize (if // changeSize is specified). If caller knows this size and // passes it in, we don't need to query the browser to get the size. // | {w: int, h: int} var node = this.domNode; // set margin box size, unless it wasn't specified, in which case use current size if(changeSize){ domGeometry.setMarginBox(node, changeSize); } // 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 = resultSize || {}; lang.mixin(mb, changeSize || {}); // changeSize overrides resultSize if( !("h" in mb) || !("w" in mb) ){ mb = lang.mixin(domGeometry.getMarginBox(node), mb); // just use domGeometry.marginBox() to fill in missing values } // Compute and save the size of my border box and content box // (w/out calling domGeometry.getContentBox() since that may fail if size was recently set) var cs = domStyle.getComputedStyle(node); var me = domGeometry.getMarginExtents(node, cs); var be = domGeometry.getBorderExtents(node, cs); var bb = (this._borderBox = { w: mb.w - (me.w + be.w), h: mb.h - (me.h + be.h) }); var pe = domGeometry.getPadExtents(node, cs); this._contentBox = { l: domStyle.toPixelValue(node, cs.paddingLeft), t: domStyle.toPixelValue(node, cs.paddingTop), w: bb.w - pe.w, h: bb.h - pe.h }; // Callback for widget to adjust size of its children this.layout(); }, layout: function(){ // summary: // Widgets override this method to size and 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. // tags: // protected extension }, _setupChild: function(/*dijit._Widget*/child){ // summary: // Common setup for initial children and children which are added after startup // tags: // protected extension var cls = this.baseClass + "-child " + (child.baseClass ? this.baseClass + "-" + child.baseClass : ""); domClass.add(child.domNode, cls); }, addChild: function(/*dijit._Widget*/ child, /*Integer?*/ insertIndex){ // Overrides _Container.addChild() to call _setupChild() this.inherited(arguments); if(this._started){ this._setupChild(child); } }, removeChild: function(/*dijit._Widget*/ child){ // Overrides _Container.removeChild() to remove class added by _setupChild() var cls = this.baseClass + "-child" + (child.baseClass ? " " + this.baseClass + "-" + child.baseClass : ""); domClass.remove(child.domNode, cls); this.inherited(arguments); } }); });