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.
80 var size = this.getViewSize();
89 var rs = this.regions;
90 var north = rs["north"];
91 var south = rs["south"];
92 var west = rs["west"];
93 var east = rs["east"];
94 var center = rs["center"];
95 //if(this.hideOnLayout){ // not supported anymore
96 //c.el.setStyle("display", "none");
98 if(north && north.isVisible()){
99 var b = north.getBox();
100 var m = north.getMargins();
101 b.width = w - (m.left+m.right);
104 centerY = b.height + b.y + m.bottom;
106 north.updateBox(this.safeBox(b));
108 if(south && south.isVisible()){
109 var b = south.getBox();
110 var m = south.getMargins();
111 b.width = w - (m.left+m.right);
113 var totalHeight = (b.height + m.top + m.bottom);
114 b.y = h - totalHeight + m.top;
115 centerH -= totalHeight;
116 south.updateBox(this.safeBox(b));
118 if(west && west.isVisible()){
119 var b = west.getBox();
120 var m = west.getMargins();
121 b.height = centerH - (m.top+m.bottom);
123 b.y = centerY + m.top;
124 var totalWidth = (b.width + m.left + m.right);
125 centerX += totalWidth;
126 centerW -= totalWidth;
127 west.updateBox(this.safeBox(b));
129 if(east && east.isVisible()){
130 var b = east.getBox();
131 var m = east.getMargins();
132 b.height = centerH - (m.top+m.bottom);
133 var totalWidth = (b.width + m.left + m.right);
134 b.x = w - totalWidth + m.left;
135 b.y = centerY + m.top;
136 centerW -= totalWidth;
137 east.updateBox(this.safeBox(b));
140 var m = center.getMargins();
144 width: centerW - (m.left+m.right),
145 height: centerH - (m.top+m.bottom)
147 //if(this.hideOnLayout){
148 //center.el.setStyle("display", "block");
150 center.updateBox(this.safeBox(centerBox));
153 this.fireEvent("layout", this);
157 safeBox : function(box){
158 box.width = Math.max(0, box.width);
159 box.height = Math.max(0, box.height);
164 * Adds a ContentPanel (or subclass) to this layout.
165 * @param {String} target The target region key (north, south, east, west or center).
166 * @param {Roo.ContentPanel} panel The panel to add
167 * @return {Roo.ContentPanel} The added panel
169 add : function(target, panel){
171 target = target.toLowerCase();
172 return this.regions[target].add(panel);
176 * Remove a ContentPanel (or subclass) to this layout.
177 * @param {String} target The target region key (north, south, east, west or center).
178 * @param {Number/String/Roo.ContentPanel} panel The index, id or panel to remove
179 * @return {Roo.ContentPanel} The removed panel
181 remove : function(target, panel){
182 target = target.toLowerCase();
183 return this.regions[target].remove(panel);
187 * Searches all regions for a panel with the specified id
188 * @param {String} panelId
189 * @return {Roo.ContentPanel} The panel or null if it wasn't found
191 findPanel : function(panelId){
192 var rs = this.regions;
193 for(var target in rs){
194 if(typeof rs[target] != "function"){
195 var p = rs[target].getPanel(panelId);
205 * Searches all regions for a panel with the specified id and activates (shows) it.
206 * @param {String/ContentPanel} panelId The panels id or the panel itself
207 * @return {Roo.ContentPanel} The shown panel or null
209 showPanel : function(panelId) {
210 var rs = this.regions;
211 for(var target in rs){
213 if(typeof r != "function"){
214 if(r.hasPanel(panelId)){
215 return r.showPanel(panelId);
223 * Restores this layout's state using Roo.state.Manager or the state provided by the passed provider.
224 * @param {Roo.state.Provider} provider (optional) An alternate state provider
227 restoreState : function(provider){
229 provider = Roo.state.Manager;
231 var sm = new Roo.LayoutStateManager();
232 sm.init(this, provider);
238 * Adds a xtype elements to the layout.
242 xtype : 'ContentPanel',
249 xtype : 'NestedLayoutPanel',
255 items : [ ... list of content panels or nested layout panels.. ]
259 * @param {Object} cfg Xtype definition of item to add.
261 addxtype : function(cfg)
263 // basically accepts a pannel...
264 // can accept a layout region..!?!?
265 //Roo.log('Roo.BorderLayout add ' + cfg.xtype)
268 // theory? children can only be panels??
270 //if (!cfg.xtype.match(/Panel$/)) {
275 if (typeof(cfg.region) == 'undefined') {
276 Roo.log("Failed to add Panel, region was not set");
280 var region = cfg.region;
293 case 'Content': // ContentPanel (el, cfg)
294 case 'Scroll': // ContentPanel (el, cfg)
296 cfg.autoCreate = true;
297 ret = new cfg.xns[cfg.xtype](cfg); // new panel!!!!!
299 // var el = this.el.createChild();
300 // ret = new Roo[cfg.xtype](el, cfg); // new panel!!!!!
303 this.add(region, ret);
307 case 'TreePanel': // our new panel!
308 cfg.el = this.el.createChild();
309 ret = new Roo[cfg.xtype](cfg); // new panel!!!!!
310 this.add(region, ret);
315 // create a new Layout (which is a Border Layout...
317 var clayout = cfg.layout;
318 clayout.el = this.el.createChild();
319 clayout.items = clayout.items || [];
323 // replace this exitems with the clayout ones..
324 xitems = clayout.items;
326 // force background off if it's in center...
327 if (region == 'center' && this.active && this.getRegion('center').panels.length < 1) {
328 cfg.background = false;
330 cfg.layout = new Roo.bootstrap.layout.Border(clayout);
333 ret = new cfg.xns[cfg.xtype](cfg); // new panel!!!!!
334 //console.log('adding nested layout panel ' + cfg.toSource());
335 this.add(region, ret);
336 nb = {}; /// find first...
341 // needs grid and region
343 //var el = this.getRegion(region).el.createChild();
344 var el = this.el.createChild();
345 // create the grid first...
347 var grid = new cfg.grid.ns[cfg.grid.xtype](el);
349 if (region == 'center' && this.active ) {
350 cfg.background = false;
352 ret = new Roo[cfg.xtype](grid, cfg); // new panel!!!!!
354 this.add(region, ret);
355 if (cfg.background) {
356 ret.on('activate', function(gp) {
357 if (!gp.grid.rendered) {
367 case 'Border': // it can get called on it'self...
377 if (typeof(Roo[cfg.xtype]) != 'undefined') {
379 ret = new Roo[cfg.xtype](cfg); // new panel!!!!!
380 this.add(region, ret);
384 throw "Can not add '" + cfg.xtype + "' to Border";
388 // GridPanel (grid, cfg)
395 Roo.each(xitems, function(i) {
396 region = nb && i.region ? i.region : false;
398 var add = ret.addxtype(i);
401 nb[region] = nb[region] == undefined ? 0 : nb[region]+1;
403 abn[region] = nb[region] ;
410 // make the last non-background panel active..
411 //if (nb) { Roo.log(abn); }
415 region = this.getRegion(r);
417 // tried using nb[r], but it does not work..
419 region.showPanel(abn[r]);
430 factory : function(cfg)
433 var validRegions = Roo.bootstrap.layout.Border.regions;
435 var target = cfg.region;
438 var r = Roo.bootstrap.layout;
442 return new r.North(cfg);
444 return new r.South(cfg);
446 return new r.East(cfg);
448 return new r.West(cfg);
450 return new r.Center(cfg);
452 throw 'Layout region "'+target+'" not supported.';