]> git.pond.sub.org Git - eow/blob - static/dojo-release-1.1.1/dijit/layout/_LayoutWidget.js
add Dojo 1.1.1
[eow] / static / dojo-release-1.1.1 / dijit / layout / _LayoutWidget.js
1 if(!dojo._hasResource["dijit.layout._LayoutWidget"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2 dojo._hasResource["dijit.layout._LayoutWidget"] = true;
3 dojo.provide("dijit.layout._LayoutWidget");
4
5 dojo.require("dijit._Widget");
6 dojo.require("dijit._Container");
7
8 dojo.declare("dijit.layout._LayoutWidget",
9         [dijit._Widget, dijit._Container, dijit._Contained],
10         {
11                 // summary
12                 //              Mixin for widgets that contain a list of children like SplitContainer.
13                 //              Widgets which mixin this code must define layout() to lay out the children
14
15                 isLayoutContainer: true,
16
17                 postCreate: function(){
18                         dojo.addClass(this.domNode, "dijitContainer");
19                 },
20
21                 startup: function(){
22                         // summary:
23                         //              Called after all the widgets have been instantiated and their
24                         //              dom nodes have been inserted somewhere under dojo.doc.body.
25                         //
26                         //              Widgets should override this method to do any initialization
27                         //              dependent on other widgets existing, and then call
28                         //              this superclass method to finish things off.
29                         //
30                         //              startup() in subclasses shouldn't do anything
31                         //              size related because the size of the widget hasn't been set yet.
32
33                         if(this._started){ return; }
34
35                         dojo.forEach(this.getChildren(), function(child){ child.startup(); });
36
37                         // If I am a top level widget
38                         if(!this.getParent || !this.getParent()){
39                                 // Do recursive sizing and layout of all my descendants
40                                 // (passing in no argument to resize means that it has to glean the size itself)
41                                 this.resize();
42
43                                 // since my parent isn't a layout container, and my style is width=height=100% (or something similar),
44                                 // then I need to watch when the window resizes, and size myself accordingly
45                                 // (passing in no argument to resize means that it has to glean the size itself)
46                                 this.connect(window, 'onresize', function(){this.resize();});
47                         }
48                         
49                         this.inherited(arguments);
50                 },
51
52                 resize: function(args){
53                         // summary:
54                         //              Explicitly set this widget's size (in pixels),
55                         //              and then call layout() to resize contents (and maybe adjust child widgets)
56                         //      
57                         // args: Object?
58                         //              {w: int, h: int, l: int, t: int}
59
60                         var node = this.domNode;
61
62                         // set margin box size, unless it wasn't specified, in which case use current size
63                         if(args){
64                                 dojo.marginBox(node, args);
65
66                                 // set offset of the node
67                                 if(args.t){ node.style.top = args.t + "px"; }
68                                 if(args.l){ node.style.left = args.l + "px"; }
69                         }
70                         // If either height or width wasn't specified by the user, then query node for it.
71                         // But note that setting the margin box and then immediately querying dimensions may return
72                         // inaccurate results, so try not to depend on it.
73                         var mb = dojo.mixin(dojo.marginBox(node), args||{});
74
75 //                      console.log(this, ": setting size to ", mb);
76
77                         // Save the size of my content box.
78                         this._contentBox = dijit.layout.marginBox2contentBox(node, mb);
79
80                         // Callback for widget to adjust size of it's children
81                         this.layout();
82                 },
83
84                 layout: function(){
85                         //      summary
86                         //              Widgets override this method to size & position their contents/children.
87                         //              When this is called this._contentBox is guaranteed to be set (see resize()).
88                         //
89                         //              This is called after startup(), and also when the widget's size has been
90                         //              changed.
91                 }
92         }
93 );
94
95 dijit.layout.marginBox2contentBox = function(/*DomNode*/ node, /*Object*/ mb){
96         // summary:
97         //              Given the margin-box size of a node, return it's content box size.
98         //              Functions like dojo.contentBox() but is more reliable since it doesn't have
99         //              to wait for the browser to compute sizes.
100         var cs = dojo.getComputedStyle(node);
101         var me=dojo._getMarginExtents(node, cs);
102         var pb=dojo._getPadBorderExtents(node, cs);
103         return {
104                 l: dojo._toPixelValue(node, cs.paddingLeft),
105                 t: dojo._toPixelValue(node, cs.paddingTop),
106                 w: mb.w - (me.w + pb.w),
107                 h: mb.h - (me.h + pb.h)
108         };
109 };
110
111 (function(){
112         var capitalize = function(word){
113                 return word.substring(0,1).toUpperCase() + word.substring(1);
114         };
115
116         var size = function(widget, dim){
117                 // size the child
118                 widget.resize ? widget.resize(dim) : dojo.marginBox(widget.domNode, dim);
119
120                 // record child's size, but favor our own numbers when we have them.
121                 // the browser lies sometimes
122                 dojo.mixin(widget, dojo.marginBox(widget.domNode));
123                 dojo.mixin(widget, dim);
124         };
125
126         dijit.layout.layoutChildren = function(/*DomNode*/ container, /*Object*/ dim, /*Object[]*/ children){
127                 /**
128                  * summary
129                  *              Layout a bunch of child dom nodes within a parent dom node
130                  * container:
131                  *              parent node
132                  * dim:
133                  *              {l, t, w, h} object specifying dimensions of container into which to place children
134                  * children:
135                  *              an array like [ {domNode: foo, layoutAlign: "bottom" }, {domNode: bar, layoutAlign: "client"} ]
136                  */
137
138                 // copy dim because we are going to modify it
139                 dim = dojo.mixin({}, dim);
140
141                 dojo.addClass(container, "dijitLayoutContainer");
142
143                 // Move "client" elements to the end of the array for layout.  a11y dictates that the author
144                 // needs to be able to put them in the document in tab-order, but this algorithm requires that
145                 // client be last.
146                 children = dojo.filter(children, function(item){ return item.layoutAlign != "client"; })
147                         .concat(dojo.filter(children, function(item){ return item.layoutAlign == "client"; }));
148
149                 // set positions/sizes
150                 dojo.forEach(children, function(child){
151                         var elm = child.domNode,
152                                 pos = child.layoutAlign;
153
154                         // set elem to upper left corner of unused space; may move it later
155                         var elmStyle = elm.style;
156                         elmStyle.left = dim.l+"px";
157                         elmStyle.top = dim.t+"px";
158                         elmStyle.bottom = elmStyle.right = "auto";
159
160                         dojo.addClass(elm, "dijitAlign" + capitalize(pos));
161
162                         // set size && adjust record of remaining space.
163                         // note that setting the width of a <div> may affect it's height.
164                         if(pos=="top" || pos=="bottom"){
165                                 size(child, { w: dim.w });
166                                 dim.h -= child.h;
167                                 if(pos=="top"){
168                                         dim.t += child.h;
169                                 }else{
170                                         elmStyle.top = dim.t + dim.h + "px";
171                                 }
172                         }else if(pos=="left" || pos=="right"){
173                                 size(child, { h: dim.h });
174                                 dim.w -= child.w;
175                                 if(pos=="left"){
176                                         dim.l += child.w;
177                                 }else{
178                                         elmStyle.left = dim.l + dim.w + "px";
179                                 }
180                         }else if(pos=="client"){
181                                 size(child, dim);
182                         }
183                 });
184         };
185
186 })();
187
188 }