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 parent : false, // this might point to a 'nest' or a ???
48 * Creates and adds a new region if it doesn't already exist.
49 * @param {String} target The target region key (north, south, east, west or center).
50 * @param {Object} config The regions config object
51 * @return {BorderLayoutRegion} The new region
53 addRegion : function(config)
55 if(!this.regions[config.region]){
56 var r = this.factory(config);
59 return this.regions[config.region];
63 bindRegion : function(r){
64 this.regions[r.config.region] = r;
66 r.on("visibilitychange", this.layout, this);
67 r.on("paneladded", this.layout, this);
68 r.on("panelremoved", this.layout, this);
69 r.on("invalidated", this.layout, this);
70 r.on("resized", this.onRegionResized, this);
71 r.on("collapsed", this.onRegionCollapsed, this);
72 r.on("expanded", this.onRegionExpanded, this);
76 * Performs a layout update.
84 // render all the rebions if they have not been done alreayd?
85 Roo.each(Roo.bootstrap.layout.Border.regions, function(region) {
86 if(this.regions[region] && !this.regions[region].bodyEl){
87 this.regions[region].onRender(this.el)
91 var size = this.getViewSize();
100 var rs = this.regions;
101 var north = rs["north"];
102 var south = rs["south"];
103 var west = rs["west"];
104 var east = rs["east"];
105 var center = rs["center"];
106 //if(this.hideOnLayout){ // not supported anymore
107 //c.el.setStyle("display", "none");
109 if(north && north.isVisible()){
110 var b = north.getBox();
111 var m = north.getMargins();
112 b.width = w - (m.left+m.right);
115 centerY = b.height + b.y + m.bottom;
117 north.updateBox(this.safeBox(b));
119 if(south && south.isVisible()){
120 var b = south.getBox();
121 var m = south.getMargins();
122 b.width = w - (m.left+m.right);
124 var totalHeight = (b.height + m.top + m.bottom);
125 b.y = h - totalHeight + m.top;
126 centerH -= totalHeight;
127 south.updateBox(this.safeBox(b));
129 if(west && west.isVisible()){
130 var b = west.getBox();
131 var m = west.getMargins();
132 b.height = centerH - (m.top+m.bottom);
134 b.y = centerY + m.top;
135 var totalWidth = (b.width + m.left + m.right);
136 centerX += totalWidth;
137 centerW -= totalWidth;
138 west.updateBox(this.safeBox(b));
140 if(east && east.isVisible()){
141 var b = east.getBox();
142 var m = east.getMargins();
143 b.height = centerH - (m.top+m.bottom);
144 var totalWidth = (b.width + m.left + m.right);
145 b.x = w - totalWidth + m.left;
146 b.y = centerY + m.top;
147 centerW -= totalWidth;
148 east.updateBox(this.safeBox(b));
151 var m = center.getMargins();
155 width: centerW - (m.left+m.right),
156 height: centerH - (m.top+m.bottom)
158 //if(this.hideOnLayout){
159 //center.el.setStyle("display", "block");
161 center.updateBox(this.safeBox(centerBox));
164 this.fireEvent("layout", this);
168 safeBox : function(box){
169 box.width = Math.max(0, box.width);
170 box.height = Math.max(0, box.height);
175 * Adds a ContentPanel (or subclass) to this layout.
176 * @param {String} target The target region key (north, south, east, west or center).
177 * @param {Roo.ContentPanel} panel The panel to add
178 * @return {Roo.ContentPanel} The added panel
180 add : function(target, panel){
182 target = target.toLowerCase();
183 return this.regions[target].add(panel);
187 * Remove a ContentPanel (or subclass) to this layout.
188 * @param {String} target The target region key (north, south, east, west or center).
189 * @param {Number/String/Roo.ContentPanel} panel The index, id or panel to remove
190 * @return {Roo.ContentPanel} The removed panel
192 remove : function(target, panel){
193 target = target.toLowerCase();
194 return this.regions[target].remove(panel);
198 * Searches all regions for a panel with the specified id
199 * @param {String} panelId
200 * @return {Roo.ContentPanel} The panel or null if it wasn't found
202 findPanel : function(panelId){
203 var rs = this.regions;
204 for(var target in rs){
205 if(typeof rs[target] != "function"){
206 var p = rs[target].getPanel(panelId);
216 * Searches all regions for a panel with the specified id and activates (shows) it.
217 * @param {String/ContentPanel} panelId The panels id or the panel itself
218 * @return {Roo.ContentPanel} The shown panel or null
220 showPanel : function(panelId) {
221 var rs = this.regions;
222 for(var target in rs){
224 if(typeof r != "function"){
225 if(r.hasPanel(panelId)){
226 return r.showPanel(panelId);
234 * Restores this layout's state using Roo.state.Manager or the state provided by the passed provider.
235 * @param {Roo.state.Provider} provider (optional) An alternate state provider
238 restoreState : function(provider){
240 provider = Roo.state.Manager;
242 var sm = new Roo.LayoutStateManager();
243 sm.init(this, provider);
249 * Adds a xtype elements to the layout.
253 xtype : 'ContentPanel',
260 xtype : 'NestedLayoutPanel',
266 items : [ ... list of content panels or nested layout panels.. ]
270 * @param {Object} cfg Xtype definition of item to add.
272 addxtype : function(cfg)
274 // basically accepts a pannel...
275 // can accept a layout region..!?!?
276 //Roo.log('Roo.BorderLayout add ' + cfg.xtype)
279 // theory? children can only be panels??
281 //if (!cfg.xtype.match(/Panel$/)) {
286 if (typeof(cfg.region) == 'undefined') {
287 Roo.log("Failed to add Panel, region was not set");
291 var region = cfg.region;
302 if ( region == 'center') {
303 Roo.log("Center: " + cfg.title);
309 case 'Content': // ContentPanel (el, cfg)
310 case 'Scroll': // ContentPanel (el, cfg)
312 cfg.autoCreate = cfg.autoCreate || true;
313 ret = new cfg.xns[cfg.xtype](cfg); // new panel!!!!!
315 // var el = this.el.createChild();
316 // ret = new Roo[cfg.xtype](el, cfg); // new panel!!!!!
319 this.add(region, ret);
323 case 'TreePanel': // our new panel!
324 cfg.el = this.el.createChild();
325 ret = new Roo[cfg.xtype](cfg); // new panel!!!!!
326 this.add(region, ret);
331 // create a new Layout (which is a Border Layout...
333 var clayout = cfg.layout;
334 clayout.el = this.el.createChild();
335 clayout.items = clayout.items || [];
339 // replace this exitems with the clayout ones..
340 xitems = clayout.items;
342 // force background off if it's in center...
343 if (region == 'center' && this.active && this.getRegion('center').panels.length < 1) {
344 cfg.background = false;
346 cfg.layout = new Roo.bootstrap.layout.Border(clayout);
349 ret = new cfg.xns[cfg.xtype](cfg); // new panel!!!!!
350 //console.log('adding nested layout panel ' + cfg.toSource());
351 this.add(region, ret);
352 nb = {}; /// find first...
357 // needs grid and region
359 //var el = this.getRegion(region).el.createChild();
361 *var el = this.el.createChild();
362 // create the grid first...
363 cfg.grid.container = el;
364 cfg.grid = new cfg.grid.xns[cfg.grid.xtype](cfg.grid);
367 if (region == 'center' && this.active ) {
368 cfg.background = false;
371 ret = new cfg.xns[cfg.xtype](cfg); // new panel!!!!!
373 this.add(region, ret);
375 if (cfg.background) {
376 // render grid on panel activation (if panel background)
377 ret.on('activate', function(gp) {
378 if (!gp.grid.rendered) {
379 // gp.grid.render(el);
383 // cfg.grid.render(el);
389 case 'Border': // it can get called on it'self... - might need to check if this is fixed?
390 // it was the old xcomponent building that caused this before.
391 // espeically if border is the top element in the tree.
401 if (typeof(Roo[cfg.xtype]) != 'undefined') {
403 ret = new Roo[cfg.xtype](cfg); // new panel!!!!!
404 this.add(region, ret);
408 throw "Can not add '" + cfg.xtype + "' to Border";
418 Roo.each(xitems, function(i) {
419 region = nb && i.region ? i.region : false;
421 var add = ret.addxtype(i);
424 nb[region] = nb[region] == undefined ? 0 : nb[region]+1;
426 abn[region] = nb[region] ;
433 // make the last non-background panel active..
434 //if (nb) { Roo.log(abn); }
438 region = this.getRegion(r);
440 // tried using nb[r], but it does not work..
442 region.showPanel(abn[r]);
453 factory : function(cfg)
456 var validRegions = Roo.bootstrap.layout.Border.regions;
458 var target = cfg.region;
461 var r = Roo.bootstrap.layout;
465 return new r.North(cfg);
467 return new r.South(cfg);
469 return new r.East(cfg);
471 return new r.West(cfg);
473 return new r.Center(cfg);
475 throw 'Layout region "'+target+'" not supported.';