cmp-foundation-debug.js
资源名称:ext-3.0.0.zip [点击查看]
上传用户:shuoshiled
上传日期:2018-01-28
资源大小:10124k
文件大小:422k
源码类别:
中间件编程
开发平台:
JavaScript
- * This is a raw adjustment where the first anchor is the offset from the right edge of the container,
- * and the second is the offset from the bottom edge. For example:<pre><code>
- // two values specified
- anchor: '-50 -100' // render item the complete width of the container
- // minus 50 pixels and
- // the complete height minus 100 pixels.
- // one value specified
- anchor: '-50' // anchor value is assumed to be the right offset value
- // bottom offset will default to 0
- * </code></pre></div></li>
- *
- * <li><b>Sides</b> : Valid values are <tt>'right'</tt> (or <tt>'r'</tt>) and <tt>'bottom'</tt>
- * (or <tt>'b'</tt>).<div class="sub-desc">
- * Either the container must have a fixed size or an anchorSize config value defined at render time in
- * order for these to have any effect.</div></li>
- *
- * <li><b>Mixed</b> : <div class="sub-desc">
- * Anchor values can also be mixed as needed. For example, to render the width offset from the container
- * right edge by 50 pixels and 75% of the container's height use:
- * <pre><code>
- anchor: '-50 75%'
- * </code></pre></div></li>
- *
- *
- * </ul></div>
- */
- // private
- monitorResize:true,
- // private
- getAnchorViewSize : function(ct, target){
- return target.dom == document.body ?
- target.getViewSize() : target.getStyleSize();
- },
- // private
- onLayout : function(ct, target){
- Ext.layout.AnchorLayout.superclass.onLayout.call(this, ct, target);
- var size = this.getAnchorViewSize(ct, target);
- var w = size.width, h = size.height;
- if(w < 20 && h < 20){
- return;
- }
- // find the container anchoring size
- var aw, ah;
- if(ct.anchorSize){
- if(typeof ct.anchorSize == 'number'){
- aw = ct.anchorSize;
- }else{
- aw = ct.anchorSize.width;
- ah = ct.anchorSize.height;
- }
- }else{
- aw = ct.initialConfig.width;
- ah = ct.initialConfig.height;
- }
- var cs = ct.items.items, len = cs.length, i, c, a, cw, ch;
- for(i = 0; i < len; i++){
- c = cs[i];
- if(c.anchor){
- a = c.anchorSpec;
- if(!a){ // cache all anchor values
- var vs = c.anchor.split(' ');
- c.anchorSpec = a = {
- right: this.parseAnchor(vs[0], c.initialConfig.width, aw),
- bottom: this.parseAnchor(vs[1], c.initialConfig.height, ah)
- };
- }
- cw = a.right ? this.adjustWidthAnchor(a.right(w), c) : undefined;
- ch = a.bottom ? this.adjustHeightAnchor(a.bottom(h), c) : undefined;
- if(cw || ch){
- c.setSize(cw || undefined, ch || undefined);
- }
- }
- }
- },
- // private
- parseAnchor : function(a, start, cstart){
- if(a && a != 'none'){
- var last;
- if(/^(r|right|b|bottom)$/i.test(a)){ // standard anchor
- var diff = cstart - start;
- return function(v){
- if(v !== last){
- last = v;
- return v - diff;
- }
- }
- }else if(a.indexOf('%') != -1){
- var ratio = parseFloat(a.replace('%', ''))*.01; // percentage
- return function(v){
- if(v !== last){
- last = v;
- return Math.floor(v*ratio);
- }
- }
- }else{
- a = parseInt(a, 10);
- if(!isNaN(a)){ // simple offset adjustment
- return function(v){
- if(v !== last){
- last = v;
- return v + a;
- }
- }
- }
- }
- }
- return false;
- },
- // private
- adjustWidthAnchor : function(value, comp){
- return value;
- },
- // private
- adjustHeightAnchor : function(value, comp){
- return value;
- }
- /**
- * @property activeItem
- * @hide
- */
- });
- Ext.Container.LAYOUTS['anchor'] = Ext.layout.AnchorLayout;/**
- * @class Ext.layout.ColumnLayout
- * @extends Ext.layout.ContainerLayout
- * <p>This is the layout style of choice for creating structural layouts in a multi-column format where the width of
- * each column can be specified as a percentage or fixed width, but the height is allowed to vary based on the content.
- * This class is intended to be extended or created via the layout:'column' {@link Ext.Container#layout} config,
- * and should generally not need to be created directly via the new keyword.</p>
- * <p>ColumnLayout does not have any direct config options (other than inherited ones), but it does support a
- * specific config property of <b><tt>columnWidth</tt></b> that can be included in the config of any panel added to it. The
- * layout will use the columnWidth (if present) or width of each panel during layout to determine how to size each panel.
- * If width or columnWidth is not specified for a given panel, its width will default to the panel's width (or auto).</p>
- * <p>The width property is always evaluated as pixels, and must be a number greater than or equal to 1.
- * The columnWidth property is always evaluated as a percentage, and must be a decimal value greater than 0 and
- * less than 1 (e.g., .25).</p>
- * <p>The basic rules for specifying column widths are pretty simple. The logic makes two passes through the
- * set of contained panels. During the first layout pass, all panels that either have a fixed width or none
- * specified (auto) are skipped, but their widths are subtracted from the overall container width. During the second
- * pass, all panels with columnWidths are assigned pixel widths in proportion to their percentages based on
- * the total <b>remaining</b> container width. In other words, percentage width panels are designed to fill the space
- * left over by all the fixed-width and/or auto-width panels. Because of this, while you can specify any number of columns
- * with different percentages, the columnWidths must always add up to 1 (or 100%) when added together, otherwise your
- * layout may not render as expected. Example usage:</p>
- * <pre><code>
- // All columns are percentages -- they must add up to 1
- var p = new Ext.Panel({
- title: 'Column Layout - Percentage Only',
- layout:'column',
- items: [{
- title: 'Column 1',
- columnWidth: .25
- },{
- title: 'Column 2',
- columnWidth: .6
- },{
- title: 'Column 3',
- columnWidth: .15
- }]
- });
- // Mix of width and columnWidth -- all columnWidth values must add up
- // to 1. The first column will take up exactly 120px, and the last two
- // columns will fill the remaining container width.
- var p = new Ext.Panel({
- title: 'Column Layout - Mixed',
- layout:'column',
- items: [{
- title: 'Column 1',
- width: 120
- },{
- title: 'Column 2',
- columnWidth: .8
- },{
- title: 'Column 3',
- columnWidth: .2
- }]
- });
- </code></pre>
- */
- Ext.layout.ColumnLayout = Ext.extend(Ext.layout.ContainerLayout, {
- // private
- monitorResize:true,
- extraCls: 'x-column',
- scrollOffset : 0,
- // private
- isValidParent : function(c, target){
- return (c.getPositionEl ? c.getPositionEl() : c.getEl()).dom.parentNode == this.innerCt.dom;
- },
- // private
- onLayout : function(ct, target){
- var cs = ct.items.items, len = cs.length, c, i;
- if(!this.innerCt){
- target.addClass('x-column-layout-ct');
- // the innerCt prevents wrapping and shuffling while
- // the container is resizing
- this.innerCt = target.createChild({cls:'x-column-inner'});
- this.innerCt.createChild({cls:'x-clear'});
- }
- this.renderAll(ct, this.innerCt);
- var size = Ext.isIE && target.dom != Ext.getBody().dom ? target.getStyleSize() : target.getViewSize();
- if(size.width < 1 && size.height < 1){ // display none?
- return;
- }
- var w = size.width - target.getPadding('lr') - this.scrollOffset,
- h = size.height - target.getPadding('tb'),
- pw = w;
- this.innerCt.setWidth(w);
- // some columns can be percentages while others are fixed
- // so we need to make 2 passes
- for(i = 0; i < len; i++){
- c = cs[i];
- if(!c.columnWidth){
- pw -= (c.getSize().width + c.getEl().getMargins('lr'));
- }
- }
- pw = pw < 0 ? 0 : pw;
- for(i = 0; i < len; i++){
- c = cs[i];
- if(c.columnWidth){
- c.setSize(Math.floor(c.columnWidth*pw) - c.getEl().getMargins('lr'));
- }
- }
- }
- /**
- * @property activeItem
- * @hide
- */
- });
- Ext.Container.LAYOUTS['column'] = Ext.layout.ColumnLayout;/** * @class Ext.layout.BorderLayout * @extends Ext.layout.ContainerLayout * <p>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.</p> * <p>This class is intended to be extended or created via the <tt>layout:'border'</tt> * {@link Ext.Container#layout} config, and should generally not need to be created directly * via the new keyword.</p> * <p>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.</p> * <p>Example usage:</p> * <pre><code> 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' }] }); </code></pre> * <p><b><u>Notes</u></b>:</p><div class="mdetail-params"><ul> * <li>Any container using the BorderLayout <b>must</b> have a child item with <tt>region:'center'</tt>. * 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.</li> * <li>Any child items with a region of <tt>west</tt> or <tt>east</tt> must have <tt>width</tt> defined * (an integer representing the number of pixels that the region should take up).</li> * <li>Any child items with a region of <tt>north</tt> or <tt>south</tt> must have <tt>height</tt> defined.</li> * <li>The regions of a BorderLayout are <b>fixed at render time</b> and thereafter, its child Components may not be removed or added</b>. 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: * <div style="margin-left:16px"><pre><code> 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}(); * </code></pre></div> * </li> * <li> To reference a {@link Ext.layout.BorderLayout.Region Region}: * <div style="margin-left:16px"><pre><code> wr = myBorderPanel.layout.west; * </code></pre></div> * </li> * </ul></div> */ 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 * <p>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}.</p> * <p>Region size is managed automatically and cannot be changed by the user -- for * {@link #split resizable regions}, see {@link Ext.layout.BorderLayout.SplitRegion}.</p> * @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: <tt>north</tt>, <tt>south</tt>, * <tt>east</tt>, <tt>west</tt> and <tt>center</tt>. Every {@link Ext.layout.BorderLayout BorderLayout} * <b>must have a center region</b> 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 * <tt>{@link #autoHide} = false</tt>). Setting <tt>{@link #animFloat} = false</tt> will * prevent the open and close of these floated panels from being animated (defaults to <tt>true</tt>). */ /** * @cfg {Boolean} autoHide * When a collapsed region's bar is clicked, the region's panel will be displayed as a floated * panel. If <tt>autoHide = true</tt>, the panel will automatically hide after the user mouses * out of the panel. If <tt>autoHide = false</tt>, the panel will continue to display until the * user clicks outside of the panel (defaults to <tt>true</tt>). */ /** * @cfg {String} collapseMode * <tt>collapseMode</tt> supports two configuration values:<div class="mdetail-params"><ul> * <li><b><tt>undefined</tt></b> (default)<div class="sub-desc">By default, {@link #collapsible} * regions are collapsed by clicking the expand/collapse tool button that renders into the region's * title bar.</div></li> * <li><b><tt>'mini'</tt></b><div class="sub-desc">Optionally, when <tt>collapseMode</tt> is set to * <tt>'mini'</tt> the region's split bar will also display a small collapse button in the center of * the bar. In <tt>'mini'</tt> mode the region will collapse to a thinner bar than in normal mode. * </div></li> * </ul></div></p> * <p><b>Note</b>: if a collapsible region does not have a title bar, then set <tt>collapseMode = * 'mini'</tt> and <tt>{@link #split} = true</tt> 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.</p> * <p>See also <tt>{@link #cmargins}</tt>.</p> */ /** * @cfg {Object} margins * An object containing margins to apply to the region when in the expanded state in the * format:<pre><code> { top: (top margin), right: (right margin), bottom: (bottom margin), left: (left margin) }</code></pre> * <p>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:</p> * <p><div class="mdetail-params"><ul> * <li>If there is only one value, it applies to all sides.</li> * <li>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.</li> * <li>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.</li> * <li>If there are four values, they apply to the top, right, bottom, and left, respectively.</li> * </ul></div></p> * <p>Defaults to:</p><pre><code> * {top:0, right:0, bottom:0, left:0} * </code></pre> */ /** * @cfg {Object} cmargins * An object containing margins to apply to the region when in the collapsed state in the * format:<pre><code> { top: (top margin), right: (right margin), bottom: (bottom margin), left: (left margin) }</code></pre> * <p>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.</p> * <p><ul> * <li>If there is only one value, it applies to all sides.</li> * <li>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.</li> * <li>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.</li> * <li>If there are four values, they apply to the top, right, bottom, and left, respectively.</li> * </ul></p> */ /** * @cfg {Boolean} collapsible * <p><tt>true</tt> to allow the user to collapse this region (defaults to <tt>false</tt>). If * <tt>true</tt>, an expand/collapse tool button will automatically be rendered into the title * bar of the region, otherwise the button will not be shown.</p> * <p><b>Note</b>: that a title bar is required to display the collapse/expand toggle button -- if * no <tt>title</tt> is specified for the region's panel, the region will only be collapsible if * <tt>{@link #collapseMode} = 'mini'</tt> and <tt>{@link #split} = true</tt>. */ collapsible : false, /** * @cfg {Boolean} split * <p><tt>true</tt> 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 <tt>false</tt> creating a * {@link Ext.layout.BorderLayout.Region Region}.</p><br> * <p><b>Notes</b>:</p><div class="mdetail-params"><ul> * <li>this configuration option is ignored if <tt>region='center'</tt></li> * <li>when <tt>split == true</tt>, it is common to specify a * <tt>{@link Ext.SplitBar#minSize minSize}</tt> and <tt>{@link Ext.SplitBar#maxSize maxSize}</tt> * for the {@link Ext.BoxComponent BoxComponent} representing the region. These are not native * configs of {@link Ext.BoxComponent BoxComponent}, and are used only by this class.</li> * <li>if <tt>{@link #collapseMode} = 'mini'</tt> requires <tt>split = true</tt> to reserve space * for the collapse tool</tt></li> * </ul></div> */ split:false, /** * @cfg {Boolean} floatable * <tt>true</tt> to allow clicking a collapsed region's bar to display the region's panel floated * above the layout, <tt>false</tt> to force the user to fully expand a collapsed region by * clicking the expand button to see it again (defaults to <tt>true</tt>). */ floatable: true, /** * @cfg {Number} minWidth * <p>The minimum allowable width in pixels for this region (defaults to <tt>50</tt>). * <tt>maxWidth</tt> may also be specified.</p><br> * <p><b>Note</b>: setting the <tt>{@link Ext.SplitBar#minSize minSize}</tt> / * <tt>{@link Ext.SplitBar#maxSize maxSize}</tt> supersedes any specified * <tt>minWidth</tt> / <tt>maxWidth</tt>.</p> */ minWidth:50, /** * @cfg {Number} minHeight * The minimum allowable height in pixels for this region (defaults to <tt>50</tt>) * <tt>maxHeight</tt> may also be specified.</p><br> * <p><b>Note</b>: setting the <tt>{@link Ext.SplitBar#minSize minSize}</tt> / * <tt>{@link Ext.SplitBar#maxSize maxSize}</tt> supersedes any specified * <tt>minHeight</tt> / <tt>maxHeight</tt>.</p> */ 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( '<div class="x-tool x-tool-{id}"> </div>' ); tt.disableFormats = true; tt.compile(); Ext.layout.BorderLayout.Region.prototype.toolTemplate = tt; } this.collapsedEl = this.targetEl.createChild({ cls: "x-layout-collapsed x-layout-collapsed-"+this.position, id: this.panel.id + '-xcollapsed' }); this.collapsedEl.enableDisplayMode('block'); if(this.collapseMode == 'mini'){ this.collapsedEl.addClass('x-layout-cmini-'+this.position); this.miniCollapsedEl = this.collapsedEl.createChild({ cls: "x-layout-mini x-layout-mini-"+this.position, html: " " }); this.miniCollapsedEl.addClassOnOver('x-layout-mini-over'); this.collapsedEl.addClassOnOver("x-layout-collapsed-over"); this.collapsedEl.on('click', this.onExpandClick, this, {stopEvent:true}); }else { if(this.collapsible !== false && !this.hideCollapseTool) { var t = this.toolTemplate.append( this.collapsedEl.dom, {id:'expand-'+this.position}, true); t.addClassOnOver('x-tool-expand-'+this.position+'-over'); t.on('click', this.onExpandClick, this, {stopEvent:true}); } if(this.floatable !== false || this.titleCollapse){ this.collapsedEl.addClassOnOver("x-layout-collapsed-over"); this.collapsedEl.on("click", this[this.floatable ? 'collapseClick' : 'onExpandClick'], this); } } } return this.collapsedEl; }, // private onExpandClick : function(e){ if(this.isSlid){ this.afterSlideIn(); this.panel.expand(false); }else{ this.panel.expand(); } }, // private onCollapseClick : function(e){ this.panel.collapse(); }, // private beforeCollapse : function(p, animate){ this.lastAnim = animate; if(this.splitEl){ this.splitEl.hide(); } this.getCollapsedEl().show(); this.panel.el.setStyle('z-index', 100); this.isCollapsed = true; this.layout.layout(); }, // private onCollapse : function(animate){ this.panel.el.setStyle('z-index', 1); if(this.lastAnim === false || this.panel.animCollapse === false){ this.getCollapsedEl().dom.style.visibility = 'visible'; }else{ this.getCollapsedEl().slideIn(this.panel.slideAnchor, {duration:.2}); } this.state.collapsed = true; this.panel.saveState(); }, // private beforeExpand : function(animate){ var c = this.getCollapsedEl(); this.el.show(); if(this.position == 'east' || this.position == 'west'){ this.panel.setSize(undefined, c.getHeight()); }else{ this.panel.setSize(c.getWidth(), undefined); } c.hide(); c.dom.style.visibility = 'hidden'; this.panel.el.setStyle('z-index', this.floatingZIndex); }, // private onExpand : function(){ this.isCollapsed = false; if(this.splitEl){ this.splitEl.show(); } this.layout.layout(); this.panel.el.setStyle('z-index', 1); this.state.collapsed = false; this.panel.saveState(); }, // private collapseClick : function(e){ if(this.isSlid){ e.stopPropagation(); this.slideIn(); }else{ e.stopPropagation(); this.slideOut(); } }, // private onHide : function(){ if(this.isCollapsed){ this.getCollapsedEl().hide(); }else if(this.splitEl){ this.splitEl.hide(); } }, // private onShow : function(){ if(this.isCollapsed){ this.getCollapsedEl().show(); }else if(this.splitEl){ this.splitEl.show(); } }, /** * True if this region is currently visible, else false. * @return {Boolean} */ isVisible : function(){ return !this.panel.hidden; }, /** * Returns the current margins for this region. If the region is collapsed, the * {@link #cmargins} (collapsed margins) value will be returned, otherwise the * {@link #margins} value will be returned. * @return {Object} An object containing the element's margins: <tt>{left: (left * margin), top: (top margin), right: (right margin), bottom: (bottom margin)}</tt> */ getMargins : function(){ return this.isCollapsed && this.cmargins ? this.cmargins : this.margins; }, /** * Returns the current size of this region. If the region is collapsed, the size of the * collapsedEl will be returned, otherwise the size of the region's panel will be returned. * @return {Object} An object containing the element's size: <tt>{width: (element width), * height: (element height)}</tt> */ getSize : function(){ return this.isCollapsed ? this.getCollapsedEl().getSize() : this.panel.getSize(); }, /** * Sets the specified panel as the container element for this region. * @param {Ext.Panel} panel The new panel */ setPanel : function(panel){ this.panel = panel; }, /** * Returns the minimum allowable width for this region. * @return {Number} The minimum width */ getMinWidth: function(){ return this.minWidth; }, /** * Returns the minimum allowable height for this region. * @return {Number} The minimum height */ getMinHeight: function(){ return this.minHeight; }, // private applyLayoutCollapsed : function(box){ var ce = this.getCollapsedEl(); ce.setLeftTop(box.x, box.y); ce.setSize(box.width, box.height); }, // private applyLayout : function(box){ if(this.isCollapsed){ this.applyLayoutCollapsed(box); }else{ this.panel.setPosition(box.x, box.y); this.panel.setSize(box.width, box.height); } }, // private beforeSlide: function(){ this.panel.beforeEffect(); }, // private afterSlide : function(){ this.panel.afterEffect(); }, // private initAutoHide : function(){ if(this.autoHide !== false){ if(!this.autoHideHd){ var st = new Ext.util.DelayedTask(this.slideIn, this); this.autoHideHd = { "mouseout": function(e){ if(!e.within(this.el, true)){ st.delay(500); } }, "mouseover" : function(e){ st.cancel(); }, scope : this }; } this.el.on(this.autoHideHd); } }, // private clearAutoHide : function(){ if(this.autoHide !== false){ this.el.un("mouseout", this.autoHideHd.mouseout); this.el.un("mouseover", this.autoHideHd.mouseover); } }, // private clearMonitor : function(){ Ext.getDoc().un("click", this.slideInIf, this); }, /** * If this Region is {@link #floatable}, this method slides this Region into full visibility <i>over the top * of the center Region</i> where it floats until either {@link #slideIn} is called, or other regions of the layout * are clicked, or the mouse exits the Region. */ slideOut : function(){ if(this.isSlid || this.el.hasActiveFx()){ return; } this.isSlid = true; var ts = this.panel.tools; if(ts && ts.toggle){ ts.toggle.hide(); } this.el.show(); if(this.position == 'east' || this.position == 'west'){ this.panel.setSize(undefined, this.collapsedEl.getHeight()); }else{ this.panel.setSize(this.collapsedEl.getWidth(), undefined); } this.restoreLT = [this.el.dom.style.left, this.el.dom.style.top]; this.el.alignTo(this.collapsedEl, this.getCollapseAnchor()); this.el.setStyle("z-index", this.floatingZIndex+2); this.panel.el.replaceClass('x-panel-collapsed', 'x-panel-floating'); if(this.animFloat !== false){ this.beforeSlide(); this.el.slideIn(this.getSlideAnchor(), { callback: function(){ this.afterSlide(); this.initAutoHide(); Ext.getDoc().on("click", this.slideInIf, this); }, scope: this, block: true }); }else{ this.initAutoHide(); Ext.getDoc().on("click", this.slideInIf, this); } }, // private afterSlideIn : function(){ this.clearAutoHide(); this.isSlid = false; this.clearMonitor(); this.el.setStyle("z-index", ""); this.panel.el.replaceClass('x-panel-floating', 'x-panel-collapsed'); this.el.dom.style.left = this.restoreLT[0]; this.el.dom.style.top = this.restoreLT[1]; var ts = this.panel.tools; if(ts && ts.toggle){ ts.toggle.show(); } }, /** * If this Region is {@link #floatable}, and this Region has been slid into floating visibility, then this method slides * this region back into its collapsed state. */ slideIn : function(cb){ if(!this.isSlid || this.el.hasActiveFx()){ Ext.callback(cb); return; } this.isSlid = false; if(this.animFloat !== false){ this.beforeSlide(); this.el.slideOut(this.getSlideAnchor(), { callback: function(){ this.el.hide(); this.afterSlide(); this.afterSlideIn(); Ext.callback(cb); }, scope: this, block: true }); }else{ this.el.hide(); this.afterSlideIn(); } }, // private slideInIf : function(e){ if(!e.within(this.el)){ this.slideIn(); } }, // private anchors : { "west" : "left", "east" : "right", "north" : "top", "south" : "bottom" }, // private sanchors : { "west" : "l", "east" : "r", "north" : "t", "south" : "b" }, // private canchors : { "west" : "tl-tr", "east" : "tr-tl", "north" : "tl-bl", "south" : "bl-tl" }, // private getAnchor : function(){ return this.anchors[this.position]; }, // private getCollapseAnchor : function(){ return this.canchors[this.position]; }, // private getSlideAnchor : function(){ return this.sanchors[this.position]; }, // private getAlignAdj : function(){ var cm = this.cmargins; switch(this.position){ case "west": return [0, 0]; break; case "east": return [0, 0]; break; case "north": return [0, 0]; break; case "south": return [0, 0]; break; } }, // private getExpandAdj : function(){ var c = this.collapsedEl, cm = this.cmargins; switch(this.position){ case "west": return [-(cm.right+c.getWidth()+cm.left), 0]; break; case "east": return [cm.right+c.getWidth()+cm.left, 0]; break; case "north": return [0, -(cm.top+cm.bottom+c.getHeight())]; break; case "south": return [0, cm.top+cm.bottom+c.getHeight()]; break; } } }; /** * @class Ext.layout.BorderLayout.SplitRegion * @extends Ext.layout.BorderLayout.Region * <p>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}.</p> * @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 <tt>"Drag to resize."</tt>). Only applies if * <tt>{@link #useSplitTips} = true</tt>. */ 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 * <tt>{@link #useSplitTips} = true</tt>. */ collapsibleSplitTip : "Drag to resize. Double click to hide.", /** * @cfg {Boolean} useSplitTips * <tt>true</tt> to display a tooltip when the user hovers over a region's split bar * (defaults to <tt>false</tt>). The tooltip text will be the value of either * <tt>{@link #splitTip}</tt> or <tt>{@link #collapsibleSplitTip}</tt> 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;/** * @class Ext.layout.FormLayout * @extends Ext.layout.AnchorLayout * <p>This layout manager is specifically designed for rendering and managing child Components of * {@link Ext.form.FormPanel forms}. It is responsible for rendering the labels of * {@link Ext.form.Field Field}s.</p> * * <p>This layout manager is used when a Container is configured with the <tt>layout:'form'</tt> * {@link Ext.Container#layout layout} config option, and should generally not need to be created directly * via the new keyword. See <tt><b>{@link Ext.Container#layout}</b></tt> for additional details.</p> * * <p>In an application, it will usually be preferrable to use a {@link Ext.form.FormPanel FormPanel} * (which is configured with FormLayout as its layout class by default) since it also provides built-in * functionality for {@link Ext.form.BasicForm#doAction loading, validating and submitting} the form.</p> * * <p>A {@link Ext.Container Container} <i>using</i> the FormLayout layout manager (e.g. * {@link Ext.form.FormPanel} or specifying <tt>layout:'form'</tt>) can also accept the following * layout-specific config properties:<div class="mdetail-params"><ul> * <li><b><tt>{@link Ext.form.FormPanel#hideLabels hideLabels}</tt></b></li> * <li><b><tt>{@link Ext.form.FormPanel#labelAlign labelAlign}</tt></b></li> * <li><b><tt>{@link Ext.form.FormPanel#labelPad labelPad}</tt></b></li> * <li><b><tt>{@link Ext.form.FormPanel#labelSeparator labelSeparator}</tt></b></li> * <li><b><tt>{@link Ext.form.FormPanel#labelWidth labelWidth}</tt></b></li> * </ul></div></p> * * <p>Any Component (including Fields) managed by FormLayout accepts the following as a config option: * <div class="mdetail-params"><ul> * <li><b><tt>{@link Ext.Component#anchor anchor}</tt></b></li> * </ul></div></p> * * <p>Any Component managed by FormLayout may be rendered as a form field (with an associated label) by * configuring it with a non-null <b><tt>{@link Ext.Component#fieldLabel fieldLabel}</tt></b>. Components configured * in this way may be configured with the following options which affect the way the FormLayout renders them: * <div class="mdetail-params"><ul> * <li><b><tt>{@link Ext.Component#clearCls clearCls}</tt></b></li> * <li><b><tt>{@link Ext.Component#fieldLabel fieldLabel}</tt></b></li> * <li><b><tt>{@link Ext.Component#hideLabel hideLabel}</tt></b></li> * <li><b><tt>{@link Ext.Component#itemCls itemCls}</tt></b></li> * <li><b><tt>{@link Ext.Component#labelSeparator labelSeparator}</tt></b></li> * <li><b><tt>{@link Ext.Component#labelStyle labelStyle}</tt></b></li> * </ul></div></p> * * <p>Example usage:</p> * <pre><code> // Required if showing validation messages Ext.QuickTips.init(); // While you can create a basic Panel with layout:'form', practically // you should usually use a FormPanel to also get its form functionality // since it already creates a FormLayout internally. var form = new Ext.form.FormPanel({ title: 'Form Layout', bodyStyle: 'padding:15px', width: 350, defaultType: 'textfield', defaults: { // applied to each contained item width: 230, msgTarget: 'side' }, items: [{ fieldLabel: 'First Name', name: 'first', allowBlank: false, {@link Ext.Component#labelSeparator labelSeparator}: ':' // override labelSeparator layout config },{ fieldLabel: 'Last Name', name: 'last' },{ fieldLabel: 'Email', name: 'email', vtype:'email' }, { xtype: 'textarea', hideLabel: true, // override hideLabels layout config name: 'msg', anchor: '100% -53' } ], buttons: [ {text: 'Save'}, {text: 'Cancel'} ], layoutConfig: { {@link #labelSeparator}: '~' // superseded by assignment below }, // config options applicable to container when layout='form': hideLabels: false, labelAlign: 'left', // or 'right' or 'top' {@link Ext.form.FormPanel#labelSeparator labelSeparator}: '>>', // takes precedence over layoutConfig value labelWidth: 65, // defaults to 100 labelPad: 8 // defaults to 5, must specify labelWidth to be honored }); </code></pre> */ Ext.layout.FormLayout = Ext.extend(Ext.layout.AnchorLayout, { /** * @cfg {String} labelSeparator * See {@link Ext.form.FormPanel}.{@link Ext.form.FormPanel#labelSeparator labelSeparator}. Configuration * of this property at the <b>container</b> level takes precedence. */ labelSeparator : ':', /** * Read only. The CSS style specification string added to field labels in this layout if not * otherwise {@link Ext.Component#labelStyle specified by each contained field}. * @type String * @property labelStyle */ // private setContainer : function(ct){ Ext.layout.FormLayout.superclass.setContainer.call(this, ct); if(ct.labelAlign){ ct.addClass('x-form-label-'+ct.labelAlign); } if(ct.hideLabels){ this.labelStyle = "display:none"; this.elementStyle = "padding-left:0;"; this.labelAdjust = 0; }else{ this.labelSeparator = ct.labelSeparator || this.labelSeparator; ct.labelWidth = ct.labelWidth || 100; if(typeof ct.labelWidth == 'number'){ var pad = (typeof ct.labelPad == 'number' ? ct.labelPad : 5); this.labelAdjust = ct.labelWidth+pad; this.labelStyle = "width:"+ct.labelWidth+"px;"; this.elementStyle = "padding-left:"+(ct.labelWidth+pad)+'px'; } if(ct.labelAlign == 'top'){ this.labelStyle = "width:auto;"; this.labelAdjust = 0; this.elementStyle = "padding-left:0;"; } } }, //private getLabelStyle: function(s){ var ls = '', items = [this.labelStyle, s]; for (var i = 0, len = items.length; i < len; ++i){ if (items[i]){ ls += items[i]; if (ls.substr(-1, 1) != ';'){ ls += ';' } } } return ls; }, /** * @cfg {Ext.Template} fieldTpl * A {@link Ext.Template#compile compile}d {@link Ext.Template} for rendering * the fully wrapped, labeled and styled form Field. Defaults to:</p><pre><code> new Ext.Template( '<div class="x-form-item {itemCls}" tabIndex="-1">', '<label for="{id}" style="{labelStyle}" class="x-form-item-label">{label}{labelSeparator}</label>', '<div class="x-form-element" id="x-form-el-{id}" style="{elementStyle}">', '</div><div class="{clearCls}"></div>', '</div>' ); </code></pre> * <p>This may be specified to produce a different DOM structure when rendering form Fields.</p> * <p>A description of the properties within the template follows:</p><div class="mdetail-params"><ul> * <li><b><tt>itemCls</tt></b> : String<div class="sub-desc">The CSS class applied to the outermost div wrapper * that contains this field label and field element (the default class is <tt>'x-form-item'</tt> and <tt>itemCls</tt> * will be added to that). If supplied, <tt>itemCls</tt> at the field level will override the default <tt>itemCls</tt> * supplied at the container level.</div></li> * <li><b><tt>id</tt></b> : String<div class="sub-desc">The id of the Field</div></li> * <li><b><tt>{@link #labelStyle}</tt></b> : String<div class="sub-desc"> * A CSS style specification string to add to the field label for this field (defaults to <tt>''</tt> or the * {@link #labelStyle layout's value for <tt>labelStyle</tt>}).</div></li> * <li><b><tt>label</tt></b> : String<div class="sub-desc">The text to display as the label for this * field (defaults to <tt>''</tt>)</div></li> * <li><b><tt>{@link #labelSeparator}</tt></b> : String<div class="sub-desc">The separator to display after * the text of the label for this field (defaults to a colon <tt>':'</tt> or the * {@link #labelSeparator layout's value for labelSeparator}). To hide the separator use empty string ''.</div></li> * <li><b><tt>elementStyle</tt></b> : String<div class="sub-desc">The styles text for the input element's wrapper.</div></li> * <li><b><tt>clearCls</tt></b> : String<div class="sub-desc">The CSS class to apply to the special clearing div * rendered directly after each form field wrapper (defaults to <tt>'x-form-clear-left'</tt>)</div></li> * </ul></div> * <p>Also see <tt>{@link #getTemplateArgs}</tt></p> */ // private renderItem : function(c, position, target){ if(c && !c.rendered && (c.isFormField || c.fieldLabel) && c.inputType != 'hidden'){ var args = this.getTemplateArgs(c); if(typeof position == 'number'){ position = target.dom.childNodes[position] || null; } if(position){ this.fieldTpl.insertBefore(position, args); }else{ this.fieldTpl.append(target, args); } c.render('x-form-el-'+c.id); }else { Ext.layout.FormLayout.superclass.renderItem.apply(this, arguments); } }, /** * <p>Provides template arguments for rendering the fully wrapped, labeled and styled form Field.</p> * <p>This method returns an object hash containing properties used by the layout's {@link #fieldTpl} * to create a correctly wrapped, labeled and styled form Field. This may be overriden to * create custom layouts. The properties which must be returned are:</p><div class="mdetail-params"><ul> * <li><b><tt>itemCls</tt></b> : String<div class="sub-desc">The CSS class applied to the outermost div wrapper * that contains this field label and field element (the default class is <tt>'x-form-item'</tt> and <tt>itemCls</tt> * will be added to that). If supplied, <tt>itemCls</tt> at the field level will override the default <tt>itemCls</tt> * supplied at the container level.</div></li> * <li><b><tt>id</tt></b> : String<div class="sub-desc">The id of the Field</div></li> * <li><b><tt>{@link #labelStyle}</tt></b> : String<div class="sub-desc"> * A CSS style specification string to add to the field label for this field (defaults to <tt>''</tt> or the * {@link #labelStyle layout's value for <tt>labelStyle</tt>}).</div></li> * <li><b><tt>label</tt></b> : String<div class="sub-desc">The text to display as the label for this * field (defaults to <tt>''</tt>)</div></li> * <li><b><tt>{@link #labelSeparator}</tt></b> : String<div class="sub-desc">The separator to display after * the text of the label for this field (defaults to a colon <tt>':'</tt> or the * {@link #labelSeparator layout's value for labelSeparator}). To hide the separator use empty string ''.</div></li> * <li><b><tt>elementStyle</tt></b> : String<div class="sub-desc">The styles text for the input element's wrapper.</div></li> * <li><b><tt>clearCls</tt></b> : String<div class="sub-desc">The CSS class to apply to the special clearing div * rendered directly after each form field wrapper (defaults to <tt>'x-form-clear-left'</tt>)</div></li> * </ul></div> * @param field The {@link Field Ext.form.Field} being rendered. * @return An object hash containing the properties required to render the Field. */ getTemplateArgs: function(field) { var noLabelSep = !field.fieldLabel || field.hideLabel; return { id: field.id, label: field.fieldLabel, labelStyle: field.labelStyle||this.labelStyle||'', elementStyle: this.elementStyle||'', labelSeparator: noLabelSep ? '' : (typeof field.labelSeparator == 'undefined' ? this.labelSeparator : field.labelSeparator), itemCls: (field.itemCls||this.container.itemCls||'') + (field.hideLabel ? ' x-hide-label' : ''), clearCls: field.clearCls || 'x-form-clear-left' }; }, // private adjustWidthAnchor : function(value, comp){ return value - (comp.isFormField || comp.fieldLabel ? (comp.hideLabel ? 0 : this.labelAdjust) : 0); }, // private isValidParent : function(c, target){ return true; } /** * @property activeItem * @hide */ }); Ext.Container.LAYOUTS['form'] = Ext.layout.FormLayout;/**
- * @class Ext.layout.AccordionLayout
- * @extends Ext.layout.FitLayout
- * <p>This is a layout that contains multiple panels in an expandable accordion style such that only
- * <b>one panel can be open at any given time</b>. Each panel has built-in support for expanding and collapsing.
- * <p>This class is intended to be extended or created via the <tt><b>{@link Ext.Container#layout layout}</b></tt>
- * configuration property. See <tt><b>{@link Ext.Container#layout}</b></tt> for additional details.</p>
- * <p>Example usage:</p>
- * <pre><code>
- var accordion = new Ext.Panel({
- title: 'Accordion Layout',
- layout:'accordion',
- defaults: {
- // applied to each contained panel
- bodyStyle: 'padding:15px'
- },
- layoutConfig: {
- // layout-specific configs go here
- titleCollapse: false,
- animate: true,
- activeOnTop: true
- },
- items: [{
- title: 'Panel 1',
- html: '<p>Panel content!</p>'
- },{
- title: 'Panel 2',
- html: '<p>Panel content!</p>'
- },{
- title: 'Panel 3',
- html: '<p>Panel content!</p>'
- }]
- });
- </code></pre>
- */
- Ext.layout.AccordionLayout = Ext.extend(Ext.layout.FitLayout, {
- /**
- * @cfg {Boolean} fill
- * True to adjust the active item's height to fill the available space in the container, false to use the
- * item's current height, or auto height if not explicitly set (defaults to true).
- */
- fill : true,
- /**
- * @cfg {Boolean} autoWidth
- * True to set each contained item's width to 'auto', false to use the item's current width (defaults to true).
- * Note that some components, in particular the {@link Ext.grid.GridPanel grid}, will not function properly within
- * layouts if they have auto width, so in such cases this config should be set to false.
- */
- autoWidth : true,
- /**
- * @cfg {Boolean} titleCollapse
- * True to allow expand/collapse of each contained panel by clicking anywhere on the title bar, false to allow
- * expand/collapse only when the toggle tool button is clicked (defaults to true). When set to false,
- * {@link #hideCollapseTool} should be false also.
- */
- titleCollapse : true,
- /**
- * @cfg {Boolean} hideCollapseTool
- * True to hide the contained panels' collapse/expand toggle buttons, false to display them (defaults to false).
- * When set to true, {@link #titleCollapse} should be true also.
- */
- hideCollapseTool : false,
- /**
- * @cfg {Boolean} collapseFirst
- * True to make sure the collapse/expand toggle button always renders first (to the left of) any other tools
- * in the contained panels' title bars, false to render it last (defaults to false).
- */
- collapseFirst : false,
- /**
- * @cfg {Boolean} animate
- * True to slide the contained panels open and closed during expand/collapse using animation, false to open and
- * close directly with no animation (defaults to false). Note: to defer to the specific config setting of each
- * contained panel for this property, set this to undefined at the layout level.
- */
- animate : false,
- /**
- * @cfg {Boolean} sequence
- * <b>Experimental</b>. If animate is set to true, this will result in each animation running in sequence.
- */
- sequence : false,
- /**
- * @cfg {Boolean} activeOnTop
- * True to swap the position of each panel as it is expanded so that it becomes the first item in the container,
- * false to keep the panels in the rendered order. <b>This is NOT compatible with "animate:true"</b> (defaults to false).
- */
- activeOnTop : false,
- renderItem : function(c){
- if(this.animate === false){
- c.animCollapse = false;
- }
- c.collapsible = true;
- if(this.autoWidth){
- c.autoWidth = true;
- }
- if(this.titleCollapse){
- c.titleCollapse = true;
- }
- if(this.hideCollapseTool){
- c.hideCollapseTool = true;
- }
- if(this.collapseFirst !== undefined){
- c.collapseFirst = this.collapseFirst;
- }
- if(!this.activeItem && !c.collapsed){
- this.activeItem = c;
- }else if(this.activeItem && this.activeItem != c){
- c.collapsed = true;
- }
- Ext.layout.AccordionLayout.superclass.renderItem.apply(this, arguments);
- c.header.addClass('x-accordion-hd');
- c.on('beforeexpand', this.beforeExpand, this);
- },
- // private
- beforeExpand : function(p, anim){
- var ai = this.activeItem;
- if(ai){
- if(this.sequence){
- delete this.activeItem;
- if (!ai.collapsed){
- ai.collapse({callback:function(){
- p.expand(anim || true);
- }, scope: this});
- return false;
- }
- }else{
- ai.collapse(this.animate);
- }
- }
- this.activeItem = p;
- if(this.activeOnTop){
- p.el.dom.parentNode.insertBefore(p.el.dom, p.el.dom.parentNode.firstChild);
- }
- this.layout();
- },
- // private
- setItemSize : function(item, size){
- if(this.fill && item){
- var hh = 0;
- this.container.items.each(function(p){
- if(p != item){
- hh += p.header.getHeight();
- }
- });
- size.height -= hh;
- item.setSize(size);
- }
- },
- /**
- * Sets the active (expanded) item in the layout.
- * @param {String/Number} item The string component id or numeric index of the item to activate
- */
- setActiveItem : function(item){
- item = this.container.getComponent(item);
- if(this.activeItem != item){
- if(item.rendered && item.collapsed){
- item.expand();
- }else{
- this.activeItem = item;
- }
- }
- }
- });
- Ext.Container.LAYOUTS.accordion = Ext.layout.AccordionLayout;
- //backwards compat
- Ext.layout.Accordion = Ext.layout.AccordionLayout;/**
- * @class Ext.layout.TableLayout
- * @extends Ext.layout.ContainerLayout
- * <p>This layout allows you to easily render content into an HTML table. The total number of columns can be
- * specified, and rowspan and colspan can be used to create complex layouts within the table.
- * This class is intended to be extended or created via the layout:'table' {@link Ext.Container#layout} config,
- * and should generally not need to be created directly via the new keyword.</p>
- * <p>Note that when creating a layout via config, the layout-specific config properties must be passed in via
- * the {@link Ext.Container#layoutConfig} object which will then be applied internally to the layout. In the
- * case of TableLayout, the only valid layout config property is {@link #columns}. However, the items added to a
- * TableLayout can supply the following table-specific config properties:</p>
- * <ul>
- * <li><b>rowspan</b> Applied to the table cell containing the item.</li>
- * <li><b>colspan</b> Applied to the table cell containing the item.</li>
- * <li><b>cellId</b> An id applied to the table cell containing the item.</li>
- * <li><b>cellCls</b> A CSS class name added to the table cell containing the item.</li>
- * </ul>
- * <p>The basic concept of building up a TableLayout is conceptually very similar to building up a standard
- * HTML table. You simply add each panel (or "cell") that you want to include along with any span attributes
- * specified as the special config properties of rowspan and colspan which work exactly like their HTML counterparts.
- * Rather than explicitly creating and nesting rows and columns as you would in HTML, you simply specify the
- * total column count in the layoutConfig and start adding panels in their natural order from left to right,
- * top to bottom. The layout will automatically figure out, based on the column count, rowspans and colspans,
- * how to position each panel within the table. Just like with HTML tables, your rowspans and colspans must add
- * up correctly in your overall layout or you'll end up with missing and/or extra cells! Example usage:</p>
- * <pre><code>
- // This code will generate a layout table that is 3 columns by 2 rows
- // with some spanning included. The basic layout will be:
- // +--------+-----------------+
- // | A | B |
- // | |--------+--------|
- // | | C | D |
- // +--------+--------+--------+
- var table = new Ext.Panel({
- title: 'Table Layout',
- layout:'table',
- defaults: {
- // applied to each contained panel
- bodyStyle:'padding:20px'
- },
- layoutConfig: {
- // The total column count must be specified here
- columns: 3
- },
- items: [{
- html: '<p>Cell A content</p>',
- rowspan: 2
- },{
- html: '<p>Cell B content</p>',
- colspan: 2
- },{
- html: '<p>Cell C content</p>',
- cellCls: 'highlight'
- },{
- html: '<p>Cell D content</p>'
- }]
- });
- </code></pre>
- */
- Ext.layout.TableLayout = Ext.extend(Ext.layout.ContainerLayout, {
- /**
- * @cfg {Number} columns
- * The total number of columns to create in the table for this layout. If not specified, all Components added to
- * this layout will be rendered into a single row using one column per Component.
- */
- // private
- monitorResize:false,
- /**
- * @cfg {Object} tableAttrs
- * <p>An object containing properties which are added to the {@link Ext.DomHelper DomHelper} specification
- * used to create the layout's <tt><table></tt> element. Example:</p><pre><code>
- {
- xtype: 'panel',
- layout: 'table',
- layoutConfig: {
- tableAttrs: {
- style: {
- width: '100%'
- }
- },
- columns: 3
- }
- }</code></pre>
- */
- tableAttrs:null,
- // private
- setContainer : function(ct){
- Ext.layout.TableLayout.superclass.setContainer.call(this, ct);
- this.currentRow = 0;
- this.currentColumn = 0;
- this.cells = [];
- },
- // private
- onLayout : function(ct, target){
- var cs = ct.items.items, len = cs.length, c, i;
- if(!this.table){
- target.addClass('x-table-layout-ct');
- this.table = target.createChild(
- Ext.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true);
- }
- this.renderAll(ct, target);
- },
- // private
- getRow : function(index){
- var row = this.table.tBodies[0].childNodes[index];
- if(!row){
- row = document.createElement('tr');
- this.table.tBodies[0].appendChild(row);
- }
- return row;
- },
- // private
- getNextCell : function(c){
- var cell = this.getNextNonSpan(this.currentColumn, this.currentRow);
- var curCol = this.currentColumn = cell[0], curRow = this.currentRow = cell[1];
- for(var rowIndex = curRow; rowIndex < curRow + (c.rowspan || 1); rowIndex++){
- if(!this.cells[rowIndex]){
- this.cells[rowIndex] = [];
- }
- for(var colIndex = curCol; colIndex < curCol + (c.colspan || 1); colIndex++){
- this.cells[rowIndex][colIndex] = true;
- }
- }
- var td = document.createElement('td');
- if(c.cellId){
- td.id = c.cellId;
- }
- var cls = 'x-table-layout-cell';
- if(c.cellCls){
- cls += ' ' + c.cellCls;
- }
- td.className = cls;
- if(c.colspan){
- td.colSpan = c.colspan;
- }
- if(c.rowspan){
- td.rowSpan = c.rowspan;
- }
- this.getRow(curRow).appendChild(td);
- return td;
- },
- // private
- getNextNonSpan: function(colIndex, rowIndex){
- var cols = this.columns;
- while((cols && colIndex >= cols) || (this.cells[rowIndex] && this.cells[rowIndex][colIndex])) {
- if(cols && colIndex >= cols){
- rowIndex++;
- colIndex = 0;
- }else{
- colIndex++;
- }
- }
- return [colIndex, rowIndex];
- },
- // private
- renderItem : function(c, position, target){
- if(c && !c.rendered){
- c.render(this.getNextCell(c));
- if(this.extraCls){
- var t = c.getPositionEl ? c.getPositionEl() : c;
- t.addClass(this.extraCls);
- }
- }
- },
- // private
- isValidParent : function(c, target){
- return true;
- }
- /**
- * @property activeItem
- * @hide
- */
- });
- Ext.Container.LAYOUTS['table'] = Ext.layout.TableLayout;/**
- * @class Ext.layout.AbsoluteLayout
- * @extends Ext.layout.AnchorLayout
- * <p>This is a layout that inherits the anchoring of <b>{@link Ext.layout.AnchorLayout}</b> and adds the
- * ability for x/y positioning using the standard x and y component config options.</p>
- * <p>This class is intended to be extended or created via the <tt><b>{@link Ext.Container#layout layout}</b></tt>
- * configuration property. See <tt><b>{@link Ext.Container#layout}</b></tt> for additional details.</p>
- * <p>Example usage:</p>
- * <pre><code>
- var form = new Ext.form.FormPanel({
- title: 'Absolute Layout',
- layout:'absolute',
- layoutConfig: {
- // layout-specific configs go here
- extraCls: 'x-abs-layout-item',
- },
- baseCls: 'x-plain',
- url:'save-form.php',
- defaultType: 'textfield',
- items: [{
- x: 0,
- y: 5,
- xtype:'label',
- text: 'Send To:'
- },{
- x: 60,
- y: 0,
- name: 'to',
- anchor:'100%' // anchor width by percentage
- },{
- x: 0,
- y: 35,
- xtype:'label',
- text: 'Subject:'
- },{
- x: 60,
- y: 30,
- name: 'subject',
- anchor: '100%' // anchor width by percentage
- },{
- x:0,
- y: 60,
- xtype: 'textarea',
- name: 'msg',
- anchor: '100% 100%' // anchor width and height
- }]
- });
- </code></pre>
- */
- Ext.layout.AbsoluteLayout = Ext.extend(Ext.layout.AnchorLayout, {
- extraCls: 'x-abs-layout-item',
- onLayout : function(ct, target){
- target.position();
- this.paddingLeft = target.getPadding('l');
- this.paddingTop = target.getPadding('t');
- Ext.layout.AbsoluteLayout.superclass.onLayout.call(this, ct, target);
- },
- // private
- adjustWidthAnchor : function(value, comp){
- return value ? value - comp.getPosition(true)[0] + this.paddingLeft : value;
- },
- // private
- adjustHeightAnchor : function(value, comp){
- return value ? value - comp.getPosition(true)[1] + this.paddingTop : value;
- }
- /**
- * @property activeItem
- * @hide
- */
- });
- Ext.Container.LAYOUTS['absolute'] = Ext.layout.AbsoluteLayout; /**
- * @class Ext.layout.BoxLayout
- * @extends Ext.layout.ContainerLayout
- * <p>Base Class for HBoxLayout and VBoxLayout Classes. Generally it should not need to be used directly.</p>
- */
- Ext.layout.BoxLayout = Ext.extend(Ext.layout.ContainerLayout, {
- /**
- * @cfg {Object} defaultMargins
- * <p>If the individual contained items do not have a <tt>margins</tt>
- * property specified, the default margins from this property will be
- * applied to each item.</p>
- * <br><p>This property may be specified as an object containing margins
- * to apply in the format:</p><pre><code>
- {
- top: (top margin),
- right: (right margin),
- bottom: (bottom margin),
- left: (left margin)
- }</code></pre>
- * <p>This property may also be specified as a string containing
- * space-separated, numeric margin values. The order of the sides associated
- * with each value matches the way CSS processes margin values:</p>
- * <div class="mdetail-params"><ul>
- * <li>If there is only one value, it applies to all sides.</li>
- * <li>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.</li>
- * <li>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.</li>
- * <li>If there are four values, they apply to the top, right, bottom, and
- * left, respectively.</li>
- * </ul></div>
- * <p>Defaults to:</p><pre><code>
- * {top:0, right:0, bottom:0, left:0}
- * </code></pre>
- */
- defaultMargins : {left:0,top:0,right:0,bottom:0},
- /**
- * @cfg {String} padding
- * Defaults to <tt>'0'</tt>. Sets the padding to be applied to all child items managed by this
- * container's layout.
- */
- padding : '0',
- // documented in subclasses
- pack : 'start',
- // private
- monitorResize : true,
- scrollOffset : 0,
- extraCls : 'x-box-item',
- ctCls : 'x-box-layout-ct',
- innerCls : 'x-box-inner',
- // private
- isValidParent : function(c, target){
- return c.getEl().dom.parentNode == this.innerCt.dom;
- },
- // private
- onLayout : function(ct, target){
- var cs = ct.items.items, len = cs.length, c, i, last = len-1, cm;
- if(!this.innerCt){
- target.addClass(this.ctCls);
- // the innerCt prevents wrapping and shuffling while
- // the container is resizing
- this.innerCt = target.createChild({cls:this.innerCls});
- this.padding = this.parseMargins(this.padding);
- }
- this.renderAll(ct, this.innerCt);
- },
- // private
- renderItem : function(c){
- if(typeof c.margins == 'string'){
- c.margins = this.parseMargins(c.margins);
- }else if(!c.margins){
- c.margins = this.defaultMargins;
- }
- Ext.layout.BoxLayout.superclass.renderItem.apply(this, arguments);
- },
- getTargetSize : function(target){ return (Ext.isIE6 && Ext.isStrict && target.dom == document.body) ? target.getStyleSize() : target.getViewSize();
- },
- getItems: function(ct){
- var items = [];
- ct.items.each(function(c){
- if(c.isVisible()){
- items.push(c);
- }
- });
- return items;
- }
- /**
- * @property activeItem
- * @hide
- */
- });
- /**
- * @class Ext.layout.VBoxLayout
- * @extends Ext.layout.BoxLayout
- * A layout that arranges items vertically
- */
- Ext.layout.VBoxLayout = Ext.extend(Ext.layout.BoxLayout, {
- /**
- * @cfg {String} align
- * Controls how the child items of the container are aligned. Acceptable configuration values for this
- * property are:
- * <div class="mdetail-params"><ul>
- * <li><b><tt>left</tt></b> : <b>Default</b><div class="sub-desc">child items are aligned horizontally
- * at the <b>left</b> side of the container</div></li>
- * <li><b><tt>center</tt></b> : <div class="sub-desc">child items are aligned horizontally at the
- * <b>mid-width</b> of the container</div></li>
- * <li><b><tt>stretch</tt></b> : <div class="sub-desc">child items are stretched horizontally to fill
- * the width of the container</div></li>
- * <li><b><tt>stretchmax</tt></b> : <div class="sub-desc">child items are stretched horizontally to
- * the size of the largest item.</div></li>
- * </ul></div>
- */
- align : 'left', // left, center, stretch, strechmax
- /**
- * @cfg {String} pack
- * Controls how the child items of the container are packed together. Acceptable configuration values
- * for this property are:
- * <div class="mdetail-params"><ul>
- * <li><b><tt>start</tt></b> : <b>Default</b><div class="sub-desc">child items are packed together at
- * <b>top</b> side of container</div></li>
- * <li><b><tt>center</tt></b> : <div class="sub-desc">child items are packed together at
- * <b>mid-height</b> of container</div></li>
- * <li><b><tt>end</tt></b> : <div class="sub-desc">child items are packed together at <b>bottom</b>
- * side of container</div></li>
- * </ul></div>
- */
- /**
- * @cfg {Number} flex
- * This configuation option is to be applied to <b>child <tt>items</tt></b> of the container managed
- * by this layout. Each child item with a <tt>flex</tt> property will be flexed <b>vertically</b>
- * according to each item's <b>relative</b> <tt>flex</tt> value compared to the sum of all items with
- * a <tt>flex</tt> value specified. Any child items that have either a <tt>flex = 0</tt> or
- * <tt>flex = undefined</tt> will not be 'flexed' (the initial size will not be changed).
- */
- // private
- onLayout : function(ct, target){
- Ext.layout.VBoxLayout.superclass.onLayout.call(this, ct, target);
- var cs = this.getItems(ct), cm, ch, margin,
- size = this.getTargetSize(target),
- w = size.width - target.getPadding('lr') - this.scrollOffset,
- h = size.height - target.getPadding('tb'),
- l = this.padding.left, t = this.padding.top,
- isStart = this.pack == 'start',
- isRestore = ['stretch', 'stretchmax'].indexOf(this.align) == -1,
- stretchWidth = w - (this.padding.left + this.padding.right),
- extraHeight = 0,
- maxWidth = 0,
- totalFlex = 0,
- flexHeight = 0,
- usedHeight = 0;
- Ext.each(cs, function(c){
- cm = c.margins;
- totalFlex += c.flex || 0;
- ch = c.getHeight();
- margin = cm.top + cm.bottom;
- extraHeight += ch + margin;
- flexHeight += margin + (c.flex ? 0 : ch);
- maxWidth = Math.max(maxWidth, c.getWidth() + cm.left + cm.right);
- });
- extraHeight = h - extraHeight - this.padding.top - this.padding.bottom;
- var innerCtWidth = maxWidth + this.padding.left + this.padding.right;
- switch(this.align){
- case 'stretch':
- this.innerCt.setSize(w, h);
- break;
- case 'stretchmax':
- case 'left':
- this.innerCt.setSize(innerCtWidth, h);
- break;
- case 'center':
- this.innerCt.setSize(w = Math.max(w, innerCtWidth), h);
- break;
- }
- var availHeight = Math.max(0, h - this.padding.top - this.padding.bottom - flexHeight),
- leftOver = availHeight,
- heights = [],
- restore = [],
- idx = 0,
- availableWidth = Math.max(0, w - this.padding.left - this.padding.right);
- Ext.each(cs, function(c){
- if(isStart && c.flex){
- ch = Math.floor(availHeight * (c.flex / totalFlex));
- leftOver -= ch;
- heights.push(ch);
- }
- });
- if(this.pack == 'center'){