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);
29 this.factory = config.factory || Roo.BorderLayout.RegionFactory;
31 Roo.each(Roo.bootstrap.layout.Border.regions, function(target) {
33 this.addRegion(target, config[target]);
39 Roo.bootstrap.layout.Border.regions = ["north","south","east","west","center"];
41 Roo.extend(Roo.bootstrap.layout.Border, Roo.bootstrap.layout.Manager, {
43 * Creates and adds a new region if it doesn't already exist.
44 * @param {String} target The target region key (north, south, east, west or center).
45 * @param {Object} config The regions config object
46 * @return {BorderLayoutRegion} The new region
48 addRegion : function(target, config){
49 if(!this.regions[target]){
50 var r = this.factory.create(target, this, config);
51 this.bindRegion(target, r);
53 return this.regions[target];
57 bindRegion : function(name, r){
58 this.regions[name] = r;
59 r.on("visibilitychange", this.layout, this);
60 r.on("paneladded", this.layout, this);
61 r.on("panelremoved", this.layout, this);
62 r.on("invalidated", this.layout, this);
63 r.on("resized", this.onRegionResized, this);
64 r.on("collapsed", this.onRegionCollapsed, this);
65 r.on("expanded", this.onRegionExpanded, this);
69 * Performs a layout update.
75 var size = this.getViewSize();
84 var rs = this.regions;
85 var north = rs["north"];
86 var south = rs["south"];
87 var west = rs["west"];
88 var east = rs["east"];
89 var center = rs["center"];
90 //if(this.hideOnLayout){ // not supported anymore
91 //c.el.setStyle("display", "none");
93 if(north && north.isVisible()){
94 var b = north.getBox();
95 var m = north.getMargins();
96 b.width = w - (m.left+m.right);
99 centerY = b.height + b.y + m.bottom;
101 north.updateBox(this.safeBox(b));
103 if(south && south.isVisible()){
104 var b = south.getBox();
105 var m = south.getMargins();
106 b.width = w - (m.left+m.right);
108 var totalHeight = (b.height + m.top + m.bottom);
109 b.y = h - totalHeight + m.top;
110 centerH -= totalHeight;
111 south.updateBox(this.safeBox(b));
113 if(west && west.isVisible()){
114 var b = west.getBox();
115 var m = west.getMargins();
116 b.height = centerH - (m.top+m.bottom);
118 b.y = centerY + m.top;
119 var totalWidth = (b.width + m.left + m.right);
120 centerX += totalWidth;
121 centerW -= totalWidth;
122 west.updateBox(this.safeBox(b));
124 if(east && east.isVisible()){
125 var b = east.getBox();
126 var m = east.getMargins();
127 b.height = centerH - (m.top+m.bottom);
128 var totalWidth = (b.width + m.left + m.right);
129 b.x = w - totalWidth + m.left;
130 b.y = centerY + m.top;
131 centerW -= totalWidth;
132 east.updateBox(this.safeBox(b));
135 var m = center.getMargins();
139 width: centerW - (m.left+m.right),
140 height: centerH - (m.top+m.bottom)
142 //if(this.hideOnLayout){
143 //center.el.setStyle("display", "block");
145 center.updateBox(this.safeBox(centerBox));
148 this.fireEvent("layout", this);
152 safeBox : function(box){
153 box.width = Math.max(0, box.width);
154 box.height = Math.max(0, box.height);
159 * Adds a ContentPanel (or subclass) to this layout.
160 * @param {String} target The target region key (north, south, east, west or center).
161 * @param {Roo.ContentPanel} panel The panel to add
162 * @return {Roo.ContentPanel} The added panel
164 add : function(target, panel){
166 target = target.toLowerCase();
167 return this.regions[target].add(panel);
171 * Remove a ContentPanel (or subclass) to this layout.
172 * @param {String} target The target region key (north, south, east, west or center).
173 * @param {Number/String/Roo.ContentPanel} panel The index, id or panel to remove
174 * @return {Roo.ContentPanel} The removed panel
176 remove : function(target, panel){
177 target = target.toLowerCase();
178 return this.regions[target].remove(panel);
182 * Searches all regions for a panel with the specified id
183 * @param {String} panelId
184 * @return {Roo.ContentPanel} The panel or null if it wasn't found
186 findPanel : function(panelId){
187 var rs = this.regions;
188 for(var target in rs){
189 if(typeof rs[target] != "function"){
190 var p = rs[target].getPanel(panelId);
200 * Searches all regions for a panel with the specified id and activates (shows) it.
201 * @param {String/ContentPanel} panelId The panels id or the panel itself
202 * @return {Roo.ContentPanel} The shown panel or null
204 showPanel : function(panelId) {
205 var rs = this.regions;
206 for(var target in rs){
208 if(typeof r != "function"){
209 if(r.hasPanel(panelId)){
210 return r.showPanel(panelId);
218 * Restores this layout's state using Roo.state.Manager or the state provided by the passed provider.
219 * @param {Roo.state.Provider} provider (optional) An alternate state provider
221 restoreState : function(provider){
223 provider = Roo.state.Manager;
225 var sm = new Roo.LayoutStateManager();
226 sm.init(this, provider);
230 * Adds a batch of multiple ContentPanels dynamically by passing a special regions config object. This config
231 * object should contain properties for each region to add ContentPanels to, and each property's value should be
232 * a valid ContentPanel config object. Example:
234 // Create the main layout
235 var layout = new Roo.BorderLayout('main-ct', {
246 // Create and add multiple ContentPanels at once via configs
251 title:'Ext Source Files',
264 * @param {Object} regions An object containing ContentPanel configs by region name
266 batchAdd : function(regions){
268 for(var rname in regions){
269 var lr = this.regions[rname];
271 this.addTypedPanels(lr, regions[rname]);
278 addTypedPanels : function(lr, ps){
279 if(typeof ps == 'string'){
280 lr.add(new Roo.ContentPanel(ps));
282 else if(ps instanceof Array){
283 for(var i =0, len = ps.length; i < len; i++){
284 this.addTypedPanels(lr, ps[i]);
287 else if(!ps.events){ // raw config?
289 delete ps.el; // prevent conflict
290 lr.add(new Roo.ContentPanel(el || Roo.id(), ps));
292 else { // panel object assumed!
297 * Adds a xtype elements to the layout.
301 xtype : 'ContentPanel',
308 xtype : 'NestedLayoutPanel',
314 items : [ ... list of content panels or nested layout panels.. ]
318 * @param {Object} cfg Xtype definition of item to add.
320 addxtype : function(cfg)
322 // basically accepts a pannel...
323 // can accept a layout region..!?!?
324 //Roo.log('Roo.BorderLayout add ' + cfg.xtype)
326 if (!cfg.xtype.match(/Panel$/)) {
331 if (typeof(cfg.region) == 'undefined') {
332 Roo.log("Failed to add Panel, region was not set");
336 var region = cfg.region;
349 case 'ContentPanel': // ContentPanel (el, cfg)
350 case 'ScrollPanel': // ContentPanel (el, cfg)
353 ret = new Roo[cfg.xtype](cfg); // new panel!!!!!
355 var el = this.el.createChild();
356 ret = new Roo[cfg.xtype](el, cfg); // new panel!!!!!
359 this.add(region, ret);
363 case 'TreePanel': // our new panel!
364 cfg.el = this.el.createChild();
365 ret = new Roo[cfg.xtype](cfg); // new panel!!!!!
366 this.add(region, ret);
369 case 'NestedLayoutPanel':
370 // create a new Layout (which is a Border Layout...
371 var el = this.el.createChild();
372 var clayout = cfg.layout;
374 clayout.items = clayout.items || [];
375 // replace this exitems with the clayout ones..
376 xitems = clayout.items;
379 if (region == 'center' && this.active && this.getRegion('center').panels.length < 1) {
380 cfg.background = false;
382 var layout = new Roo.BorderLayout(el, clayout);
384 ret = new Roo[cfg.xtype](layout, cfg); // new panel!!!!!
385 //console.log('adding nested layout panel ' + cfg.toSource());
386 this.add(region, ret);
387 nb = {}; /// find first...
392 // needs grid and region
394 //var el = this.getRegion(region).el.createChild();
395 var el = this.el.createChild();
396 // create the grid first...
398 var grid = new Roo.grid[cfg.grid.xtype](el, cfg.grid);
400 if (region == 'center' && this.active ) {
401 cfg.background = false;
403 ret = new Roo[cfg.xtype](grid, cfg); // new panel!!!!!
405 this.add(region, ret);
406 if (cfg.background) {
407 ret.on('activate', function(gp) {
408 if (!gp.grid.rendered) {
423 if (typeof(Roo[cfg.xtype]) != 'undefined') {
425 ret = new Roo[cfg.xtype](cfg); // new panel!!!!!
426 this.add(region, ret);
429 alert("Can not add '" + cfg.xtype + "' to BorderLayout");
433 // GridPanel (grid, cfg)
440 Roo.each(xitems, function(i) {
441 region = nb && i.region ? i.region : false;
443 var add = ret.addxtype(i);
446 nb[region] = nb[region] == undefined ? 0 : nb[region]+1;
448 abn[region] = nb[region] ;
455 // make the last non-background panel active..
456 //if (nb) { Roo.log(abn); }
460 region = this.getRegion(r);
462 // tried using nb[r], but it does not work..
464 region.showPanel(abn[r]);
475 factory : function(cfg)
478 var validRegions = ["north","south","east","west","center"];
480 var target = cfg.region;
483 var r = Roo.bootstrap.layout;
487 return new r.North(cfg);
489 return new r.South(cfg);
491 return new r.East(cfg);
493 return new r.West(cfg);
495 return new r.Center(cfg);
497 throw 'Layout region "'+target+'" not supported.';