+/*
+ * Based on:
+ * Ext JS Library 1.1.1
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ *
+ * Originally Released Under LGPL - original licence link has changed is not relivant.
+ *
+ * Fork - LGPL
+ * <script type="text/javascript">
+ */
+/**
+ * @class Roo.bootstrap.layout.Border
+ * @extends Roo.bootstrap.layout.Manager
+ * This class represents a common layout manager used in desktop applications. For screenshots and more details,
+ * please see: examples/bootstrap/nested.html<br><br>
+
+<b>The container the layout is rendered into can be either the body element or any other element.
+If it is not the body element, the container needs to either be an absolute positioned element,
+or you will need to add "position:relative" to the css of the container. You will also need to specify
+the container size if it is not the body element.</b>
+
+* @constructor
+* Create a new Border
+* @param {Object} config Configuration options
+ */
+Roo.bootstrap.layout.Border = function(config){
+ config = config || {};
+ Roo.bootstrap.layout.Border.superclass.constructor.call(this, config);
+
+
+
+ Roo.each(Roo.bootstrap.layout.Border.regions, function(region) {
+ if(config[region]){
+ config[region].region = region;
+ this.addRegion(config[region]);
+ }
+ },this);
+
+};
+
+Roo.bootstrap.layout.Border.regions = ["north","south","east","west","center"];
+
+Roo.extend(Roo.bootstrap.layout.Border, Roo.bootstrap.layout.Manager, {
+ /**
+ * Creates and adds a new region if it doesn't already exist.
+ * @param {String} target The target region key (north, south, east, west or center).
+ * @param {Object} config The regions config object
+ * @return {BorderLayoutRegion} The new region
+ */
+ addRegion : function(config)
+ {
+ if(!this.regions[config.region]){
+ var r = this.factory(config);
+ this.bindRegion(r);
+ }
+ return this.regions[config.region];
+ },
+
+ // private (kinda)
+ bindRegion : function(r){
+ this.regions[r.config.region] = r;
+
+ r.on("visibilitychange", this.layout, this);
+ r.on("paneladded", this.layout, this);
+ r.on("panelremoved", this.layout, this);
+ r.on("invalidated", this.layout, this);
+ r.on("resized", this.onRegionResized, this);
+ r.on("collapsed", this.onRegionCollapsed, this);
+ r.on("expanded", this.onRegionExpanded, this);
+ },
+
+ /**
+ * Performs a layout update.
+ */
+ layout : function()
+ {
+ if(this.updating) {
+ return;
+ }
+
+ // render all the rebions if they have not been done alreayd?
+ Roo.each(Roo.bootstrap.layout.Border.regions, function(region) {
+ if(this.regions[region] && !this.regions[region].bodyEl){
+ this.regions[region].onRender(this.el)
+ }
+ },this);
+
+ var size = this.getViewSize();
+ var w = size.width;
+ var h = size.height;
+ var centerW = w;
+ var centerH = h;
+ var centerY = 0;
+ var centerX = 0;
+ //var x = 0, y = 0;
+
+ var rs = this.regions;
+ var north = rs["north"];
+ var south = rs["south"];
+ var west = rs["west"];
+ var east = rs["east"];
+ var center = rs["center"];
+ //if(this.hideOnLayout){ // not supported anymore
+ //c.el.setStyle("display", "none");
+ //}
+ if(north && north.isVisible()){
+ var b = north.getBox();
+ var m = north.getMargins();
+ b.width = w - (m.left+m.right);
+ b.x = m.left;
+ b.y = m.top;
+ centerY = b.height + b.y + m.bottom;
+ centerH -= centerY;
+ north.updateBox(this.safeBox(b));
+ }
+ if(south && south.isVisible()){
+ var b = south.getBox();
+ var m = south.getMargins();
+ b.width = w - (m.left+m.right);
+ b.x = m.left;
+ var totalHeight = (b.height + m.top + m.bottom);
+ b.y = h - totalHeight + m.top;
+ centerH -= totalHeight;
+ south.updateBox(this.safeBox(b));
+ }
+ if(west && west.isVisible()){
+ var b = west.getBox();
+ var m = west.getMargins();
+ b.height = centerH - (m.top+m.bottom);
+ b.x = m.left;
+ b.y = centerY + m.top;
+ var totalWidth = (b.width + m.left + m.right);
+ centerX += totalWidth;
+ centerW -= totalWidth;
+ west.updateBox(this.safeBox(b));
+ }
+ if(east && east.isVisible()){
+ var b = east.getBox();
+ var m = east.getMargins();
+ b.height = centerH - (m.top+m.bottom);
+ var totalWidth = (b.width + m.left + m.right);
+ b.x = w - totalWidth + m.left;
+ b.y = centerY + m.top;
+ centerW -= totalWidth;
+ east.updateBox(this.safeBox(b));
+ }
+ if(center){
+ var m = center.getMargins();
+ var centerBox = {
+ x: centerX + m.left,
+ y: centerY + m.top,
+ width: centerW - (m.left+m.right),
+ height: centerH - (m.top+m.bottom)
+ };
+ //if(this.hideOnLayout){
+ //center.el.setStyle("display", "block");
+ //}
+ center.updateBox(this.safeBox(centerBox));
+ }
+ this.el.repaint();
+ this.fireEvent("layout", this);
+ },
+
+ // private
+ safeBox : function(box){
+ box.width = Math.max(0, box.width);
+ box.height = Math.max(0, box.height);
+ return box;
+ },
+
+ /**
+ * Adds a ContentPanel (or subclass) to this layout.
+ * @param {String} target The target region key (north, south, east, west or center).
+ * @param {Roo.ContentPanel} panel The panel to add
+ * @return {Roo.ContentPanel} The added panel
+ */
+ add : function(target, panel){
+
+ target = target.toLowerCase();
+ return this.regions[target].add(panel);
+ },
+
+ /**
+ * Remove a ContentPanel (or subclass) to this layout.
+ * @param {String} target The target region key (north, south, east, west or center).
+ * @param {Number/String/Roo.ContentPanel} panel The index, id or panel to remove
+ * @return {Roo.ContentPanel} The removed panel
+ */
+ remove : function(target, panel){
+ target = target.toLowerCase();
+ return this.regions[target].remove(panel);
+ },
+
+ /**
+ * Searches all regions for a panel with the specified id
+ * @param {String} panelId
+ * @return {Roo.ContentPanel} The panel or null if it wasn't found
+ */
+ findPanel : function(panelId){
+ var rs = this.regions;
+ for(var target in rs){
+ if(typeof rs[target] != "function"){
+ var p = rs[target].getPanel(panelId);
+ if(p){
+ return p;
+ }
+ }
+ }
+ return null;
+ },
+
+ /**
+ * Searches all regions for a panel with the specified id and activates (shows) it.
+ * @param {String/ContentPanel} panelId The panels id or the panel itself
+ * @return {Roo.ContentPanel} The shown panel or null
+ */
+ showPanel : function(panelId) {
+ var rs = this.regions;
+ for(var target in rs){
+ var r = rs[target];
+ if(typeof r != "function"){
+ if(r.hasPanel(panelId)){
+ return r.showPanel(panelId);
+ }
+ }
+ }
+ return null;
+ },
+
+ /**
+ * Restores this layout's state using Roo.state.Manager or the state provided by the passed provider.
+ * @param {Roo.state.Provider} provider (optional) An alternate state provider
+ */
+ /*
+ restoreState : function(provider){
+ if(!provider){
+ provider = Roo.state.Manager;
+ }
+ var sm = new Roo.LayoutStateManager();
+ sm.init(this, provider);
+ },
+*/
+
+
+ /**
+ * Adds a xtype elements to the layout.
+ * <pre><code>
+
+layout.addxtype({
+ xtype : 'ContentPanel',
+ region: 'west',
+ items: [ .... ]
+ }
+);
+
+layout.addxtype({
+ xtype : 'NestedLayoutPanel',
+ region: 'west',
+ layout: {
+ center: { },
+ west: { }
+ },
+ items : [ ... list of content panels or nested layout panels.. ]
+ }
+);
+</code></pre>
+ * @param {Object} cfg Xtype definition of item to add.
+ */
+ addxtype : function(cfg)
+ {
+ // basically accepts a pannel...
+ // can accept a layout region..!?!?
+ //Roo.log('Roo.BorderLayout add ' + cfg.xtype)
+
+
+ // theory? children can only be panels??
+
+ //if (!cfg.xtype.match(/Panel$/)) {
+ // return false;
+ //}
+ var ret = false;
+
+ if (typeof(cfg.region) == 'undefined') {
+ Roo.log("Failed to add Panel, region was not set");
+ Roo.log(cfg);
+ return false;
+ }
+ var region = cfg.region;
+ delete cfg.region;
+
+
+ var xitems = [];
+ if (cfg.items) {
+ xitems = cfg.items;
+ delete cfg.items;
+ }
+ var nb = false;
+
+ if (cfg.region == 'center') {
+ Roo.log("Center" + cfg.title);
+ }
+
+
+ switch(cfg.xtype)
+ {
+ case 'Content': // ContentPanel (el, cfg)
+ case 'Scroll': // ContentPanel (el, cfg)
+ case 'View':
+ cfg.autoCreate = cfg.autoCreate || true;
+ ret = new cfg.xns[cfg.xtype](cfg); // new panel!!!!!
+ //} else {
+ // var el = this.el.createChild();
+ // ret = new Roo[cfg.xtype](el, cfg); // new panel!!!!!
+ //}
+
+ this.add(region, ret);
+ break;
+
+ /*
+ case 'TreePanel': // our new panel!
+ cfg.el = this.el.createChild();
+ ret = new Roo[cfg.xtype](cfg); // new panel!!!!!
+ this.add(region, ret);
+ break;
+ */
+
+ case 'Nest':
+ // create a new Layout (which is a Border Layout...
+
+ var clayout = cfg.layout;
+ clayout.el = this.el.createChild();
+ clayout.items = clayout.items || [];
+
+ delete cfg.layout;
+
+ // replace this exitems with the clayout ones..
+ xitems = clayout.items;
+
+ // force background off if it's in center...
+ if (region == 'center' && this.active && this.getRegion('center').panels.length < 1) {
+ cfg.background = false;
+ }
+ cfg.layout = new Roo.bootstrap.layout.Border(clayout);
+
+
+ ret = new cfg.xns[cfg.xtype](cfg); // new panel!!!!!
+ //console.log('adding nested layout panel ' + cfg.toSource());
+ this.add(region, ret);
+ nb = {}; /// find first...
+ break;
+
+ case 'Grid':
+
+ // needs grid and region
+
+ //var el = this.getRegion(region).el.createChild();
+ /*
+ *var el = this.el.createChild();
+ // create the grid first...
+ cfg.grid.container = el;
+ cfg.grid = new cfg.grid.xns[cfg.grid.xtype](cfg.grid);
+ */
+
+ if (region == 'center' && this.active ) {
+ cfg.background = false;
+ }
+
+ ret = new cfg.xns[cfg.xtype](cfg); // new panel!!!!!
+
+ this.add(region, ret);
+ /*
+ if (cfg.background) {
+ // render grid on panel activation (if panel background)
+ ret.on('activate', function(gp) {
+ if (!gp.grid.rendered) {
+ // gp.grid.render(el);
+ }
+ });
+ } else {
+ // cfg.grid.render(el);
+ }
+ */
+ break;
+
+
+ case 'Border': // it can get called on it'self... - might need to check if this is fixed?
+ // it was the old xcomponent building that caused this before.
+ // espeically if border is the top element in the tree.
+ ret = this;
+ break;
+
+
+
+
+
+ default:
+ /*
+ if (typeof(Roo[cfg.xtype]) != 'undefined') {
+
+ ret = new Roo[cfg.xtype](cfg); // new panel!!!!!
+ this.add(region, ret);
+ } else {
+ */
+ Roo.log(cfg);
+ throw "Can not add '" + cfg.xtype + "' to Border";
+ return null;
+
+
+
+ }
+ this.beginUpdate();
+ // add children..
+ var region = '';
+ var abn = {};
+ Roo.each(xitems, function(i) {
+ region = nb && i.region ? i.region : false;
+
+ var add = ret.addxtype(i);
+
+ if (region) {
+ nb[region] = nb[region] == undefined ? 0 : nb[region]+1;
+ if (!i.background) {
+ abn[region] = nb[region] ;
+ }
+ }
+
+ });
+ this.endUpdate();
+
+ // make the last non-background panel active..
+ //if (nb) { Roo.log(abn); }
+ if (nb) {
+
+ for(var r in abn) {
+ region = this.getRegion(r);
+ if (region) {
+ // tried using nb[r], but it does not work..
+
+ region.showPanel(abn[r]);
+
+ }
+ }
+ }
+ return ret;
+
+ },
+
+
+// private
+ factory : function(cfg)
+ {
+
+ var validRegions = Roo.bootstrap.layout.Border.regions;
+
+ var target = cfg.region;
+ cfg.mgr = this;
+
+ var r = Roo.bootstrap.layout;
+ Roo.log(target);
+ switch(target){
+ case "north":
+ return new r.North(cfg);
+ case "south":
+ return new r.South(cfg);
+ case "east":
+ return new r.East(cfg);
+ case "west":
+ return new r.West(cfg);
+ case "center":
+ return new r.Center(cfg);
+ }
+ throw 'Layout region "'+target+'" not supported.';
+ }
+
+
+});
+
\ No newline at end of file