/** * @class Ext.AbstractPanel * @extends Ext.container.Container *

Panel is a container that has specific functionality and structural components that make * it the perfect building block for application-oriented user interfaces.

*

Panels are, by virtue of their inheritance from {@link Ext.Container}, capable * of being configured with a {@link Ext.Container#layout layout}, and containing child Components.

*

When either specifying child {@link Ext.Component#items items} of a Panel, or dynamically {@link Ext.Container#add adding} Components * to a Panel, remember to consider how you wish the Panel to arrange those child elements, and whether * those child elements need to be sized using one of Ext's built-in {@link Ext.Container#layout layout} schemes. By * default, Panels use the {@link Ext.layout.ContainerLayout ContainerLayout} scheme. This simply renders * child components, appending them one after the other inside the Container, and does not apply any sizing * at all.

*

A Panel may also contain {@link #bbar bottom} and {@link #tbar top} toolbars, along with separate * {@link #header}, {@link #footer} and {@link #body} sections (see {@link #frame} for additional * information).

*

Panel also provides built-in {@link #collapsible expandable and collapsible behavior}, along with * a variety of {@link #tools prebuilt tool buttons} that can be wired up to provide other customized * behavior. Panels can be easily dropped into any {@link Ext.Container Container} or layout, and the * layout and rendering pipeline is {@link Ext.Container#add completely managed by the framework}.

*

Note: By default, the {@link #closable close} header tool destroys the Window resulting in * destruction of any child Components. This makes the Window object, and all its descendants unusable. To enable * re-use of a Window, use {@link #closeAction closeAction: 'hide'}.

* @constructor * @param {Object} config The config object * @xtype panel */ Ext.define('Ext.AbstractPanel', { /* Begin Definitions */ extend: 'Ext.container.Container', requires: ['Ext.util.MixedCollection', 'Ext.core.Element', 'Ext.toolbar.Toolbar'], /* End Definitions */
/** * @cfg {String} baseCls * The base CSS class to apply to this panel's element (defaults to 'x-panel'). */ baseCls : Ext.baseCSSPrefix + 'panel',
/** * @cfg {Number/Boolean} bodyPadding * 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. */
/** * @cfg {Number/Boolean} bodyMargin * A shortcut for setting a margin style on the body element. The value can either be * a number to be applied to all sides, or a normal css string describing margins. * Defaults to undefined. */
/** * @cfg {Number/Boolean} bodyBorder * A shortcut for setting a border style on the body element. The value can either be * a number to be applied to all sides, or a normal css string describing borders. * Defaults to undefined. */ isPanel: true, componentLayout: 'dock', renderTpl: ['
{bodyCls}" style="{bodyStyle}">
'],
/** * @cfg {Object/Array} dockedItems * A component or series of components to be added as docked items to this panel. * The docked items can be docked to either the top, right, left or bottom of a panel. * This is typically used for things like toolbars or tab bars: *

var panel = new Ext.Panel({
    fullscreen: true,
    dockedItems: [{
        xtype: 'toolbar',
        dock: 'top',
        items: [{
            text: 'Docked to the bottom'
        }]
    }]
});
*/ initComponent : function() { this.addEvents(
/** * @event bodyresize * Fires after the Panel has been resized. * @param {Ext.Panel} p the Panel which has been resized. * @param {Number} width The Panel body's new width. * @param {Number} height The Panel body's new height. */ 'bodyresize' // // inherited // 'activate', // // inherited // 'deactivate' ); Ext.applyIf(this.renderSelectors, { body: '.' + this.baseCls + '-body' }); Ext.AbstractPanel.superclass.initComponent.call(this); }, // @private initItems : function() { Ext.AbstractPanel.superclass.initItems.call(this); var items = this.dockedItems; this.dockedItems = new Ext.util.MixedCollection(false, this.getComponentId); if (items) { this.addDocked(items); } },
/** * Finds a docked component by id, itemId or position * @param {String/Number} comp The id, itemId or position of the docked component (see {@link #getComponent} for details) * @return {Ext.Component} The docked component (if found) */ getDockedComponent: function(comp) { if (Ext.isObject(comp)) { comp = comp.getItemId(); } return this.dockedItems.get(comp); },
/** * Attempts a default component lookup (see {@link Ext.container.Container#getComponent}). If the component is not found in the normal * items, the dockedItems are searched and the matched component (if any) returned (see {@loink #getDockedComponent}). Note that docked * items will only be matched by component id or itemId -- if you pass a numeric index only non-docked child components will be searched. * @param {String/Number} comp The component id, itemId or position to find * @return {Ext.Component} The component (if found) */ getComponent: function(comp) { var component = Ext.AbstractPanel.superclass.getComponent.call(this, comp); if (component == undefined && !Ext.isNumber(comp)) { // If the arg is a numeric index skip docked items component = this.getDockedComponent(comp); } return component; }, /** * Function description * @return {String} A CSS style string with style, padding, margin and border. * @private */ initBodyStyles: function() { var bodyStyle = Ext.isString(this.bodyStyle) ? this.bodyStyle.split(';') : [], Element = Ext.core.Element; if (this.bodyPadding != undefined) { bodyStyle.push('padding: ' + Element.unitizeBox((this.bodyPadding === true) ? 5 : this.bodyPadding)); } if (this.bodyMargin != undefined) { bodyStyle.push('margin: ' + Element.unitizeBox((this.bodyMargin === true) ? 5 : this.bodyMargin)); } if (this.bodyBorder != undefined) { bodyStyle.push('border-width: ' + Element.unitizeBox((this.bodyBorder === true) ? 1 : this.bodyBorder)); } delete this.bodyStyle; return bodyStyle.length ? bodyStyle.join(';') : undefined; }, /** * Initialized the renderData to be used when rendering the renderTpl. * @return {Object} Object with keys and values that are going to be applied to the renderTpl * @private */ initRenderData: function() { return Ext.applyIf(Ext.AbstractPanel.superclass.initRenderData.call(this), { bodyStyle: this.initBodyStyles(), bodyCls: this.bodyCls }); },
/** * Adds docked item(s) to the panel. * @param {Object/Array} component. The Component or array of components to add. The components * must include a 'dock' parameter on each component to indicate where it should be docked ('top', 'right', * 'bottom', 'left'). * @param {Number} pos (optional) The index at which the Component will be added */ addDocked : function(items, pos) { var me = this, item, i, ln; items = me.prepareItems(items); for (i = 0, ln = items.length; i < ln; i++) { item = items[i]; item.dock = item.dock || 'top'; // Allow older browsers to target docked items to style without borders if (me.border === false) { item.cls = item.cls||'' + ' ' + me.baseCls + '-noborder-docked-' + item.dock; } if (pos !== undefined) { me.dockedItems.insert(pos + i, item); } else { me.dockedItems.add(item); } item.onAdded(me, i); me.onDockedAdd(item); } if (me.rendered) { me.doComponentLayout(); } return items; }, // Placeholder empty functions onDockedAdd : Ext.emptyFn, onDockedRemove : Ext.emptyFn,
/** * Inserts docked item(s) to the panel at the indicated position. * @param {Number} pos The index at which the Component will be inserted * @param {Object/Array} component. The Component or array of components to add. The components * must include a 'dock' paramater on each component to indicate where it should be docked ('top', 'right', * 'bottom', 'left'). */ insertDocked : function(pos, items) { this.addDocked(items, pos); },
/** * Removes the docked item from the panel. * @param {Ext.Component} item. The Component to remove. * @param {Boolean} autoDestroy (optional) Destroy the component after removal. */ removeDocked : function(item, autoDestroy) { if (!this.dockedItems.contains(item)) { return item; } var layout = this.componentLayout, hasLayout = layout && this.rendered; if (hasLayout) { layout.onRemove(item); } this.dockedItems.remove(item); item.onRemoved(); this.onDockedRemove(item); if (autoDestroy === true || (autoDestroy !== false && this.autoDestroy)) { item.destroy(); } if (hasLayout && !autoDestroy) { layout.afterRemove(item); } this.doComponentLayout(); return item; },
/** * Retrieve an array of all currently docked components. * @return {Array} An array of components. */ getDockedItems : function() { if (this.dockedItems && this.dockedItems.items.length) { return this.dockedItems.items.slice(); } return []; }, // @private getTargetEl : function() { return this.body; }, getRefItems: function(deep) { var refItems = Ext.AbstractPanel.superclass.getRefItems.call(this, deep), // deep does not account for dockedItems within dockedItems. dockedItems = this.getDockedItems(), ln = dockedItems.length, i = 0, item; refItems = refItems.concat(dockedItems); if (deep) { for (; i < ln; i++) { item = dockedItems[i]; if (item.getRefItems) { refItems = refItems.concat(item.getRefItems(true)); } } } return refItems; }, beforeDestroy: function(){ var docked = this.dockedItems, c; if (docked) { while ((c = docked.first())) { this.removeDocked(c, true); } } Ext.AbstractPanel.superclass.beforeDestroy.call(this); } });