commit extjs-2.2.1
[extjs.git] / source / widgets / layout / ContainerLayout.js
1 /*\r
2  * Ext JS Library 2.2.1\r
3  * Copyright(c) 2006-2009, Ext JS, LLC.\r
4  * licensing@extjs.com\r
5  * \r
6  * http://extjs.com/license\r
7  */\r
8 \r
9 /**\r
10  * @class Ext.layout.ContainerLayout\r
11  * <p>Every {@link Ext.Container Container} delegates the rendering of its child {@link Ext.Component Component}s\r
12  * to a layout manager class which must be {@link Ext.Container#layout configured} into the Container.</p> Some\r
13  * layouts also provide sizing and positioning of child Components/\r
14  *\r
15  * <p>The ContainerLayout class is the default layout manager used when no layout is configured into a Container.\r
16  * It provides the basic foundation for all other layout classes in Ext. It simply renders all child Components\r
17  * into the Container, performing no sizing os positioning services. This class is intended to be extended and should\r
18  * generally not need to be created directly via the new keyword.\r
19  */\r
20 Ext.layout.ContainerLayout = function(config){\r
21     Ext.apply(this, config);\r
22 };\r
23 \r
24 Ext.layout.ContainerLayout.prototype = {\r
25     /**\r
26      * @cfg {String} extraCls\r
27      * An optional extra CSS class that will be added to the container (defaults to '').  This can be useful for\r
28      * adding customized styles to the container or any of its children using standard CSS rules.\r
29      */\r
30     /**\r
31      * @cfg {Boolean} renderHidden\r
32      * True to hide each contained item on render (defaults to false).\r
33      */\r
34 \r
35     /**\r
36      * A reference to the {@link Ext.Component} that is active.  For example,\r
37      * if(myPanel.layout.activeItem.id == 'item-1') { ... }.  activeItem only applies to layout styles that can\r
38      * display items one at a time (like {@link Ext.layout.Accordion}, {@link Ext.layout.CardLayout}\r
39      * and {@link Ext.layout.FitLayout}).  Read-only.  Related to {@link Ext.Container#activeItem}.\r
40      * @type {Ext.Component}\r
41      * @property activeItem\r
42      */\r
43 \r
44     // private\r
45     monitorResize:false,\r
46     // private\r
47     activeItem : null,\r
48 \r
49     // private\r
50     layout : function(){\r
51         var target = this.container.getLayoutTarget();\r
52         this.onLayout(this.container, target);\r
53         this.container.fireEvent('afterlayout', this.container, this);\r
54     },\r
55 \r
56     // private\r
57     onLayout : function(ct, target){\r
58         this.renderAll(ct, target);\r
59     },\r
60 \r
61     // private\r
62     isValidParent : function(c, target){\r
63                 var el = c.getPositionEl ? c.getPositionEl() : c.getEl();\r
64                 return el.dom.parentNode == target.dom;\r
65     },\r
66 \r
67     // private\r
68     renderAll : function(ct, target){\r
69         var items = ct.items.items;\r
70         for(var i = 0, len = items.length; i < len; i++) {\r
71             var c = items[i];\r
72             if(c && (!c.rendered || !this.isValidParent(c, target))){\r
73                 this.renderItem(c, i, target);\r
74             }\r
75         }\r
76     },\r
77 \r
78     // private\r
79     renderItem : function(c, position, target){\r
80         if(c && !c.rendered){\r
81             c.render(target, position);\r
82             if(this.extraCls){\r
83                 var t = c.getPositionEl ? c.getPositionEl() : c;\r
84                 t.addClass(this.extraCls);\r
85             }\r
86             if (this.renderHidden && c != this.activeItem) {\r
87                 c.hide();\r
88             }\r
89         }else if(c && !this.isValidParent(c, target)){\r
90             if(this.extraCls){\r
91                 var t = c.getPositionEl ? c.getPositionEl() : c;\r
92                 t.addClass(this.extraCls);\r
93             }\r
94             if(typeof position == 'number'){\r
95                 position = target.dom.childNodes[position];\r
96             }\r
97             target.dom.insertBefore(c.getEl().dom, position || null);\r
98             if (this.renderHidden && c != this.activeItem) {\r
99                 c.hide();\r
100             }\r
101         }\r
102     },\r
103 \r
104     // private\r
105     onResize: function(){\r
106         if(this.container.collapsed){\r
107             return;\r
108         }\r
109         var b = this.container.bufferResize;\r
110         if(b){\r
111             if(!this.resizeTask){\r
112                 this.resizeTask = new Ext.util.DelayedTask(this.layout, this);\r
113                 this.resizeBuffer = typeof b == 'number' ? b : 100;\r
114             }\r
115             this.resizeTask.delay(this.resizeBuffer);\r
116         }else{\r
117             this.layout();\r
118         }\r
119     },\r
120 \r
121     // private\r
122     setContainer : function(ct){\r
123         if(this.monitorResize && ct != this.container){\r
124             if(this.container){\r
125                 this.container.un('resize', this.onResize, this);\r
126             }\r
127             if(ct){\r
128                 ct.on('resize', this.onResize, this);\r
129             }\r
130         }\r
131         this.container = ct;\r
132     },\r
133 \r
134     // private\r
135     parseMargins : function(v){\r
136         var ms = v.split(' ');\r
137         var len = ms.length;\r
138         if(len == 1){\r
139             ms[1] = ms[0];\r
140             ms[2] = ms[0];\r
141             ms[3] = ms[0];\r
142         }\r
143         if(len == 2){\r
144             ms[2] = ms[0];\r
145             ms[3] = ms[1];\r
146         }\r
147         return {\r
148             top:parseInt(ms[0], 10) || 0,\r
149             right:parseInt(ms[1], 10) || 0,\r
150             bottom:parseInt(ms[2], 10) || 0,\r
151             left:parseInt(ms[3], 10) || 0\r
152         };\r
153     },\r
154 \r
155     /*\r
156      * Destroys this layout. This is a template method that is empty by default, but should be implemented\r
157      * by subclasses that require explicit destruction to purge event handlers or remove DOM nodes.\r
158      * @protected\r
159      */\r
160     destroy : Ext.emptyFn\r
161 };\r
162 Ext.Container.LAYOUTS['auto'] = Ext.layout.ContainerLayout;