[483] | 1 | define([ |
---|
| 2 | "dojo/_base/array", |
---|
| 3 | "dojo/_base/declare", // declare |
---|
| 4 | "dojo/dom-class", |
---|
| 5 | "dojo/dom-style", |
---|
| 6 | "dojo/_base/lang", |
---|
| 7 | "../_WidgetBase", |
---|
| 8 | "./_LayoutWidget", |
---|
| 9 | "./utils" // layoutUtils.layoutChildren |
---|
| 10 | ], function(array, declare, domClass, domStyle, lang, _WidgetBase, _LayoutWidget, layoutUtils){ |
---|
| 11 | |
---|
| 12 | // module: |
---|
| 13 | // dijit/layout/LayoutContainer |
---|
| 14 | |
---|
| 15 | var LayoutContainer = declare("dijit.layout.LayoutContainer", _LayoutWidget, { |
---|
| 16 | // summary: |
---|
| 17 | // A LayoutContainer is a box with a specified size, such as style="width: 500px; height: 500px;", |
---|
| 18 | // that contains a child widget marked region="center" and optionally children widgets marked |
---|
| 19 | // region equal to "top", "bottom", "leading", "trailing", "left" or "right". |
---|
| 20 | // Children along the edges will be laid out according to width or height dimensions. The remaining |
---|
| 21 | // space is designated for the center region. |
---|
| 22 | // |
---|
| 23 | // The outer size must be specified on the LayoutContainer node. Width must be specified for the sides |
---|
| 24 | // and height for the top and bottom, respectively. No dimensions should be specified on the center; |
---|
| 25 | // it will fill the remaining space. Regions named "leading" and "trailing" may be used just like |
---|
| 26 | // "left" and "right" except that they will be reversed in right-to-left environments. |
---|
| 27 | // |
---|
| 28 | // For complex layouts, multiple children can be specified for a single region. In this case, the |
---|
| 29 | // layoutPriority flag on the children determines which child is closer to the edge (low layoutPriority) |
---|
| 30 | // and which child is closer to the center (high layoutPriority). layoutPriority can also be used |
---|
| 31 | // instead of the design attribute to control layout precedence of horizontal vs. vertical panes. |
---|
| 32 | // |
---|
| 33 | // See `LayoutContainer.ChildWidgetProperties` for details on the properties that can be set on |
---|
| 34 | // children of a `LayoutContainer`. |
---|
| 35 | // |
---|
| 36 | // If layoutPriority is not set, lays out each child in the natural order the children occur in. |
---|
| 37 | // Basically each child is laid out into the "remaining space", where "remaining space" is initially |
---|
| 38 | // the content area of this widget, but is reduced to a smaller rectangle each time a child is added. |
---|
| 39 | |
---|
| 40 | // design: String |
---|
| 41 | // Which design is used for the layout: |
---|
| 42 | // |
---|
| 43 | // - "headline" (default) where the top and bottom extend the full width of the container |
---|
| 44 | // - "sidebar" where the left and right sides extend from top to bottom. |
---|
| 45 | design: "headline", |
---|
| 46 | |
---|
| 47 | baseClass: "dijitLayoutContainer", |
---|
| 48 | |
---|
| 49 | startup: function(){ |
---|
| 50 | if(this._started){ |
---|
| 51 | return; |
---|
| 52 | } |
---|
| 53 | array.forEach(this.getChildren(), this._setupChild, this); |
---|
| 54 | this.inherited(arguments); |
---|
| 55 | }, |
---|
| 56 | |
---|
| 57 | _setupChild: function(/*dijit/_WidgetBase*/ child){ |
---|
| 58 | // Override _LayoutWidget._setupChild(). |
---|
| 59 | |
---|
| 60 | this.inherited(arguments); |
---|
| 61 | |
---|
| 62 | var region = child.region; |
---|
| 63 | if(region){ |
---|
| 64 | domClass.add(child.domNode, this.baseClass + "Pane"); |
---|
| 65 | } |
---|
| 66 | }, |
---|
| 67 | |
---|
| 68 | _getOrderedChildren: function(){ |
---|
| 69 | // summary: |
---|
| 70 | // Return list of my children in the order that I want layoutChildren() |
---|
| 71 | // to process them (i.e. from the outside to the inside) |
---|
| 72 | |
---|
| 73 | var wrappers = array.map(this.getChildren(), function(child, idx){ |
---|
| 74 | return { |
---|
| 75 | pane: child, |
---|
| 76 | weight: [ |
---|
| 77 | child.region == "center" ? Infinity : 0, |
---|
| 78 | child.layoutPriority, |
---|
| 79 | (this.design == "sidebar" ? 1 : -1) * (/top|bottom/.test(child.region) ? 1 : -1), |
---|
| 80 | idx |
---|
| 81 | ] |
---|
| 82 | }; |
---|
| 83 | }, this); |
---|
| 84 | wrappers.sort(function(a, b){ |
---|
| 85 | var aw = a.weight, bw = b.weight; |
---|
| 86 | for(var i = 0; i < aw.length; i++){ |
---|
| 87 | if(aw[i] != bw[i]){ |
---|
| 88 | return aw[i] - bw[i]; |
---|
| 89 | } |
---|
| 90 | } |
---|
| 91 | return 0; |
---|
| 92 | }); |
---|
| 93 | |
---|
| 94 | return array.map(wrappers, function(w){ return w.pane; }); |
---|
| 95 | }, |
---|
| 96 | |
---|
| 97 | layout: function(){ |
---|
| 98 | layoutUtils.layoutChildren(this.domNode, this._contentBox, this._getOrderedChildren()); |
---|
| 99 | }, |
---|
| 100 | |
---|
| 101 | addChild: function(/*dijit/_WidgetBase*/ child, /*Integer?*/ insertIndex){ |
---|
| 102 | this.inherited(arguments); |
---|
| 103 | if(this._started){ |
---|
| 104 | this.layout(); |
---|
| 105 | } |
---|
| 106 | }, |
---|
| 107 | |
---|
| 108 | removeChild: function(/*dijit/_WidgetBase*/ child){ |
---|
| 109 | this.inherited(arguments); |
---|
| 110 | if(this._started){ |
---|
| 111 | this.layout(); |
---|
| 112 | } |
---|
| 113 | |
---|
| 114 | // Clean up whatever style changes we made to the child pane. |
---|
| 115 | // Unclear how height and width should be handled. |
---|
| 116 | domClass.remove(child.domNode, this.baseClass + "Pane"); |
---|
| 117 | domStyle.set(child.domNode, { |
---|
| 118 | top: "auto", |
---|
| 119 | bottom: "auto", |
---|
| 120 | left: "auto", |
---|
| 121 | right: "auto", |
---|
| 122 | position: "static" |
---|
| 123 | }); |
---|
| 124 | domStyle.set(child.domNode, /top|bottom/.test(child.region) ? "width" : "height", "auto"); |
---|
| 125 | } |
---|
| 126 | }); |
---|
| 127 | |
---|
| 128 | LayoutContainer.ChildWidgetProperties = { |
---|
| 129 | // summary: |
---|
| 130 | // These properties can be specified for the children of a LayoutContainer. |
---|
| 131 | |
---|
| 132 | // region: [const] String |
---|
| 133 | // Values: "top", "bottom", "leading", "trailing", "left", "right", "center". |
---|
| 134 | // See the `dijit/layout/LayoutContainer` description for details. |
---|
| 135 | region: '', |
---|
| 136 | |
---|
| 137 | // layoutAlign: [const deprecated] String |
---|
| 138 | // Synonym for region, except using "client" instead of "center". Deprecated; use region instead. |
---|
| 139 | layoutAlign: '', |
---|
| 140 | |
---|
| 141 | // layoutPriority: [const] Number |
---|
| 142 | // Children with a higher layoutPriority will be placed closer to the LayoutContainer center, |
---|
| 143 | // between children with a lower layoutPriority. |
---|
| 144 | layoutPriority: 0 |
---|
| 145 | }; |
---|
| 146 | |
---|
| 147 | // Since any widget can be specified as a LayoutContainer child, mix it |
---|
| 148 | // into the base widget class. (This is a hack, but it's effective.) |
---|
| 149 | // This is for the benefit of the parser. Remove for 2.0. Also, hide from doc viewer. |
---|
| 150 | lang.extend(_WidgetBase, /*===== {} || =====*/ LayoutContainer.ChildWidgetProperties); |
---|
| 151 | |
---|
| 152 | return LayoutContainer; |
---|
| 153 | }); |
---|