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 config[target].target = region;
34 this.addRegion(config[target]);
40 Roo.bootstrap.layout.Border.regions = ["north","south","east","west","center"];
42 Roo.extend(Roo.bootstrap.layout.Border, Roo.bootstrap.layout.Manager, {
44 * Creates and adds a new region if it doesn't already exist.
45 * @param {String} target The target region key (north, south, east, west or center).
46 * @param {Object} config The regions config object
47 * @return {BorderLayoutRegion} The new region
49 addRegion : function(target, config)
51 if(!this.regions[target]){
52 var r = this.factory(config);
53 this.bindRegion(target, r);
55 return this.regions[target];
59 bindRegion : function(name, r){
60 this.regions[name] = r;
61 r.on("visibilitychange", this.layout, this);
62 r.on("paneladded", this.layout, this);
63 r.on("panelremoved", this.layout, this);
64 r.on("invalidated", this.layout, this);
65 r.on("resized", this.onRegionResized, this);
66 r.on("collapsed", this.onRegionCollapsed, this);
67 r.on("expanded", this.onRegionExpanded, this);
71 * Performs a layout update.
77 var size = this.getViewSize();
86 var rs = this.regions;
87 var north = rs["north"];
88 var south = rs["south"];
89 var west = rs["west"];
90 var east = rs["east"];
91 var center = rs["center"];
92 //if(this.hideOnLayout){ // not supported anymore
93 //c.el.setStyle("display", "none");
95 if(north && north.isVisible()){
96 var b = north.getBox();
97 var m = north.getMargins();
98 b.width = w - (m.left+m.right);
101 centerY = b.height + b.y + m.bottom;
103 north.updateBox(this.safeBox(b));
105 if(south && south.isVisible()){
106 var b = south.getBox();
107 var m = south.getMargins();
108 b.width = w - (m.left+m.right);
110 var totalHeight = (b.height + m.top + m.bottom);
111 b.y = h - totalHeight + m.top;
112 centerH -= totalHeight;
113 south.updateBox(this.safeBox(b));
115 if(west && west.isVisible()){
116 var b = west.getBox();
117 var m = west.getMargins();
118 b.height = centerH - (m.top+m.bottom);
120 b.y = centerY + m.top;
121 var totalWidth = (b.width + m.left + m.right);
122 centerX += totalWidth;
123 centerW -= totalWidth;
124 west.updateBox(this.safeBox(b));
126 if(east && east.isVisible()){
127 var b = east.getBox();
128 var m = east.getMargins();
129 b.height = centerH - (m.top+m.bottom);
130 var totalWidth = (b.width + m.left + m.right);
131 b.x = w - totalWidth + m.left;
132 b.y = centerY + m.top;
133 centerW -= totalWidth;
134 east.updateBox(this.safeBox(b));
137 var m = center.getMargins();
141 width: centerW - (m.left+m.right),
142 height: centerH - (m.top+m.bottom)
144 //if(this.hideOnLayout){
145 //center.el.setStyle("display", "block");
147 center.updateBox(this.safeBox(centerBox));
150 this.fireEvent("layout", this);
154 safeBox : function(box){
155 box.width = Math.max(0, box.width);
156 box.height = Math.max(0, box.height);
161 * Adds a ContentPanel (or subclass) to this layout.
162 * @param {String} target The target region key (north, south, east, west or center).
163 * @param {Roo.ContentPanel} panel The panel to add
164 * @return {Roo.ContentPanel} The added panel
166 add : function(target, panel){
168 target = target.toLowerCase();
169 return this.regions[target].add(panel);
173 * Remove a ContentPanel (or subclass) to this layout.
174 * @param {String} target The target region key (north, south, east, west or center).
175 * @param {Number/String/Roo.ContentPanel} panel The index, id or panel to remove
176 * @return {Roo.ContentPanel} The removed panel
178 remove : function(target, panel){
179 target = target.toLowerCase();
180 return this.regions[target].remove(panel);
184 * Searches all regions for a panel with the specified id
185 * @param {String} panelId
186 * @return {Roo.ContentPanel} The panel or null if it wasn't found
188 findPanel : function(panelId){
189 var rs = this.regions;
190 for(var target in rs){
191 if(typeof rs[target] != "function"){
192 var p = rs[target].getPanel(panelId);
202 * Searches all regions for a panel with the specified id and activates (shows) it.
203 * @param {String/ContentPanel} panelId The panels id or the panel itself
204 * @return {Roo.ContentPanel} The shown panel or null
206 showPanel : function(panelId) {
207 var rs = this.regions;
208 for(var target in rs){
210 if(typeof r != "function"){
211 if(r.hasPanel(panelId)){
212 return r.showPanel(panelId);
220 * Restores this layout's state using Roo.state.Manager or the state provided by the passed provider.
221 * @param {Roo.state.Provider} provider (optional) An alternate state provider
223 restoreState : function(provider){
225 provider = Roo.state.Manager;
227 var sm = new Roo.LayoutStateManager();
228 sm.init(this, provider);
232 * Adds a batch of multiple ContentPanels dynamically by passing a special regions config object. This config
233 * object should contain properties for each region to add ContentPanels to, and each property's value should be
234 * a valid ContentPanel config object. Example:
236 // Create the main layout
237 var layout = new Roo.BorderLayout('main-ct', {
248 // Create and add multiple ContentPanels at once via configs
253 title:'Ext Source Files',
266 * @param {Object} regions An object containing ContentPanel configs by region name
268 batchAdd : function(regions){
270 for(var rname in regions){
271 var lr = this.regions[rname];
273 this.addTypedPanels(lr, regions[rname]);
280 addTypedPanels : function(lr, ps){
281 if(typeof ps == 'string'){
282 lr.add(new Roo.ContentPanel(ps));
284 else if(ps instanceof Array){
285 for(var i =0, len = ps.length; i < len; i++){
286 this.addTypedPanels(lr, ps[i]);
289 else if(!ps.events){ // raw config?
291 delete ps.el; // prevent conflict
292 lr.add(new Roo.ContentPanel(el || Roo.id(), ps));
294 else { // panel object assumed!
299 * Adds a xtype elements to the layout.
303 xtype : 'ContentPanel',
310 xtype : 'NestedLayoutPanel',
316 items : [ ... list of content panels or nested layout panels.. ]
320 * @param {Object} cfg Xtype definition of item to add.
322 addxtype : function(cfg)
324 // basically accepts a pannel...
325 // can accept a layout region..!?!?
326 //Roo.log('Roo.BorderLayout add ' + cfg.xtype)
328 if (!cfg.xtype.match(/Panel$/)) {
333 if (typeof(cfg.region) == 'undefined') {
334 Roo.log("Failed to add Panel, region was not set");
338 var region = cfg.region;
351 case 'ContentPanel': // ContentPanel (el, cfg)
352 case 'ScrollPanel': // ContentPanel (el, cfg)
355 ret = new Roo[cfg.xtype](cfg); // new panel!!!!!
357 var el = this.el.createChild();
358 ret = new Roo[cfg.xtype](el, cfg); // new panel!!!!!
361 this.add(region, ret);
365 case 'TreePanel': // our new panel!
366 cfg.el = this.el.createChild();
367 ret = new Roo[cfg.xtype](cfg); // new panel!!!!!
368 this.add(region, ret);
371 case 'NestedLayoutPanel':
372 // create a new Layout (which is a Border Layout...
373 var el = this.el.createChild();
374 var clayout = cfg.layout;
376 clayout.items = clayout.items || [];
377 // replace this exitems with the clayout ones..
378 xitems = clayout.items;
381 if (region == 'center' && this.active && this.getRegion('center').panels.length < 1) {
382 cfg.background = false;
384 var layout = new Roo.BorderLayout(el, clayout);
386 ret = new Roo[cfg.xtype](layout, cfg); // new panel!!!!!
387 //console.log('adding nested layout panel ' + cfg.toSource());
388 this.add(region, ret);
389 nb = {}; /// find first...
394 // needs grid and region
396 //var el = this.getRegion(region).el.createChild();
397 var el = this.el.createChild();
398 // create the grid first...
400 var grid = new Roo.grid[cfg.grid.xtype](el, cfg.grid);
402 if (region == 'center' && this.active ) {
403 cfg.background = false;
405 ret = new Roo[cfg.xtype](grid, cfg); // new panel!!!!!
407 this.add(region, ret);
408 if (cfg.background) {
409 ret.on('activate', function(gp) {
410 if (!gp.grid.rendered) {
425 if (typeof(Roo[cfg.xtype]) != 'undefined') {
427 ret = new Roo[cfg.xtype](cfg); // new panel!!!!!
428 this.add(region, ret);
431 alert("Can not add '" + cfg.xtype + "' to BorderLayout");
435 // GridPanel (grid, cfg)
442 Roo.each(xitems, function(i) {
443 region = nb && i.region ? i.region : false;
445 var add = ret.addxtype(i);
448 nb[region] = nb[region] == undefined ? 0 : nb[region]+1;
450 abn[region] = nb[region] ;
457 // make the last non-background panel active..
458 //if (nb) { Roo.log(abn); }
462 region = this.getRegion(r);
464 // tried using nb[r], but it does not work..
466 region.showPanel(abn[r]);
477 factory : function(cfg)
480 var validRegions = ["north","south","east","west","center"];
482 var target = cfg.region;
485 var r = Roo.bootstrap.layout;
489 return new r.North(cfg);
491 return new r.South(cfg);
493 return new r.East(cfg);
495 return new r.West(cfg);
497 return new r.Center(cfg);
499 throw 'Layout region "'+target+'" not supported.';