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;
299 if (cfg.region == 'center') {
300 Roo.log("Center" + cfg.title);
306 case 'Content': // ContentPanel (el, cfg)
307 case 'Scroll': // ContentPanel (el, cfg)
309 cfg.autoCreate = cfg.autoCreate || true;
310 ret = new cfg.xns[cfg.xtype](cfg); // new panel!!!!!
312 // var el = this.el.createChild();
313 // ret = new Roo[cfg.xtype](el, cfg); // new panel!!!!!
316 this.add(region, ret);
320 case 'TreePanel': // our new panel!
321 cfg.el = this.el.createChild();
322 ret = new Roo[cfg.xtype](cfg); // new panel!!!!!
323 this.add(region, ret);
328 // create a new Layout (which is a Border Layout...
330 var clayout = cfg.layout;
331 clayout.el = this.el.createChild();
332 clayout.items = clayout.items || [];
336 // replace this exitems with the clayout ones..
337 xitems = clayout.items;
339 // force background off if it's in center...
340 if (region == 'center' && this.active && this.getRegion('center').panels.length < 1) {
341 cfg.background = false;
343 cfg.layout = new Roo.bootstrap.layout.Border(clayout);
346 ret = new cfg.xns[cfg.xtype](cfg); // new panel!!!!!
347 //console.log('adding nested layout panel ' + cfg.toSource());
348 this.add(region, ret);
349 nb = {}; /// find first...
354 // needs grid and region
356 //var el = this.getRegion(region).el.createChild();
358 *var el = this.el.createChild();
359 // create the grid first...
360 cfg.grid.container = el;
361 cfg.grid = new cfg.grid.xns[cfg.grid.xtype](cfg.grid);
364 if (region == 'center' && this.active ) {
365 cfg.background = false;
368 ret = new cfg.xns[cfg.xtype](cfg); // new panel!!!!!
370 this.add(region, ret);
372 if (cfg.background) {
373 // render grid on panel activation (if panel background)
374 ret.on('activate', function(gp) {
375 if (!gp.grid.rendered) {
376 // gp.grid.render(el);
380 // cfg.grid.render(el);
386 case 'Border': // it can get called on it'self... - might need to check if this is fixed?
387 // it was the old xcomponent building that caused this before.
388 // espeically if border is the top element in the tree.
398 if (typeof(Roo[cfg.xtype]) != 'undefined') {
400 ret = new Roo[cfg.xtype](cfg); // new panel!!!!!
401 this.add(region, ret);
405 throw "Can not add '" + cfg.xtype + "' to Border";
415 Roo.each(xitems, function(i) {
416 region = nb && i.region ? i.region : false;
418 var add = ret.addxtype(i);
421 nb[region] = nb[region] == undefined ? 0 : nb[region]+1;
423 abn[region] = nb[region] ;
430 // make the last non-background panel active..
431 //if (nb) { Roo.log(abn); }
435 region = this.getRegion(r);
437 // tried using nb[r], but it does not work..
439 region.showPanel(abn[r]);
450 factory : function(cfg)
453 var validRegions = Roo.bootstrap.layout.Border.regions;
455 var target = cfg.region;
458 var r = Roo.bootstrap.layout;
462 return new r.North(cfg);
464 return new r.South(cfg);
466 return new r.East(cfg);
468 return new r.West(cfg);
470 return new r.Center(cfg);
472 throw 'Layout region "'+target+'" not supported.';