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
15 * This class represents a common layout manager used in desktop applications. For screenshots and more details,
16 * please see: examples/bootstrap/nested.html<br><br>
18 <b>The container the layout is rendered into can be either the body element or any other element.
19 If it is not the body element, the container needs to either be an absolute positioned element,
20 or you will need to add "position:relative" to the css of the container. You will also need to specify
21 the container size if it is not the body element.</b>
25 * @param {Object} config Configuration options
27 Roo.bootstrap.layout.Border = function(config){
28 config = config || {};
29 Roo.bootstrap.layout.Border.superclass.constructor.call(this, config);
33 Roo.each(Roo.bootstrap.layout.Border.regions, function(region) {
35 config[region].region = region;
36 this.addRegion(config[region]);
42 Roo.bootstrap.layout.Border.regions = ["center", "north","south","east","west"];
44 Roo.extend(Roo.bootstrap.layout.Border, Roo.bootstrap.layout.Manager, {
46 parent : false, // this might point to a 'nest' or a ???
49 * Creates and adds a new region if it doesn't already exist.
50 * @param {String} target The target region key (north, south, east, west or center).
51 * @param {Object} config The regions config object
52 * @return {BorderLayoutRegion} The new region
54 addRegion : function(config)
56 if(!this.regions[config.region]){
57 var r = this.factory(config);
60 return this.regions[config.region];
64 bindRegion : function(r){
65 this.regions[r.config.region] = r;
67 r.on("visibilitychange", this.layout, this);
68 r.on("paneladded", this.layout, this);
69 r.on("panelremoved", this.layout, this);
70 r.on("invalidated", this.layout, this);
71 r.on("resized", this.onRegionResized, this);
72 r.on("collapsed", this.onRegionCollapsed, this);
73 r.on("expanded", this.onRegionExpanded, this);
77 * Performs a layout update.
85 // render all the rebions if they have not been done alreayd?
86 Roo.each(Roo.bootstrap.layout.Border.regions, function(region) {
87 if(this.regions[region] && !this.regions[region].bodyEl){
88 this.regions[region].onRender(this.el)
92 var size = this.getViewSize();
101 var rs = this.regions;
102 var north = rs["north"];
103 var south = rs["south"];
104 var west = rs["west"];
105 var east = rs["east"];
106 var center = rs["center"];
107 //if(this.hideOnLayout){ // not supported anymore
108 //c.el.setStyle("display", "none");
110 if(north && north.isVisible()){
111 var b = north.getBox();
112 var m = north.getMargins();
113 b.width = w - (m.left+m.right);
116 centerY = b.height + b.y + m.bottom;
118 north.updateBox(this.safeBox(b));
120 if(south && south.isVisible()){
121 var b = south.getBox();
122 var m = south.getMargins();
123 b.width = w - (m.left+m.right);
125 var totalHeight = (b.height + m.top + m.bottom);
126 b.y = h - totalHeight + m.top;
127 centerH -= totalHeight;
128 south.updateBox(this.safeBox(b));
130 if(west && west.isVisible()){
131 var b = west.getBox();
132 var m = west.getMargins();
133 b.height = centerH - (m.top+m.bottom);
135 b.y = centerY + m.top;
136 var totalWidth = (b.width + m.left + m.right);
137 centerX += totalWidth;
138 centerW -= totalWidth;
139 west.updateBox(this.safeBox(b));
141 if(east && east.isVisible()){
142 var b = east.getBox();
143 var m = east.getMargins();
144 b.height = centerH - (m.top+m.bottom);
145 var totalWidth = (b.width + m.left + m.right);
146 b.x = w - totalWidth + m.left;
147 b.y = centerY + m.top;
148 centerW -= totalWidth;
149 east.updateBox(this.safeBox(b));
152 var m = center.getMargins();
156 width: centerW - (m.left+m.right),
157 height: centerH - (m.top+m.bottom)
159 //if(this.hideOnLayout){
160 //center.el.setStyle("display", "block");
162 center.updateBox(this.safeBox(centerBox));
165 this.fireEvent("layout", this);
169 safeBox : function(box){
170 box.width = Math.max(0, box.width);
171 box.height = Math.max(0, box.height);
176 * Adds a ContentPanel (or subclass) to this layout.
177 * @param {String} target The target region key (north, south, east, west or center).
178 * @param {Roo.ContentPanel} panel The panel to add
179 * @return {Roo.ContentPanel} The added panel
181 add : function(target, panel){
183 target = target.toLowerCase();
184 return this.regions[target].add(panel);
188 * Remove a ContentPanel (or subclass) to this layout.
189 * @param {String} target The target region key (north, south, east, west or center).
190 * @param {Number/String/Roo.ContentPanel} panel The index, id or panel to remove
191 * @return {Roo.ContentPanel} The removed panel
193 remove : function(target, panel){
194 target = target.toLowerCase();
195 return this.regions[target].remove(panel);
199 * Searches all regions for a panel with the specified id
200 * @param {String} panelId
201 * @return {Roo.ContentPanel} The panel or null if it wasn't found
203 findPanel : function(panelId){
204 var rs = this.regions;
205 for(var target in rs){
206 if(typeof rs[target] != "function"){
207 var p = rs[target].getPanel(panelId);
217 * Searches all regions for a panel with the specified id and activates (shows) it.
218 * @param {String/ContentPanel} panelId The panels id or the panel itself
219 * @return {Roo.ContentPanel} The shown panel or null
221 showPanel : function(panelId) {
222 var rs = this.regions;
223 for(var target in rs){
225 if(typeof r != "function"){
226 if(r.hasPanel(panelId)){
227 return r.showPanel(panelId);
235 * Restores this layout's state using Roo.state.Manager or the state provided by the passed provider.
236 * @param {Roo.state.Provider} provider (optional) An alternate state provider
239 restoreState : function(provider){
241 provider = Roo.state.Manager;
243 var sm = new Roo.LayoutStateManager();
244 sm.init(this, provider);
250 * Adds a xtype elements to the layout.
254 xtype : 'ContentPanel',
261 xtype : 'NestedLayoutPanel',
267 items : [ ... list of content panels or nested layout panels.. ]
271 * @param {Object} cfg Xtype definition of item to add.
273 addxtype : function(cfg)
275 // basically accepts a pannel...
276 // can accept a layout region..!?!?
277 //Roo.log('Roo.BorderLayout add ' + cfg.xtype)
280 // theory? children can only be panels??
282 //if (!cfg.xtype.match(/Panel$/)) {
287 if (typeof(cfg.region) == 'undefined') {
288 Roo.log("Failed to add Panel, region was not set");
292 var region = cfg.region;
303 if ( region == 'center') {
304 Roo.log("Center: " + cfg.title);
310 case 'Content': // ContentPanel (el, cfg)
311 case 'Scroll': // ContentPanel (el, cfg)
313 cfg.autoCreate = cfg.autoCreate || true;
314 ret = new cfg.xns[cfg.xtype](cfg); // new panel!!!!!
316 // var el = this.el.createChild();
317 // ret = new Roo[cfg.xtype](el, cfg); // new panel!!!!!
320 this.add(region, ret);
324 case 'TreePanel': // our new panel!
325 cfg.el = this.el.createChild();
326 ret = new Roo[cfg.xtype](cfg); // new panel!!!!!
327 this.add(region, ret);
332 // create a new Layout (which is a Border Layout...
334 var clayout = cfg.layout;
335 clayout.el = this.el.createChild();
336 clayout.items = clayout.items || [];
340 // replace this exitems with the clayout ones..
341 xitems = clayout.items;
343 // force background off if it's in center...
344 if (region == 'center' && this.active && this.getRegion('center').panels.length < 1) {
345 cfg.background = false;
347 cfg.layout = new Roo.bootstrap.layout.Border(clayout);
350 ret = new cfg.xns[cfg.xtype](cfg); // new panel!!!!!
351 //console.log('adding nested layout panel ' + cfg.toSource());
352 this.add(region, ret);
353 nb = {}; /// find first...
358 // needs grid and region
360 //var el = this.getRegion(region).el.createChild();
362 *var el = this.el.createChild();
363 // create the grid first...
364 cfg.grid.container = el;
365 cfg.grid = new cfg.grid.xns[cfg.grid.xtype](cfg.grid);
368 if (region == 'center' && this.active ) {
369 cfg.background = false;
372 ret = new cfg.xns[cfg.xtype](cfg); // new panel!!!!!
374 this.add(region, ret);
376 if (cfg.background) {
377 // render grid on panel activation (if panel background)
378 ret.on('activate', function(gp) {
379 if (!gp.grid.rendered) {
380 // gp.grid.render(el);
384 // cfg.grid.render(el);
390 case 'Border': // it can get called on it'self... - might need to check if this is fixed?
391 // it was the old xcomponent building that caused this before.
392 // espeically if border is the top element in the tree.
402 if (typeof(Roo[cfg.xtype]) != 'undefined') {
404 ret = new Roo[cfg.xtype](cfg); // new panel!!!!!
405 this.add(region, ret);
409 throw "Can not add '" + cfg.xtype + "' to Border";
419 Roo.each(xitems, function(i) {
420 region = nb && i.region ? i.region : false;
422 var add = ret.addxtype(i);
425 nb[region] = nb[region] == undefined ? 0 : nb[region]+1;
427 abn[region] = nb[region] ;
434 // make the last non-background panel active..
435 //if (nb) { Roo.log(abn); }
439 region = this.getRegion(r);
441 // tried using nb[r], but it does not work..
443 region.showPanel(abn[r]);
454 factory : function(cfg)
457 var validRegions = Roo.bootstrap.layout.Border.regions;
459 var target = cfg.region;
462 var r = Roo.bootstrap.layout;
466 return new r.North(cfg);
468 return new r.South(cfg);
470 return new r.East(cfg);
472 return new r.West(cfg);
474 return new r.Center(cfg);
476 throw 'Layout region "'+target+'" not supported.';