X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/25ef3491bd9ae007ff1fc2b0d7943e6eaaccf775..6a7e4474cba9d8be4b2ec445e10f1691f7277c50:/src/widgets/Panel.js diff --git a/src/widgets/Panel.js b/src/widgets/Panel.js index 6f806f0d..a5fc524c 100644 --- a/src/widgets/Panel.js +++ b/src/widgets/Panel.js @@ -1,6 +1,6 @@ /*! - * Ext JS Library 3.0.3 - * Copyright(c) 2006-2009 Ext JS, LLC + * Ext JS Library 3.2.0 + * Copyright(c) 2006-2010 Ext JS, Inc. * licensing@extjs.com * http://www.extjs.com/license */ @@ -359,7 +359,7 @@ var w = new Ext.Window({ *
  • event : Ext.EventObject
    The click event.
  • *
  • toolEl : Ext.Element
    The tool Element.
  • *
  • panel : Ext.Panel
    The host Panel
  • - *
  • tc : Ext.Panel
    The tool configuration object
  • + *
  • tc : Object
    The tool configuration object
  • * *
  • stopEvent : Boolean
    Defaults to true. Specify as false to allow click event to propagate.
  • *
  • scope : Object
    The scope in which to call the handler.
  • @@ -444,11 +444,7 @@ var win = new Ext.Window({ * {@link Ext.layout.BorderLayout.Region BorderLayout.Region} * {@link Ext.layout.BorderLayout.Region#floatable floatable} config option. */ - /** - * @cfg {Boolean} autoScroll - * true to use overflow:'auto' on the panel's body element and show scroll bars automatically when - * necessary, false to clip any overflowing content (defaults to false). - */ + /** * @cfg {Mixed} floating *

    This property is used to configure the underlying {@link Ext.Layer}. Acceptable values for this @@ -484,33 +480,6 @@ var win = new Ext.Window({ * false to disable the iframe shim in browsers which need one (defaults to true). * Note that this option only applies when {@link #floating} = true. */ - /** - * @cfg {String/Object} html - * An HTML fragment, or a {@link Ext.DomHelper DomHelper} specification to use as the panel's body - * content (defaults to ''). The HTML content is added by the Panel's {@link #afterRender} method, - * and so the document will not contain this HTML at the time the {@link #render} event is fired. - * This content is inserted into the body before any configured {@link #contentEl} is appended. - */ - /** - * @cfg {String} contentEl - *

    Optional. Specify an existing HTML element, or the id of an existing HTML element to use as this Panel's - * {@link #body} content.

    - * - */ /** * @cfg {Object/Array} keys * A {@link Ext.KeyMap} config object (in the format expected by {@link Ext.KeyMap#addBinding} @@ -680,7 +649,16 @@ new Ext.Panel({ * footer, etc.). */ preventBodyReset : false, - + + /** + * @cfg {Number/String} padding + * A shortcut for setting a padding style on the body element. The value can either be + * a number to be applied to all sides, or a normal css string describing padding. + * Defaults to undefined. + * + */ + padding: undefined, + /** @cfg {String} resizeEvent * The event to listen to for resizing in layouts. Defaults to 'bodyresize'. */ @@ -714,8 +692,8 @@ new Ext.Panel({ * @event bodyresize * Fires after the Panel has been resized. * @param {Ext.Panel} p the Panel which has been resized. - * @param {Number} width The Panel's new width. - * @param {Number} height The Panel's new height. + * @param {Number} width The Panel body's new width. + * @param {Number} height The Panel body's new height. */ 'bodyresize', /** @@ -799,62 +777,87 @@ new Ext.Panel({ this.baseCls = 'x-plain'; } + + this.toolbars = []; // shortcuts if(this.tbar){ this.elements += ',tbar'; - if(Ext.isObject(this.tbar)){ - this.topToolbar = this.tbar; - } - delete this.tbar; + this.topToolbar = this.createToolbar(this.tbar); + this.tbar = null; + } if(this.bbar){ this.elements += ',bbar'; - if(Ext.isObject(this.bbar)){ - this.bottomToolbar = this.bbar; - } - delete this.bbar; + this.bottomToolbar = this.createToolbar(this.bbar); + this.bbar = null; } if(this.header === true){ this.elements += ',header'; - delete this.header; + this.header = null; }else if(this.headerCfg || (this.title && this.header !== false)){ this.elements += ',header'; } if(this.footerCfg || this.footer === true){ this.elements += ',footer'; - delete this.footer; + this.footer = null; } if(this.buttons){ - this.elements += ',footer'; - var btns = this.buttons; - /** - * This Panel's Array of buttons as created from the {@link #buttons} - * config property. Read only. - * @type Array - * @property buttons - */ - this.buttons = []; - Ext.each(btns, function(btn){ - if(btn.render){ // button instance - this.buttons.push(btn); - }else if(btn.xtype){ - this.buttons.push(Ext.create(btn, 'button')); - }else{ - this.addButton(btn); - } - }, this); + this.fbar = this.buttons; + this.buttons = null; } if(this.fbar){ - this.elements += ',footer'; + this.createFbar(this.fbar); } if(this.autoLoad){ this.on('render', this.doAutoLoad, this, {delay:10}); } }, + // private + createFbar : function(fbar){ + var min = this.minButtonWidth; + this.elements += ',footer'; + this.fbar = this.createToolbar(fbar, { + buttonAlign: this.buttonAlign, + toolbarCls: 'x-panel-fbar', + enableOverflow: false, + defaults: function(c){ + return { + minWidth: c.minWidth || min + }; + } + }); + // @compat addButton and buttons could possibly be removed + // @target 4.0 + /** + * This Panel's Array of buttons as created from the {@link #buttons} + * config property. Read only. + * @type Array + * @property buttons + */ + this.fbar.items.each(function(c){ + c.minWidth = c.minWidth || this.minButtonWidth; + }, this); + this.buttons = this.fbar.items.items; + }, + + // private + createToolbar: function(tb, options){ + var result; + // Convert array to proper toolbar config + if(Ext.isArray(tb)){ + tb = { + items: tb + }; + } + result = tb.events ? Ext.apply(tb, options) : this.createComponent(Ext.apply({}, tb, options), 'toolbar'); + this.toolbars.push(result); + return result; + }, + // private createElement : function(name, pnode){ if(this[name]){ @@ -888,23 +891,23 @@ new Ext.Panel({ d = el.dom, bw, ts; - - + + if(this.collapsible && !this.hideCollapseTool){ this.tools = this.tools ? this.tools.slice(0) : []; this.tools[this.collapseFirst?'unshift':'push']({ id: 'toggle', handler : this.toggleCollapse, scope: this - }); + }); } - + if(this.tools){ ts = this.tools; this.elements += (this.header !== false) ? ',header' : ''; } this.tools = {}; - + el.addClass(this.baseCls); if(d.firstChild){ // existing markup this.header = el.down('.'+this.headerCls); @@ -957,7 +960,7 @@ new Ext.Panel({ * b) The last element is reported incorrectly when using a loadmask */ this.ft = Ext.get(this.bwrap.dom.lastChild); - this.mc = Ext.get(this.bwrap.dom.firstChild.firstChild.firstChild); + this.mc = Ext.get(mc); }else{ this.createElement('header', d); this.createElement('bwrap', d); @@ -1030,49 +1033,20 @@ new Ext.Panel({ this.addTool.apply(this, ts); } - if(this.buttons && this.buttons.length > 0){ - this.fbar = new Ext.Toolbar({ - items: this.buttons, - toolbarCls: 'x-panel-fbar' - }); - } - this.toolbars = []; + // Render Toolbars. if(this.fbar){ - this.fbar = Ext.create(this.fbar, 'toolbar'); - this.fbar.enableOverflow = false; - if(this.fbar.items){ - this.fbar.items.each(function(c){ - c.minWidth = c.minWidth || this.minButtonWidth; - }, this); - } - this.fbar.toolbarCls = 'x-panel-fbar'; - - var bct = this.footer.createChild({cls: 'x-panel-btns x-panel-btns-'+this.buttonAlign}); + this.footer.addClass('x-panel-btns'); this.fbar.ownerCt = this; - this.fbar.render(bct); - bct.createChild({cls:'x-clear'}); - this.toolbars.push(this.fbar); + this.fbar.render(this.footer); + this.footer.createChild({cls:'x-clear'}); } - if(this.tbar && this.topToolbar){ - if(Ext.isArray(this.topToolbar)){ - this.topToolbar = new Ext.Toolbar(this.topToolbar); - }else if(!this.topToolbar.events){ - this.topToolbar = Ext.create(this.topToolbar, 'toolbar'); - } this.topToolbar.ownerCt = this; this.topToolbar.render(this.tbar); - this.toolbars.push(this.topToolbar); } if(this.bbar && this.bottomToolbar){ - if(Ext.isArray(this.bottomToolbar)){ - this.bottomToolbar = new Ext.Toolbar(this.bottomToolbar); - }else if(!this.bottomToolbar.events){ - this.bottomToolbar = Ext.create(this.bottomToolbar, 'toolbar'); - } this.bottomToolbar.ownerCt = this; this.bottomToolbar.render(this.bbar); - this.toolbars.push(this.bottomToolbar); } }, @@ -1094,9 +1068,12 @@ new Ext.Panel({ if(img){ Ext.fly(img).replaceClass(old, this.iconCls); }else{ - Ext.DomHelper.insertBefore(hd.dom.firstChild, { - tag:'img', src: Ext.BLANK_IMAGE_URL, cls:'x-panel-inline-icon '+this.iconCls - }); + var hdspan = hd.child('span.' + this.headerTextCls); + if (hdspan) { + Ext.DomHelper.insertBefore(hdspan.dom, { + tag:'img', src: Ext.BLANK_IMAGE_URL, cls:'x-panel-inline-icon '+this.iconCls + }); + } } } } @@ -1106,14 +1083,12 @@ new Ext.Panel({ // private makeFloating : function(cfg){ this.floating = true; - this.el = new Ext.Layer( - Ext.isObject(cfg) ? cfg : { - shadow: Ext.isDefined(this.shadow) ? this.shadow : 'sides', - shadowOffset: this.shadowOffset, - constrain:false, - shim: this.shim === false ? false : undefined - }, this.el - ); + this.el = new Ext.Layer(Ext.apply({}, cfg, { + shadow: Ext.isDefined(this.shadow) ? this.shadow : 'sides', + shadowOffset: this.shadowOffset, + constrain:false, + shim: this.shim === false ? false : undefined + }), this.el); }, /** @@ -1131,6 +1106,14 @@ new Ext.Panel({ getBottomToolbar : function(){ return this.bottomToolbar; }, + + /** + * Returns the {@link Ext.Toolbar toolbar} from the footer ({@link #fbar}) section of the panel. + * @return {Ext.Toolbar} The toolbar + */ + getFooterToolbar : function() { + return this.fbar; + }, /** * Adds a button to this panel. Note that this method must be called prior to rendering. The preferred @@ -1138,27 +1121,23 @@ new Ext.Panel({ * @param {String/Object} config A valid {@link Ext.Button} config. A string will become the text for a default * button config, an object will be treated as a button config object. * @param {Function} handler The function to be called on button {@link Ext.Button#click} - * @param {Object} scope The scope to use for the button handler function + * @param {Object} scope The scope (this reference) in which the button handler function is executed. Defaults to the Button. * @return {Ext.Button} The button that was added */ addButton : function(config, handler, scope){ - var bc = { - handler: handler, - scope: scope, - minWidth: this.minButtonWidth, - hideParent:true - }; - if(Ext.isString(config)){ - bc.text = config; - }else{ - Ext.apply(bc, config); + if(!this.fbar){ + this.createFbar([]); } - var btn = new Ext.Button(bc); - if(!this.buttons){ - this.buttons = []; + if(handler){ + if(Ext.isString(config)){ + config = {text: config}; + } + config = Ext.apply({ + handler: handler, + scope: scope + }, config); } - this.buttons.push(btn); - return btn; + return this.fbar.add(config); }, // private @@ -1168,7 +1147,7 @@ new Ext.Panel({ this.tools = []; } Ext.each(arguments, function(arg){ - this.tools.push(arg) + this.tools.push(arg); }, this); return; } @@ -1189,7 +1168,7 @@ new Ext.Panel({ var tc = a[i]; if(!this.tools[tc.id]){ var overCls = 'x-tool-'+tc.id+'-over'; - var t = this.toolTemplate.insertFirst((tc.align !== 'left') ? this[this.toolTarget] : this[this.toolTarget].child('span'), tc, true); + var t = this.toolTemplate.insertFirst(this[this.toolTarget], tc, true); this.tools[tc.id] = t; t.enableDisplayMode('block'); this.mon(t, 'click', this.createToolHandler(t, tc, overCls, this)); @@ -1214,6 +1193,7 @@ new Ext.Panel({ }, onLayout : function(shallow, force){ + Ext.Panel.superclass.onLayout.apply(this, arguments); if(this.hasLayout && this.toolbars.length > 0){ Ext.each(this.toolbars, function(tb){ tb.doLayout(undefined, force); @@ -1225,15 +1205,16 @@ new Ext.Panel({ syncHeight : function(){ var h = this.toolbarHeight, bd = this.body, - lsh = this.lastSize.height; - + lsh = this.lastSize.height, + sz; + if(this.autoHeight || !Ext.isDefined(lsh) || lsh == 'auto'){ return; } - - + + if(h != this.getToolbarHeight()){ - h = Math.max(0, this.adjustBodyHeight(lsh - this.getFrameHeight())); + h = Math.max(0, lsh - this.getFrameHeight()); bd.setHeight(h); sz = bd.getSize(); this.toolbarHeight = this.getToolbarHeight(); @@ -1278,36 +1259,14 @@ new Ext.Panel({ if(this.title){ this.setTitle(this.title); } - this.setAutoScroll(); - if(this.html){ - this.body.update(Ext.isObject(this.html) ? - Ext.DomHelper.markup(this.html) : - this.html); - delete this.html; - } - if(this.contentEl){ - var ce = Ext.getDom(this.contentEl); - Ext.fly(ce).removeClass(['x-hidden', 'x-hide-display']); - this.body.dom.appendChild(ce); - } - if(this.collapsed){ + Ext.Panel.superclass.afterRender.call(this); // do sizing calcs last + if (this.collapsed) { this.collapsed = false; this.collapse(false); } - Ext.Panel.superclass.afterRender.call(this); // do sizing calcs last this.initEvents(); }, - // private - setAutoScroll : function(){ - if(this.rendered && this.autoScroll){ - var el = this.body || this.el; - if(el){ - el.setOverflow('auto'); - } - } - }, - // private getKeyMap : function(){ if(!this.keyMap){ @@ -1333,10 +1292,9 @@ new Ext.Panel({ remove: this.syncHeight }); }, this); - if(!this.ownerCt){ - this.syncHeight(); - } + this.syncHeight(); } + }, // private @@ -1365,9 +1323,7 @@ new Ext.Panel({ // private afterEffect : function(anim){ this.syncShadow(); - if(anim !== false){ - this.el.removeClass('x-panel-animated'); - } + this.el.removeClass('x-panel-animated'); }, // private - wraps up an animation param with internal callbacks @@ -1414,7 +1370,7 @@ new Ext.Panel({ Ext.apply(this.createEffect(animArg||true, this.afterCollapse, this), this.collapseDefaults)); }else{ - this[this.collapseEl].hide(); + this[this.collapseEl].hide(this.hideMode); this.afterCollapse(false); } }, @@ -1423,7 +1379,17 @@ new Ext.Panel({ afterCollapse : function(anim){ this.collapsed = true; this.el.addClass(this.collapsedCls); + if(anim !== false){ + this[this.collapseEl].hide(this.hideMode); + } this.afterEffect(anim); + + // Reset lastSize of all sub-components so they KNOW they are in a collapsed container + this.cascade(function(c) { + if (c.lastSize) { + c.lastSize = { width: 0, height: 0 }; + } + }); this.fireEvent('collapse', this); }, @@ -1452,7 +1418,7 @@ new Ext.Panel({ Ext.apply(this.createEffect(animArg||true, this.afterExpand, this), this.expandDefaults)); }else{ - this[this.collapseEl].show(); + this[this.collapseEl].show(this.hideMode); this.afterExpand(false); } }, @@ -1460,8 +1426,12 @@ new Ext.Panel({ // private afterExpand : function(anim){ this.collapsed = false; + if(anim !== false){ + this[this.collapseEl].show(this.hideMode); + } this.afterEffect(anim); - if(Ext.isDefined(this.deferLayout)){ + if (this.deferLayout) { + delete this.deferLayout; this.doLayout(true); } this.fireEvent('expand', this); @@ -1495,54 +1465,52 @@ new Ext.Panel({ }, // private - onResize : function(w, h){ + onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){ + var w = adjWidth, + h = adjHeight; + if(Ext.isDefined(w) || Ext.isDefined(h)){ if(!this.collapsed){ + // First, set the the Panel's body width. + // If we have auto-widthed it, get the resulting full offset width so we can size the Toolbars to match + // The Toolbars must not buffer this resize operation because we need to know their heights. + if(Ext.isNumber(w)){ - w = this.adjustBodyWidth(w - this.getFrameWidth()); - if(this.tbar){ - this.tbar.setWidth(w); - if(this.topToolbar){ - this.topToolbar.setSize(w); - } + this.body.setWidth(w = this.adjustBodyWidth(w - this.getFrameWidth())); + } else if (w == 'auto') { + w = this.body.setWidth('auto').dom.offsetWidth; + } else { + w = this.body.dom.offsetWidth; + } + + if(this.tbar){ + this.tbar.setWidth(w); + if(this.topToolbar){ + this.topToolbar.setSize(w); } - if(this.bbar){ - this.bbar.setWidth(w); - if(this.bottomToolbar){ - this.bottomToolbar.setSize(w); + } + if(this.bbar){ + this.bbar.setWidth(w); + if(this.bottomToolbar){ + this.bottomToolbar.setSize(w); + // The bbar does not move on resize without this. + if (Ext.isIE) { + this.bbar.setStyle('position', 'static'); + this.bbar.setStyle('position', ''); } } + } + if(this.footer){ + this.footer.setWidth(w); if(this.fbar){ - var f = this.fbar, - fWidth = 1, - strict = Ext.isStrict; - if(this.buttonAlign == 'left'){ - fWidth = w - f.container.getFrameWidth('lr'); - }else{ - //center/right alignment off in webkit - if(Ext.isIE || Ext.isWebKit){ - //center alignment ok on webkit. - //right broken in both, center on IE - if(!(this.buttonAlign == 'center' && Ext.isWebKit) && (!strict || (!Ext.isIE8 && strict))){ - (function(){ - f.setWidth(f.getEl().child('.x-toolbar-ct').getWidth()); - }).defer(1); - }else{ - fWidth = 'auto'; - } - }else{ - fWidth = 'auto'; - } - } - f.setWidth(fWidth); + this.fbar.setSize(Ext.isIE ? (w - this.footer.getFrameWidth('lr')) : 'auto'); } - this.body.setWidth(w); - }else if(w == 'auto'){ - this.body.setWidth(w); } + // At this point, the Toolbars must be layed out for getFrameHeight to find a result. if(Ext.isNumber(h)){ - h = Math.max(0, this.adjustBodyHeight(h - this.getFrameHeight())); + h = Math.max(0, h - this.getFrameHeight()); + //h = Math.max(0, h - (this.getHeight() - this.body.getHeight())); this.body.setHeight(h); }else if(h == 'auto'){ this.body.setHeight(h); @@ -1552,26 +1520,28 @@ new Ext.Panel({ this.el._mask.setSize(this.el.dom.clientWidth, this.el.getHeight()); } }else{ + // Adds an event to set the correct height afterExpand. This accounts for the deferHeight flag in panel this.queuedBodySize = {width: w, height: h}; if(!this.queuedExpand && this.allowQueuedExpand !== false){ this.queuedExpand = true; this.on('expand', function(){ delete this.queuedExpand; this.onResize(this.queuedBodySize.width, this.queuedBodySize.height); - this.doLayout(); }, this, {single:true}); } } this.onBodyResize(w, h); } this.syncShadow(); + Ext.Panel.superclass.onResize.call(this, adjWidth, adjHeight, rawWidth, rawHeight); + }, - + // private onBodyResize: function(w, h){ this.fireEvent('bodyresize', this, w, h); }, - + // private getToolbarHeight: function(){ var h = 0; @@ -1583,7 +1553,7 @@ new Ext.Panel({ return h; }, - // private + // deprecate adjustBodyHeight : function(h){ return h; }, @@ -1619,18 +1589,27 @@ new Ext.Panel({ * header and footer elements, but not including the body height). To retrieve the body height see {@link #getInnerHeight}. * @return {Number} The frame height */ - getFrameHeight : function(){ - var h = this.el.getFrameWidth('tb') + this.bwrap.getFrameWidth('tb'); - h += (this.tbar ? this.tbar.getHeight() : 0) + - (this.bbar ? this.bbar.getHeight() : 0); + getFrameHeight : function() { + var h = Math.max(0, this.getHeight() - this.body.getHeight()); - if(this.frame){ - h += this.el.dom.firstChild.offsetHeight + this.ft.dom.offsetHeight + this.mc.getFrameWidth('tb'); - }else{ - h += (this.header ? this.header.getHeight() : 0) + - (this.footer ? this.footer.getHeight() : 0); + if (isNaN(h)) { + h = 0; } return h; + + /* Deprecate + var h = this.el.getFrameWidth('tb') + this.bwrap.getFrameWidth('tb'); + h += (this.tbar ? this.tbar.getHeight() : 0) + + (this.bbar ? this.bbar.getHeight() : 0); + + if(this.frame){ + h += this.el.dom.firstChild.offsetHeight + this.ft.dom.offsetHeight + this.mc.getFrameWidth('tb'); + }else{ + h += (this.header ? this.header.getHeight() : 0) + + (this.footer ? this.footer.getHeight() : 0); + } + return h; + */ }, /** @@ -1648,7 +1627,10 @@ new Ext.Panel({ * @return {Number} The body height */ getInnerHeight : function(){ - return this.getSize().height - this.getFrameHeight(); + return this.body.getHeight(); + /* Deprecate + return this.getSize().height - this.getFrameHeight(); + */ }, // private @@ -1663,6 +1645,11 @@ new Ext.Panel({ return this.body; }, + // private + getContentTarget : function(){ + return this.body; + }, + /** *

    Sets the title text for the panel and optionally the {@link #iconCls icon class}.

    *

    In order to be able to set the title, a header element must have been created @@ -1720,38 +1707,50 @@ panel.load({ // private beforeDestroy : function(){ + Ext.Panel.superclass.beforeDestroy.call(this); if(this.header){ this.header.removeAllListeners(); - if(this.headerAsText){ - Ext.Element.uncache(this.header.child('span')); - } } - Ext.Element.uncache( - this.ft, - this.mc, - this.header, - this.tbar, - this.bbar, - this.footer, - this.body, - this.bwrap - ); if(this.tools){ for(var k in this.tools){ Ext.destroy(this.tools[k]); } } - if(this.buttons){ - for(var b in this.buttons){ - Ext.destroy(this.buttons[b]); + if(this.toolbars.length > 0){ + Ext.each(this.toolbars, function(tb){ + tb.un('afterlayout', this.syncHeight, this); + tb.un('remove', this.syncHeight, this); + }, this); + } + if(Ext.isArray(this.buttons)){ + while(this.buttons.length) { + Ext.destroy(this.buttons[0]); } } if(this.rendered){ - Ext.destroy(this.toolbars); + Ext.destroy( + this.ft, + this.header, + this.footer, + this.toolbars, + this.tbar, + this.bbar, + this.body, + this.mc, + this.bwrap + ); + if (this.fbar) { + Ext.destroy( + this.fbar, + this.fbar.el + ); + } }else{ - Ext.destroy(this.topToolbar, this.bottomToolbar); + Ext.destroy( + this.topToolbar, + this.bottomToolbar + ); } - Ext.Panel.superclass.beforeDestroy.call(this); }, // private