[483] | 1 | define([ |
---|
| 2 | "dojo/_base/lang", // lang.mixin |
---|
| 3 | "../_Widget", |
---|
| 4 | "../_Container", |
---|
| 5 | "../_Contained", |
---|
| 6 | "../Viewport", |
---|
| 7 | "dojo/_base/declare", // declare |
---|
| 8 | "dojo/dom-class", // domClass.add domClass.remove |
---|
| 9 | "dojo/dom-geometry", // domGeometry.marginBox |
---|
| 10 | "dojo/dom-style" // domStyle.getComputedStyle |
---|
| 11 | ], function(lang, _Widget, _Container, _Contained, Viewport, |
---|
| 12 | declare, domClass, domGeometry, domStyle){ |
---|
| 13 | |
---|
| 14 | // module: |
---|
| 15 | // dijit/layout/_LayoutWidget |
---|
| 16 | |
---|
| 17 | |
---|
| 18 | return declare("dijit.layout._LayoutWidget", [_Widget, _Container, _Contained], { |
---|
| 19 | // summary: |
---|
| 20 | // Base class for a _Container widget which is responsible for laying out its children. |
---|
| 21 | // Widgets which mixin this code must define layout() to manage placement and sizing of the children. |
---|
| 22 | |
---|
| 23 | // baseClass: [protected extension] String |
---|
| 24 | // This class name is applied to the widget's domNode |
---|
| 25 | // and also may be used to generate names for sub nodes, |
---|
| 26 | // for example dijitTabContainer-content. |
---|
| 27 | baseClass: "dijitLayoutContainer", |
---|
| 28 | |
---|
| 29 | // isLayoutContainer: [protected] Boolean |
---|
| 30 | // Indicates that this widget is going to call resize() on its |
---|
| 31 | // children widgets, setting their size, when they become visible. |
---|
| 32 | isLayoutContainer: true, |
---|
| 33 | |
---|
| 34 | buildRendering: function(){ |
---|
| 35 | this.inherited(arguments); |
---|
| 36 | domClass.add(this.domNode, "dijitContainer"); |
---|
| 37 | }, |
---|
| 38 | |
---|
| 39 | startup: function(){ |
---|
| 40 | // summary: |
---|
| 41 | // Called after all the widgets have been instantiated and their |
---|
| 42 | // dom nodes have been inserted somewhere under <body>. |
---|
| 43 | // |
---|
| 44 | // Widgets should override this method to do any initialization |
---|
| 45 | // dependent on other widgets existing, and then call |
---|
| 46 | // this superclass method to finish things off. |
---|
| 47 | // |
---|
| 48 | // startup() in subclasses shouldn't do anything |
---|
| 49 | // size related because the size of the widget hasn't been set yet. |
---|
| 50 | |
---|
| 51 | if(this._started){ return; } |
---|
| 52 | |
---|
| 53 | // Need to call inherited first - so that child widgets get started |
---|
| 54 | // up correctly |
---|
| 55 | this.inherited(arguments); |
---|
| 56 | |
---|
| 57 | // If I am a not being controlled by a parent layout widget... |
---|
| 58 | var parent = this.getParent && this.getParent(); |
---|
| 59 | if(!(parent && parent.isLayoutContainer)){ |
---|
| 60 | // Do recursive sizing and layout of all my descendants |
---|
| 61 | // (passing in no argument to resize means that it has to glean the size itself) |
---|
| 62 | this.resize(); |
---|
| 63 | |
---|
| 64 | // Since my parent isn't a layout container, and my style *may be* width=height=100% |
---|
| 65 | // or something similar (either set directly or via a CSS class), |
---|
| 66 | // monitor when viewport size changes so that I can re-layout. |
---|
| 67 | this.own(Viewport.on("resize", lang.hitch(this, "resize"))); |
---|
| 68 | } |
---|
| 69 | }, |
---|
| 70 | |
---|
| 71 | resize: function(changeSize, resultSize){ |
---|
| 72 | // summary: |
---|
| 73 | // Call this to resize a widget, or after its size has changed. |
---|
| 74 | // description: |
---|
| 75 | // ####Change size mode: |
---|
| 76 | // |
---|
| 77 | // When changeSize is specified, changes the marginBox of this widget |
---|
| 78 | // and forces it to re-layout its contents accordingly. |
---|
| 79 | // changeSize may specify height, width, or both. |
---|
| 80 | // |
---|
| 81 | // If resultSize is specified it indicates the size the widget will |
---|
| 82 | // become after changeSize has been applied. |
---|
| 83 | // |
---|
| 84 | // ####Notification mode: |
---|
| 85 | // |
---|
| 86 | // When changeSize is null, indicates that the caller has already changed |
---|
| 87 | // the size of the widget, or perhaps it changed because the browser |
---|
| 88 | // window was resized. Tells widget to re-layout its contents accordingly. |
---|
| 89 | // |
---|
| 90 | // If resultSize is also specified it indicates the size the widget has |
---|
| 91 | // become. |
---|
| 92 | // |
---|
| 93 | // In either mode, this method also: |
---|
| 94 | // |
---|
| 95 | // 1. Sets this._borderBox and this._contentBox to the new size of |
---|
| 96 | // the widget. Queries the current domNode size if necessary. |
---|
| 97 | // 2. Calls layout() to resize contents (and maybe adjust child widgets). |
---|
| 98 | // changeSize: Object? |
---|
| 99 | // Sets the widget to this margin-box size and position. |
---|
| 100 | // May include any/all of the following properties: |
---|
| 101 | // | {w: int, h: int, l: int, t: int} |
---|
| 102 | // resultSize: Object? |
---|
| 103 | // The margin-box size of this widget after applying changeSize (if |
---|
| 104 | // changeSize is specified). If caller knows this size and |
---|
| 105 | // passes it in, we don't need to query the browser to get the size. |
---|
| 106 | // | {w: int, h: int} |
---|
| 107 | |
---|
| 108 | var node = this.domNode; |
---|
| 109 | |
---|
| 110 | // set margin box size, unless it wasn't specified, in which case use current size |
---|
| 111 | if(changeSize){ |
---|
| 112 | domGeometry.setMarginBox(node, changeSize); |
---|
| 113 | } |
---|
| 114 | |
---|
| 115 | // If either height or width wasn't specified by the user, then query node for it. |
---|
| 116 | // But note that setting the margin box and then immediately querying dimensions may return |
---|
| 117 | // inaccurate results, so try not to depend on it. |
---|
| 118 | var mb = resultSize || {}; |
---|
| 119 | lang.mixin(mb, changeSize || {}); // changeSize overrides resultSize |
---|
| 120 | if( !("h" in mb) || !("w" in mb) ){ |
---|
| 121 | mb = lang.mixin(domGeometry.getMarginBox(node), mb); // just use domGeometry.marginBox() to fill in missing values |
---|
| 122 | } |
---|
| 123 | |
---|
| 124 | // Compute and save the size of my border box and content box |
---|
| 125 | // (w/out calling domGeometry.getContentBox() since that may fail if size was recently set) |
---|
| 126 | var cs = domStyle.getComputedStyle(node); |
---|
| 127 | var me = domGeometry.getMarginExtents(node, cs); |
---|
| 128 | var be = domGeometry.getBorderExtents(node, cs); |
---|
| 129 | var bb = (this._borderBox = { |
---|
| 130 | w: mb.w - (me.w + be.w), |
---|
| 131 | h: mb.h - (me.h + be.h) |
---|
| 132 | }); |
---|
| 133 | var pe = domGeometry.getPadExtents(node, cs); |
---|
| 134 | this._contentBox = { |
---|
| 135 | l: domStyle.toPixelValue(node, cs.paddingLeft), |
---|
| 136 | t: domStyle.toPixelValue(node, cs.paddingTop), |
---|
| 137 | w: bb.w - pe.w, |
---|
| 138 | h: bb.h - pe.h |
---|
| 139 | }; |
---|
| 140 | |
---|
| 141 | // Callback for widget to adjust size of its children |
---|
| 142 | this.layout(); |
---|
| 143 | }, |
---|
| 144 | |
---|
| 145 | layout: function(){ |
---|
| 146 | // summary: |
---|
| 147 | // Widgets override this method to size and position their contents/children. |
---|
| 148 | // When this is called this._contentBox is guaranteed to be set (see resize()). |
---|
| 149 | // |
---|
| 150 | // This is called after startup(), and also when the widget's size has been |
---|
| 151 | // changed. |
---|
| 152 | // tags: |
---|
| 153 | // protected extension |
---|
| 154 | }, |
---|
| 155 | |
---|
| 156 | _setupChild: function(/*dijit/_WidgetBase*/child){ |
---|
| 157 | // summary: |
---|
| 158 | // Common setup for initial children and children which are added after startup |
---|
| 159 | // tags: |
---|
| 160 | // protected extension |
---|
| 161 | |
---|
| 162 | var cls = this.baseClass + "-child " |
---|
| 163 | + (child.baseClass ? this.baseClass + "-" + child.baseClass : ""); |
---|
| 164 | domClass.add(child.domNode, cls); |
---|
| 165 | }, |
---|
| 166 | |
---|
| 167 | addChild: function(/*dijit/_WidgetBase*/ child, /*Integer?*/ insertIndex){ |
---|
| 168 | // Overrides _Container.addChild() to call _setupChild() |
---|
| 169 | this.inherited(arguments); |
---|
| 170 | if(this._started){ |
---|
| 171 | this._setupChild(child); |
---|
| 172 | } |
---|
| 173 | }, |
---|
| 174 | |
---|
| 175 | removeChild: function(/*dijit/_WidgetBase*/ child){ |
---|
| 176 | // Overrides _Container.removeChild() to remove class added by _setupChild() |
---|
| 177 | var cls = this.baseClass + "-child" |
---|
| 178 | + (child.baseClass ? |
---|
| 179 | " " + this.baseClass + "-" + child.baseClass : ""); |
---|
| 180 | domClass.remove(child.domNode, cls); |
---|
| 181 | |
---|
| 182 | this.inherited(arguments); |
---|
| 183 | } |
---|
| 184 | }); |
---|
| 185 | }); |
---|