X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/ee06f37b0f6f6d94cd05a6ffae556660f7c4a2bc..c930e9176a5a85509c5b0230e2bff5c22a591432:/docs/source/BorderLayout.html?ds=sidebyside diff --git a/docs/source/BorderLayout.html b/docs/source/BorderLayout.html new file mode 100644 index 00000000..0856904c --- /dev/null +++ b/docs/source/BorderLayout.html @@ -0,0 +1,1111 @@ + +
+/** + * @class Ext.layout.BorderLayout + * @extends Ext.layout.ContainerLayout + *This is a multi-pane, application-oriented UI layout style that supports multiple + * nested panels, automatic {@link Ext.layout.BorderLayout.Region#split split} bars between + * {@link Ext.layout.BorderLayout.Region#BorderLayout.Region regions} and built-in + * {@link Ext.layout.BorderLayout.Region#collapsible expanding and collapsing} of regions.
+ *This class is intended to be extended or created via the layout:'border' + * {@link Ext.Container#layout} config, and should generally not need to be created directly + * via the new keyword.
+ *BorderLayout does not have any direct config options (other than inherited ones). + * All configuration options available for customizing the BorderLayout are at the + * {@link Ext.layout.BorderLayout.Region} and {@link Ext.layout.BorderLayout.SplitRegion} + * levels.
+ *Example usage:
+ *+ *+var myBorderPanel = new Ext.Panel({ + {@link Ext.Component#renderTo renderTo}: document.body, + {@link Ext.BoxComponent#width width}: 700, + {@link Ext.BoxComponent#height height}: 500, + {@link Ext.Panel#title title}: 'Border Layout', + {@link Ext.Container#layout layout}: 'border', + {@link Ext.Container#items items}: [{ + {@link Ext.Panel#title title}: 'South Region is resizable', + {@link Ext.layout.BorderLayout.Region#BorderLayout.Region region}: 'south', // position for region + {@link Ext.BoxComponent#height height}: 100, + {@link Ext.layout.BorderLayout.Region#split split}: true, // enable resizing + {@link Ext.SplitBar#minSize minSize}: 75, // defaults to {@link Ext.layout.BorderLayout.Region#minHeight 50} + {@link Ext.SplitBar#maxSize maxSize}: 150, + {@link Ext.layout.BorderLayout.Region#margins margins}: '0 5 5 5' + },{ + // xtype: 'panel' implied by default + {@link Ext.Panel#title title}: 'West Region is collapsible', + {@link Ext.layout.BorderLayout.Region#BorderLayout.Region region}:'west', + {@link Ext.layout.BorderLayout.Region#margins margins}: '5 0 0 5', + {@link Ext.BoxComponent#width width}: 200, + {@link Ext.layout.BorderLayout.Region#collapsible collapsible}: true, // make collapsible + {@link Ext.layout.BorderLayout.Region#cmargins cmargins}: '5 5 0 5', // adjust top margin when collapsed + {@link Ext.Component#id id}: 'west-region-container', + {@link Ext.Container#layout layout}: 'fit', + {@link Ext.Panel#unstyled unstyled}: true + },{ + {@link Ext.Panel#title title}: 'Center Region', + {@link Ext.layout.BorderLayout.Region#BorderLayout.Region region}: 'center', // center region is required, no width/height specified + {@link Ext.Component#xtype xtype}: 'container', + {@link Ext.Container#layout layout}: 'fit', + {@link Ext.layout.BorderLayout.Region#margins margins}: '5 5 0 0' + }] +}); +
Notes:
+ */ +Ext.layout.BorderLayout = Ext.extend(Ext.layout.ContainerLayout, { + // private + monitorResize:true, + // private + rendered : false, + + // private + onLayout : function(ct, target){ + var collapsed; + if(!this.rendered){ + target.addClass('x-border-layout-ct'); + var items = ct.items.items; + collapsed = []; + for(var i = 0, len = items.length; i < len; i++) { + var c = items[i]; + var pos = c.region; + if(c.collapsed){ + collapsed.push(c); + } + c.collapsed = false; + if(!c.rendered){ + c.cls = c.cls ? c.cls +' x-border-panel' : 'x-border-panel'; + c.render(target, i); + } + this[pos] = pos != 'center' && c.split ? + new Ext.layout.BorderLayout.SplitRegion(this, c.initialConfig, pos) : + new Ext.layout.BorderLayout.Region(this, c.initialConfig, pos); + this[pos].render(target, c); + } + this.rendered = true; + } + + var size = target.getViewSize(); + if(size.width < 20 || size.height < 20){ // display none? + if(collapsed){ + this.restoreCollapsed = collapsed; + } + return; + }else if(this.restoreCollapsed){ + collapsed = this.restoreCollapsed; + delete this.restoreCollapsed; + } + + var w = size.width, h = size.height; + var centerW = w, centerH = h, centerY = 0, centerX = 0; + + var n = this.north, s = this.south, west = this.west, e = this.east, c = this.center; + if(!c && Ext.layout.BorderLayout.WARN !== false){ + throw 'No center region defined in BorderLayout ' + ct.id; + } + + if(n && n.isVisible()){ + var b = n.getSize(); + var m = n.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; + n.applyLayout(b); + } + if(s && s.isVisible()){ + var b = s.getSize(); + var m = s.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; + s.applyLayout(b); + } + if(west && west.isVisible()){ + var b = west.getSize(); + 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.applyLayout(b); + } + if(e && e.isVisible()){ + var b = e.getSize(); + var m = e.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; + e.applyLayout(b); + } + if(c){ + var m = c.getMargins(); + var centerBox = { + x: centerX + m.left, + y: centerY + m.top, + width: centerW - (m.left+m.right), + height: centerH - (m.top+m.bottom) + }; + c.applyLayout(centerBox); + } + if(collapsed){ + for(var i = 0, len = collapsed.length; i < len; i++){ + collapsed[i].collapse(false); + } + } + if(Ext.isIE && Ext.isStrict){ // workaround IE strict repainting issue + target.repaint(); + } + }, + + destroy: function() { + var r = ['north', 'south', 'east', 'west']; + for (var i = 0; i < r.length; i++) { + var region = this[r[i]]; + if(region){ + if(region.destroy){ + region.destroy(); + }else if (region.split){ + region.split.destroy(true); + } + } + } + Ext.layout.BorderLayout.superclass.destroy.call(this); + } + + /** + * @property activeItem + * @hide + */ +}); + +/** + * @class Ext.layout.BorderLayout.Region + *+ *
- Any container using the BorderLayout must have a child item with region:'center'. + * The child item in the center region will always be resized to fill the remaining space not used by + * the other regions in the layout.
+ *- Any child items with a region of west or east must have width defined + * (an integer representing the number of pixels that the region should take up).
+ *- Any child items with a region of north or south must have height defined.
+ *- The regions of a BorderLayout are fixed at render time and thereafter, its child Components may not be removed or added. To add/remove + * Components within a BorderLayout, have them wrapped by an additional Container which is directly + * managed by the BorderLayout. If the region is to be collapsible, the Container used directly + * by the BorderLayout manager should be a Panel. In the following example a Container (an Ext.Panel) + * is added to the west region: + *
+ *+ *+wrc = {@link Ext#getCmp Ext.getCmp}('west-region-container'); +wrc.{@link Ext.Panel#removeAll removeAll}(); +wrc.{@link Ext.Container#add add}({ + title: 'Added Panel', + html: 'Some content' +}); +wrc.{@link Ext.Container#doLayout doLayout}(); + *
- To reference a {@link Ext.layout.BorderLayout.Region Region}: + *
+ *+ *+wr = myBorderPanel.layout.west; + *
This is a region of a {@link Ext.layout.BorderLayout BorderLayout} that acts as a subcontainer + * within the layout. Each region has its own {@link Ext.layout.ContainerLayout layout} that is + * independent of other regions and the containing BorderLayout, and can be any of the + * {@link Ext.layout.ContainerLayout valid Ext layout types}.
+ *Region size is managed automatically and cannot be changed by the user -- for + * {@link #split resizable regions}, see {@link Ext.layout.BorderLayout.SplitRegion}.
+ * @constructor + * Create a new Region. + * @param {Layout} layout The {@link Ext.layout.BorderLayout BorderLayout} instance that is managing this Region. + * @param {Object} config The configuration options + * @param {String} position The region position. Valid values are: north, south, + * east, west and center. Every {@link Ext.layout.BorderLayout BorderLayout} + * must have a center region for the primary content -- all other regions are optional. + */ +Ext.layout.BorderLayout.Region = function(layout, config, pos){ + Ext.apply(this, config); + this.layout = layout; + this.position = pos; + this.state = {}; + if(typeof this.margins == 'string'){ + this.margins = this.layout.parseMargins(this.margins); + } + this.margins = Ext.applyIf(this.margins || {}, this.defaultMargins); + if(this.collapsible){ + if(typeof this.cmargins == 'string'){ + this.cmargins = this.layout.parseMargins(this.cmargins); + } + if(this.collapseMode == 'mini' && !this.cmargins){ + this.cmargins = {left:0,top:0,right:0,bottom:0}; + }else{ + this.cmargins = Ext.applyIf(this.cmargins || {}, + pos == 'north' || pos == 'south' ? this.defaultNSCMargins : this.defaultEWCMargins); + } + } +}; + +Ext.layout.BorderLayout.Region.prototype = { + /** + * @cfg {Boolean} animFloat + * When a collapsed region's bar is clicked, the region's panel will be displayed as a floated + * panel that will close again once the user mouses out of that panel (or clicks out if + * {@link #autoHide} = false). Setting {@link #animFloat} = false will + * prevent the open and close of these floated panels from being animated (defaults to true). + */ + /** + * @cfg {Boolean} autoHide + * When a collapsed region's bar is clicked, the region's panel will be displayed as a floated + * panel. If autoHide = true, the panel will automatically hide after the user mouses + * out of the panel. If autoHide = false, the panel will continue to display until the + * user clicks outside of the panel (defaults to true). + */ + /** + * @cfg {String} collapseMode + * collapseMode supports two configuration values:+ *+ *
- undefined (default)
+ *By default, {@link #collapsible} + * regions are collapsed by clicking the expand/collapse tool button that renders into the region's + * title bar.- 'mini'
+ *Optionally, when collapseMode is set to + * 'mini' the region's split bar will also display a small collapse button in the center of + * the bar. In 'mini' mode the region will collapse to a thinner bar than in normal mode. + *Note: if a collapsible region does not have a title bar, then set collapseMode = + * 'mini' and {@link #split} = true in order for the region to be {@link #collapsible} + * by the user as the expand/collapse tool button (that would go in the title bar) will not be rendered.
+ *See also {@link #cmargins}.
+ */ + /** + * @cfg {Object} margins + * An object containing margins to apply to the region when in the expanded state in the + * format:+ *+{ + top: (top margin), + right: (right margin), + bottom: (bottom margin), + left: (left margin) +}
May also be a string containing space-separated, numeric margin values. The order of the + * sides associated with each value matches the way CSS processes margin values:
+ *+ *+ *
- If there is only one value, it applies to all sides.
+ *- If there are two values, the top and bottom borders are set to the first value and the + * right and left are set to the second.
+ *- If there are three values, the top is set to the first value, the left and right are set + * to the second, and the bottom is set to the third.
+ *- If there are four values, they apply to the top, right, bottom, and left, respectively.
+ *Defaults to:
+ */ + /** + * @cfg {Object} cmargins + * An object containing margins to apply to the region when in the collapsed state in the + * format:+ * {top:0, right:0, bottom:0, left:0} + *
+ *+{ + top: (top margin), + right: (right margin), + bottom: (bottom margin), + left: (left margin) +}
May also be a string containing space-separated, numeric margin values. The order of the + * sides associated with each value matches the way CSS processes margin values.
+ *
true to allow the user to collapse this region (defaults to false). If + * true, an expand/collapse tool button will automatically be rendered into the title + * bar of the region, otherwise the button will not be shown.
+ *Note: that a title bar is required to display the collapse/expand toggle button -- if + * no title is specified for the region's panel, the region will only be collapsible if + * {@link #collapseMode} = 'mini' and {@link #split} = true. + */ + collapsible : false, +
/** + * @cfg {Boolean} split + *true to create a {@link Ext.layout.BorderLayout.SplitRegion SplitRegion} and + * display a 5px wide {@link Ext.SplitBar} between this region and its neighbor, allowing the user to + * resize the regions dynamically. Defaults to false creating a + * {@link Ext.layout.BorderLayout.Region Region}.
Notes:
The minimum allowable width in pixels for this region (defaults to 50). + * maxWidth may also be specified.
Note: setting the {@link Ext.SplitBar#minSize minSize} / + * {@link Ext.SplitBar#maxSize maxSize} supersedes any specified + * minWidth / maxWidth.
+ */ + minWidth:50, + /** + * @cfg {Number} minHeight + * The minimum allowable height in pixels for this region (defaults to 50) + * maxHeight may also be specified.Note: setting the {@link Ext.SplitBar#minSize minSize} / + * {@link Ext.SplitBar#maxSize maxSize} supersedes any specified + * minHeight / maxHeight.
+ */ + minHeight:50, + + // private + defaultMargins : {left:0,top:0,right:0,bottom:0}, + // private + defaultNSCMargins : {left:5,top:5,right:5,bottom:5}, + // private + defaultEWCMargins : {left:5,top:0,right:5,bottom:0}, + floatingZIndex: 100, + + /** + * True if this region is collapsed. Read-only. + * @type Boolean + * @property + */ + isCollapsed : false, + + /** + * This region's panel. Read-only. + * @type Ext.Panel + * @property panel + */ + /** + * This region's layout. Read-only. + * @type Layout + * @property layout + */ + /** + * This region's layout position (north, south, east, west or center). Read-only. + * @type String + * @property position + */ + + // private + render : function(ct, p){ + this.panel = p; + p.el.enableDisplayMode(); + this.targetEl = ct; + this.el = p.el; + + var gs = p.getState, ps = this.position; + p.getState = function(){ + return Ext.apply(gs.call(p) || {}, this.state); + }.createDelegate(this); + + if(ps != 'center'){ + p.allowQueuedExpand = false; + p.on({ + beforecollapse: this.beforeCollapse, + collapse: this.onCollapse, + beforeexpand: this.beforeExpand, + expand: this.onExpand, + hide: this.onHide, + show: this.onShow, + scope: this + }); + if(this.collapsible || this.floatable){ + p.collapseEl = 'el'; + p.slideAnchor = this.getSlideAnchor(); + } + if(p.tools && p.tools.toggle){ + p.tools.toggle.addClass('x-tool-collapse-'+ps); + p.tools.toggle.addClassOnOver('x-tool-collapse-'+ps+'-over'); + } + } + }, + + // private + getCollapsedEl : function(){ + if(!this.collapsedEl){ + if(!this.toolTemplate){ + var tt = new Ext.Template( + 'This is a specialized type of {@link Ext.layout.BorderLayout.Region BorderLayout region} that + * has a built-in {@link Ext.SplitBar} for user resizing of regions. The movement of the split bar + * is configurable to move either {@link #tickSize smooth or incrementally}.
+ * @constructor + * Create a new SplitRegion. + * @param {Layout} layout The {@link Ext.layout.BorderLayout BorderLayout} instance that is managing this Region. + * @param {Object} config The configuration options + * @param {String} position The region position. Valid values are: north, south, east, west and center. Every + * BorderLayout must have a center region for the primary content -- all other regions are optional. + */ +Ext.layout.BorderLayout.SplitRegion = function(layout, config, pos){ + Ext.layout.BorderLayout.SplitRegion.superclass.constructor.call(this, layout, config, pos); + // prevent switch + this.applyLayout = this.applyFns[pos]; +}; + +Ext.extend(Ext.layout.BorderLayout.SplitRegion, Ext.layout.BorderLayout.Region, { + /** + * @cfg {Number} tickSize + * The increment, in pixels by which to move this Region's {@link Ext.SplitBar SplitBar}. + * By default, the {@link Ext.SplitBar SplitBar} moves smoothly. + */ + /** + * @cfg {String} splitTip + * The tooltip to display when the user hovers over a + * {@link Ext.layout.BorderLayout.Region#collapsible non-collapsible} region's split bar + * (defaults to "Drag to resize."). Only applies if + * {@link #useSplitTips} = true. + */ + splitTip : "Drag to resize.", + /** + * @cfg {String} collapsibleSplitTip + * The tooltip to display when the user hovers over a + * {@link Ext.layout.BorderLayout.Region#collapsible collapsible} region's split bar + * (defaults to "Drag to resize. Double click to hide."). Only applies if + * {@link #useSplitTips} = true. + */ + collapsibleSplitTip : "Drag to resize. Double click to hide.", + /** + * @cfg {Boolean} useSplitTips + * true to display a tooltip when the user hovers over a region's split bar + * (defaults to false). The tooltip text will be the value of either + * {@link #splitTip} or {@link #collapsibleSplitTip} as appropriate. + */ + useSplitTips : false, + + // private + splitSettings : { + north : { + orientation: Ext.SplitBar.VERTICAL, + placement: Ext.SplitBar.TOP, + maxFn : 'getVMaxSize', + minProp: 'minHeight', + maxProp: 'maxHeight' + }, + south : { + orientation: Ext.SplitBar.VERTICAL, + placement: Ext.SplitBar.BOTTOM, + maxFn : 'getVMaxSize', + minProp: 'minHeight', + maxProp: 'maxHeight' + }, + east : { + orientation: Ext.SplitBar.HORIZONTAL, + placement: Ext.SplitBar.RIGHT, + maxFn : 'getHMaxSize', + minProp: 'minWidth', + maxProp: 'maxWidth' + }, + west : { + orientation: Ext.SplitBar.HORIZONTAL, + placement: Ext.SplitBar.LEFT, + maxFn : 'getHMaxSize', + minProp: 'minWidth', + maxProp: 'maxWidth' + } + }, + + // private + applyFns : { + west : function(box){ + if(this.isCollapsed){ + return this.applyLayoutCollapsed(box); + } + var sd = this.splitEl.dom, s = sd.style; + this.panel.setPosition(box.x, box.y); + var sw = sd.offsetWidth; + s.left = (box.x+box.width-sw)+'px'; + s.top = (box.y)+'px'; + s.height = Math.max(0, box.height)+'px'; + this.panel.setSize(box.width-sw, box.height); + }, + east : function(box){ + if(this.isCollapsed){ + return this.applyLayoutCollapsed(box); + } + var sd = this.splitEl.dom, s = sd.style; + var sw = sd.offsetWidth; + this.panel.setPosition(box.x+sw, box.y); + s.left = (box.x)+'px'; + s.top = (box.y)+'px'; + s.height = Math.max(0, box.height)+'px'; + this.panel.setSize(box.width-sw, box.height); + }, + north : function(box){ + if(this.isCollapsed){ + return this.applyLayoutCollapsed(box); + } + var sd = this.splitEl.dom, s = sd.style; + var sh = sd.offsetHeight; + this.panel.setPosition(box.x, box.y); + s.left = (box.x)+'px'; + s.top = (box.y+box.height-sh)+'px'; + s.width = Math.max(0, box.width)+'px'; + this.panel.setSize(box.width, box.height-sh); + }, + south : function(box){ + if(this.isCollapsed){ + return this.applyLayoutCollapsed(box); + } + var sd = this.splitEl.dom, s = sd.style; + var sh = sd.offsetHeight; + this.panel.setPosition(box.x, box.y+sh); + s.left = (box.x)+'px'; + s.top = (box.y)+'px'; + s.width = Math.max(0, box.width)+'px'; + this.panel.setSize(box.width, box.height-sh); + } + }, + + // private + render : function(ct, p){ + Ext.layout.BorderLayout.SplitRegion.superclass.render.call(this, ct, p); + + var ps = this.position; + + this.splitEl = ct.createChild({ + cls: "x-layout-split x-layout-split-"+ps, html: " ", + id: this.panel.id + '-xsplit' + }); + + if(this.collapseMode == 'mini'){ + this.miniSplitEl = this.splitEl.createChild({ + cls: "x-layout-mini x-layout-mini-"+ps, html: " " + }); + this.miniSplitEl.addClassOnOver('x-layout-mini-over'); + this.miniSplitEl.on('click', this.onCollapseClick, this, {stopEvent:true}); + } + + var s = this.splitSettings[ps]; + + this.split = new Ext.SplitBar(this.splitEl.dom, p.el, s.orientation); + this.split.tickSize = this.tickSize; + this.split.placement = s.placement; + this.split.getMaximumSize = this[s.maxFn].createDelegate(this); + this.split.minSize = this.minSize || this[s.minProp]; + this.split.on("beforeapply", this.onSplitMove, this); + this.split.useShim = this.useShim === true; + this.maxSize = this.maxSize || this[s.maxProp]; + + if(p.hidden){ + this.splitEl.hide(); + } + + if(this.useSplitTips){ + this.splitEl.dom.title = this.collapsible ? this.collapsibleSplitTip : this.splitTip; + } + if(this.collapsible){ + this.splitEl.on("dblclick", this.onCollapseClick, this); + } + }, + + //docs inherit from superclass + getSize : function(){ + if(this.isCollapsed){ + return this.collapsedEl.getSize(); + } + var s = this.panel.getSize(); + if(this.position == 'north' || this.position == 'south'){ + s.height += this.splitEl.dom.offsetHeight; + }else{ + s.width += this.splitEl.dom.offsetWidth; + } + return s; + }, + + // private + getHMaxSize : function(){ + var cmax = this.maxSize || 10000; + var center = this.layout.center; + return Math.min(cmax, (this.el.getWidth()+center.el.getWidth())-center.getMinWidth()); + }, + + // private + getVMaxSize : function(){ + var cmax = this.maxSize || 10000; + var center = this.layout.center; + return Math.min(cmax, (this.el.getHeight()+center.el.getHeight())-center.getMinHeight()); + }, + + // private + onSplitMove : function(split, newSize){ + var s = this.panel.getSize(); + this.lastSplitSize = newSize; + if(this.position == 'north' || this.position == 'south'){ + this.panel.setSize(s.width, newSize); + this.state.height = newSize; + }else{ + this.panel.setSize(newSize, s.height); + this.state.width = newSize; + } + this.layout.layout(); + this.panel.saveState(); + return false; + }, + + /** + * Returns a reference to the split bar in use by this region. + * @return {Ext.SplitBar} The split bar + */ + getSplitBar : function(){ + return this.split; + }, + + // inherit docs + destroy : function() { + Ext.destroy( + this.miniSplitEl, + this.split, + this.splitEl + ); + } +}); + +Ext.Container.LAYOUTS['border'] = Ext.layout.BorderLayout; + + \ No newline at end of file