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 | }); |
---|