4 * Copyright(c) 2006-2007, Ext JS, LLC.
6 * Originally Released Under LGPL - original licence link has changed is not relivant.
9 * <script type="text/javascript">
12 * @class Roo.bootstrap.layout.Border
13 * @extends Roo.bootstrap.layout.Manager
14 * @children Roo.bootstrap.panel.Content Roo.bootstrap.panel.Nest Roo.bootstrap.panel.Grid
15 * @parent builder Roo.bootstrap.panel.Nest Roo.bootstrap.panel.Nest Roo.bootstrap.Modal
16 * This class represents a common layout manager used in desktop applications. For screenshots and more details,
17 * please see: examples/bootstrap/nested.html<br><br>
19 <b>The container the layout is rendered into can be either the body element or any other element.
20 If it is not the body element, the container needs to either be an absolute positioned element,
21 or you will need to add "position:relative" to the css of the container. You will also need to specify
22 the container size if it is not the body element.</b>
26 * @param {Object} config Configuration options
28 Roo.bootstrap.layout.Border = function(config){
29 config = config || {};
30 Roo.bootstrap.layout.Border.superclass.constructor.call(this, config);
34 Roo.each(Roo.bootstrap.layout.Border.regions, function(region) {
36 config[region].region = region;
37 this.addRegion(config[region]);
43 Roo.bootstrap.layout.Border.regions = ["center", "north","south","east","west"];
45 Roo.extend(Roo.bootstrap.layout.Border, Roo.bootstrap.layout.Manager, {
48 * @cfg {Roo.bootstrap.layout.Region} center region to go in center
51 * @cfg {Roo.bootstrap.layout.Region} west region to go in west
54 * @cfg {Roo.bootstrap.layout.Region} east region to go in east
57 * @cfg {Roo.bootstrap.layout.Region} south region to go in south
60 * @cfg {Roo.bootstrap.layout.Region} north region to go in north
66 parent : false, // this might point to a 'nest' or a ???
69 * Creates and adds a new region if it doesn't already exist.
70 * @param {String} target The target region key (north, south, east, west or center).
71 * @param {Object} config The regions config object
72 * @return {BorderLayoutRegion} The new region
74 addRegion : function(config)
76 if(!this.regions[config.region]){
77 var r = this.factory(config);
80 return this.regions[config.region];
84 bindRegion : function(r){
85 this.regions[r.config.region] = r;
87 r.on("visibilitychange", this.layout, this);
88 r.on("paneladded", this.layout, this);
89 r.on("panelremoved", this.layout, this);
90 r.on("invalidated", this.layout, this);
91 r.on("resized", this.onRegionResized, this);
92 r.on("collapsed", this.onRegionCollapsed, this);
93 r.on("expanded", this.onRegionExpanded, this);
97 * Performs a layout update.
105 // render all the rebions if they have not been done alreayd?
106 Roo.each(Roo.bootstrap.layout.Border.regions, function(region) {
107 if(this.regions[region] && !this.regions[region].bodyEl){
108 this.regions[region].onRender(this.el)
112 var size = this.getViewSize();
121 var rs = this.regions;
122 var north = rs["north"];
123 var south = rs["south"];
124 var west = rs["west"];
125 var east = rs["east"];
126 var center = rs["center"];
127 //if(this.hideOnLayout){ // not supported anymore
128 //c.el.setStyle("display", "none");
130 if(north && north.isVisible()){
131 var b = north.getBox();
132 var m = north.getMargins();
133 b.width = w - (m.left+m.right);
136 centerY = b.height + b.y + m.bottom;
138 north.updateBox(this.safeBox(b));
140 if(south && south.isVisible()){
141 var b = south.getBox();
142 var m = south.getMargins();
143 b.width = w - (m.left+m.right);
145 var totalHeight = (b.height + m.top + m.bottom);
146 b.y = h - totalHeight + m.top;
147 centerH -= totalHeight;
148 south.updateBox(this.safeBox(b));
150 if(west && west.isVisible()){
151 var b = west.getBox();
152 var m = west.getMargins();
153 b.height = centerH - (m.top+m.bottom);
155 b.y = centerY + m.top;
156 var totalWidth = (b.width + m.left + m.right);
157 centerX += totalWidth;
158 centerW -= totalWidth;
159 west.updateBox(this.safeBox(b));
161 if(east && east.isVisible()){
162 var b = east.getBox();
163 var m = east.getMargins();
164 b.height = centerH - (m.top+m.bottom);
165 var totalWidth = (b.width + m.left + m.right);
166 b.x = w - totalWidth + m.left;
167 b.y = centerY + m.top;
168 centerW -= totalWidth;
169 east.updateBox(this.safeBox(b));
172 var m = center.getMargins();
176 width: centerW - (m.left+m.right),
177 height: centerH - (m.top+m.bottom)
179 //if(this.hideOnLayout){
180 //center.el.setStyle("display", "block");
182 center.updateBox(this.safeBox(centerBox));
185 this.fireEvent("layout", this);
189 safeBox : function(box){
190 box.width = Math.max(0, box.width);
191 box.height = Math.max(0, box.height);
196 * Adds a ContentPanel (or subclass) to this layout.
197 * @param {String} target The target region key (north, south, east, west or center).
198 * @param {Roo.ContentPanel} panel The panel to add
199 * @return {Roo.ContentPanel} The added panel
201 add : function(target, panel){
203 target = target.toLowerCase();
204 return this.regions[target].add(panel);
208 * Remove a ContentPanel (or subclass) to this layout.
209 * @param {String} target The target region key (north, south, east, west or center).
210 * @param {Number/String/Roo.ContentPanel} panel The index, id or panel to remove
211 * @return {Roo.ContentPanel} The removed panel
213 remove : function(target, panel){
214 target = target.toLowerCase();
215 return this.regions[target].remove(panel);
219 * Searches all regions for a panel with the specified id
220 * @param {String} panelId
221 * @return {Roo.ContentPanel} The panel or null if it wasn't found
223 findPanel : function(panelId){
224 var rs = this.regions;
225 for(var target in rs){
226 if(typeof rs[target] != "function"){
227 var p = rs[target].getPanel(panelId);
237 * Searches all regions for a panel with the specified id and activates (shows) it.
238 * @param {String/ContentPanel} panelId The panels id or the panel itself
239 * @return {Roo.ContentPanel} The shown panel or null
241 showPanel : function(panelId) {
242 var rs = this.regions;
243 for(var target in rs){
245 if(typeof r != "function"){
246 if(r.hasPanel(panelId)){
247 return r.showPanel(panelId);
255 * Restores this layout's state using Roo.state.Manager or the state provided by the passed provider.
256 * @param {Roo.state.Provider} provider (optional) An alternate state provider
259 restoreState : function(provider){
261 provider = Roo.state.Manager;
263 var sm = new Roo.layout.StateManager();
264 sm.init(this, provider);
270 * Adds a xtype elements to the layout.
274 xtype : 'ContentPanel',
281 xtype : 'NestedLayoutPanel',
287 items : [ ... list of content panels or nested layout panels.. ]
291 * @param {Object} cfg Xtype definition of item to add.
293 addxtype : function(cfg)
295 // basically accepts a pannel...
296 // can accept a layout region..!?!?
297 //Roo.log('Roo.layout.Border add ' + cfg.xtype)
300 // theory? children can only be panels??
302 //if (!cfg.xtype.match(/Panel$/)) {
307 if (typeof(cfg.region) == 'undefined') {
308 Roo.log("Failed to add Panel, region was not set");
312 var region = cfg.region;
323 if ( region == 'center') {
324 Roo.log("Center: " + cfg.title);
330 case 'Content': // ContentPanel (el, cfg)
331 case 'Scroll': // ContentPanel (el, cfg)
333 cfg.autoCreate = cfg.autoCreate || true;
334 ret = new cfg.xns[cfg.xtype](cfg); // new panel!!!!!
336 // var el = this.el.createChild();
337 // ret = new Roo[cfg.xtype](el, cfg); // new panel!!!!!
340 this.add(region, ret);
344 case 'TreePanel': // our new panel!
345 cfg.el = this.el.createChild();
346 ret = new Roo[cfg.xtype](cfg); // new panel!!!!!
347 this.add(region, ret);
352 // create a new Layout (which is a Border Layout...
354 var clayout = cfg.layout;
355 clayout.el = this.el.createChild();
356 clayout.items = clayout.items || [];
360 // replace this exitems with the clayout ones..
361 xitems = clayout.items;
363 // force background off if it's in center...
364 if (region == 'center' && this.active && this.getRegion('center').panels.length < 1) {
365 cfg.background = false;
367 cfg.layout = new Roo.bootstrap.layout.Border(clayout);
370 ret = new cfg.xns[cfg.xtype](cfg); // new panel!!!!!
371 //console.log('adding nested layout panel ' + cfg.toSource());
372 this.add(region, ret);
373 nb = {}; /// find first...
378 // needs grid and region
380 //var el = this.getRegion(region).el.createChild();
382 *var el = this.el.createChild();
383 // create the grid first...
384 cfg.grid.container = el;
385 cfg.grid = new cfg.grid.xns[cfg.grid.xtype](cfg.grid);
388 if (region == 'center' && this.active ) {
389 cfg.background = false;
392 ret = new cfg.xns[cfg.xtype](cfg); // new panel!!!!!
394 this.add(region, ret);
396 if (cfg.background) {
397 // render grid on panel activation (if panel background)
398 ret.on('activate', function(gp) {
399 if (!gp.grid.rendered) {
400 // gp.grid.render(el);
404 // cfg.grid.render(el);
410 case 'Border': // it can get called on it'self... - might need to check if this is fixed?
411 // it was the old xcomponent building that caused this before.
412 // espeically if border is the top element in the tree.
422 if (typeof(Roo[cfg.xtype]) != 'undefined') {
424 ret = new Roo[cfg.xtype](cfg); // new panel!!!!!
425 this.add(region, ret);
429 throw "Can not add '" + cfg.xtype + "' to Border";
439 Roo.each(xitems, function(i) {
440 region = nb && i.region ? i.region : false;
442 var add = ret.addxtype(i);
445 nb[region] = nb[region] == undefined ? 0 : nb[region]+1;
447 abn[region] = nb[region] ;
454 // make the last non-background panel active..
455 //if (nb) { Roo.log(abn); }
459 region = this.getRegion(r);
461 // tried using nb[r], but it does not work..
463 region.showPanel(abn[r]);
474 factory : function(cfg)
477 var validRegions = Roo.bootstrap.layout.Border.regions;
479 var target = cfg.region;
482 var r = Roo.bootstrap.layout;
486 return new r.North(cfg);
488 return new r.South(cfg);
490 return new r.East(cfg);
492 return new r.West(cfg);
494 return new r.Center(cfg);
496 throw 'Layout region "'+target+'" not supported.';