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);
55 return this.regions[target];
59 bindRegion : function(r){
60 this.regions[r.target] = r;
62 r.on("visibilitychange", this.layout, this);
63 r.on("paneladded", this.layout, this);
64 r.on("panelremoved", this.layout, this);
65 r.on("invalidated", this.layout, this);
66 r.on("resized", this.onRegionResized, this);
67 r.on("collapsed", this.onRegionCollapsed, this);
68 r.on("expanded", this.onRegionExpanded, this);
72 * Performs a layout update.
78 var size = this.getViewSize();
87 var rs = this.regions;
88 var north = rs["north"];
89 var south = rs["south"];
90 var west = rs["west"];
91 var east = rs["east"];
92 var center = rs["center"];
93 //if(this.hideOnLayout){ // not supported anymore
94 //c.el.setStyle("display", "none");
96 if(north && north.isVisible()){
97 var b = north.getBox();
98 var m = north.getMargins();
99 b.width = w - (m.left+m.right);
102 centerY = b.height + b.y + m.bottom;
104 north.updateBox(this.safeBox(b));
106 if(south && south.isVisible()){
107 var b = south.getBox();
108 var m = south.getMargins();
109 b.width = w - (m.left+m.right);
111 var totalHeight = (b.height + m.top + m.bottom);
112 b.y = h - totalHeight + m.top;
113 centerH -= totalHeight;
114 south.updateBox(this.safeBox(b));
116 if(west && west.isVisible()){
117 var b = west.getBox();
118 var m = west.getMargins();
119 b.height = centerH - (m.top+m.bottom);
121 b.y = centerY + m.top;
122 var totalWidth = (b.width + m.left + m.right);
123 centerX += totalWidth;
124 centerW -= totalWidth;
125 west.updateBox(this.safeBox(b));
127 if(east && east.isVisible()){
128 var b = east.getBox();
129 var m = east.getMargins();
130 b.height = centerH - (m.top+m.bottom);
131 var totalWidth = (b.width + m.left + m.right);
132 b.x = w - totalWidth + m.left;
133 b.y = centerY + m.top;
134 centerW -= totalWidth;
135 east.updateBox(this.safeBox(b));
138 var m = center.getMargins();
142 width: centerW - (m.left+m.right),
143 height: centerH - (m.top+m.bottom)
145 //if(this.hideOnLayout){
146 //center.el.setStyle("display", "block");
148 center.updateBox(this.safeBox(centerBox));
151 this.fireEvent("layout", this);
155 safeBox : function(box){
156 box.width = Math.max(0, box.width);
157 box.height = Math.max(0, box.height);
162 * Adds a ContentPanel (or subclass) to this layout.
163 * @param {String} target The target region key (north, south, east, west or center).
164 * @param {Roo.ContentPanel} panel The panel to add
165 * @return {Roo.ContentPanel} The added panel
167 add : function(target, panel){
169 target = target.toLowerCase();
170 return this.regions[target].add(panel);
174 * Remove a ContentPanel (or subclass) to this layout.
175 * @param {String} target The target region key (north, south, east, west or center).
176 * @param {Number/String/Roo.ContentPanel} panel The index, id or panel to remove
177 * @return {Roo.ContentPanel} The removed panel
179 remove : function(target, panel){
180 target = target.toLowerCase();
181 return this.regions[target].remove(panel);
185 * Searches all regions for a panel with the specified id
186 * @param {String} panelId
187 * @return {Roo.ContentPanel} The panel or null if it wasn't found
189 findPanel : function(panelId){
190 var rs = this.regions;
191 for(var target in rs){
192 if(typeof rs[target] != "function"){
193 var p = rs[target].getPanel(panelId);
203 * Searches all regions for a panel with the specified id and activates (shows) it.
204 * @param {String/ContentPanel} panelId The panels id or the panel itself
205 * @return {Roo.ContentPanel} The shown panel or null
207 showPanel : function(panelId) {
208 var rs = this.regions;
209 for(var target in rs){
211 if(typeof r != "function"){
212 if(r.hasPanel(panelId)){
213 return r.showPanel(panelId);
221 * Restores this layout's state using Roo.state.Manager or the state provided by the passed provider.
222 * @param {Roo.state.Provider} provider (optional) An alternate state provider
224 restoreState : function(provider){
226 provider = Roo.state.Manager;
228 var sm = new Roo.LayoutStateManager();
229 sm.init(this, provider);
233 * Adds a batch of multiple ContentPanels dynamically by passing a special regions config object. This config
234 * object should contain properties for each region to add ContentPanels to, and each property's value should be
235 * a valid ContentPanel config object. Example:
237 // Create the main layout
238 var layout = new Roo.BorderLayout('main-ct', {
249 // Create and add multiple ContentPanels at once via configs
254 title:'Ext Source Files',
267 * @param {Object} regions An object containing ContentPanel configs by region name
269 batchAdd : function(regions){
271 for(var rname in regions){
272 var lr = this.regions[rname];
274 this.addTypedPanels(lr, regions[rname]);
281 addTypedPanels : function(lr, ps){
282 if(typeof ps == 'string'){
283 lr.add(new Roo.ContentPanel(ps));
285 else if(ps instanceof Array){
286 for(var i =0, len = ps.length; i < len; i++){
287 this.addTypedPanels(lr, ps[i]);
290 else if(!ps.events){ // raw config?
292 delete ps.el; // prevent conflict
293 lr.add(new Roo.ContentPanel(el || Roo.id(), ps));
295 else { // panel object assumed!
300 * Adds a xtype elements to the layout.
304 xtype : 'ContentPanel',
311 xtype : 'NestedLayoutPanel',
317 items : [ ... list of content panels or nested layout panels.. ]
321 * @param {Object} cfg Xtype definition of item to add.
323 addxtype : function(cfg)
325 // basically accepts a pannel...
326 // can accept a layout region..!?!?
327 //Roo.log('Roo.BorderLayout add ' + cfg.xtype)
329 if (!cfg.xtype.match(/Panel$/)) {
334 if (typeof(cfg.region) == 'undefined') {
335 Roo.log("Failed to add Panel, region was not set");
339 var region = cfg.region;
352 case 'ContentPanel': // ContentPanel (el, cfg)
353 case 'ScrollPanel': // ContentPanel (el, cfg)
356 ret = new Roo[cfg.xtype](cfg); // new panel!!!!!
358 var el = this.el.createChild();
359 ret = new Roo[cfg.xtype](el, cfg); // new panel!!!!!
362 this.add(region, ret);
366 case 'TreePanel': // our new panel!
367 cfg.el = this.el.createChild();
368 ret = new Roo[cfg.xtype](cfg); // new panel!!!!!
369 this.add(region, ret);
372 case 'NestedLayoutPanel':
373 // create a new Layout (which is a Border Layout...
374 var el = this.el.createChild();
375 var clayout = cfg.layout;
377 clayout.items = clayout.items || [];
378 // replace this exitems with the clayout ones..
379 xitems = clayout.items;
382 if (region == 'center' && this.active && this.getRegion('center').panels.length < 1) {
383 cfg.background = false;
385 var layout = new Roo.BorderLayout(el, clayout);
387 ret = new Roo[cfg.xtype](layout, cfg); // new panel!!!!!
388 //console.log('adding nested layout panel ' + cfg.toSource());
389 this.add(region, ret);
390 nb = {}; /// find first...
395 // needs grid and region
397 //var el = this.getRegion(region).el.createChild();
398 var el = this.el.createChild();
399 // create the grid first...
401 var grid = new Roo.grid[cfg.grid.xtype](el, cfg.grid);
403 if (region == 'center' && this.active ) {
404 cfg.background = false;
406 ret = new Roo[cfg.xtype](grid, cfg); // new panel!!!!!
408 this.add(region, ret);
409 if (cfg.background) {
410 ret.on('activate', function(gp) {
411 if (!gp.grid.rendered) {
426 if (typeof(Roo[cfg.xtype]) != 'undefined') {
428 ret = new Roo[cfg.xtype](cfg); // new panel!!!!!
429 this.add(region, ret);
432 alert("Can not add '" + cfg.xtype + "' to BorderLayout");
436 // GridPanel (grid, cfg)
443 Roo.each(xitems, function(i) {
444 region = nb && i.region ? i.region : false;
446 var add = ret.addxtype(i);
449 nb[region] = nb[region] == undefined ? 0 : nb[region]+1;
451 abn[region] = nb[region] ;
458 // make the last non-background panel active..
459 //if (nb) { Roo.log(abn); }
463 region = this.getRegion(r);
465 // tried using nb[r], but it does not work..
467 region.showPanel(abn[r]);
478 factory : function(cfg)
481 var validRegions = ["north","south","east","west","center"];
483 var target = cfg.region;
486 var r = Roo.bootstrap.layout;
490 return new r.North(cfg);
492 return new r.South(cfg);
494 return new r.East(cfg);
496 return new r.West(cfg);
498 return new r.Center(cfg);
500 throw 'Layout region "'+target+'" not supported.';