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.
81 // render all the rebions if they have not been done alreayd?
82 Roo.each(Roo.bootstrap.layout.Border.regions, function(region) {
83 if(this.regions[region] && !this.regions[region].bodyEl){
84 this.regions[region].onRender(this.el)
88 var size = this.getViewSize();
97 var rs = this.regions;
98 var north = rs["north"];
99 var south = rs["south"];
100 var west = rs["west"];
101 var east = rs["east"];
102 var center = rs["center"];
103 //if(this.hideOnLayout){ // not supported anymore
104 //c.el.setStyle("display", "none");
106 if(north && north.isVisible()){
107 var b = north.getBox();
108 var m = north.getMargins();
109 b.width = w - (m.left+m.right);
112 centerY = b.height + b.y + m.bottom;
114 north.updateBox(this.safeBox(b));
116 if(south && south.isVisible()){
117 var b = south.getBox();
118 var m = south.getMargins();
119 b.width = w - (m.left+m.right);
121 var totalHeight = (b.height + m.top + m.bottom);
122 b.y = h - totalHeight + m.top;
123 centerH -= totalHeight;
124 south.updateBox(this.safeBox(b));
126 if(west && west.isVisible()){
127 var b = west.getBox();
128 var m = west.getMargins();
129 b.height = centerH - (m.top+m.bottom);
131 b.y = centerY + m.top;
132 var totalWidth = (b.width + m.left + m.right);
133 centerX += totalWidth;
134 centerW -= totalWidth;
135 west.updateBox(this.safeBox(b));
137 if(east && east.isVisible()){
138 var b = east.getBox();
139 var m = east.getMargins();
140 b.height = centerH - (m.top+m.bottom);
141 var totalWidth = (b.width + m.left + m.right);
142 b.x = w - totalWidth + m.left;
143 b.y = centerY + m.top;
144 centerW -= totalWidth;
145 east.updateBox(this.safeBox(b));
148 var m = center.getMargins();
152 width: centerW - (m.left+m.right),
153 height: centerH - (m.top+m.bottom)
155 //if(this.hideOnLayout){
156 //center.el.setStyle("display", "block");
158 center.updateBox(this.safeBox(centerBox));
161 this.fireEvent("layout", this);
165 safeBox : function(box){
166 box.width = Math.max(0, box.width);
167 box.height = Math.max(0, box.height);
172 * Adds a ContentPanel (or subclass) to this layout.
173 * @param {String} target The target region key (north, south, east, west or center).
174 * @param {Roo.ContentPanel} panel The panel to add
175 * @return {Roo.ContentPanel} The added panel
177 add : function(target, panel){
179 target = target.toLowerCase();
180 return this.regions[target].add(panel);
184 * Remove a ContentPanel (or subclass) to this layout.
185 * @param {String} target The target region key (north, south, east, west or center).
186 * @param {Number/String/Roo.ContentPanel} panel The index, id or panel to remove
187 * @return {Roo.ContentPanel} The removed panel
189 remove : function(target, panel){
190 target = target.toLowerCase();
191 return this.regions[target].remove(panel);
195 * Searches all regions for a panel with the specified id
196 * @param {String} panelId
197 * @return {Roo.ContentPanel} The panel or null if it wasn't found
199 findPanel : function(panelId){
200 var rs = this.regions;
201 for(var target in rs){
202 if(typeof rs[target] != "function"){
203 var p = rs[target].getPanel(panelId);
213 * Searches all regions for a panel with the specified id and activates (shows) it.
214 * @param {String/ContentPanel} panelId The panels id or the panel itself
215 * @return {Roo.ContentPanel} The shown panel or null
217 showPanel : function(panelId) {
218 var rs = this.regions;
219 for(var target in rs){
221 if(typeof r != "function"){
222 if(r.hasPanel(panelId)){
223 return r.showPanel(panelId);
231 * Restores this layout's state using Roo.state.Manager or the state provided by the passed provider.
232 * @param {Roo.state.Provider} provider (optional) An alternate state provider
235 restoreState : function(provider){
237 provider = Roo.state.Manager;
239 var sm = new Roo.LayoutStateManager();
240 sm.init(this, provider);
246 * Adds a xtype elements to the layout.
250 xtype : 'ContentPanel',
257 xtype : 'NestedLayoutPanel',
263 items : [ ... list of content panels or nested layout panels.. ]
267 * @param {Object} cfg Xtype definition of item to add.
269 addxtype : function(cfg)
271 // basically accepts a pannel...
272 // can accept a layout region..!?!?
273 //Roo.log('Roo.BorderLayout add ' + cfg.xtype)
276 // theory? children can only be panels??
278 //if (!cfg.xtype.match(/Panel$/)) {
283 if (typeof(cfg.region) == 'undefined') {
284 Roo.log("Failed to add Panel, region was not set");
288 var region = cfg.region;
301 case 'Content': // ContentPanel (el, cfg)
302 case 'Scroll': // ContentPanel (el, cfg)
304 cfg.autoCreate = cfg.autoCreate || true;
305 ret = new cfg.xns[cfg.xtype](cfg); // new panel!!!!!
307 // var el = this.el.createChild();
308 // ret = new Roo[cfg.xtype](el, cfg); // new panel!!!!!
311 this.add(region, ret);
315 case 'TreePanel': // our new panel!
316 cfg.el = this.el.createChild();
317 ret = new Roo[cfg.xtype](cfg); // new panel!!!!!
318 this.add(region, ret);
323 // create a new Layout (which is a Border Layout...
325 var clayout = cfg.layout;
326 clayout.el = this.el.createChild();
327 clayout.items = clayout.items || [];
331 // replace this exitems with the clayout ones..
332 xitems = clayout.items;
334 // force background off if it's in center...
335 if (region == 'center' && this.active && this.getRegion('center').panels.length < 1) {
336 cfg.background = false;
338 cfg.layout = new Roo.bootstrap.layout.Border(clayout);
341 ret = new cfg.xns[cfg.xtype](cfg); // new panel!!!!!
342 //console.log('adding nested layout panel ' + cfg.toSource());
343 this.add(region, ret);
344 nb = {}; /// find first...
349 // needs grid and region
351 //var el = this.getRegion(region).el.createChild();
353 *var el = this.el.createChild();
354 // create the grid first...
355 cfg.grid.container = el;
356 cfg.grid = new cfg.grid.xns[cfg.grid.xtype](cfg.grid);
359 if (region == 'center' && this.active ) {
360 cfg.background = false;
363 ret = new cfg.xns[cfg.xtype](cfg); // new panel!!!!!
365 this.add(region, ret);
367 if (cfg.background) {
368 // render grid on panel activation (if panel background)
369 ret.on('activate', function(gp) {
370 if (!gp.grid.rendered) {
371 // gp.grid.render(el);
375 // cfg.grid.render(el);
381 case 'Border': // it can get called on it'self... - might need to check if this is fixed?
382 // it was the old xcomponent building that caused this before.
383 // espeically if border is the top element in the tree.
393 if (typeof(Roo[cfg.xtype]) != 'undefined') {
395 ret = new Roo[cfg.xtype](cfg); // new panel!!!!!
396 this.add(region, ret);
400 throw "Can not add '" + cfg.xtype + "' to Border";
410 Roo.each(xitems, function(i) {
411 region = nb && i.region ? i.region : false;
413 var add = ret.addxtype(i);
416 nb[region] = nb[region] == undefined ? 0 : nb[region]+1;
418 abn[region] = nb[region] ;
425 // make the last non-background panel active..
426 //if (nb) { Roo.log(abn); }
430 region = this.getRegion(r);
432 // tried using nb[r], but it does not work..
434 region.showPanel(abn[r]);
445 factory : function(cfg)
448 var validRegions = Roo.bootstrap.layout.Border.regions;
450 var target = cfg.region;
453 var r = Roo.bootstrap.layout;
457 return new r.North(cfg);
459 return new r.South(cfg);
461 return new r.East(cfg);
463 return new r.West(cfg);
465 return new r.Center(cfg);
467 throw 'Layout region "'+target+'" not supported.';