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 * This class represents a common layout manager used in desktop applications. For screenshots and more details,
15 * please see: examples/bootstrap/nested.html<br><br>
17 <b>The container the layout is rendered into can be either the body element or any other element.
18 If it is not the body element, the container needs to either be an absolute positioned element,
19 or you will need to add "position:relative" to the css of the container. You will also need to specify
20 the container size if it is not the body element.</b>
24 * @param {Object} config Configuration options
26 Roo.bootstrap.layout.Border = function(config){
27 config = config || {};
28 Roo.bootstrap.layout.Border.superclass.constructor.call(this, config);
32 Roo.each(Roo.bootstrap.layout.Border.regions, function(region) {
34 config[region].region = region;
35 this.addRegion(config[region]);
41 Roo.bootstrap.layout.Border.regions = ["north","south","east","west","center"];
43 Roo.extend(Roo.bootstrap.layout.Border, Roo.bootstrap.layout.Manager, {
45 * Creates and adds a new region if it doesn't already exist.
46 * @param {String} target The target region key (north, south, east, west or center).
47 * @param {Object} config The regions config object
48 * @return {BorderLayoutRegion} The new region
50 addRegion : function(config)
52 if(!this.regions[config.region]){
53 var r = this.factory(config);
56 return this.regions[config.region];
60 bindRegion : function(r){
61 this.regions[r.config.region] = r;
63 r.on("visibilitychange", this.layout, this);
64 r.on("paneladded", this.layout, this);
65 r.on("panelremoved", this.layout, this);
66 r.on("invalidated", this.layout, this);
67 r.on("resized", this.onRegionResized, this);
68 r.on("collapsed", this.onRegionCollapsed, this);
69 r.on("expanded", this.onRegionExpanded, this);
73 * Performs a layout update.
77 Roo.log('calling layout!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
83 // render all the rebions if they have not been done alreayd?
84 Roo.each(Roo.bootstrap.layout.Border.regions, function(region) {
85 if(this.regions[region] && !this.regions[region].bodyEl){
86 this.regions[region].onRender(this.el)
90 var size = this.getViewSize();
99 var rs = this.regions;
100 var north = rs["north"];
101 var south = rs["south"];
102 var west = rs["west"];
103 var east = rs["east"];
104 var center = rs["center"];
105 //if(this.hideOnLayout){ // not supported anymore
106 //c.el.setStyle("display", "none");
108 if(north && north.isVisible()){
109 var b = north.getBox();
110 var m = north.getMargins();
111 b.width = w - (m.left+m.right);
114 centerY = b.height + b.y + m.bottom;
116 north.updateBox(this.safeBox(b));
118 if(south && south.isVisible()){
119 var b = south.getBox();
120 var m = south.getMargins();
121 b.width = w - (m.left+m.right);
123 var totalHeight = (b.height + m.top + m.bottom);
124 b.y = h - totalHeight + m.top;
125 centerH -= totalHeight;
126 south.updateBox(this.safeBox(b));
128 if(west && west.isVisible()){
129 var b = west.getBox();
130 var m = west.getMargins();
131 b.height = centerH - (m.top+m.bottom);
133 b.y = centerY + m.top;
134 var totalWidth = (b.width + m.left + m.right);
135 centerX += totalWidth;
136 centerW -= totalWidth;
137 west.updateBox(this.safeBox(b));
139 if(east && east.isVisible()){
140 var b = east.getBox();
141 var m = east.getMargins();
142 b.height = centerH - (m.top+m.bottom);
143 var totalWidth = (b.width + m.left + m.right);
144 b.x = w - totalWidth + m.left;
145 b.y = centerY + m.top;
146 centerW -= totalWidth;
147 east.updateBox(this.safeBox(b));
150 var m = center.getMargins();
154 width: centerW - (m.left+m.right),
155 height: centerH - (m.top+m.bottom)
157 //if(this.hideOnLayout){
158 //center.el.setStyle("display", "block");
160 center.updateBox(this.safeBox(centerBox));
163 this.fireEvent("layout", this);
167 safeBox : function(box){
168 box.width = Math.max(0, box.width);
169 box.height = Math.max(0, box.height);
174 * Adds a ContentPanel (or subclass) to this layout.
175 * @param {String} target The target region key (north, south, east, west or center).
176 * @param {Roo.ContentPanel} panel The panel to add
177 * @return {Roo.ContentPanel} The added panel
179 add : function(target, panel){
181 target = target.toLowerCase();
182 return this.regions[target].add(panel);
186 * Remove a ContentPanel (or subclass) to this layout.
187 * @param {String} target The target region key (north, south, east, west or center).
188 * @param {Number/String/Roo.ContentPanel} panel The index, id or panel to remove
189 * @return {Roo.ContentPanel} The removed panel
191 remove : function(target, panel){
192 target = target.toLowerCase();
193 return this.regions[target].remove(panel);
197 * Searches all regions for a panel with the specified id
198 * @param {String} panelId
199 * @return {Roo.ContentPanel} The panel or null if it wasn't found
201 findPanel : function(panelId){
202 var rs = this.regions;
203 for(var target in rs){
204 if(typeof rs[target] != "function"){
205 var p = rs[target].getPanel(panelId);
215 * Searches all regions for a panel with the specified id and activates (shows) it.
216 * @param {String/ContentPanel} panelId The panels id or the panel itself
217 * @return {Roo.ContentPanel} The shown panel or null
219 showPanel : function(panelId) {
220 var rs = this.regions;
221 for(var target in rs){
223 if(typeof r != "function"){
224 if(r.hasPanel(panelId)){
225 return r.showPanel(panelId);
233 * Restores this layout's state using Roo.state.Manager or the state provided by the passed provider.
234 * @param {Roo.state.Provider} provider (optional) An alternate state provider
237 restoreState : function(provider){
239 provider = Roo.state.Manager;
241 var sm = new Roo.LayoutStateManager();
242 sm.init(this, provider);
248 * Adds a xtype elements to the layout.
252 xtype : 'ContentPanel',
259 xtype : 'NestedLayoutPanel',
265 items : [ ... list of content panels or nested layout panels.. ]
269 * @param {Object} cfg Xtype definition of item to add.
271 addxtype : function(cfg)
273 // basically accepts a pannel...
274 // can accept a layout region..!?!?
275 //Roo.log('Roo.BorderLayout add ' + cfg.xtype)
278 // theory? children can only be panels??
280 //if (!cfg.xtype.match(/Panel$/)) {
285 if (typeof(cfg.region) == 'undefined') {
286 Roo.log("Failed to add Panel, region was not set");
290 var region = cfg.region;
303 case 'Content': // ContentPanel (el, cfg)
304 case 'Scroll': // ContentPanel (el, cfg)
306 cfg.autoCreate = true;
307 ret = new cfg.xns[cfg.xtype](cfg); // new panel!!!!!
309 // var el = this.el.createChild();
310 // ret = new Roo[cfg.xtype](el, cfg); // new panel!!!!!
313 this.add(region, ret);
317 case 'TreePanel': // our new panel!
318 cfg.el = this.el.createChild();
319 ret = new Roo[cfg.xtype](cfg); // new panel!!!!!
320 this.add(region, ret);
325 // create a new Layout (which is a Border Layout...
327 var clayout = cfg.layout;
328 clayout.el = this.el.createChild();
329 clayout.items = clayout.items || [];
333 // replace this exitems with the clayout ones..
334 xitems = clayout.items;
336 // force background off if it's in center...
337 if (region == 'center' && this.active && this.getRegion('center').panels.length < 1) {
338 cfg.background = false;
340 cfg.layout = new Roo.bootstrap.layout.Border(clayout);
343 ret = new cfg.xns[cfg.xtype](cfg); // new panel!!!!!
344 //console.log('adding nested layout panel ' + cfg.toSource());
345 this.add(region, ret);
346 nb = {}; /// find first...
351 // needs grid and region
353 //var el = this.getRegion(region).el.createChild();
355 *var el = this.el.createChild();
356 // create the grid first...
357 cfg.grid.container = el;
358 cfg.grid = new cfg.grid.xns[cfg.grid.xtype](cfg.grid);
361 if (region == 'center' && this.active ) {
362 cfg.background = false;
365 ret = new cfg.xns[cfg.xtype](cfg); // new panel!!!!!
367 this.add(region, ret);
369 if (cfg.background) {
370 // render grid on panel activation (if panel background)
371 ret.on('activate', function(gp) {
372 if (!gp.grid.rendered) {
373 // gp.grid.render(el);
377 // cfg.grid.render(el);
383 case 'Border': // it can get called on it'self... - might need to check if this is fixed?
384 // it was the old xcomponent building that caused this before.
385 // espeically if border is the top element in the tree.
395 if (typeof(Roo[cfg.xtype]) != 'undefined') {
397 ret = new Roo[cfg.xtype](cfg); // new panel!!!!!
398 this.add(region, ret);
402 throw "Can not add '" + cfg.xtype + "' to Border";
412 Roo.each(xitems, function(i) {
413 region = nb && i.region ? i.region : false;
415 var add = ret.addxtype(i);
418 nb[region] = nb[region] == undefined ? 0 : nb[region]+1;
420 abn[region] = nb[region] ;
427 // make the last non-background panel active..
428 //if (nb) { Roo.log(abn); }
432 region = this.getRegion(r);
434 // tried using nb[r], but it does not work..
436 region.showPanel(abn[r]);
447 factory : function(cfg)
450 var validRegions = Roo.bootstrap.layout.Border.regions;
452 var target = cfg.region;
455 var r = Roo.bootstrap.layout;
459 return new r.North(cfg);
461 return new r.South(cfg);
463 return new r.East(cfg);
465 return new r.West(cfg);
467 return new r.Center(cfg);
469 throw 'Layout region "'+target+'" not supported.';