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 || {};
29 Roo.bootstrap.layout.Border.superclass.constructor.call(this, config);
31 Roo.each(Roo.bootstrap.layout.Border.regions, function(region) {
33 config[region].region = region;
34 this.addRegion(config[region]);
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(config)
51 if(!this.regions[config.region]){
52 var r = this.factory(config);
55 return this.regions[config.region];
59 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);
72 onVisibilitychange : function()
78 * Performs a layout update.
82 Roo.log('calling layout!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
88 // render all the rebions if they have not been done alreayd?
89 Roo.each(Roo.bootstrap.layout.Border.regions, function(region) {
90 if(this.regions[region] && !this.regions[region].bodyEl){
91 this.regions[region].onRender(this.el)
95 var size = this.getViewSize();
104 var rs = this.regions;
105 var north = rs["north"];
106 var south = rs["south"];
107 var west = rs["west"];
108 var east = rs["east"];
109 var center = rs["center"];
110 //if(this.hideOnLayout){ // not supported anymore
111 //c.el.setStyle("display", "none");
113 if(north && north.isVisible()){
114 var b = north.getBox();
115 var m = north.getMargins();
116 b.width = w - (m.left+m.right);
119 centerY = b.height + b.y + m.bottom;
121 north.updateBox(this.safeBox(b));
123 if(south && south.isVisible()){
124 var b = south.getBox();
125 var m = south.getMargins();
126 b.width = w - (m.left+m.right);
128 var totalHeight = (b.height + m.top + m.bottom);
129 b.y = h - totalHeight + m.top;
130 centerH -= totalHeight;
131 south.updateBox(this.safeBox(b));
133 if(west && west.isVisible()){
134 var b = west.getBox();
135 var m = west.getMargins();
136 b.height = centerH - (m.top+m.bottom);
138 b.y = centerY + m.top;
139 var totalWidth = (b.width + m.left + m.right);
140 centerX += totalWidth;
141 centerW -= totalWidth;
142 west.updateBox(this.safeBox(b));
144 if(east && east.isVisible()){
145 var b = east.getBox();
146 var m = east.getMargins();
147 b.height = centerH - (m.top+m.bottom);
148 var totalWidth = (b.width + m.left + m.right);
149 b.x = w - totalWidth + m.left;
150 b.y = centerY + m.top;
151 centerW -= totalWidth;
152 east.updateBox(this.safeBox(b));
155 var m = center.getMargins();
159 width: centerW - (m.left+m.right),
160 height: centerH - (m.top+m.bottom)
162 //if(this.hideOnLayout){
163 //center.el.setStyle("display", "block");
165 center.updateBox(this.safeBox(centerBox));
168 this.fireEvent("layout", this);
172 safeBox : function(box){
173 box.width = Math.max(0, box.width);
174 box.height = Math.max(0, box.height);
179 * Adds a ContentPanel (or subclass) to this layout.
180 * @param {String} target The target region key (north, south, east, west or center).
181 * @param {Roo.ContentPanel} panel The panel to add
182 * @return {Roo.ContentPanel} The added panel
184 add : function(target, panel){
186 target = target.toLowerCase();
187 return this.regions[target].add(panel);
191 * Remove a ContentPanel (or subclass) to this layout.
192 * @param {String} target The target region key (north, south, east, west or center).
193 * @param {Number/String/Roo.ContentPanel} panel The index, id or panel to remove
194 * @return {Roo.ContentPanel} The removed panel
196 remove : function(target, panel){
197 target = target.toLowerCase();
198 return this.regions[target].remove(panel);
202 * Searches all regions for a panel with the specified id
203 * @param {String} panelId
204 * @return {Roo.ContentPanel} The panel or null if it wasn't found
206 findPanel : function(panelId){
207 var rs = this.regions;
208 for(var target in rs){
209 if(typeof rs[target] != "function"){
210 var p = rs[target].getPanel(panelId);
220 * Searches all regions for a panel with the specified id and activates (shows) it.
221 * @param {String/ContentPanel} panelId The panels id or the panel itself
222 * @return {Roo.ContentPanel} The shown panel or null
224 showPanel : function(panelId) {
225 var rs = this.regions;
226 for(var target in rs){
228 if(typeof r != "function"){
229 if(r.hasPanel(panelId)){
230 return r.showPanel(panelId);
238 * Restores this layout's state using Roo.state.Manager or the state provided by the passed provider.
239 * @param {Roo.state.Provider} provider (optional) An alternate state provider
242 restoreState : function(provider){
244 provider = Roo.state.Manager;
246 var sm = new Roo.LayoutStateManager();
247 sm.init(this, provider);
253 * Adds a xtype elements to the layout.
257 xtype : 'ContentPanel',
264 xtype : 'NestedLayoutPanel',
270 items : [ ... list of content panels or nested layout panels.. ]
274 * @param {Object} cfg Xtype definition of item to add.
276 addxtype : function(cfg)
278 // basically accepts a pannel...
279 // can accept a layout region..!?!?
280 //Roo.log('Roo.BorderLayout add ' + cfg.xtype)
283 // theory? children can only be panels??
285 //if (!cfg.xtype.match(/Panel$/)) {
290 if (typeof(cfg.region) == 'undefined') {
291 Roo.log("Failed to add Panel, region was not set");
295 var region = cfg.region;
308 case 'Content': // ContentPanel (el, cfg)
309 case 'Scroll': // ContentPanel (el, cfg)
311 cfg.autoCreate = true;
312 ret = new cfg.xns[cfg.xtype](cfg); // new panel!!!!!
314 // var el = this.el.createChild();
315 // ret = new Roo[cfg.xtype](el, cfg); // new panel!!!!!
318 this.add(region, ret);
322 case 'TreePanel': // our new panel!
323 cfg.el = this.el.createChild();
324 ret = new Roo[cfg.xtype](cfg); // new panel!!!!!
325 this.add(region, ret);
330 // create a new Layout (which is a Border Layout...
332 var clayout = cfg.layout;
333 clayout.el = this.el.createChild();
334 clayout.items = clayout.items || [];
338 // replace this exitems with the clayout ones..
339 xitems = clayout.items;
341 // force background off if it's in center...
342 if (region == 'center' && this.active && this.getRegion('center').panels.length < 1) {
343 cfg.background = false;
345 cfg.layout = new Roo.bootstrap.layout.Border(clayout);
348 ret = new cfg.xns[cfg.xtype](cfg); // new panel!!!!!
349 //console.log('adding nested layout panel ' + cfg.toSource());
350 this.add(region, ret);
351 nb = {}; /// find first...
356 // needs grid and region
358 //var el = this.getRegion(region).el.createChild();
360 *var el = this.el.createChild();
361 // create the grid first...
362 cfg.grid.container = el;
363 cfg.grid = new cfg.grid.xns[cfg.grid.xtype](cfg.grid);
366 if (region == 'center' && this.active ) {
367 cfg.background = false;
370 ret = new cfg.xns[cfg.xtype](cfg); // new panel!!!!!
372 this.add(region, ret);
374 if (cfg.background) {
375 // render grid on panel activation (if panel background)
376 ret.on('activate', function(gp) {
377 if (!gp.grid.rendered) {
378 // gp.grid.render(el);
382 // cfg.grid.render(el);
388 case 'Border': // it can get called on it'self... - might need to check if this is fixed?
389 // it was the old xcomponent building that caused this before.
390 // espeically if border is the top element in the tree.
400 if (typeof(Roo[cfg.xtype]) != 'undefined') {
402 ret = new Roo[cfg.xtype](cfg); // new panel!!!!!
403 this.add(region, ret);
407 throw "Can not add '" + cfg.xtype + "' to Border";
417 Roo.each(xitems, function(i) {
418 region = nb && i.region ? i.region : false;
420 var add = ret.addxtype(i);
423 nb[region] = nb[region] == undefined ? 0 : nb[region]+1;
425 abn[region] = nb[region] ;
432 // make the last non-background panel active..
433 //if (nb) { Roo.log(abn); }
437 region = this.getRegion(r);
439 // tried using nb[r], but it does not work..
441 region.showPanel(abn[r]);
451 factory : function(cfg)
454 var validRegions = Roo.bootstrap.layout.Border.regions;
456 var target = cfg.region;
459 var r = Roo.bootstrap.layout;
463 return new r.North(cfg);
465 return new r.South(cfg);
467 return new r.East(cfg);
469 return new r.West(cfg);
471 return new r.Center(cfg);
473 throw 'Layout region "'+target+'" not supported.';