source: Dev/branches/rest-dojo-ui/client/dijit/layout/_LayoutWidget.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

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