X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/0494b8d9b9bb03ab6c22b34dae81261e3cd7e3e6..7a654f8d43fdb43d78b63d90528bed6e86b608cc:/pkgs/cmp-foundation-debug.js diff --git a/pkgs/cmp-foundation-debug.js b/pkgs/cmp-foundation-debug.js deleted file mode 100644 index f6bcd75b..00000000 --- a/pkgs/cmp-foundation-debug.js +++ /dev/null @@ -1,14754 +0,0 @@ -/*! - * Ext JS Library 3.3.1 - * Copyright(c) 2006-2010 Sencha Inc. - * licensing@sencha.com - * http://www.sencha.com/license - */ -/** - * @class Ext.ComponentMgr - *

Provides a registry of all Components (instances of {@link Ext.Component} or any subclass - * thereof) on a page so that they can be easily accessed by {@link Ext.Component component} - * {@link Ext.Component#id id} (see {@link #get}, or the convenience method {@link Ext#getCmp Ext.getCmp}).

- *

This object also provides a registry of available Component classes - * indexed by a mnemonic code known as the Component's {@link Ext.Component#xtype xtype}. - * The {@link Ext.Component#xtype xtype} provides a way to avoid instantiating child Components - * when creating a full, nested config object for a complete Ext page.

- *

A child Component may be specified simply as a config object - * as long as the correct {@link Ext.Component#xtype xtype} is specified so that if and when the Component - * needs rendering, the correct type can be looked up for lazy instantiation.

- *

For a list of all available {@link Ext.Component#xtype xtypes}, see {@link Ext.Component}.

- * @singleton - */ -Ext.ComponentMgr = function(){ - var all = new Ext.util.MixedCollection(); - var types = {}; - var ptypes = {}; - - return { - /** - * Registers a component. - * @param {Ext.Component} c The component - */ - register : function(c){ - all.add(c); - }, - - /** - * Unregisters a component. - * @param {Ext.Component} c The component - */ - unregister : function(c){ - all.remove(c); - }, - - /** - * Returns a component by {@link Ext.Component#id id}. - * For additional details see {@link Ext.util.MixedCollection#get}. - * @param {String} id The component {@link Ext.Component#id id} - * @return Ext.Component The Component, undefined if not found, or null if a - * Class was found. - */ - get : function(id){ - return all.get(id); - }, - - /** - * Registers a function that will be called when a Component with the specified id is added to ComponentMgr. This will happen on instantiation. - * @param {String} id The component {@link Ext.Component#id id} - * @param {Function} fn The callback function - * @param {Object} scope The scope (this reference) in which the callback is executed. Defaults to the Component. - */ - onAvailable : function(id, fn, scope){ - all.on("add", function(index, o){ - if(o.id == id){ - fn.call(scope || o, o); - all.un("add", fn, scope); - } - }); - }, - - /** - * The MixedCollection used internally for the component cache. An example usage may be subscribing to - * events on the MixedCollection to monitor addition or removal. Read-only. - * @type {MixedCollection} - */ - all : all, - - /** - * The xtypes that have been registered with the component manager. - * @type {Object} - */ - types : types, - - /** - * The ptypes that have been registered with the component manager. - * @type {Object} - */ - ptypes: ptypes, - - /** - * Checks if a Component type is registered. - * @param {Ext.Component} xtype The mnemonic string by which the Component class may be looked up - * @return {Boolean} Whether the type is registered. - */ - isRegistered : function(xtype){ - return types[xtype] !== undefined; - }, - - /** - * Checks if a Plugin type is registered. - * @param {Ext.Component} ptype The mnemonic string by which the Plugin class may be looked up - * @return {Boolean} Whether the type is registered. - */ - isPluginRegistered : function(ptype){ - return ptypes[ptype] !== undefined; - }, - - /** - *

Registers a new Component constructor, keyed by a new - * {@link Ext.Component#xtype}.

- *

Use this method (or its alias {@link Ext#reg Ext.reg}) to register new - * subclasses of {@link Ext.Component} so that lazy instantiation may be used when specifying - * child Components. - * see {@link Ext.Container#items}

- * @param {String} xtype The mnemonic string by which the Component class may be looked up. - * @param {Constructor} cls The new Component class. - */ - registerType : function(xtype, cls){ - types[xtype] = cls; - cls.xtype = xtype; - }, - - /** - * Creates a new Component from the specified config object using the - * config object's {@link Ext.component#xtype xtype} to determine the class to instantiate. - * @param {Object} config A configuration object for the Component you wish to create. - * @param {Constructor} defaultType The constructor to provide the default Component type if - * the config object does not contain a xtype. (Optional if the config contains a xtype). - * @return {Ext.Component} The newly instantiated Component. - */ - create : function(config, defaultType){ - return config.render ? config : new types[config.xtype || defaultType](config); - }, - - /** - *

Registers a new Plugin constructor, keyed by a new - * {@link Ext.Component#ptype}.

- *

Use this method (or its alias {@link Ext#preg Ext.preg}) to register new - * plugins for {@link Ext.Component}s so that lazy instantiation may be used when specifying - * Plugins.

- * @param {String} ptype The mnemonic string by which the Plugin class may be looked up. - * @param {Constructor} cls The new Plugin class. - */ - registerPlugin : function(ptype, cls){ - ptypes[ptype] = cls; - cls.ptype = ptype; - }, - - /** - * Creates a new Plugin from the specified config object using the - * config object's {@link Ext.component#ptype ptype} to determine the class to instantiate. - * @param {Object} config A configuration object for the Plugin you wish to create. - * @param {Constructor} defaultType The constructor to provide the default Plugin type if - * the config object does not contain a ptype. (Optional if the config contains a ptype). - * @return {Ext.Component} The newly instantiated Plugin. - */ - createPlugin : function(config, defaultType){ - var PluginCls = ptypes[config.ptype || defaultType]; - if (PluginCls.init) { - return PluginCls; - } else { - return new PluginCls(config); - } - } - }; -}(); - -/** - * Shorthand for {@link Ext.ComponentMgr#registerType} - * @param {String} xtype The {@link Ext.component#xtype mnemonic string} by which the Component class - * may be looked up. - * @param {Constructor} cls The new Component class. - * @member Ext - * @method reg - */ -Ext.reg = Ext.ComponentMgr.registerType; // this will be called a lot internally, shorthand to keep the bytes down -/** - * Shorthand for {@link Ext.ComponentMgr#registerPlugin} - * @param {String} ptype The {@link Ext.component#ptype mnemonic string} by which the Plugin class - * may be looked up. - * @param {Constructor} cls The new Plugin class. - * @member Ext - * @method preg - */ -Ext.preg = Ext.ComponentMgr.registerPlugin; -/** - * Shorthand for {@link Ext.ComponentMgr#create} - * Creates a new Component from the specified config object using the - * config object's {@link Ext.component#xtype xtype} to determine the class to instantiate. - * @param {Object} config A configuration object for the Component you wish to create. - * @param {Constructor} defaultType The constructor to provide the default Component type if - * the config object does not contain a xtype. (Optional if the config contains a xtype). - * @return {Ext.Component} The newly instantiated Component. - * @member Ext - * @method create - */ -Ext.create = Ext.ComponentMgr.create;/** - * @class Ext.Component - * @extends Ext.util.Observable - *

Base class for all Ext components. All subclasses of Component may participate in the automated - * Ext component lifecycle of creation, rendering and destruction which is provided by the {@link Ext.Container Container} class. - * Components may be added to a Container through the {@link Ext.Container#items items} config option at the time the Container is created, - * or they may be added dynamically via the {@link Ext.Container#add add} method.

- *

The Component base class has built-in support for basic hide/show and enable/disable behavior.

- *

All Components are registered with the {@link Ext.ComponentMgr} on construction so that they can be referenced at any time via - * {@link Ext#getCmp}, passing the {@link #id}.

- *

All user-developed visual widgets that are required to participate in automated lifecycle and size management should subclass Component (or - * {@link Ext.BoxComponent} if managed box model handling is required, ie height and width management).

- *

See the Creating new UI controls tutorial for details on how - * and to either extend or augment ExtJs base classes to create custom Components.

- *

Every component has a specific xtype, which is its Ext-specific type name, along with methods for checking the - * xtype like {@link #getXType} and {@link #isXType}. This is the list of all valid xtypes:

- *
-xtype            Class
--------------    ------------------
-box              {@link Ext.BoxComponent}
-button           {@link Ext.Button}
-buttongroup      {@link Ext.ButtonGroup}
-colorpalette     {@link Ext.ColorPalette}
-component        {@link Ext.Component}
-container        {@link Ext.Container}
-cycle            {@link Ext.CycleButton}
-dataview         {@link Ext.DataView}
-datepicker       {@link Ext.DatePicker}
-editor           {@link Ext.Editor}
-editorgrid       {@link Ext.grid.EditorGridPanel}
-flash            {@link Ext.FlashComponent}
-grid             {@link Ext.grid.GridPanel}
-listview         {@link Ext.ListView}
-multislider      {@link Ext.slider.MultiSlider}
-panel            {@link Ext.Panel}
-progress         {@link Ext.ProgressBar}
-propertygrid     {@link Ext.grid.PropertyGrid}
-slider           {@link Ext.slider.SingleSlider}
-spacer           {@link Ext.Spacer}
-splitbutton      {@link Ext.SplitButton}
-tabpanel         {@link Ext.TabPanel}
-treepanel        {@link Ext.tree.TreePanel}
-viewport         {@link Ext.ViewPort}
-window           {@link Ext.Window}
-
-Toolbar components
----------------------------------------
-paging           {@link Ext.PagingToolbar}
-toolbar          {@link Ext.Toolbar}
-tbbutton         {@link Ext.Toolbar.Button}        (deprecated; use button)
-tbfill           {@link Ext.Toolbar.Fill}
-tbitem           {@link Ext.Toolbar.Item}
-tbseparator      {@link Ext.Toolbar.Separator}
-tbspacer         {@link Ext.Toolbar.Spacer}
-tbsplit          {@link Ext.Toolbar.SplitButton}   (deprecated; use splitbutton)
-tbtext           {@link Ext.Toolbar.TextItem}
-
-Menu components
----------------------------------------
-menu             {@link Ext.menu.Menu}
-colormenu        {@link Ext.menu.ColorMenu}
-datemenu         {@link Ext.menu.DateMenu}
-menubaseitem     {@link Ext.menu.BaseItem}
-menucheckitem    {@link Ext.menu.CheckItem}
-menuitem         {@link Ext.menu.Item}
-menuseparator    {@link Ext.menu.Separator}
-menutextitem     {@link Ext.menu.TextItem}
-
-Form components
----------------------------------------
-form             {@link Ext.form.FormPanel}
-checkbox         {@link Ext.form.Checkbox}
-checkboxgroup    {@link Ext.form.CheckboxGroup}
-combo            {@link Ext.form.ComboBox}
-compositefield   {@link Ext.form.CompositeField}
-datefield        {@link Ext.form.DateField}
-displayfield     {@link Ext.form.DisplayField}
-field            {@link Ext.form.Field}
-fieldset         {@link Ext.form.FieldSet}
-hidden           {@link Ext.form.Hidden}
-htmleditor       {@link Ext.form.HtmlEditor}
-label            {@link Ext.form.Label}
-numberfield      {@link Ext.form.NumberField}
-radio            {@link Ext.form.Radio}
-radiogroup       {@link Ext.form.RadioGroup}
-textarea         {@link Ext.form.TextArea}
-textfield        {@link Ext.form.TextField}
-timefield        {@link Ext.form.TimeField}
-trigger          {@link Ext.form.TriggerField}
-
-Chart components
----------------------------------------
-chart            {@link Ext.chart.Chart}
-barchart         {@link Ext.chart.BarChart}
-cartesianchart   {@link Ext.chart.CartesianChart}
-columnchart      {@link Ext.chart.ColumnChart}
-linechart        {@link Ext.chart.LineChart}
-piechart         {@link Ext.chart.PieChart}
-
-Store xtypes
----------------------------------------
-arraystore       {@link Ext.data.ArrayStore}
-directstore      {@link Ext.data.DirectStore}
-groupingstore    {@link Ext.data.GroupingStore}
-jsonstore        {@link Ext.data.JsonStore}
-simplestore      {@link Ext.data.SimpleStore}      (deprecated; use arraystore)
-store            {@link Ext.data.Store}
-xmlstore         {@link Ext.data.XmlStore}
-
- * @constructor - * @param {Ext.Element/String/Object} config The configuration options may be specified as either: - *
- */ -Ext.Component = function(config){ - config = config || {}; - if(config.initialConfig){ - if(config.isAction){ // actions - this.baseAction = config; - } - config = config.initialConfig; // component cloning / action set up - }else if(config.tagName || config.dom || Ext.isString(config)){ // element object - config = {applyTo: config, id: config.id || config}; - } - - /** - * This Component's initial configuration specification. Read-only. - * @type Object - * @property initialConfig - */ - this.initialConfig = config; - - Ext.apply(this, config); - this.addEvents( - /** - * @event added - * Fires when a component is added to an Ext.Container - * @param {Ext.Component} this - * @param {Ext.Container} ownerCt Container which holds the component - * @param {number} index Position at which the component was added - */ - 'added', - /** - * @event disable - * Fires after the component is disabled. - * @param {Ext.Component} this - */ - 'disable', - /** - * @event enable - * Fires after the component is enabled. - * @param {Ext.Component} this - */ - 'enable', - /** - * @event beforeshow - * Fires before the component is shown by calling the {@link #show} method. - * Return false from an event handler to stop the show. - * @param {Ext.Component} this - */ - 'beforeshow', - /** - * @event show - * Fires after the component is shown when calling the {@link #show} method. - * @param {Ext.Component} this - */ - 'show', - /** - * @event beforehide - * Fires before the component is hidden by calling the {@link #hide} method. - * Return false from an event handler to stop the hide. - * @param {Ext.Component} this - */ - 'beforehide', - /** - * @event hide - * Fires after the component is hidden. - * Fires after the component is hidden when calling the {@link #hide} method. - * @param {Ext.Component} this - */ - 'hide', - /** - * @event removed - * Fires when a component is removed from an Ext.Container - * @param {Ext.Component} this - * @param {Ext.Container} ownerCt Container which holds the component - */ - 'removed', - /** - * @event beforerender - * Fires before the component is {@link #rendered}. Return false from an - * event handler to stop the {@link #render}. - * @param {Ext.Component} this - */ - 'beforerender', - /** - * @event render - * Fires after the component markup is {@link #rendered}. - * @param {Ext.Component} this - */ - 'render', - /** - * @event afterrender - *

Fires after the component rendering is finished.

- *

The afterrender event is fired after this Component has been {@link #rendered}, been postprocesed - * by any afterRender method defined for the Component, and, if {@link #stateful}, after state - * has been restored.

- * @param {Ext.Component} this - */ - 'afterrender', - /** - * @event beforedestroy - * Fires before the component is {@link #destroy}ed. Return false from an event handler to stop the {@link #destroy}. - * @param {Ext.Component} this - */ - 'beforedestroy', - /** - * @event destroy - * Fires after the component is {@link #destroy}ed. - * @param {Ext.Component} this - */ - 'destroy', - /** - * @event beforestaterestore - * Fires before the state of the component is restored. Return false from an event handler to stop the restore. - * @param {Ext.Component} this - * @param {Object} state The hash of state values returned from the StateProvider. If this - * event is not vetoed, then the state object is passed to applyState. By default, - * that simply copies property values into this Component. The method maybe overriden to - * provide custom state restoration. - */ - 'beforestaterestore', - /** - * @event staterestore - * Fires after the state of the component is restored. - * @param {Ext.Component} this - * @param {Object} state The hash of state values returned from the StateProvider. This is passed - * to applyState. By default, that simply copies property values into this - * Component. The method maybe overriden to provide custom state restoration. - */ - 'staterestore', - /** - * @event beforestatesave - * Fires before the state of the component is saved to the configured state provider. Return false to stop the save. - * @param {Ext.Component} this - * @param {Object} state The hash of state values. This is determined by calling - * getState() on the Component. This method must be provided by the - * developer to return whetever representation of state is required, by default, Ext.Component - * has a null implementation. - */ - 'beforestatesave', - /** - * @event statesave - * Fires after the state of the component is saved to the configured state provider. - * @param {Ext.Component} this - * @param {Object} state The hash of state values. This is determined by calling - * getState() on the Component. This method must be provided by the - * developer to return whetever representation of state is required, by default, Ext.Component - * has a null implementation. - */ - 'statesave' - ); - this.getId(); - Ext.ComponentMgr.register(this); - Ext.Component.superclass.constructor.call(this); - - if(this.baseAction){ - this.baseAction.addComponent(this); - } - - this.initComponent(); - - if(this.plugins){ - if(Ext.isArray(this.plugins)){ - for(var i = 0, len = this.plugins.length; i < len; i++){ - this.plugins[i] = this.initPlugin(this.plugins[i]); - } - }else{ - this.plugins = this.initPlugin(this.plugins); - } - } - - if(this.stateful !== false){ - this.initState(); - } - - if(this.applyTo){ - this.applyToMarkup(this.applyTo); - delete this.applyTo; - }else if(this.renderTo){ - this.render(this.renderTo); - delete this.renderTo; - } -}; - -// private -Ext.Component.AUTO_ID = 1000; - -Ext.extend(Ext.Component, Ext.util.Observable, { - // Configs below are used for all Components when rendered by FormLayout. - /** - * @cfg {String} fieldLabel

The label text to display next to this Component (defaults to '').

- *

Note: this config is only used when this Component is rendered by a Container which - * has been configured to use the {@link Ext.layout.FormLayout FormLayout} layout manager (e.g. - * {@link Ext.form.FormPanel} or specifying layout:'form').


- *

Also see {@link #hideLabel} and - * {@link Ext.layout.FormLayout}.{@link Ext.layout.FormLayout#fieldTpl fieldTpl}.

- * Example use:

-new Ext.FormPanel({
-    height: 100,
-    renderTo: Ext.getBody(),
-    items: [{
-        xtype: 'textfield',
-        fieldLabel: 'Name'
-    }]
-});
-
- */ - /** - * @cfg {String} labelStyle

A CSS style specification string to apply directly to this field's - * label. Defaults to the container's labelStyle value if set (e.g., - * {@link Ext.layout.FormLayout#labelStyle} , or '').

- *

Note: see the note for {@link #clearCls}.


- *

Also see {@link #hideLabel} and - * {@link Ext.layout.FormLayout}.{@link Ext.layout.FormLayout#fieldTpl fieldTpl}.

- * Example use:

-new Ext.FormPanel({
-    height: 100,
-    renderTo: Ext.getBody(),
-    items: [{
-        xtype: 'textfield',
-        fieldLabel: 'Name',
-        labelStyle: 'font-weight:bold;'
-    }]
-});
-
- */ - /** - * @cfg {String} labelSeparator

The separator to display after the text of each - * {@link #fieldLabel}. This property may be configured at various levels. - * The order of precedence is: - *

- * To display no separator for this field's label specify empty string ''.

- *

Note: see the note for {@link #clearCls}.


- *

Also see {@link #hideLabel} and - * {@link Ext.layout.FormLayout}.{@link Ext.layout.FormLayout#fieldTpl fieldTpl}.

- * Example use:

-new Ext.FormPanel({
-    height: 100,
-    renderTo: Ext.getBody(),
-    layoutConfig: {
-        labelSeparator: '~'   // layout config has lowest priority (defaults to ':')
-    },
-    {@link Ext.layout.FormLayout#labelSeparator labelSeparator}: '>>',     // config at container level
-    items: [{
-        xtype: 'textfield',
-        fieldLabel: 'Field 1',
-        labelSeparator: '...' // field/component level config supersedes others
-    },{
-        xtype: 'textfield',
-        fieldLabel: 'Field 2' // labelSeparator will be '='
-    }]
-});
-
- */ - /** - * @cfg {Boolean} hideLabel

true to completely hide the label element - * ({@link #fieldLabel label} and {@link #labelSeparator separator}). Defaults to false. - * By default, even if you do not specify a {@link #fieldLabel} the space will still be - * reserved so that the field will line up with other fields that do have labels. - * Setting this to true will cause the field to not reserve that space.

- *

Note: see the note for {@link #clearCls}.


- * Example use:

-new Ext.FormPanel({
-    height: 100,
-    renderTo: Ext.getBody(),
-    items: [{
-        xtype: 'textfield'
-        hideLabel: true
-    }]
-});
-
- */ - /** - * @cfg {String} clearCls

The CSS class used to to apply to the special clearing div rendered - * directly after each form field wrapper to provide field clearing (defaults to - * 'x-form-clear-left').

- *

Note: this config is only used when this Component is rendered by a Container - * which has been configured to use the {@link Ext.layout.FormLayout FormLayout} layout - * manager (e.g. {@link Ext.form.FormPanel} or specifying layout:'form') and either a - * {@link #fieldLabel} is specified or isFormField=true is specified.


- *

See {@link Ext.layout.FormLayout}.{@link Ext.layout.FormLayout#fieldTpl fieldTpl} also.

- */ - /** - * @cfg {String} itemCls - *

Note: this config is only used when this Component is rendered by a Container which - * has been configured to use the {@link Ext.layout.FormLayout FormLayout} layout manager (e.g. - * {@link Ext.form.FormPanel} or specifying layout:'form').


- *

An additional CSS class to apply to the div wrapping the form item - * element of this field. If supplied, itemCls at the field level will override - * the default itemCls supplied at the container level. The value specified for - * itemCls will be added to the default class ('x-form-item').

- *

Since it is applied to the item wrapper (see - * {@link Ext.layout.FormLayout}.{@link Ext.layout.FormLayout#fieldTpl fieldTpl}), it allows - * you to write standard CSS rules that can apply to the field, the label (if specified), or - * any other element within the markup for the field.

- *

Note: see the note for {@link #fieldLabel}.


- * Example use:

-// Apply a style to the field's label:
-<style>
-    .required .x-form-item-label {font-weight:bold;color:red;}
-</style>
-
-new Ext.FormPanel({
-    height: 100,
-    renderTo: Ext.getBody(),
-    items: [{
-        xtype: 'textfield',
-        fieldLabel: 'Name',
-        itemCls: 'required' //this label will be styled
-    },{
-        xtype: 'textfield',
-        fieldLabel: 'Favorite Color'
-    }]
-});
-
- */ - - /** - * @cfg {String} id - *

The unique id of this component (defaults to an {@link #getId auto-assigned id}). - * You should assign an id if you need to be able to access the component later and you do - * not have an object reference available (e.g., using {@link Ext}.{@link Ext#getCmp getCmp}).

- *

Note that this id will also be used as the element id for the containing HTML element - * that is rendered to the page for this component. This allows you to write id-based CSS - * rules to style the specific instance of this component uniquely, and also to select - * sub-elements using this component's id as the parent.

- *

Note: to avoid complications imposed by a unique id also see - * {@link #itemId} and {@link #ref}.

- *

Note: to access the container of an item see {@link #ownerCt}.

- */ - /** - * @cfg {String} itemId - *

An itemId can be used as an alternative way to get a reference to a component - * when no object reference is available. Instead of using an {@link #id} with - * {@link Ext}.{@link Ext#getCmp getCmp}, use itemId with - * {@link Ext.Container}.{@link Ext.Container#getComponent getComponent} which will retrieve - * itemId's or {@link #id}'s. Since itemId's are an index to the - * container's internal MixedCollection, the itemId is scoped locally to the container -- - * avoiding potential conflicts with {@link Ext.ComponentMgr} which requires a unique - * {@link #id}.

- *

-var c = new Ext.Panel({ //
-    {@link Ext.BoxComponent#height height}: 300,
-    {@link #renderTo}: document.body,
-    {@link Ext.Container#layout layout}: 'auto',
-    {@link Ext.Container#items items}: [
-        {
-            itemId: 'p1',
-            {@link Ext.Panel#title title}: 'Panel 1',
-            {@link Ext.BoxComponent#height height}: 150
-        },
-        {
-            itemId: 'p2',
-            {@link Ext.Panel#title title}: 'Panel 2',
-            {@link Ext.BoxComponent#height height}: 150
-        }
-    ]
-})
-p1 = c.{@link Ext.Container#getComponent getComponent}('p1'); // not the same as {@link Ext#getCmp Ext.getCmp()}
-p2 = p1.{@link #ownerCt}.{@link Ext.Container#getComponent getComponent}('p2'); // reference via a sibling
-     * 
- *

Also see {@link #id} and {@link #ref}.

- *

Note: to access the container of an item see {@link #ownerCt}.

- */ - /** - * @cfg {String} xtype - * The registered xtype to create. This config option is not used when passing - * a config object into a constructor. This config option is used only when - * lazy instantiation is being used, and a child item of a Container is being - * specified not as a fully instantiated Component, but as a Component config - * object. The xtype will be looked up at render time up to determine what - * type of child Component to create.

- * The predefined xtypes are listed {@link Ext.Component here}. - *

- * If you subclass Components to create your own Components, you may register - * them using {@link Ext.ComponentMgr#registerType} in order to be able to - * take advantage of lazy instantiation and rendering. - */ - /** - * @cfg {String} ptype - * The registered ptype to create. This config option is not used when passing - * a config object into a constructor. This config option is used only when - * lazy instantiation is being used, and a Plugin is being - * specified not as a fully instantiated Component, but as a Component config - * object. The ptype will be looked up at render time up to determine what - * type of Plugin to create.

- * If you create your own Plugins, you may register them using - * {@link Ext.ComponentMgr#registerPlugin} in order to be able to - * take advantage of lazy instantiation and rendering. - */ - /** - * @cfg {String} cls - * An optional extra CSS class that will be added to this component's Element (defaults to ''). This can be - * useful for adding customized styles to the component or any of its children using standard CSS rules. - */ - /** - * @cfg {String} overCls - * An optional extra CSS class that will be added to this component's Element when the mouse moves - * over the Element, and removed when the mouse moves out. (defaults to ''). This can be - * useful for adding customized 'active' or 'hover' styles to the component or any of its children using standard CSS rules. - */ - /** - * @cfg {String} style - * A custom style specification to be applied to this component's Element. Should be a valid argument to - * {@link Ext.Element#applyStyles}. - *

-new Ext.Panel({
-    title: 'Some Title',
-    renderTo: Ext.getBody(),
-    width: 400, height: 300,
-    layout: 'form',
-    items: [{
-        xtype: 'textarea',
-        style: {
-            width: '95%',
-            marginBottom: '10px'
-        }
-    },
-        new Ext.Button({
-            text: 'Send',
-            minWidth: '100',
-            style: {
-                marginBottom: '10px'
-            }
-        })
-    ]
-});
-     * 
- */ - /** - * @cfg {String} ctCls - *

An optional extra CSS class that will be added to this component's container. This can be useful for - * adding customized styles to the container or any of its children using standard CSS rules. See - * {@link Ext.layout.ContainerLayout}.{@link Ext.layout.ContainerLayout#extraCls extraCls} also.

- *

Note: ctCls defaults to '' except for the following class - * which assigns a value by default: - *

- * To configure the above Class with an extra CSS class append to the default. For example, - * for BoxLayout (Hbox and Vbox):

-     * ctCls: 'x-box-layout-ct custom-class'
-     * 
- *

- */ - /** - * @cfg {Boolean} disabled - * Render this component disabled (default is false). - */ - disabled : false, - /** - * @cfg {Boolean} hidden - * Render this component hidden (default is false). If true, the - * {@link #hide} method will be called internally. - */ - hidden : false, - /** - * @cfg {Object/Array} plugins - * An object or array of objects that will provide custom functionality for this component. The only - * requirement for a valid plugin is that it contain an init method that accepts a reference of type Ext.Component. - * When a component is created, if any plugins are available, the component will call the init method on each - * plugin, passing a reference to itself. Each plugin can then call methods or respond to events on the - * component as needed to provide its functionality. - */ - /** - * @cfg {Mixed} applyTo - *

Specify the id of the element, a DOM element or an existing Element corresponding to a DIV - * that is already present in the document that specifies some structural markup for this - * component.

- */ - /** - * @cfg {Mixed} renderTo - *

Specify the id of the element, a DOM element or an existing Element that this component - * will be rendered into.

- *

See {@link #render} also.

- */ - /** - * @cfg {Boolean} stateful - *

A flag which causes the Component to attempt to restore the state of - * internal properties from a saved state on startup. The component must have - * either a {@link #stateId} or {@link #id} assigned - * for state to be managed. Auto-generated ids are not guaranteed to be stable - * across page loads and cannot be relied upon to save and restore the same - * state for a component.

- *

For state saving to work, the state manager's provider must have been - * set to an implementation of {@link Ext.state.Provider} which overrides the - * {@link Ext.state.Provider#set set} and {@link Ext.state.Provider#get get} - * methods to save and recall name/value pairs. A built-in implementation, - * {@link Ext.state.CookieProvider} is available.

- *

To set the state provider for the current page:

- *

-Ext.state.Manager.setProvider(new Ext.state.CookieProvider({
-    expires: new Date(new Date().getTime()+(1000*60*60*24*7)), //7 days from now
-}));
-     * 
- *

A stateful Component attempts to save state when one of the events - * listed in the {@link #stateEvents} configuration fires.

- *

To save state, a stateful Component first serializes its state by - * calling getState. By default, this function does - * nothing. The developer must provide an implementation which returns an - * object hash which represents the Component's restorable state.

- *

The value yielded by getState is passed to {@link Ext.state.Manager#set} - * which uses the configured {@link Ext.state.Provider} to save the object - * keyed by the Component's {@link stateId}, or, if that is not - * specified, its {@link #id}.

- *

During construction, a stateful Component attempts to restore - * its state by calling {@link Ext.state.Manager#get} passing the - * {@link #stateId}, or, if that is not specified, the - * {@link #id}.

- *

The resulting object is passed to applyState. - * The default implementation of applyState simply copies - * properties into the object, but a developer may override this to support - * more behaviour.

- *

You can perform extra processing on state save and restore by attaching - * handlers to the {@link #beforestaterestore}, {@link #staterestore}, - * {@link #beforestatesave} and {@link #statesave} events.

- */ - /** - * @cfg {String} stateId - * The unique id for this component to use for state management purposes - * (defaults to the component id if one was set, otherwise null if the - * component is using a generated id). - *

See {@link #stateful} for an explanation of saving and - * restoring Component state.

- */ - /** - * @cfg {Array} stateEvents - *

An array of events that, when fired, should trigger this component to - * save its state (defaults to none). stateEvents may be any type - * of event supported by this component, including browser or custom events - * (e.g., ['click', 'customerchange']).

- *

See {@link #stateful} for an explanation of saving and - * restoring Component state.

- */ - /** - * @cfg {Mixed} autoEl - *

A tag name or {@link Ext.DomHelper DomHelper} spec used to create the {@link #getEl Element} which will - * encapsulate this Component.

- *

You do not normally need to specify this. For the base classes {@link Ext.Component}, {@link Ext.BoxComponent}, - * and {@link Ext.Container}, this defaults to 'div'. The more complex Ext classes use a more complex - * DOM structure created by their own onRender methods.

- *

This is intended to allow the developer to create application-specific utility Components encapsulated by - * different DOM elements. Example usage:


-{
-    xtype: 'box',
-    autoEl: {
-        tag: 'img',
-        src: 'http://www.example.com/example.jpg'
-    }
-}, {
-    xtype: 'box',
-    autoEl: {
-        tag: 'blockquote',
-        html: 'autoEl is cool!'
-    }
-}, {
-    xtype: 'container',
-    autoEl: 'ul',
-    cls: 'ux-unordered-list',
-    items: {
-        xtype: 'box',
-        autoEl: 'li',
-        html: 'First list item'
-    }
-}
-
- */ - autoEl : 'div', - - /** - * @cfg {String} disabledClass - * CSS class added to the component when it is disabled (defaults to 'x-item-disabled'). - */ - disabledClass : 'x-item-disabled', - /** - * @cfg {Boolean} allowDomMove - * Whether the component can move the Dom node when rendering (defaults to true). - */ - allowDomMove : true, - /** - * @cfg {Boolean} autoShow - * True if the component should check for hidden classes (e.g. 'x-hidden' or 'x-hide-display') and remove - * them on render (defaults to false). - */ - autoShow : false, - /** - * @cfg {String} hideMode - *

How this component should be hidden. Supported values are 'visibility' - * (css visibility), 'offsets' (negative offset position) and 'display' - * (css display).

- *

Note: the default of 'display' is generally preferred - * since items are automatically laid out when they are first shown (no sizing - * is done while hidden).

- */ - hideMode : 'display', - /** - * @cfg {Boolean} hideParent - * True to hide and show the component's container when hide/show is called on the component, false to hide - * and show the component itself (defaults to false). For example, this can be used as a shortcut for a hide - * button on a window by setting hide:true on the button when adding it to its parent container. - */ - hideParent : false, - /** - *

The {@link Ext.Element} which encapsulates this Component. Read-only.

- *

This will usually be a <DIV> element created by the class's onRender method, but - * that may be overridden using the {@link #autoEl} config.

- *

Note: this element will not be available until this Component has been rendered.


- *

To add listeners for DOM events to this Component (as opposed to listeners - * for this Component's own Observable events), see the {@link Ext.util.Observable#listeners listeners} - * config for a suggestion, or use a render listener directly:


-new Ext.Panel({
-    title: 'The Clickable Panel',
-    listeners: {
-        render: function(p) {
-            // Append the Panel to the click handler's argument list.
-            p.getEl().on('click', handlePanelClick.createDelegate(null, [p], true));
-        },
-        single: true  // Remove the listener after first invocation
-    }
-});
-
- *

See also {@link #getEl getEl}

- * @type Ext.Element - * @property el - */ - /** - * This Component's owner {@link Ext.Container Container} (defaults to undefined, and is set automatically when - * this Component is added to a Container). Read-only. - *

Note: to access items within the Container see {@link #itemId}.

- * @type Ext.Container - * @property ownerCt - */ - /** - * True if this component is hidden. Read-only. - * @type Boolean - * @property hidden - */ - /** - * True if this component is disabled. Read-only. - * @type Boolean - * @property disabled - */ - /** - * True if this component has been rendered. Read-only. - * @type Boolean - * @property rendered - */ - rendered : false, - - /** - * @cfg {String} contentEl - *

Optional. Specify an existing HTML element, or the id of an existing HTML element to use as the content - * for this component.

- * - */ - /** - * @cfg {String/Object} html - * An HTML fragment, or a {@link Ext.DomHelper DomHelper} specification to use as the layout element - * content (defaults to ''). The HTML content is added after the component is rendered, - * 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 {Mixed} tpl - * An {@link Ext.Template}, {@link Ext.XTemplate} - * or an array of strings to form an Ext.XTemplate. - * Used in conjunction with the {@link #data} and - * {@link #tplWriteMode} configurations. - */ - - /** - * @cfg {String} tplWriteMode The Ext.(X)Template method to use when - * updating the content area of the Component. Defaults to 'overwrite' - * (see {@link Ext.XTemplate#overwrite}). - */ - tplWriteMode : 'overwrite', - - /** - * @cfg {Mixed} data - * The initial set of data to apply to the {@link #tpl} to - * update the content area of the Component. - */ - - /** - * @cfg {Array} bubbleEvents - *

An array of events that, when fired, should be bubbled to any parent container. - * See {@link Ext.util.Observable#enableBubble}. - * Defaults to []. - */ - bubbleEvents: [], - - - // private - ctype : 'Ext.Component', - - // private - actionMode : 'el', - - // private - getActionEl : function(){ - return this[this.actionMode]; - }, - - initPlugin : function(p){ - if(p.ptype && !Ext.isFunction(p.init)){ - p = Ext.ComponentMgr.createPlugin(p); - }else if(Ext.isString(p)){ - p = Ext.ComponentMgr.createPlugin({ - ptype: p - }); - } - p.init(this); - return p; - }, - - /* // protected - * Function to be implemented by Component subclasses to be part of standard component initialization flow (it is empty by default). - *


-// Traditional constructor:
-Ext.Foo = function(config){
-    // call superclass constructor:
-    Ext.Foo.superclass.constructor.call(this, config);
-
-    this.addEvents({
-        // add events
-    });
-};
-Ext.extend(Ext.Foo, Ext.Bar, {
-   // class body
-}
-
-// initComponent replaces the constructor:
-Ext.Foo = Ext.extend(Ext.Bar, {
-    initComponent : function(){
-        // call superclass initComponent
-        Ext.Container.superclass.initComponent.call(this);
-
-        this.addEvents({
-            // add events
-        });
-    }
-}
-
- */ - initComponent : function(){ - /* - * this is double processing, however it allows people to be able to do - * Ext.apply(this, { - * listeners: { - * //here - * } - * }); - * MyClass.superclass.initComponent.call(this); - */ - if(this.listeners){ - this.on(this.listeners); - delete this.listeners; - } - this.enableBubble(this.bubbleEvents); - }, - - /** - *

Render this Component into the passed HTML element.

- *

If you are using a {@link Ext.Container Container} object to house this Component, then - * do not use the render method.

- *

A Container's child Components are rendered by that Container's - * {@link Ext.Container#layout layout} manager when the Container is first rendered.

- *

Certain layout managers allow dynamic addition of child components. Those that do - * include {@link Ext.layout.CardLayout}, {@link Ext.layout.AnchorLayout}, - * {@link Ext.layout.FormLayout}, {@link Ext.layout.TableLayout}.

- *

If the Container is already rendered when a new child Component is added, you may need to call - * the Container's {@link Ext.Container#doLayout doLayout} to refresh the view which causes any - * unrendered child Components to be rendered. This is required so that you can add multiple - * child components if needed while only refreshing the layout once.

- *

When creating complex UIs, it is important to remember that sizing and positioning - * of child items is the responsibility of the Container's {@link Ext.Container#layout layout} manager. - * If you expect child items to be sized in response to user interactions, you must - * configure the Container with a layout manager which creates and manages the type of layout you - * have in mind.

- *

Omitting the Container's {@link Ext.Container#layout layout} config means that a basic - * layout manager is used which does nothing but render child components sequentially into the - * Container. No sizing or positioning will be performed in this situation.

- * @param {Element/HTMLElement/String} container (optional) The element this Component should be - * rendered into. If it is being created from existing markup, this should be omitted. - * @param {String/Number} position (optional) The element ID or DOM node index within the container before - * which this component will be inserted (defaults to appending to the end of the container) - */ - render : function(container, position){ - if(!this.rendered && this.fireEvent('beforerender', this) !== false){ - if(!container && this.el){ - this.el = Ext.get(this.el); - container = this.el.dom.parentNode; - this.allowDomMove = false; - } - this.container = Ext.get(container); - if(this.ctCls){ - this.container.addClass(this.ctCls); - } - this.rendered = true; - if(position !== undefined){ - if(Ext.isNumber(position)){ - position = this.container.dom.childNodes[position]; - }else{ - position = Ext.getDom(position); - } - } - this.onRender(this.container, position || null); - if(this.autoShow){ - this.el.removeClass(['x-hidden','x-hide-' + this.hideMode]); - } - if(this.cls){ - this.el.addClass(this.cls); - delete this.cls; - } - if(this.style){ - this.el.applyStyles(this.style); - delete this.style; - } - if(this.overCls){ - this.el.addClassOnOver(this.overCls); - } - this.fireEvent('render', this); - - - // Populate content of the component with html, contentEl or - // a tpl. - var contentTarget = this.getContentTarget(); - if (this.html){ - contentTarget.update(Ext.DomHelper.markup(this.html)); - delete this.html; - } - if (this.contentEl){ - var ce = Ext.getDom(this.contentEl); - Ext.fly(ce).removeClass(['x-hidden', 'x-hide-display']); - contentTarget.appendChild(ce); - } - if (this.tpl) { - if (!this.tpl.compile) { - this.tpl = new Ext.XTemplate(this.tpl); - } - if (this.data) { - this.tpl[this.tplWriteMode](contentTarget, this.data); - delete this.data; - } - } - this.afterRender(this.container); - - - if(this.hidden){ - // call this so we don't fire initial hide events. - this.doHide(); - } - if(this.disabled){ - // pass silent so the event doesn't fire the first time. - this.disable(true); - } - - if(this.stateful !== false){ - this.initStateEvents(); - } - this.fireEvent('afterrender', this); - } - return this; - }, - - - /** - * Update the content area of a component. - * @param {Mixed} htmlOrData - * If this component has been configured with a template via the tpl config - * then it will use this argument as data to populate the template. - * If this component was not configured with a template, the components - * content area will be updated via Ext.Element update - * @param {Boolean} loadScripts - * (optional) Only legitimate when using the html configuration. Defaults to false - * @param {Function} callback - * (optional) Only legitimate when using the html configuration. Callback to execute when scripts have finished loading - */ - update: function(htmlOrData, loadScripts, cb) { - var contentTarget = this.getContentTarget(); - if (this.tpl && typeof htmlOrData !== "string") { - this.tpl[this.tplWriteMode](contentTarget, htmlOrData || {}); - } else { - var html = Ext.isObject(htmlOrData) ? Ext.DomHelper.markup(htmlOrData) : htmlOrData; - contentTarget.update(html, loadScripts, cb); - } - }, - - - /** - * @private - * Method to manage awareness of when components are added to their - * respective Container, firing an added event. - * References are established at add time rather than at render time. - * @param {Ext.Container} container Container which holds the component - * @param {number} pos Position at which the component was added - */ - onAdded : function(container, pos) { - this.ownerCt = container; - this.initRef(); - this.fireEvent('added', this, container, pos); - }, - - /** - * @private - * Method to manage awareness of when components are removed from their - * respective Container, firing an removed event. References are properly - * cleaned up after removing a component from its owning container. - */ - onRemoved : function() { - this.removeRef(); - this.fireEvent('removed', this, this.ownerCt); - delete this.ownerCt; - }, - - /** - * @private - * Method to establish a reference to a component. - */ - initRef : function() { - /** - * @cfg {String} ref - *

A path specification, relative to the Component's {@link #ownerCt} - * specifying into which ancestor Container to place a named reference to this Component.

- *

The ancestor axis can be traversed by using '/' characters in the path. - * For example, to put a reference to a Toolbar Button into the Panel which owns the Toolbar:


-var myGrid = new Ext.grid.EditorGridPanel({
-    title: 'My EditorGridPanel',
-    store: myStore,
-    colModel: myColModel,
-    tbar: [{
-        text: 'Save',
-        handler: saveChanges,
-        disabled: true,
-        ref: '../saveButton'
-    }],
-    listeners: {
-        afteredit: function() {
-//          The button reference is in the GridPanel
-            myGrid.saveButton.enable();
-        }
-    }
-});
-
- *

In the code above, if the ref had been 'saveButton' - * the reference would have been placed into the Toolbar. Each '/' in the ref - * moves up one level from the Component's {@link #ownerCt}.

- *

Also see the {@link #added} and {@link #removed} events.

- */ - if(this.ref && !this.refOwner){ - var levels = this.ref.split('/'), - last = levels.length, - i = 0, - t = this; - - while(t && i < last){ - t = t.ownerCt; - ++i; - } - if(t){ - t[this.refName = levels[--i]] = this; - /** - * @type Ext.Container - * @property refOwner - * The ancestor Container into which the {@link #ref} reference was inserted if this Component - * is a child of a Container, and has been configured with a ref. - */ - this.refOwner = t; - } - } - }, - - removeRef : function() { - if (this.refOwner && this.refName) { - delete this.refOwner[this.refName]; - delete this.refOwner; - } - }, - - // private - initState : function(){ - if(Ext.state.Manager){ - var id = this.getStateId(); - if(id){ - var state = Ext.state.Manager.get(id); - if(state){ - if(this.fireEvent('beforestaterestore', this, state) !== false){ - this.applyState(Ext.apply({}, state)); - this.fireEvent('staterestore', this, state); - } - } - } - } - }, - - // private - getStateId : function(){ - return this.stateId || ((/^(ext-comp-|ext-gen)/).test(String(this.id)) ? null : this.id); - }, - - // private - initStateEvents : function(){ - if(this.stateEvents){ - for(var i = 0, e; e = this.stateEvents[i]; i++){ - this.on(e, this.saveState, this, {delay:100}); - } - } - }, - - // private - applyState : function(state){ - if(state){ - Ext.apply(this, state); - } - }, - - // private - getState : function(){ - return null; - }, - - // private - saveState : function(){ - if(Ext.state.Manager && this.stateful !== false){ - var id = this.getStateId(); - if(id){ - var state = this.getState(); - if(this.fireEvent('beforestatesave', this, state) !== false){ - Ext.state.Manager.set(id, state); - this.fireEvent('statesave', this, state); - } - } - } - }, - - /** - * Apply this component to existing markup that is valid. With this function, no call to render() is required. - * @param {String/HTMLElement} el - */ - applyToMarkup : function(el){ - this.allowDomMove = false; - this.el = Ext.get(el); - this.render(this.el.dom.parentNode); - }, - - /** - * Adds a CSS class to the component's underlying element. - * @param {string} cls The CSS class name to add - * @return {Ext.Component} this - */ - addClass : function(cls){ - if(this.el){ - this.el.addClass(cls); - }else{ - this.cls = this.cls ? this.cls + ' ' + cls : cls; - } - return this; - }, - - /** - * Removes a CSS class from the component's underlying element. - * @param {string} cls The CSS class name to remove - * @return {Ext.Component} this - */ - removeClass : function(cls){ - if(this.el){ - this.el.removeClass(cls); - }else if(this.cls){ - this.cls = this.cls.split(' ').remove(cls).join(' '); - } - return this; - }, - - // private - // default function is not really useful - onRender : function(ct, position){ - if(!this.el && this.autoEl){ - if(Ext.isString(this.autoEl)){ - this.el = document.createElement(this.autoEl); - }else{ - var div = document.createElement('div'); - Ext.DomHelper.overwrite(div, this.autoEl); - this.el = div.firstChild; - } - if (!this.el.id) { - this.el.id = this.getId(); - } - } - if(this.el){ - this.el = Ext.get(this.el); - if(this.allowDomMove !== false){ - ct.dom.insertBefore(this.el.dom, position); - if (div) { - Ext.removeNode(div); - div = null; - } - } - } - }, - - // private - getAutoCreate : function(){ - var cfg = Ext.isObject(this.autoCreate) ? - this.autoCreate : Ext.apply({}, this.defaultAutoCreate); - if(this.id && !cfg.id){ - cfg.id = this.id; - } - return cfg; - }, - - // private - afterRender : Ext.emptyFn, - - /** - * Destroys this component by purging any event listeners, removing the component's element from the DOM, - * removing the component from its {@link Ext.Container} (if applicable) and unregistering it from - * {@link Ext.ComponentMgr}. Destruction is generally handled automatically by the framework and this method - * should usually not need to be called directly. - * - */ - destroy : function(){ - if(!this.isDestroyed){ - if(this.fireEvent('beforedestroy', this) !== false){ - this.destroying = true; - this.beforeDestroy(); - if(this.ownerCt && this.ownerCt.remove){ - this.ownerCt.remove(this, false); - } - if(this.rendered){ - this.el.remove(); - if(this.actionMode == 'container' || this.removeMode == 'container'){ - this.container.remove(); - } - } - // Stop any buffered tasks - if(this.focusTask && this.focusTask.cancel){ - this.focusTask.cancel(); - } - this.onDestroy(); - Ext.ComponentMgr.unregister(this); - this.fireEvent('destroy', this); - this.purgeListeners(); - this.destroying = false; - this.isDestroyed = true; - } - } - }, - - deleteMembers : function(){ - var args = arguments; - for(var i = 0, len = args.length; i < len; ++i){ - delete this[args[i]]; - } - }, - - // private - beforeDestroy : Ext.emptyFn, - - // private - onDestroy : Ext.emptyFn, - - /** - *

Returns the {@link Ext.Element} which encapsulates this Component.

- *

This will usually be a <DIV> element created by the class's onRender method, but - * that may be overridden using the {@link #autoEl} config.

- *

Note: this element will not be available until this Component has been rendered.


- *

To add listeners for DOM events to this Component (as opposed to listeners - * for this Component's own Observable events), see the {@link #listeners} config for a suggestion, - * or use a render listener directly:


-new Ext.Panel({
-    title: 'The Clickable Panel',
-    listeners: {
-        render: function(p) {
-            // Append the Panel to the click handler's argument list.
-            p.getEl().on('click', handlePanelClick.createDelegate(null, [p], true));
-        },
-        single: true  // Remove the listener after first invocation
-    }
-});
-
- * @return {Ext.Element} The Element which encapsulates this Component. - */ - getEl : function(){ - return this.el; - }, - - // private - getContentTarget : function(){ - return this.el; - }, - - /** - * Returns the id of this component or automatically generates and - * returns an id if an id is not defined yet:

-     * 'ext-comp-' + (++Ext.Component.AUTO_ID)
-     * 
- * @return {String} id - */ - getId : function(){ - return this.id || (this.id = 'ext-comp-' + (++Ext.Component.AUTO_ID)); - }, - - /** - * Returns the {@link #itemId} of this component. If an - * {@link #itemId} was not assigned through configuration the - * id is returned using {@link #getId}. - * @return {String} - */ - getItemId : function(){ - return this.itemId || this.getId(); - }, - - /** - * Try to focus this component. - * @param {Boolean} selectText (optional) If applicable, true to also select the text in this component - * @param {Boolean/Number} delay (optional) Delay the focus this number of milliseconds (true for 10 milliseconds) - * @return {Ext.Component} this - */ - focus : function(selectText, delay){ - if(delay){ - this.focusTask = new Ext.util.DelayedTask(this.focus, this, [selectText, false]); - this.focusTask.delay(Ext.isNumber(delay) ? delay : 10); - return this; - } - if(this.rendered && !this.isDestroyed){ - this.el.focus(); - if(selectText === true){ - this.el.dom.select(); - } - } - return this; - }, - - // private - blur : function(){ - if(this.rendered){ - this.el.blur(); - } - return this; - }, - - /** - * Disable this component and fire the 'disable' event. - * @return {Ext.Component} this - */ - disable : function(/* private */ silent){ - if(this.rendered){ - this.onDisable(); - } - this.disabled = true; - if(silent !== true){ - this.fireEvent('disable', this); - } - return this; - }, - - // private - onDisable : function(){ - this.getActionEl().addClass(this.disabledClass); - this.el.dom.disabled = true; - }, - - /** - * Enable this component and fire the 'enable' event. - * @return {Ext.Component} this - */ - enable : function(){ - if(this.rendered){ - this.onEnable(); - } - this.disabled = false; - this.fireEvent('enable', this); - return this; - }, - - // private - onEnable : function(){ - this.getActionEl().removeClass(this.disabledClass); - this.el.dom.disabled = false; - }, - - /** - * Convenience function for setting disabled/enabled by boolean. - * @param {Boolean} disabled - * @return {Ext.Component} this - */ - setDisabled : function(disabled){ - return this[disabled ? 'disable' : 'enable'](); - }, - - /** - * Show this component. Listen to the '{@link #beforeshow}' event and return - * false to cancel showing the component. Fires the '{@link #show}' - * event after showing the component. - * @return {Ext.Component} this - */ - show : function(){ - if(this.fireEvent('beforeshow', this) !== false){ - this.hidden = false; - if(this.autoRender){ - this.render(Ext.isBoolean(this.autoRender) ? Ext.getBody() : this.autoRender); - } - if(this.rendered){ - this.onShow(); - } - this.fireEvent('show', this); - } - return this; - }, - - // private - onShow : function(){ - this.getVisibilityEl().removeClass('x-hide-' + this.hideMode); - }, - - /** - * Hide this component. Listen to the '{@link #beforehide}' event and return - * false to cancel hiding the component. Fires the '{@link #hide}' - * event after hiding the component. Note this method is called internally if - * the component is configured to be {@link #hidden}. - * @return {Ext.Component} this - */ - hide : function(){ - if(this.fireEvent('beforehide', this) !== false){ - this.doHide(); - this.fireEvent('hide', this); - } - return this; - }, - - // private - doHide: function(){ - this.hidden = true; - if(this.rendered){ - this.onHide(); - } - }, - - // private - onHide : function(){ - this.getVisibilityEl().addClass('x-hide-' + this.hideMode); - }, - - // private - getVisibilityEl : function(){ - return this.hideParent ? this.container : this.getActionEl(); - }, - - /** - * Convenience function to hide or show this component by boolean. - * @param {Boolean} visible True to show, false to hide - * @return {Ext.Component} this - */ - setVisible : function(visible){ - return this[visible ? 'show' : 'hide'](); - }, - - /** - * Returns true if this component is visible. - * @return {Boolean} True if this component is visible, false otherwise. - */ - isVisible : function(){ - return this.rendered && this.getVisibilityEl().isVisible(); - }, - - /** - * Clone the current component using the original config values passed into this instance by default. - * @param {Object} overrides A new config containing any properties to override in the cloned version. - * An id property can be passed on this object, otherwise one will be generated to avoid duplicates. - * @return {Ext.Component} clone The cloned copy of this component - */ - cloneConfig : function(overrides){ - overrides = overrides || {}; - var id = overrides.id || Ext.id(); - var cfg = Ext.applyIf(overrides, this.initialConfig); - cfg.id = id; // prevent dup id - return new this.constructor(cfg); - }, - - /** - * Gets the xtype for this component as registered with {@link Ext.ComponentMgr}. For a list of all - * available xtypes, see the {@link Ext.Component} header. Example usage: - *

-var t = new Ext.form.TextField();
-alert(t.getXType());  // alerts 'textfield'
-
- * @return {String} The xtype - */ - getXType : function(){ - return this.constructor.xtype; - }, - - /** - *

Tests whether or not this Component is of a specific xtype. This can test whether this Component is descended - * from the xtype (default) or whether it is directly of the xtype specified (shallow = true).

- *

If using your own subclasses, be aware that a Component must register its own xtype - * to participate in determination of inherited xtypes.

- *

For a list of all available xtypes, see the {@link Ext.Component} header.

- *

Example usage:

- *

-var t = new Ext.form.TextField();
-var isText = t.isXType('textfield');        // true
-var isBoxSubclass = t.isXType('box');       // true, descended from BoxComponent
-var isBoxInstance = t.isXType('box', true); // false, not a direct BoxComponent instance
-
- * @param {String/Ext.Component/Class} xtype The xtype to check for this Component. Note that the the component can either be an instance - * or a component class: - *

-var c = new Ext.Component();
-console.log(c.isXType(c));
-console.log(c.isXType(Ext.Component)); 
-
- * @param {Boolean} shallow (optional) False to check whether this Component is descended from the xtype (this is - * the default), or true to check whether this Component is directly of the specified xtype. - * @return {Boolean} True if this component descends from the specified xtype, false otherwise. - */ - isXType : function(xtype, shallow){ - //assume a string by default - if (Ext.isFunction(xtype)){ - xtype = xtype.xtype; //handle being passed the class, e.g. Ext.Component - }else if (Ext.isObject(xtype)){ - xtype = xtype.constructor.xtype; //handle being passed an instance - } - - return !shallow ? ('/' + this.getXTypes() + '/').indexOf('/' + xtype + '/') != -1 : this.constructor.xtype == xtype; - }, - - /** - *

Returns this Component's xtype hierarchy as a slash-delimited string. For a list of all - * available xtypes, see the {@link Ext.Component} header.

- *

If using your own subclasses, be aware that a Component must register its own xtype - * to participate in determination of inherited xtypes.

- *

Example usage:

- *

-var t = new Ext.form.TextField();
-alert(t.getXTypes());  // alerts 'component/box/field/textfield'
-
- * @return {String} The xtype hierarchy string - */ - getXTypes : function(){ - var tc = this.constructor; - if(!tc.xtypes){ - var c = [], sc = this; - while(sc && sc.constructor.xtype){ - c.unshift(sc.constructor.xtype); - sc = sc.constructor.superclass; - } - tc.xtypeChain = c; - tc.xtypes = c.join('/'); - } - return tc.xtypes; - }, - - /** - * Find a container above this component at any level by a custom function. If the passed function returns - * true, the container will be returned. - * @param {Function} fn The custom function to call with the arguments (container, this component). - * @return {Ext.Container} The first Container for which the custom function returns true - */ - findParentBy : function(fn) { - for (var p = this.ownerCt; (p != null) && !fn(p, this); p = p.ownerCt); - return p || null; - }, - - /** - * Find a container above this component at any level by xtype or class - * @param {String/Ext.Component/Class} xtype The xtype to check for this Component. Note that the the component can either be an instance - * or a component class: - * @param {Boolean} shallow (optional) False to check whether this Component is descended from the xtype (this is - * the default), or true to check whether this Component is directly of the specified xtype. - * @return {Ext.Container} The first Container which matches the given xtype or class - */ - findParentByType : function(xtype, shallow){ - return this.findParentBy(function(c){ - return c.isXType(xtype, shallow); - }); - }, - - /** - * Bubbles up the component/container heirarchy, calling the specified function with each component. The scope (this) of - * function call will be the scope provided or the current component. The arguments to the function - * will be the args provided or the current component. If the function returns false at any point, - * the bubble is stopped. - * @param {Function} fn The function to call - * @param {Object} scope (optional) The scope of the function (defaults to current node) - * @param {Array} args (optional) The args to call the function with (default to passing the current component) - * @return {Ext.Component} this - */ - bubble : function(fn, scope, args){ - var p = this; - while(p){ - if(fn.apply(scope || p, args || [p]) === false){ - break; - } - p = p.ownerCt; - } - return this; - }, - - // protected - getPositionEl : function(){ - return this.positionEl || this.el; - }, - - // private - purgeListeners : function(){ - Ext.Component.superclass.purgeListeners.call(this); - if(this.mons){ - this.on('beforedestroy', this.clearMons, this, {single: true}); - } - }, - - // private - clearMons : function(){ - Ext.each(this.mons, function(m){ - m.item.un(m.ename, m.fn, m.scope); - }, this); - this.mons = []; - }, - - // private - createMons: function(){ - if(!this.mons){ - this.mons = []; - this.on('beforedestroy', this.clearMons, this, {single: true}); - } - }, - - /** - *

Adds listeners to any Observable object (or Elements) which are automatically removed when this Component - * is destroyed. Usage:

-myGridPanel.mon(myGridPanel.getSelectionModel(), 'selectionchange', handleSelectionChange, null, {buffer: 50});
-
- *

or:

-myGridPanel.mon(myGridPanel.getSelectionModel(), {
-    selectionchange: handleSelectionChange,
-    buffer: 50
-});
-
- * @param {Observable|Element} item The item to which to add a listener/listeners. - * @param {Object|String} ename The event name, or an object containing event name properties. - * @param {Function} fn Optional. If the ename parameter was an event name, this - * is the handler function. - * @param {Object} scope Optional. If the ename parameter was an event name, this - * is the scope (this reference) in which the handler function is executed. - * @param {Object} opt Optional. If the ename parameter was an event name, this - * is the {@link Ext.util.Observable#addListener addListener} options. - */ - mon : function(item, ename, fn, scope, opt){ - this.createMons(); - if(Ext.isObject(ename)){ - var propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/; - - var o = ename; - for(var e in o){ - if(propRe.test(e)){ - continue; - } - if(Ext.isFunction(o[e])){ - // shared options - this.mons.push({ - item: item, ename: e, fn: o[e], scope: o.scope - }); - item.on(e, o[e], o.scope, o); - }else{ - // individual options - this.mons.push({ - item: item, ename: e, fn: o[e], scope: o.scope - }); - item.on(e, o[e]); - } - } - return; - } - - this.mons.push({ - item: item, ename: ename, fn: fn, scope: scope - }); - item.on(ename, fn, scope, opt); - }, - - /** - * Removes listeners that were added by the {@link #mon} method. - * @param {Observable|Element} item The item from which to remove a listener/listeners. - * @param {Object|String} ename The event name, or an object containing event name properties. - * @param {Function} fn Optional. If the ename parameter was an event name, this - * is the handler function. - * @param {Object} scope Optional. If the ename parameter was an event name, this - * is the scope (this reference) in which the handler function is executed. - */ - mun : function(item, ename, fn, scope){ - var found, mon; - this.createMons(); - for(var i = 0, len = this.mons.length; i < len; ++i){ - mon = this.mons[i]; - if(item === mon.item && ename == mon.ename && fn === mon.fn && scope === mon.scope){ - this.mons.splice(i, 1); - item.un(ename, fn, scope); - found = true; - break; - } - } - return found; - }, - - /** - * Returns the next component in the owning container - * @return Ext.Component - */ - nextSibling : function(){ - if(this.ownerCt){ - var index = this.ownerCt.items.indexOf(this); - if(index != -1 && index+1 < this.ownerCt.items.getCount()){ - return this.ownerCt.items.itemAt(index+1); - } - } - return null; - }, - - /** - * Returns the previous component in the owning container - * @return Ext.Component - */ - previousSibling : function(){ - if(this.ownerCt){ - var index = this.ownerCt.items.indexOf(this); - if(index > 0){ - return this.ownerCt.items.itemAt(index-1); - } - } - return null; - }, - - /** - * Provides the link for Observable's fireEvent method to bubble up the ownership hierarchy. - * @return {Ext.Container} the Container which owns this Component. - */ - getBubbleTarget : function(){ - return this.ownerCt; - } -}); - -Ext.reg('component', Ext.Component); -/** - * @class Ext.Action - *

An Action is a piece of reusable functionality that can be abstracted out of any particular component so that it - * can be usefully shared among multiple components. Actions let you share handlers, configuration options and UI - * updates across any components that support the Action interface (primarily {@link Ext.Toolbar}, {@link Ext.Button} - * and {@link Ext.menu.Menu} components).

- *

Aside from supporting the config object interface, any component that needs to use Actions must also support - * the following method list, as these will be called as needed by the Action class: setText(string), setIconCls(string), - * setDisabled(boolean), setVisible(boolean) and setHandler(function).

- * Example usage:
- *

-// Define the shared action.  Each component below will have the same
-// display text and icon, and will display the same message on click.
-var action = new Ext.Action({
-    {@link #text}: 'Do something',
-    {@link #handler}: function(){
-        Ext.Msg.alert('Click', 'You did something.');
-    },
-    {@link #iconCls}: 'do-something',
-    {@link #itemId}: 'myAction'
-});
-
-var panel = new Ext.Panel({
-    title: 'Actions',
-    width: 500,
-    height: 300,
-    tbar: [
-        // Add the action directly to a toolbar as a menu button
-        action,
-        {
-            text: 'Action Menu',
-            // Add the action to a menu as a text item
-            menu: [action]
-        }
-    ],
-    items: [
-        // Add the action to the panel body as a standard button
-        new Ext.Button(action)
-    ],
-    renderTo: Ext.getBody()
-});
-
-// Change the text for all components using the action
-action.setText('Something else');
-
-// Reference an action through a container using the itemId
-var btn = panel.getComponent('myAction');
-var aRef = btn.baseAction;
-aRef.setText('New text');
-
- * @constructor - * @param {Object} config The configuration options - */ -Ext.Action = Ext.extend(Object, { - /** - * @cfg {String} text The text to set for all components using this action (defaults to ''). - */ - /** - * @cfg {String} iconCls - * The CSS class selector that specifies a background image to be used as the header icon for - * all components using this action (defaults to ''). - *

An example of specifying a custom icon class would be something like: - *


-// specify the property in the config for the class:
-     ...
-     iconCls: 'do-something'
-
-// css class that specifies background image to be used as the icon image:
-.do-something { background-image: url(../images/my-icon.gif) 0 6px no-repeat !important; }
-
- */ - /** - * @cfg {Boolean} disabled True to disable all components using this action, false to enable them (defaults to false). - */ - /** - * @cfg {Boolean} hidden True to hide all components using this action, false to show them (defaults to false). - */ - /** - * @cfg {Function} handler The function that will be invoked by each component tied to this action - * when the component's primary event is triggered (defaults to undefined). - */ - /** - * @cfg {String} itemId - * See {@link Ext.Component}.{@link Ext.Component#itemId itemId}. - */ - /** - * @cfg {Object} scope The scope (this reference) in which the - * {@link #handler} is executed. Defaults to this Button. - */ - - constructor : function(config){ - this.initialConfig = config; - this.itemId = config.itemId = (config.itemId || config.id || Ext.id()); - this.items = []; - }, - - // private - isAction : true, - - /** - * Sets the text to be displayed by all components using this action. - * @param {String} text The text to display - */ - setText : function(text){ - this.initialConfig.text = text; - this.callEach('setText', [text]); - }, - - /** - * Gets the text currently displayed by all components using this action. - */ - getText : function(){ - return this.initialConfig.text; - }, - - /** - * Sets the icon CSS class for all components using this action. The class should supply - * a background image that will be used as the icon image. - * @param {String} cls The CSS class supplying the icon image - */ - setIconClass : function(cls){ - this.initialConfig.iconCls = cls; - this.callEach('setIconClass', [cls]); - }, - - /** - * Gets the icon CSS class currently used by all components using this action. - */ - getIconClass : function(){ - return this.initialConfig.iconCls; - }, - - /** - * Sets the disabled state of all components using this action. Shortcut method - * for {@link #enable} and {@link #disable}. - * @param {Boolean} disabled True to disable the component, false to enable it - */ - setDisabled : function(v){ - this.initialConfig.disabled = v; - this.callEach('setDisabled', [v]); - }, - - /** - * Enables all components using this action. - */ - enable : function(){ - this.setDisabled(false); - }, - - /** - * Disables all components using this action. - */ - disable : function(){ - this.setDisabled(true); - }, - - /** - * Returns true if the components using this action are currently disabled, else returns false. - */ - isDisabled : function(){ - return this.initialConfig.disabled; - }, - - /** - * Sets the hidden state of all components using this action. Shortcut method - * for {@link #hide} and {@link #show}. - * @param {Boolean} hidden True to hide the component, false to show it - */ - setHidden : function(v){ - this.initialConfig.hidden = v; - this.callEach('setVisible', [!v]); - }, - - /** - * Shows all components using this action. - */ - show : function(){ - this.setHidden(false); - }, - - /** - * Hides all components using this action. - */ - hide : function(){ - this.setHidden(true); - }, - - /** - * Returns true if the components using this action are currently hidden, else returns false. - */ - isHidden : function(){ - return this.initialConfig.hidden; - }, - - /** - * Sets the function that will be called by each Component using this action when its primary event is triggered. - * @param {Function} fn The function that will be invoked by the action's components. The function - * will be called with no arguments. - * @param {Object} scope The scope (this reference) in which the function is executed. Defaults to the Component firing the event. - */ - setHandler : function(fn, scope){ - this.initialConfig.handler = fn; - this.initialConfig.scope = scope; - this.callEach('setHandler', [fn, scope]); - }, - - /** - * Executes the specified function once for each Component currently tied to this action. The function passed - * in should accept a single argument that will be an object that supports the basic Action config/method interface. - * @param {Function} fn The function to execute for each component - * @param {Object} scope The scope (this reference) in which the function is executed. Defaults to the Component. - */ - each : function(fn, scope){ - Ext.each(this.items, fn, scope); - }, - - // private - callEach : function(fnName, args){ - var cs = this.items; - for(var i = 0, len = cs.length; i < len; i++){ - cs[i][fnName].apply(cs[i], args); - } - }, - - // private - addComponent : function(comp){ - this.items.push(comp); - comp.on('destroy', this.removeComponent, this); - }, - - // private - removeComponent : function(comp){ - this.items.remove(comp); - }, - - /** - * Executes this action manually using the handler function specified in the original config object - * or the handler function set with {@link #setHandler}. Any arguments passed to this - * function will be passed on to the handler function. - * @param {Mixed} arg1 (optional) Variable number of arguments passed to the handler function - * @param {Mixed} arg2 (optional) - * @param {Mixed} etc... (optional) - */ - execute : function(){ - this.initialConfig.handler.apply(this.initialConfig.scope || window, arguments); - } -}); -/** - * @class Ext.Layer - * @extends Ext.Element - * An extended {@link Ext.Element} object that supports a shadow and shim, constrain to viewport and - * automatic maintaining of shadow/shim positions. - * @cfg {Boolean} shim False to disable the iframe shim in browsers which need one (defaults to true) - * @cfg {String/Boolean} shadow True to automatically create an {@link Ext.Shadow}, or a string indicating the - * shadow's display {@link Ext.Shadow#mode}. False to disable the shadow. (defaults to false) - * @cfg {Object} dh DomHelper object config to create element with (defaults to {tag: 'div', cls: 'x-layer'}). - * @cfg {Boolean} constrain False to disable constrain to viewport (defaults to true) - * @cfg {String} cls CSS class to add to the element - * @cfg {Number} zindex Starting z-index (defaults to 11000) - * @cfg {Number} shadowOffset Number of pixels to offset the shadow (defaults to 4) - * @cfg {Boolean} useDisplay - * Defaults to use css offsets to hide the Layer. Specify true - * to use css style 'display:none;' to hide the Layer. - * @constructor - * @param {Object} config An object with config options. - * @param {String/HTMLElement} existingEl (optional) Uses an existing DOM element. If the element is not found it creates it. - */ -(function(){ -Ext.Layer = function(config, existingEl){ - config = config || {}; - var dh = Ext.DomHelper, - cp = config.parentEl, pel = cp ? Ext.getDom(cp) : document.body; - - if (existingEl) { - this.dom = Ext.getDom(existingEl); - } - if(!this.dom){ - var o = config.dh || {tag: 'div', cls: 'x-layer'}; - this.dom = dh.append(pel, o); - } - if(config.cls){ - this.addClass(config.cls); - } - this.constrain = config.constrain !== false; - this.setVisibilityMode(Ext.Element.VISIBILITY); - if(config.id){ - this.id = this.dom.id = config.id; - }else{ - this.id = Ext.id(this.dom); - } - this.zindex = config.zindex || this.getZIndex(); - this.position('absolute', this.zindex); - if(config.shadow){ - this.shadowOffset = config.shadowOffset || 4; - this.shadow = new Ext.Shadow({ - offset : this.shadowOffset, - mode : config.shadow - }); - }else{ - this.shadowOffset = 0; - } - this.useShim = config.shim !== false && Ext.useShims; - this.useDisplay = config.useDisplay; - this.hide(); -}; - -var supr = Ext.Element.prototype; - -// shims are shared among layer to keep from having 100 iframes -var shims = []; - -Ext.extend(Ext.Layer, Ext.Element, { - - getZIndex : function(){ - return this.zindex || parseInt((this.getShim() || this).getStyle('z-index'), 10) || 11000; - }, - - getShim : function(){ - if(!this.useShim){ - return null; - } - if(this.shim){ - return this.shim; - } - var shim = shims.shift(); - if(!shim){ - shim = this.createShim(); - shim.enableDisplayMode('block'); - shim.dom.style.display = 'none'; - shim.dom.style.visibility = 'visible'; - } - var pn = this.dom.parentNode; - if(shim.dom.parentNode != pn){ - pn.insertBefore(shim.dom, this.dom); - } - shim.setStyle('z-index', this.getZIndex()-2); - this.shim = shim; - return shim; - }, - - hideShim : function(){ - if(this.shim){ - this.shim.setDisplayed(false); - shims.push(this.shim); - delete this.shim; - } - }, - - disableShadow : function(){ - if(this.shadow){ - this.shadowDisabled = true; - this.shadow.hide(); - this.lastShadowOffset = this.shadowOffset; - this.shadowOffset = 0; - } - }, - - enableShadow : function(show){ - if(this.shadow){ - this.shadowDisabled = false; - this.shadowOffset = this.lastShadowOffset; - delete this.lastShadowOffset; - if(show){ - this.sync(true); - } - } - }, - - // private - // this code can execute repeatedly in milliseconds (i.e. during a drag) so - // code size was sacrificed for effeciency (e.g. no getBox/setBox, no XY calls) - sync : function(doShow){ - var shadow = this.shadow; - if(!this.updating && this.isVisible() && (shadow || this.useShim)){ - var shim = this.getShim(), - w = this.getWidth(), - h = this.getHeight(), - l = this.getLeft(true), - t = this.getTop(true); - - if(shadow && !this.shadowDisabled){ - if(doShow && !shadow.isVisible()){ - shadow.show(this); - }else{ - shadow.realign(l, t, w, h); - } - if(shim){ - if(doShow){ - shim.show(); - } - // fit the shim behind the shadow, so it is shimmed too - var shadowAdj = shadow.el.getXY(), shimStyle = shim.dom.style, - shadowSize = shadow.el.getSize(); - shimStyle.left = (shadowAdj[0])+'px'; - shimStyle.top = (shadowAdj[1])+'px'; - shimStyle.width = (shadowSize.width)+'px'; - shimStyle.height = (shadowSize.height)+'px'; - } - }else if(shim){ - if(doShow){ - shim.show(); - } - shim.setSize(w, h); - shim.setLeftTop(l, t); - } - } - }, - - // private - destroy : function(){ - this.hideShim(); - if(this.shadow){ - this.shadow.hide(); - } - this.removeAllListeners(); - Ext.removeNode(this.dom); - delete this.dom; - }, - - remove : function(){ - this.destroy(); - }, - - // private - beginUpdate : function(){ - this.updating = true; - }, - - // private - endUpdate : function(){ - this.updating = false; - this.sync(true); - }, - - // private - hideUnders : function(negOffset){ - if(this.shadow){ - this.shadow.hide(); - } - this.hideShim(); - }, - - // private - constrainXY : function(){ - if(this.constrain){ - var vw = Ext.lib.Dom.getViewWidth(), - vh = Ext.lib.Dom.getViewHeight(); - var s = Ext.getDoc().getScroll(); - - var xy = this.getXY(); - var x = xy[0], y = xy[1]; - var so = this.shadowOffset; - var w = this.dom.offsetWidth+so, h = this.dom.offsetHeight+so; - // only move it if it needs it - var moved = false; - // first validate right/bottom - if((x + w) > vw+s.left){ - x = vw - w - so; - moved = true; - } - if((y + h) > vh+s.top){ - y = vh - h - so; - moved = true; - } - // then make sure top/left isn't negative - if(x < s.left){ - x = s.left; - moved = true; - } - if(y < s.top){ - y = s.top; - moved = true; - } - if(moved){ - if(this.avoidY){ - var ay = this.avoidY; - if(y <= ay && (y+h) >= ay){ - y = ay-h-5; - } - } - xy = [x, y]; - this.storeXY(xy); - supr.setXY.call(this, xy); - this.sync(); - } - } - return this; - }, - - getConstrainOffset : function(){ - return this.shadowOffset; - }, - - isVisible : function(){ - return this.visible; - }, - - // private - showAction : function(){ - this.visible = true; // track visibility to prevent getStyle calls - if(this.useDisplay === true){ - this.setDisplayed(''); - }else if(this.lastXY){ - supr.setXY.call(this, this.lastXY); - }else if(this.lastLT){ - supr.setLeftTop.call(this, this.lastLT[0], this.lastLT[1]); - } - }, - - // private - hideAction : function(){ - this.visible = false; - if(this.useDisplay === true){ - this.setDisplayed(false); - }else{ - this.setLeftTop(-10000,-10000); - } - }, - - // overridden Element method - setVisible : function(v, a, d, c, e){ - if(v){ - this.showAction(); - } - if(a && v){ - var cb = function(){ - this.sync(true); - if(c){ - c(); - } - }.createDelegate(this); - supr.setVisible.call(this, true, true, d, cb, e); - }else{ - if(!v){ - this.hideUnders(true); - } - var cb = c; - if(a){ - cb = function(){ - this.hideAction(); - if(c){ - c(); - } - }.createDelegate(this); - } - supr.setVisible.call(this, v, a, d, cb, e); - if(v){ - this.sync(true); - }else if(!a){ - this.hideAction(); - } - } - return this; - }, - - storeXY : function(xy){ - delete this.lastLT; - this.lastXY = xy; - }, - - storeLeftTop : function(left, top){ - delete this.lastXY; - this.lastLT = [left, top]; - }, - - // private - beforeFx : function(){ - this.beforeAction(); - return Ext.Layer.superclass.beforeFx.apply(this, arguments); - }, - - // private - afterFx : function(){ - Ext.Layer.superclass.afterFx.apply(this, arguments); - this.sync(this.isVisible()); - }, - - // private - beforeAction : function(){ - if(!this.updating && this.shadow){ - this.shadow.hide(); - } - }, - - // overridden Element method - setLeft : function(left){ - this.storeLeftTop(left, this.getTop(true)); - supr.setLeft.apply(this, arguments); - this.sync(); - return this; - }, - - setTop : function(top){ - this.storeLeftTop(this.getLeft(true), top); - supr.setTop.apply(this, arguments); - this.sync(); - return this; - }, - - setLeftTop : function(left, top){ - this.storeLeftTop(left, top); - supr.setLeftTop.apply(this, arguments); - this.sync(); - return this; - }, - - setXY : function(xy, a, d, c, e){ - this.fixDisplay(); - this.beforeAction(); - this.storeXY(xy); - var cb = this.createCB(c); - supr.setXY.call(this, xy, a, d, cb, e); - if(!a){ - cb(); - } - return this; - }, - - // private - createCB : function(c){ - var el = this; - return function(){ - el.constrainXY(); - el.sync(true); - if(c){ - c(); - } - }; - }, - - // overridden Element method - setX : function(x, a, d, c, e){ - this.setXY([x, this.getY()], a, d, c, e); - return this; - }, - - // overridden Element method - setY : function(y, a, d, c, e){ - this.setXY([this.getX(), y], a, d, c, e); - return this; - }, - - // overridden Element method - setSize : function(w, h, a, d, c, e){ - this.beforeAction(); - var cb = this.createCB(c); - supr.setSize.call(this, w, h, a, d, cb, e); - if(!a){ - cb(); - } - return this; - }, - - // overridden Element method - setWidth : function(w, a, d, c, e){ - this.beforeAction(); - var cb = this.createCB(c); - supr.setWidth.call(this, w, a, d, cb, e); - if(!a){ - cb(); - } - return this; - }, - - // overridden Element method - setHeight : function(h, a, d, c, e){ - this.beforeAction(); - var cb = this.createCB(c); - supr.setHeight.call(this, h, a, d, cb, e); - if(!a){ - cb(); - } - return this; - }, - - // overridden Element method - setBounds : function(x, y, w, h, a, d, c, e){ - this.beforeAction(); - var cb = this.createCB(c); - if(!a){ - this.storeXY([x, y]); - supr.setXY.call(this, [x, y]); - supr.setSize.call(this, w, h, a, d, cb, e); - cb(); - }else{ - supr.setBounds.call(this, x, y, w, h, a, d, cb, e); - } - return this; - }, - - /** - * Sets the z-index of this layer and adjusts any shadow and shim z-indexes. The layer z-index is automatically - * incremented by two more than the value passed in so that it always shows above any shadow or shim (the shadow - * element, if any, will be assigned z-index + 1, and the shim element, if any, will be assigned the unmodified z-index). - * @param {Number} zindex The new z-index to set - * @return {this} The Layer - */ - setZIndex : function(zindex){ - this.zindex = zindex; - this.setStyle('z-index', zindex + 2); - if(this.shadow){ - this.shadow.setZIndex(zindex + 1); - } - if(this.shim){ - this.shim.setStyle('z-index', zindex); - } - return this; - } -}); -})(); -/** - * @class Ext.Shadow - * Simple class that can provide a shadow effect for any element. Note that the element MUST be absolutely positioned, - * and the shadow does not provide any shimming. This should be used only in simple cases -- for more advanced - * functionality that can also provide the same shadow effect, see the {@link Ext.Layer} class. - * @constructor - * Create a new Shadow - * @param {Object} config The config object - */ -Ext.Shadow = function(config) { - Ext.apply(this, config); - if (typeof this.mode != "string") { - this.mode = this.defaultMode; - } - var o = this.offset, - a = { - h: 0 - }, - rad = Math.floor(this.offset / 2); - switch (this.mode.toLowerCase()) { - // all this hideous nonsense calculates the various offsets for shadows - case "drop": - a.w = 0; - a.l = a.t = o; - a.t -= 1; - if (Ext.isIE) { - a.l -= this.offset + rad; - a.t -= this.offset + rad; - a.w -= rad; - a.h -= rad; - a.t += 1; - } - break; - case "sides": - a.w = (o * 2); - a.l = -o; - a.t = o - 1; - if (Ext.isIE) { - a.l -= (this.offset - rad); - a.t -= this.offset + rad; - a.l += 1; - a.w -= (this.offset - rad) * 2; - a.w -= rad + 1; - a.h -= 1; - } - break; - case "frame": - a.w = a.h = (o * 2); - a.l = a.t = -o; - a.t += 1; - a.h -= 2; - if (Ext.isIE) { - a.l -= (this.offset - rad); - a.t -= (this.offset - rad); - a.l += 1; - a.w -= (this.offset + rad + 1); - a.h -= (this.offset + rad); - a.h += 1; - } - break; - }; - - this.adjusts = a; -}; - -Ext.Shadow.prototype = { - /** - * @cfg {String} mode - * The shadow display mode. Supports the following options:
- */ - /** - * @cfg {String} offset - * The number of pixels to offset the shadow from the element (defaults to 4) - */ - offset: 4, - - // private - defaultMode: "drop", - - /** - * Displays the shadow under the target element - * @param {Mixed} targetEl The id or element under which the shadow should display - */ - show: function(target) { - target = Ext.get(target); - if (!this.el) { - this.el = Ext.Shadow.Pool.pull(); - if (this.el.dom.nextSibling != target.dom) { - this.el.insertBefore(target); - } - } - this.el.setStyle("z-index", this.zIndex || parseInt(target.getStyle("z-index"), 10) - 1); - if (Ext.isIE) { - this.el.dom.style.filter = "progid:DXImageTransform.Microsoft.alpha(opacity=50) progid:DXImageTransform.Microsoft.Blur(pixelradius=" + (this.offset) + ")"; - } - this.realign( - target.getLeft(true), - target.getTop(true), - target.getWidth(), - target.getHeight() - ); - this.el.dom.style.display = "block"; - }, - - /** - * Returns true if the shadow is visible, else false - */ - isVisible: function() { - return this.el ? true: false; - }, - - /** - * Direct alignment when values are already available. Show must be called at least once before - * calling this method to ensure it is initialized. - * @param {Number} left The target element left position - * @param {Number} top The target element top position - * @param {Number} width The target element width - * @param {Number} height The target element height - */ - realign: function(l, t, w, h) { - if (!this.el) { - return; - } - var a = this.adjusts, - d = this.el.dom, - s = d.style, - iea = 0, - sw = (w + a.w), - sh = (h + a.h), - sws = sw + "px", - shs = sh + "px", - cn, - sww; - s.left = (l + a.l) + "px"; - s.top = (t + a.t) + "px"; - if (s.width != sws || s.height != shs) { - s.width = sws; - s.height = shs; - if (!Ext.isIE) { - cn = d.childNodes; - sww = Math.max(0, (sw - 12)) + "px"; - cn[0].childNodes[1].style.width = sww; - cn[1].childNodes[1].style.width = sww; - cn[2].childNodes[1].style.width = sww; - cn[1].style.height = Math.max(0, (sh - 12)) + "px"; - } - } - }, - - /** - * Hides this shadow - */ - hide: function() { - if (this.el) { - this.el.dom.style.display = "none"; - Ext.Shadow.Pool.push(this.el); - delete this.el; - } - }, - - /** - * Adjust the z-index of this shadow - * @param {Number} zindex The new z-index - */ - setZIndex: function(z) { - this.zIndex = z; - if (this.el) { - this.el.setStyle("z-index", z); - } - } -}; - -// Private utility class that manages the internal Shadow cache -Ext.Shadow.Pool = function() { - var p = [], - markup = Ext.isIE ? - '
': - '
'; - return { - pull: function() { - var sh = p.shift(); - if (!sh) { - sh = Ext.get(Ext.DomHelper.insertHtml("beforeBegin", document.body.firstChild, markup)); - sh.autoBoxAdjust = false; - } - return sh; - }, - - push: function(sh) { - p.push(sh); - } - }; -}();/** - * @class Ext.BoxComponent - * @extends Ext.Component - *

Base class for any {@link Ext.Component Component} that is to be sized as a box, using width and height.

- *

BoxComponent provides automatic box model adjustments for sizing and positioning and will work correctly - * within the Component rendering model.

- *

A BoxComponent may be created as a custom Component which encapsulates any HTML element, either a pre-existing - * element, or one that is created to your specifications at render time. Usually, to participate in layouts, - * a Component will need to be a BoxComponent in order to have its width and height managed.

- *

To use a pre-existing element as a BoxComponent, configure it so that you preset the el property to the - * element to reference:


-var pageHeader = new Ext.BoxComponent({
-    el: 'my-header-div'
-});
- * This may then be {@link Ext.Container#add added} to a {@link Ext.Container Container} as a child item.

- *

To create a BoxComponent based around a HTML element to be created at render time, use the - * {@link Ext.Component#autoEl autoEl} config option which takes the form of a - * {@link Ext.DomHelper DomHelper} specification:


-var myImage = new Ext.BoxComponent({
-    autoEl: {
-        tag: 'img',
-        src: '/images/my-image.jpg'
-    }
-});

- * @constructor - * @param {Ext.Element/String/Object} config The configuration options. - * @xtype box - */ -Ext.BoxComponent = Ext.extend(Ext.Component, { - - // Configs below are used for all Components when rendered by BoxLayout. - /** - * @cfg {Number} flex - *

Note: this config is only used when this Component is rendered - * by a Container which has been configured to use a {@link Ext.layout.BoxLayout BoxLayout}. - * Each child Component with a flex property will be flexed either vertically (by a VBoxLayout) - * or horizontally (by an HBoxLayout) according to the item's relative flex value - * compared to the sum of all Components with flex value specified. Any child items that have - * either a flex = 0 or flex = undefined will not be 'flexed' (the initial size will not be changed). - */ - // Configs below are used for all Components when rendered by AnchorLayout. - /** - * @cfg {String} anchor

Note: this config is only used when this Component is rendered - * by a Container which has been configured to use an {@link Ext.layout.AnchorLayout AnchorLayout} (or subclass thereof). - * based layout manager, for example:

- *

See {@link Ext.layout.AnchorLayout}.{@link Ext.layout.AnchorLayout#anchor anchor} also.

- */ - // tabTip config is used when a BoxComponent is a child of a TabPanel - /** - * @cfg {String} tabTip - *

Note: this config is only used when this BoxComponent is a child item of a TabPanel.

- * A string to be used as innerHTML (html tags are accepted) to show in a tooltip when mousing over - * the associated tab selector element. {@link Ext.QuickTips}.init() - * must be called in order for the tips to render. - */ - // Configs below are used for all Components when rendered by BorderLayout. - /** - * @cfg {String} region

Note: this config is only used when this BoxComponent is rendered - * by a Container which has been configured to use the {@link Ext.layout.BorderLayout BorderLayout} - * layout manager (e.g. specifying layout:'border').


- *

See {@link Ext.layout.BorderLayout} also.

- */ - // margins config is used when a BoxComponent is rendered by BorderLayout or BoxLayout. - /** - * @cfg {Object} margins

Note: this config is only used when this BoxComponent is rendered - * by a Container which has been configured to use the {@link Ext.layout.BorderLayout BorderLayout} - * or one of the two {@link Ext.layout.BoxLayout BoxLayout} subclasses.

- *

An object containing margins to apply to this BoxComponent in the - * format:


-{
-    top: (top margin),
-    right: (right margin),
-    bottom: (bottom margin),
-    left: (left margin)
-}
- *

May also be a string containing space-separated, numeric margin values. The order of the - * sides associated with each value matches the way CSS processes margin values:

- *

    - *
  • If there is only one value, it applies to all sides.
  • - *
  • If there are two values, the top and bottom borders are set to the first value and the - * right and left are set to the second.
  • - *
  • If there are three values, the top is set to the first value, the left and right are set - * to the second, and the bottom is set to the third.
  • - *
  • If there are four values, they apply to the top, right, bottom, and left, respectively.
  • - *

- *

Defaults to:


-     * {top:0, right:0, bottom:0, left:0}
-     * 
- */ - /** - * @cfg {Number} x - * The local x (left) coordinate for this component if contained within a positioning container. - */ - /** - * @cfg {Number} y - * The local y (top) coordinate for this component if contained within a positioning container. - */ - /** - * @cfg {Number} pageX - * The page level x coordinate for this component if contained within a positioning container. - */ - /** - * @cfg {Number} pageY - * The page level y coordinate for this component if contained within a positioning container. - */ - /** - * @cfg {Number} height - * The height of this component in pixels (defaults to auto). - * Note to express this dimension as a percentage or offset see {@link Ext.Component#anchor}. - */ - /** - * @cfg {Number} width - * The width of this component in pixels (defaults to auto). - * Note to express this dimension as a percentage or offset see {@link Ext.Component#anchor}. - */ - /** - * @cfg {Number} boxMinHeight - *

The minimum value in pixels which this BoxComponent will set its height to.

- *

Warning: This will override any size management applied by layout managers.

- */ - /** - * @cfg {Number} boxMinWidth - *

The minimum value in pixels which this BoxComponent will set its width to.

- *

Warning: This will override any size management applied by layout managers.

- */ - /** - * @cfg {Number} boxMaxHeight - *

The maximum value in pixels which this BoxComponent will set its height to.

- *

Warning: This will override any size management applied by layout managers.

- */ - /** - * @cfg {Number} boxMaxWidth - *

The maximum value in pixels which this BoxComponent will set its width to.

- *

Warning: This will override any size management applied by layout managers.

- */ - /** - * @cfg {Boolean} autoHeight - *

True to use height:'auto', false to use fixed height (or allow it to be managed by its parent - * Container's {@link Ext.Container#layout layout manager}. Defaults to false.

- *

Note: Although many components inherit this config option, not all will - * function as expected with a height of 'auto'. Setting autoHeight:true means that the - * browser will manage height based on the element's contents, and that Ext will not manage it at all.

- *

If the browser is managing the height, be aware that resizes performed by the browser in response - * to changes within the structure of the Component cannot be detected. Therefore changes to the height might - * result in elements needing to be synchronized with the new height. Example:


-var w = new Ext.Window({
-    title: 'Window',
-    width: 600,
-    autoHeight: true,
-    items: {
-        title: 'Collapse Me',
-        height: 400,
-        collapsible: true,
-        border: false,
-        listeners: {
-            beforecollapse: function() {
-                w.el.shadow.hide();
-            },
-            beforeexpand: function() {
-                w.el.shadow.hide();
-            },
-            collapse: function() {
-                w.syncShadow();
-            },
-            expand: function() {
-                w.syncShadow();
-            }
-        }
-    }
-}).show();
-
- */ - /** - * @cfg {Boolean} autoWidth - *

True to use width:'auto', false to use fixed width (or allow it to be managed by its parent - * Container's {@link Ext.Container#layout layout manager}. Defaults to false.

- *

Note: Although many components inherit this config option, not all will - * function as expected with a width of 'auto'. Setting autoWidth:true means that the - * browser will manage width based on the element's contents, and that Ext will not manage it at all.

- *

If the browser is managing the width, be aware that resizes performed by the browser in response - * to changes within the structure of the Component cannot be detected. Therefore changes to the width might - * result in elements needing to be synchronized with the new width. For example, where the target element is:


-<div id='grid-container' style='margin-left:25%;width:50%'></div>
-
- * A Panel rendered into that target element must listen for browser window resize in order to relay its - * child items when the browser changes its width:

-var myPanel = new Ext.Panel({
-    renderTo: 'grid-container',
-    monitorResize: true, // relay on browser resize
-    title: 'Panel',
-    height: 400,
-    autoWidth: true,
-    layout: 'hbox',
-    layoutConfig: {
-        align: 'stretch'
-    },
-    defaults: {
-        flex: 1
-    },
-    items: [{
-        title: 'Box 1',
-    }, {
-        title: 'Box 2'
-    }, {
-        title: 'Box 3'
-    }],
-});
-
- */ - /** - * @cfg {Boolean} autoScroll - * true to use overflow:'auto' on the components layout element and show scroll bars automatically when - * necessary, false to clip any overflowing content (defaults to false). - */ - - /* // private internal config - * {Boolean} deferHeight - * True to defer height calculations to an external component, false to allow this component to set its own - * height (defaults to false). - */ - - // private - initComponent : function(){ - Ext.BoxComponent.superclass.initComponent.call(this); - this.addEvents( - /** - * @event resize - * Fires after the component is resized. - * @param {Ext.Component} this - * @param {Number} adjWidth The box-adjusted width that was set - * @param {Number} adjHeight The box-adjusted height that was set - * @param {Number} rawWidth The width that was originally specified - * @param {Number} rawHeight The height that was originally specified - */ - 'resize', - /** - * @event move - * Fires after the component is moved. - * @param {Ext.Component} this - * @param {Number} x The new x position - * @param {Number} y The new y position - */ - 'move' - ); - }, - - // private, set in afterRender to signify that the component has been rendered - boxReady : false, - // private, used to defer height settings to subclasses - deferHeight: false, - - /** - * Sets the width and height of this BoxComponent. This method fires the {@link #resize} event. This method can accept - * either width and height as separate arguments, or you can pass a size object like {width:10, height:20}. - * @param {Mixed} width The new width to set. This may be one of:
    - *
  • A Number specifying the new width in the {@link #getEl Element}'s {@link Ext.Element#defaultUnit}s (by default, pixels).
  • - *
  • A String used to set the CSS width style.
  • - *
  • A size object in the format {width: widthValue, height: heightValue}.
  • - *
  • undefined to leave the width unchanged.
  • - *
- * @param {Mixed} height The new height to set (not required if a size object is passed as the first arg). - * This may be one of:
    - *
  • A Number specifying the new height in the {@link #getEl Element}'s {@link Ext.Element#defaultUnit}s (by default, pixels).
  • - *
  • A String used to set the CSS height style. Animation may not be used.
  • - *
  • undefined to leave the height unchanged.
  • - *
- * @return {Ext.BoxComponent} this - */ - setSize : function(w, h){ - - // support for standard size objects - if(typeof w == 'object'){ - h = w.height; - w = w.width; - } - if (Ext.isDefined(w) && Ext.isDefined(this.boxMinWidth) && (w < this.boxMinWidth)) { - w = this.boxMinWidth; - } - if (Ext.isDefined(h) && Ext.isDefined(this.boxMinHeight) && (h < this.boxMinHeight)) { - h = this.boxMinHeight; - } - if (Ext.isDefined(w) && Ext.isDefined(this.boxMaxWidth) && (w > this.boxMaxWidth)) { - w = this.boxMaxWidth; - } - if (Ext.isDefined(h) && Ext.isDefined(this.boxMaxHeight) && (h > this.boxMaxHeight)) { - h = this.boxMaxHeight; - } - // not rendered - if(!this.boxReady){ - this.width = w; - this.height = h; - return this; - } - - // prevent recalcs when not needed - if(this.cacheSizes !== false && this.lastSize && this.lastSize.width == w && this.lastSize.height == h){ - return this; - } - this.lastSize = {width: w, height: h}; - var adj = this.adjustSize(w, h), - aw = adj.width, - ah = adj.height, - rz; - if(aw !== undefined || ah !== undefined){ // this code is nasty but performs better with floaters - rz = this.getResizeEl(); - if(!this.deferHeight && aw !== undefined && ah !== undefined){ - rz.setSize(aw, ah); - }else if(!this.deferHeight && ah !== undefined){ - rz.setHeight(ah); - }else if(aw !== undefined){ - rz.setWidth(aw); - } - this.onResize(aw, ah, w, h); - this.fireEvent('resize', this, aw, ah, w, h); - } - return this; - }, - - /** - * Sets the width of the component. This method fires the {@link #resize} event. - * @param {Mixed} width The new width to set. This may be one of:
    - *
  • A Number specifying the new width in the {@link #getEl Element}'s {@link Ext.Element#defaultUnit defaultUnit}s (by default, pixels).
  • - *
  • A String used to set the CSS width style.
  • - *
- * @return {Ext.BoxComponent} this - */ - setWidth : function(width){ - return this.setSize(width); - }, - - /** - * Sets the height of the component. This method fires the {@link #resize} event. - * @param {Mixed} height The new height to set. This may be one of:
    - *
  • A Number specifying the new height in the {@link #getEl Element}'s {@link Ext.Element#defaultUnit defaultUnit}s (by default, pixels).
  • - *
  • A String used to set the CSS height style.
  • - *
  • undefined to leave the height unchanged.
  • - *
- * @return {Ext.BoxComponent} this - */ - setHeight : function(height){ - return this.setSize(undefined, height); - }, - - /** - * Gets the current size of the component's underlying element. - * @return {Object} An object containing the element's size {width: (element width), height: (element height)} - */ - getSize : function(){ - return this.getResizeEl().getSize(); - }, - - /** - * Gets the current width of the component's underlying element. - * @return {Number} - */ - getWidth : function(){ - return this.getResizeEl().getWidth(); - }, - - /** - * Gets the current height of the component's underlying element. - * @return {Number} - */ - getHeight : function(){ - return this.getResizeEl().getHeight(); - }, - - /** - * Gets the current size of the component's underlying element, including space taken by its margins. - * @return {Object} An object containing the element's size {width: (element width + left/right margins), height: (element height + top/bottom margins)} - */ - getOuterSize : function(){ - var el = this.getResizeEl(); - return {width: el.getWidth() + el.getMargins('lr'), - height: el.getHeight() + el.getMargins('tb')}; - }, - - /** - * Gets the current XY position of the component's underlying element. - * @param {Boolean} local (optional) If true the element's left and top are returned instead of page XY (defaults to false) - * @return {Array} The XY position of the element (e.g., [100, 200]) - */ - getPosition : function(local){ - var el = this.getPositionEl(); - if(local === true){ - return [el.getLeft(true), el.getTop(true)]; - } - return this.xy || el.getXY(); - }, - - /** - * Gets the current box measurements of the component's underlying element. - * @param {Boolean} local (optional) If true the element's left and top are returned instead of page XY (defaults to false) - * @return {Object} box An object in the format {x, y, width, height} - */ - getBox : function(local){ - var pos = this.getPosition(local); - var s = this.getSize(); - s.x = pos[0]; - s.y = pos[1]; - return s; - }, - - /** - * Sets the current box measurements of the component's underlying element. - * @param {Object} box An object in the format {x, y, width, height} - * @return {Ext.BoxComponent} this - */ - updateBox : function(box){ - this.setSize(box.width, box.height); - this.setPagePosition(box.x, box.y); - return this; - }, - - /** - *

Returns the outermost Element of this Component which defines the Components overall size.

- *

Usually this will return the same Element as {@link #getEl}, - * but in some cases, a Component may have some more wrapping Elements around its main - * active Element.

- *

An example is a ComboBox. It is encased in a wrapping Element which - * contains both the <input> Element (which is what would be returned - * by its {@link #getEl} method, and the trigger button Element. - * This Element is returned as the resizeEl. - * @return {Ext.Element} The Element which is to be resized by size managing layouts. - */ - getResizeEl : function(){ - return this.resizeEl || this.el; - }, - - /** - * Sets the overflow on the content element of the component. - * @param {Boolean} scroll True to allow the Component to auto scroll. - * @return {Ext.BoxComponent} this - */ - setAutoScroll : function(scroll){ - if(this.rendered){ - this.getContentTarget().setOverflow(scroll ? 'auto' : ''); - } - this.autoScroll = scroll; - return this; - }, - - /** - * Sets the left and top of the component. To set the page XY position instead, use {@link #setPagePosition}. - * This method fires the {@link #move} event. - * @param {Number} left The new left - * @param {Number} top The new top - * @return {Ext.BoxComponent} this - */ - setPosition : function(x, y){ - if(x && typeof x[1] == 'number'){ - y = x[1]; - x = x[0]; - } - this.x = x; - this.y = y; - if(!this.boxReady){ - return this; - } - var adj = this.adjustPosition(x, y); - var ax = adj.x, ay = adj.y; - - var el = this.getPositionEl(); - if(ax !== undefined || ay !== undefined){ - if(ax !== undefined && ay !== undefined){ - el.setLeftTop(ax, ay); - }else if(ax !== undefined){ - el.setLeft(ax); - }else if(ay !== undefined){ - el.setTop(ay); - } - this.onPosition(ax, ay); - this.fireEvent('move', this, ax, ay); - } - return this; - }, - - /** - * Sets the page XY position of the component. To set the left and top instead, use {@link #setPosition}. - * This method fires the {@link #move} event. - * @param {Number} x The new x position - * @param {Number} y The new y position - * @return {Ext.BoxComponent} this - */ - setPagePosition : function(x, y){ - if(x && typeof x[1] == 'number'){ - y = x[1]; - x = x[0]; - } - this.pageX = x; - this.pageY = y; - if(!this.boxReady){ - return; - } - if(x === undefined || y === undefined){ // cannot translate undefined points - return; - } - var p = this.getPositionEl().translatePoints(x, y); - this.setPosition(p.left, p.top); - return this; - }, - - // private - afterRender : function(){ - Ext.BoxComponent.superclass.afterRender.call(this); - if(this.resizeEl){ - this.resizeEl = Ext.get(this.resizeEl); - } - if(this.positionEl){ - this.positionEl = Ext.get(this.positionEl); - } - this.boxReady = true; - Ext.isDefined(this.autoScroll) && this.setAutoScroll(this.autoScroll); - this.setSize(this.width, this.height); - if(this.x || this.y){ - this.setPosition(this.x, this.y); - }else if(this.pageX || this.pageY){ - this.setPagePosition(this.pageX, this.pageY); - } - }, - - /** - * Force the component's size to recalculate based on the underlying element's current height and width. - * @return {Ext.BoxComponent} this - */ - syncSize : function(){ - delete this.lastSize; - this.setSize(this.autoWidth ? undefined : this.getResizeEl().getWidth(), this.autoHeight ? undefined : this.getResizeEl().getHeight()); - return this; - }, - - /* // protected - * Called after the component is resized, this method is empty by default but can be implemented by any - * subclass that needs to perform custom logic after a resize occurs. - * @param {Number} adjWidth The box-adjusted width that was set - * @param {Number} adjHeight The box-adjusted height that was set - * @param {Number} rawWidth The width that was originally specified - * @param {Number} rawHeight The height that was originally specified - */ - onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){ - }, - - /* // protected - * Called after the component is moved, this method is empty by default but can be implemented by any - * subclass that needs to perform custom logic after a move occurs. - * @param {Number} x The new x position - * @param {Number} y The new y position - */ - onPosition : function(x, y){ - - }, - - // private - adjustSize : function(w, h){ - if(this.autoWidth){ - w = 'auto'; - } - if(this.autoHeight){ - h = 'auto'; - } - return {width : w, height: h}; - }, - - // private - adjustPosition : function(x, y){ - return {x : x, y: y}; - } -}); -Ext.reg('box', Ext.BoxComponent); - - -/** - * @class Ext.Spacer - * @extends Ext.BoxComponent - *

Used to provide a sizable space in a layout.

- * @constructor - * @param {Object} config - */ -Ext.Spacer = Ext.extend(Ext.BoxComponent, { - autoEl:'div' -}); -Ext.reg('spacer', Ext.Spacer);/** - * @class Ext.SplitBar - * @extends Ext.util.Observable - * Creates draggable splitter bar functionality from two elements (element to be dragged and element to be resized). - *

- * Usage: - *

-var split = new Ext.SplitBar("elementToDrag", "elementToSize",
-                   Ext.SplitBar.HORIZONTAL, Ext.SplitBar.LEFT);
-split.setAdapter(new Ext.SplitBar.AbsoluteLayoutAdapter("container"));
-split.minSize = 100;
-split.maxSize = 600;
-split.animate = true;
-split.on('moved', splitterMoved);
-
- * @constructor - * Create a new SplitBar - * @param {Mixed} dragElement The element to be dragged and act as the SplitBar. - * @param {Mixed} resizingElement The element to be resized based on where the SplitBar element is dragged - * @param {Number} orientation (optional) Either Ext.SplitBar.HORIZONTAL or Ext.SplitBar.VERTICAL. (Defaults to HORIZONTAL) - * @param {Number} placement (optional) Either Ext.SplitBar.LEFT or Ext.SplitBar.RIGHT for horizontal or - Ext.SplitBar.TOP or Ext.SplitBar.BOTTOM for vertical. (By default, this is determined automatically by the initial - position of the SplitBar). - */ -Ext.SplitBar = function(dragElement, resizingElement, orientation, placement, existingProxy){ - - /** @private */ - this.el = Ext.get(dragElement, true); - this.el.dom.unselectable = "on"; - /** @private */ - this.resizingEl = Ext.get(resizingElement, true); - - /** - * @private - * The orientation of the split. Either Ext.SplitBar.HORIZONTAL or Ext.SplitBar.VERTICAL. (Defaults to HORIZONTAL) - * Note: If this is changed after creating the SplitBar, the placement property must be manually updated - * @type Number - */ - this.orientation = orientation || Ext.SplitBar.HORIZONTAL; - - /** - * The increment, in pixels by which to move this SplitBar. When undefined, the SplitBar moves smoothly. - * @type Number - * @property tickSize - */ - /** - * The minimum size of the resizing element. (Defaults to 0) - * @type Number - */ - this.minSize = 0; - - /** - * The maximum size of the resizing element. (Defaults to 2000) - * @type Number - */ - this.maxSize = 2000; - - /** - * Whether to animate the transition to the new size - * @type Boolean - */ - this.animate = false; - - /** - * Whether to create a transparent shim that overlays the page when dragging, enables dragging across iframes. - * @type Boolean - */ - this.useShim = false; - - /** @private */ - this.shim = null; - - if(!existingProxy){ - /** @private */ - this.proxy = Ext.SplitBar.createProxy(this.orientation); - }else{ - this.proxy = Ext.get(existingProxy).dom; - } - /** @private */ - this.dd = new Ext.dd.DDProxy(this.el.dom.id, "XSplitBars", {dragElId : this.proxy.id}); - - /** @private */ - this.dd.b4StartDrag = this.onStartProxyDrag.createDelegate(this); - - /** @private */ - this.dd.endDrag = this.onEndProxyDrag.createDelegate(this); - - /** @private */ - this.dragSpecs = {}; - - /** - * @private The adapter to use to positon and resize elements - */ - this.adapter = new Ext.SplitBar.BasicLayoutAdapter(); - this.adapter.init(this); - - if(this.orientation == Ext.SplitBar.HORIZONTAL){ - /** @private */ - this.placement = placement || (this.el.getX() > this.resizingEl.getX() ? Ext.SplitBar.LEFT : Ext.SplitBar.RIGHT); - this.el.addClass("x-splitbar-h"); - }else{ - /** @private */ - this.placement = placement || (this.el.getY() > this.resizingEl.getY() ? Ext.SplitBar.TOP : Ext.SplitBar.BOTTOM); - this.el.addClass("x-splitbar-v"); - } - - this.addEvents( - /** - * @event resize - * Fires when the splitter is moved (alias for {@link #moved}) - * @param {Ext.SplitBar} this - * @param {Number} newSize the new width or height - */ - "resize", - /** - * @event moved - * Fires when the splitter is moved - * @param {Ext.SplitBar} this - * @param {Number} newSize the new width or height - */ - "moved", - /** - * @event beforeresize - * Fires before the splitter is dragged - * @param {Ext.SplitBar} this - */ - "beforeresize", - - "beforeapply" - ); - - Ext.SplitBar.superclass.constructor.call(this); -}; - -Ext.extend(Ext.SplitBar, Ext.util.Observable, { - onStartProxyDrag : function(x, y){ - this.fireEvent("beforeresize", this); - this.overlay = Ext.DomHelper.append(document.body, {cls: "x-drag-overlay", html: " "}, true); - this.overlay.unselectable(); - this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true)); - this.overlay.show(); - Ext.get(this.proxy).setDisplayed("block"); - var size = this.adapter.getElementSize(this); - this.activeMinSize = this.getMinimumSize(); - this.activeMaxSize = this.getMaximumSize(); - var c1 = size - this.activeMinSize; - var c2 = Math.max(this.activeMaxSize - size, 0); - if(this.orientation == Ext.SplitBar.HORIZONTAL){ - this.dd.resetConstraints(); - this.dd.setXConstraint( - this.placement == Ext.SplitBar.LEFT ? c1 : c2, - this.placement == Ext.SplitBar.LEFT ? c2 : c1, - this.tickSize - ); - this.dd.setYConstraint(0, 0); - }else{ - this.dd.resetConstraints(); - this.dd.setXConstraint(0, 0); - this.dd.setYConstraint( - this.placement == Ext.SplitBar.TOP ? c1 : c2, - this.placement == Ext.SplitBar.TOP ? c2 : c1, - this.tickSize - ); - } - this.dragSpecs.startSize = size; - this.dragSpecs.startPoint = [x, y]; - Ext.dd.DDProxy.prototype.b4StartDrag.call(this.dd, x, y); - }, - - /** - * @private Called after the drag operation by the DDProxy - */ - onEndProxyDrag : function(e){ - Ext.get(this.proxy).setDisplayed(false); - var endPoint = Ext.lib.Event.getXY(e); - if(this.overlay){ - Ext.destroy(this.overlay); - delete this.overlay; - } - var newSize; - if(this.orientation == Ext.SplitBar.HORIZONTAL){ - newSize = this.dragSpecs.startSize + - (this.placement == Ext.SplitBar.LEFT ? - endPoint[0] - this.dragSpecs.startPoint[0] : - this.dragSpecs.startPoint[0] - endPoint[0] - ); - }else{ - newSize = this.dragSpecs.startSize + - (this.placement == Ext.SplitBar.TOP ? - endPoint[1] - this.dragSpecs.startPoint[1] : - this.dragSpecs.startPoint[1] - endPoint[1] - ); - } - newSize = Math.min(Math.max(newSize, this.activeMinSize), this.activeMaxSize); - if(newSize != this.dragSpecs.startSize){ - if(this.fireEvent('beforeapply', this, newSize) !== false){ - this.adapter.setElementSize(this, newSize); - this.fireEvent("moved", this, newSize); - this.fireEvent("resize", this, newSize); - } - } - }, - - /** - * Get the adapter this SplitBar uses - * @return The adapter object - */ - getAdapter : function(){ - return this.adapter; - }, - - /** - * Set the adapter this SplitBar uses - * @param {Object} adapter A SplitBar adapter object - */ - setAdapter : function(adapter){ - this.adapter = adapter; - this.adapter.init(this); - }, - - /** - * Gets the minimum size for the resizing element - * @return {Number} The minimum size - */ - getMinimumSize : function(){ - return this.minSize; - }, - - /** - * Sets the minimum size for the resizing element - * @param {Number} minSize The minimum size - */ - setMinimumSize : function(minSize){ - this.minSize = minSize; - }, - - /** - * Gets the maximum size for the resizing element - * @return {Number} The maximum size - */ - getMaximumSize : function(){ - return this.maxSize; - }, - - /** - * Sets the maximum size for the resizing element - * @param {Number} maxSize The maximum size - */ - setMaximumSize : function(maxSize){ - this.maxSize = maxSize; - }, - - /** - * Sets the initialize size for the resizing element - * @param {Number} size The initial size - */ - setCurrentSize : function(size){ - var oldAnimate = this.animate; - this.animate = false; - this.adapter.setElementSize(this, size); - this.animate = oldAnimate; - }, - - /** - * Destroy this splitbar. - * @param {Boolean} removeEl True to remove the element - */ - destroy : function(removeEl){ - Ext.destroy(this.shim, Ext.get(this.proxy)); - this.dd.unreg(); - if(removeEl){ - this.el.remove(); - } - this.purgeListeners(); - } -}); - -/** - * @private static Create our own proxy element element. So it will be the same same size on all browsers, we won't use borders. Instead we use a background color. - */ -Ext.SplitBar.createProxy = function(dir){ - var proxy = new Ext.Element(document.createElement("div")); - document.body.appendChild(proxy.dom); - proxy.unselectable(); - var cls = 'x-splitbar-proxy'; - proxy.addClass(cls + ' ' + (dir == Ext.SplitBar.HORIZONTAL ? cls +'-h' : cls + '-v')); - return proxy.dom; -}; - -/** - * @class Ext.SplitBar.BasicLayoutAdapter - * Default Adapter. It assumes the splitter and resizing element are not positioned - * elements and only gets/sets the width of the element. Generally used for table based layouts. - */ -Ext.SplitBar.BasicLayoutAdapter = function(){ -}; - -Ext.SplitBar.BasicLayoutAdapter.prototype = { - // do nothing for now - init : function(s){ - - }, - /** - * Called before drag operations to get the current size of the resizing element. - * @param {Ext.SplitBar} s The SplitBar using this adapter - */ - getElementSize : function(s){ - if(s.orientation == Ext.SplitBar.HORIZONTAL){ - return s.resizingEl.getWidth(); - }else{ - return s.resizingEl.getHeight(); - } - }, - - /** - * Called after drag operations to set the size of the resizing element. - * @param {Ext.SplitBar} s The SplitBar using this adapter - * @param {Number} newSize The new size to set - * @param {Function} onComplete A function to be invoked when resizing is complete - */ - setElementSize : function(s, newSize, onComplete){ - if(s.orientation == Ext.SplitBar.HORIZONTAL){ - if(!s.animate){ - s.resizingEl.setWidth(newSize); - if(onComplete){ - onComplete(s, newSize); - } - }else{ - s.resizingEl.setWidth(newSize, true, .1, onComplete, 'easeOut'); - } - }else{ - - if(!s.animate){ - s.resizingEl.setHeight(newSize); - if(onComplete){ - onComplete(s, newSize); - } - }else{ - s.resizingEl.setHeight(newSize, true, .1, onComplete, 'easeOut'); - } - } - } -}; - -/** - *@class Ext.SplitBar.AbsoluteLayoutAdapter - * @extends Ext.SplitBar.BasicLayoutAdapter - * Adapter that moves the splitter element to align with the resized sizing element. - * Used with an absolute positioned SplitBar. - * @param {Mixed} container The container that wraps around the absolute positioned content. If it's - * document.body, make sure you assign an id to the body element. - */ -Ext.SplitBar.AbsoluteLayoutAdapter = function(container){ - this.basic = new Ext.SplitBar.BasicLayoutAdapter(); - this.container = Ext.get(container); -}; - -Ext.SplitBar.AbsoluteLayoutAdapter.prototype = { - init : function(s){ - this.basic.init(s); - }, - - getElementSize : function(s){ - return this.basic.getElementSize(s); - }, - - setElementSize : function(s, newSize, onComplete){ - this.basic.setElementSize(s, newSize, this.moveSplitter.createDelegate(this, [s])); - }, - - moveSplitter : function(s){ - var yes = Ext.SplitBar; - switch(s.placement){ - case yes.LEFT: - s.el.setX(s.resizingEl.getRight()); - break; - case yes.RIGHT: - s.el.setStyle("right", (this.container.getWidth() - s.resizingEl.getLeft()) + "px"); - break; - case yes.TOP: - s.el.setY(s.resizingEl.getBottom()); - break; - case yes.BOTTOM: - s.el.setY(s.resizingEl.getTop() - s.el.getHeight()); - break; - } - } -}; - -/** - * Orientation constant - Create a vertical SplitBar - * @static - * @type Number - */ -Ext.SplitBar.VERTICAL = 1; - -/** - * Orientation constant - Create a horizontal SplitBar - * @static - * @type Number - */ -Ext.SplitBar.HORIZONTAL = 2; - -/** - * Placement constant - The resizing element is to the left of the splitter element - * @static - * @type Number - */ -Ext.SplitBar.LEFT = 1; - -/** - * Placement constant - The resizing element is to the right of the splitter element - * @static - * @type Number - */ -Ext.SplitBar.RIGHT = 2; - -/** - * Placement constant - The resizing element is positioned above the splitter element - * @static - * @type Number - */ -Ext.SplitBar.TOP = 3; - -/** - * Placement constant - The resizing element is positioned under splitter element - * @static - * @type Number - */ -Ext.SplitBar.BOTTOM = 4; -/** - * @class Ext.Container - * @extends Ext.BoxComponent - *

Base class for any {@link Ext.BoxComponent} that may contain other Components. Containers handle the - * basic behavior of containing items, namely adding, inserting and removing items.

- * - *

The most commonly used Container classes are {@link Ext.Panel}, {@link Ext.Window} and {@link Ext.TabPanel}. - * If you do not need the capabilities offered by the aforementioned classes you can create a lightweight - * Container to be encapsulated by an HTML element to your specifications by using the - * {@link Ext.Component#autoEl autoEl} config option. This is a useful technique when creating - * embedded {@link Ext.layout.ColumnLayout column} layouts inside {@link Ext.form.FormPanel FormPanels} - * for example.

- * - *

The code below illustrates both how to explicitly create a Container, and how to implicitly - * create one using the 'container' xtype:


-// explicitly create a Container
-var embeddedColumns = new Ext.Container({
-    autoEl: 'div',  // This is the default
-    layout: 'column',
-    defaults: {
-        // implicitly create Container by specifying xtype
-        xtype: 'container',
-        autoEl: 'div', // This is the default.
-        layout: 'form',
-        columnWidth: 0.5,
-        style: {
-            padding: '10px'
-        }
-    },
-//  The two items below will be Ext.Containers, each encapsulated by a <DIV> element.
-    items: [{
-        items: {
-            xtype: 'datefield',
-            name: 'startDate',
-            fieldLabel: 'Start date'
-        }
-    }, {
-        items: {
-            xtype: 'datefield',
-            name: 'endDate',
-            fieldLabel: 'End date'
-        }
-    }]
-});

- * - *

Layout

- *

Container classes delegate the rendering of child Components to a layout - * manager class which must be configured into the Container using the - * {@link #layout} configuration property.

- *

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

- *

A common mistake is when a developer neglects to specify a - * {@link #layout} (e.g. widgets like GridPanels or - * TreePanels are added to Containers for which no {@link #layout} - * has been specified). If a Container is left to use the default - * {@link Ext.layout.ContainerLayout ContainerLayout} scheme, none of its - * child components will be resized, or changed in any way when the Container - * is resized.

- *

Certain layout managers allow dynamic addition of child components. - * Those that do include {@link Ext.layout.CardLayout}, - * {@link Ext.layout.AnchorLayout}, {@link Ext.layout.FormLayout}, and - * {@link Ext.layout.TableLayout}. For example:


-//  Create the GridPanel.
-var myNewGrid = new Ext.grid.GridPanel({
-    store: myStore,
-    columns: myColumnModel,
-    title: 'Results', // the title becomes the title of the tab
-});
-
-myTabPanel.add(myNewGrid); // {@link Ext.TabPanel} implicitly uses {@link Ext.layout.CardLayout CardLayout}
-myTabPanel.{@link Ext.TabPanel#setActiveTab setActiveTab}(myNewGrid);
- * 

- *

The example above adds a newly created GridPanel to a TabPanel. Note that - * a TabPanel uses {@link Ext.layout.CardLayout} as its layout manager which - * means all its child items are sized to {@link Ext.layout.FitLayout fit} - * exactly into its client area. - *

Overnesting is a common problem. - * An example of overnesting occurs when a GridPanel is added to a TabPanel - * by wrapping the GridPanel inside a wrapping Panel (that has no - * {@link #layout} specified) and then add that wrapping Panel - * to the TabPanel. The point to realize is that a GridPanel is a - * Component which can be added directly to a Container. If the wrapping Panel - * has no {@link #layout} configuration, then the overnested - * GridPanel will not be sized as expected.

- * - *

Adding via remote configuration

- * - *

A server side script can be used to add Components which are generated dynamically on the server. - * An example of adding a GridPanel to a TabPanel where the GridPanel is generated by the server - * based on certain parameters: - *


-// execute an Ajax request to invoke server side script:
-Ext.Ajax.request({
-    url: 'gen-invoice-grid.php',
-    // send additional parameters to instruct server script
-    params: {
-        startDate: Ext.getCmp('start-date').getValue(),
-        endDate: Ext.getCmp('end-date').getValue()
-    },
-    // process the response object to add it to the TabPanel:
-    success: function(xhr) {
-        var newComponent = eval(xhr.responseText); // see discussion below
-        myTabPanel.add(newComponent); // add the component to the TabPanel
-        myTabPanel.setActiveTab(newComponent);
-    },
-    failure: function() {
-        Ext.Msg.alert("Grid create failed", "Server communication failure");
-    }
-});
-
- *

The server script needs to return an executable Javascript statement which, when processed - * using eval(), will return either a config object with an {@link Ext.Component#xtype xtype}, - * or an instantiated Component. The server might return this for example:


-(function() {
-    function formatDate(value){
-        return value ? value.dateFormat('M d, Y') : '';
-    };
-
-    var store = new Ext.data.Store({
-        url: 'get-invoice-data.php',
-        baseParams: {
-            startDate: '01/01/2008',
-            endDate: '01/31/2008'
-        },
-        reader: new Ext.data.JsonReader({
-            record: 'transaction',
-            idProperty: 'id',
-            totalRecords: 'total'
-        }, [
-           'customer',
-           'invNo',
-           {name: 'date', type: 'date', dateFormat: 'm/d/Y'},
-           {name: 'value', type: 'float'}
-        ])
-    });
-
-    var grid = new Ext.grid.GridPanel({
-        title: 'Invoice Report',
-        bbar: new Ext.PagingToolbar(store),
-        store: store,
-        columns: [
-            {header: "Customer", width: 250, dataIndex: 'customer', sortable: true},
-            {header: "Invoice Number", width: 120, dataIndex: 'invNo', sortable: true},
-            {header: "Invoice Date", width: 100, dataIndex: 'date', renderer: formatDate, sortable: true},
-            {header: "Value", width: 120, dataIndex: 'value', renderer: 'usMoney', sortable: true}
-        ],
-    });
-    store.load();
-    return grid;  // return instantiated component
-})();
-
- *

When the above code fragment is passed through the eval function in the success handler - * of the Ajax request, the code is executed by the Javascript processor, and the anonymous function - * runs, and returns the instantiated grid component.

- *

Note: since the code above is generated by a server script, the baseParams for - * the Store, the metadata to allow generation of the Record layout, and the ColumnModel - * can all be generated into the code since these are all known on the server.

- * - * @xtype container - */ -Ext.Container = Ext.extend(Ext.BoxComponent, { - /** - * @cfg {Boolean} monitorResize - * True to automatically monitor window resize events to handle anything that is sensitive to the current size - * of the viewport. This value is typically managed by the chosen {@link #layout} and should not need - * to be set manually. - */ - /** - * @cfg {String/Object} layout - *

*Important: In order for child items to be correctly sized and - * positioned, typically a layout manager must be specified through - * the layout configuration option.

- *

The sizing and positioning of child {@link items} is the responsibility of - * the Container's layout manager which creates and manages the type of layout - * you have in mind. For example:


-new Ext.Window({
-    width:300, height: 300,
-    layout: 'fit', // explicitly set layout manager: override the default (layout:'auto')
-    items: [{
-        title: 'Panel inside a Window'
-    }]
-}).show();
-     * 
- *

If the {@link #layout} configuration is not explicitly specified for - * a general purpose container (e.g. Container or Panel) the - * {@link Ext.layout.ContainerLayout default layout manager} will be used - * which does nothing but render child components sequentially into the - * Container (no sizing or positioning will be performed in this situation). - * Some container classes implicitly specify a default layout - * (e.g. FormPanel specifies layout:'form'). Other specific - * purpose classes internally specify/manage their internal layout (e.g. - * GridPanel, TabPanel, TreePanel, Toolbar, Menu, etc.).

- *

layout may be specified as either as an Object or - * as a String:

    - * - *
  • Specify as an Object
  • - *
      - *
    • Example usage:
    • -
      
      -layout: {
      -    type: 'vbox',
      -    padding: '5',
      -    align: 'left'
      -}
      -
      - * - *
    • type
    • - *

      The layout type to be used for this container. If not specified, - * a default {@link Ext.layout.ContainerLayout} will be created and used.

      - *

      Valid layout type values are:

      - *
        - *
      • {@link Ext.layout.AbsoluteLayout absolute}
      • - *
      • {@link Ext.layout.AccordionLayout accordion}
      • - *
      • {@link Ext.layout.AnchorLayout anchor}
      • - *
      • {@link Ext.layout.ContainerLayout auto}     Default
      • - *
      • {@link Ext.layout.BorderLayout border}
      • - *
      • {@link Ext.layout.CardLayout card}
      • - *
      • {@link Ext.layout.ColumnLayout column}
      • - *
      • {@link Ext.layout.FitLayout fit}
      • - *
      • {@link Ext.layout.FormLayout form}
      • - *
      • {@link Ext.layout.HBoxLayout hbox}
      • - *
      • {@link Ext.layout.MenuLayout menu}
      • - *
      • {@link Ext.layout.TableLayout table}
      • - *
      • {@link Ext.layout.ToolbarLayout toolbar}
      • - *
      • {@link Ext.layout.VBoxLayout vbox}
      • - *
      - * - *
    • Layout specific configuration properties
    • - *

      Additional layout specific configuration properties may also be - * specified. For complete details regarding the valid config options for - * each layout type, see the layout class corresponding to the type - * specified.

      - * - *
    - * - *
  • Specify as a String
  • - *
      - *
    • Example usage:
    • -
      
      -layout: 'vbox',
      -layoutConfig: {
      -    padding: '5',
      -    align: 'left'
      -}
      -
      - *
    • layout
    • - *

      The layout type to be used for this container (see list - * of valid layout type values above).


      - *
    • {@link #layoutConfig}
    • - *

      Additional layout specific configuration properties. For complete - * details regarding the valid config options for each layout type, see the - * layout class corresponding to the layout specified.

      - *
- */ - /** - * @cfg {Object} layoutConfig - * This is a config object containing properties specific to the chosen - * {@link #layout} if {@link #layout} - * has been specified as a string.

- */ - /** - * @cfg {Boolean/Number} bufferResize - * When set to true (50 milliseconds) or a number of milliseconds, the layout assigned for this container will buffer - * the frequency it calculates and does a re-layout of components. This is useful for heavy containers or containers - * with a large quantity of sub-components for which frequent layout calls would be expensive. Defaults to 50. - */ - bufferResize: 50, - - /** - * @cfg {String/Number} activeItem - * A string component id or the numeric index of the component that should be initially activated within the - * container's layout on render. For example, activeItem: 'item-1' or activeItem: 0 (index 0 = the first - * item in the container's collection). activeItem only applies to layout styles that can display - * items one at a time (like {@link Ext.layout.AccordionLayout}, {@link Ext.layout.CardLayout} and - * {@link Ext.layout.FitLayout}). Related to {@link Ext.layout.ContainerLayout#activeItem}. - */ - /** - * @cfg {Object/Array} items - *
** IMPORTANT: be sure to {@link #layout specify a layout} if needed ! **
- *

A single item, or an array of child Components to be added to this container, - * for example:

- *

-// specifying a single item
-items: {...},
-layout: 'fit',    // specify a layout!
-
-// specifying multiple items
-items: [{...}, {...}],
-layout: 'anchor', // specify a layout!
-     * 
- *

Each item may be:

- *
    - *
  • any type of object based on {@link Ext.Component}
  • - *
  • a fully instanciated object or
  • - *
  • an object literal that:
  • - *
      - *
    • has a specified {@link Ext.Component#xtype xtype}
    • - *
    • the {@link Ext.Component#xtype} specified is associated with the Component - * desired and should be chosen from one of the available xtypes as listed - * in {@link Ext.Component}.
    • - *
    • If an {@link Ext.Component#xtype xtype} is not explicitly - * specified, the {@link #defaultType} for that Container is used.
    • - *
    • will be "lazily instanciated", avoiding the overhead of constructing a fully - * instanciated Component object
    • - *
- *

Notes:

- *
    - *
  • Ext uses lazy rendering. Child Components will only be rendered - * should it become necessary. Items are automatically laid out when they are first - * shown (no sizing is done while hidden), or in response to a {@link #doLayout} call.
  • - *
  • Do not specify {@link Ext.Panel#contentEl contentEl}/ - * {@link Ext.Panel#html html} with items.
  • - *
- */ - /** - * @cfg {Object|Function} defaults - *

This option is a means of applying default settings to all added items whether added through the {@link #items} - * config or via the {@link #add} or {@link #insert} methods.

- *

If an added item is a config object, and not an instantiated Component, then the default properties are - * unconditionally applied. If the added item is an instantiated Component, then the default properties are - * applied conditionally so as not to override existing properties in the item.

- *

If the defaults option is specified as a function, then the function will be called using this Container as the - * scope (this reference) and passing the added item as the first parameter. Any resulting object - * from that call is then applied to the item as default properties.

- *

For example, to automatically apply padding to the body of each of a set of - * contained {@link Ext.Panel} items, you could pass: defaults: {bodyStyle:'padding:15px'}.

- *

Usage:


-defaults: {               // defaults are applied to items, not the container
-    autoScroll:true
-},
-items: [
-    {
-        xtype: 'panel',   // defaults do not have precedence over
-        id: 'panel1',     // options in config objects, so the defaults
-        autoScroll: false // will not be applied here, panel1 will be autoScroll:false
-    },
-    new Ext.Panel({       // defaults do have precedence over options
-        id: 'panel2',     // options in components, so the defaults
-        autoScroll: false // will be applied here, panel2 will be autoScroll:true.
-    })
-]
-     * 
- */ - - - /** @cfg {Boolean} autoDestroy - * If true the container will automatically destroy any contained component that is removed from it, else - * destruction must be handled manually (defaults to true). - */ - autoDestroy : true, - - /** @cfg {Boolean} forceLayout - * If true the container will force a layout initially even if hidden or collapsed. This option - * is useful for forcing forms to render in collapsed or hidden containers. (defaults to false). - */ - forceLayout: false, - - /** @cfg {Boolean} hideBorders - * True to hide the borders of each contained component, false to defer to the component's existing - * border settings (defaults to false). - */ - /** @cfg {String} defaultType - *

The default {@link Ext.Component xtype} of child Components to create in this Container when - * a child item is specified as a raw configuration object, rather than as an instantiated Component.

- *

Defaults to 'panel', except {@link Ext.menu.Menu} which defaults to 'menuitem', - * and {@link Ext.Toolbar} and {@link Ext.ButtonGroup} which default to 'button'.

- */ - defaultType : 'panel', - - /** @cfg {String} resizeEvent - * The event to listen to for resizing in layouts. Defaults to 'resize'. - */ - resizeEvent: 'resize', - - /** - * @cfg {Array} bubbleEvents - *

An array of events that, when fired, should be bubbled to any parent container. - * See {@link Ext.util.Observable#enableBubble}. - * Defaults to ['add', 'remove']. - */ - bubbleEvents: ['add', 'remove'], - - // private - initComponent : function(){ - Ext.Container.superclass.initComponent.call(this); - - this.addEvents( - /** - * @event afterlayout - * Fires when the components in this container are arranged by the associated layout manager. - * @param {Ext.Container} this - * @param {ContainerLayout} layout The ContainerLayout implementation for this container - */ - 'afterlayout', - /** - * @event beforeadd - * Fires before any {@link Ext.Component} is added or inserted into the container. - * A handler can return false to cancel the add. - * @param {Ext.Container} this - * @param {Ext.Component} component The component being added - * @param {Number} index The index at which the component will be added to the container's items collection - */ - 'beforeadd', - /** - * @event beforeremove - * Fires before any {@link Ext.Component} is removed from the container. A handler can return - * false to cancel the remove. - * @param {Ext.Container} this - * @param {Ext.Component} component The component being removed - */ - 'beforeremove', - /** - * @event add - * @bubbles - * Fires after any {@link Ext.Component} is added or inserted into the container. - * @param {Ext.Container} this - * @param {Ext.Component} component The component that was added - * @param {Number} index The index at which the component was added to the container's items collection - */ - 'add', - /** - * @event remove - * @bubbles - * Fires after any {@link Ext.Component} is removed from the container. - * @param {Ext.Container} this - * @param {Ext.Component} component The component that was removed - */ - 'remove' - ); - - /** - * The collection of components in this container as a {@link Ext.util.MixedCollection} - * @type MixedCollection - * @property items - */ - var items = this.items; - if(items){ - delete this.items; - this.add(items); - } - }, - - // private - initItems : function(){ - if(!this.items){ - this.items = new Ext.util.MixedCollection(false, this.getComponentId); - this.getLayout(); // initialize the layout - } - }, - - // private - setLayout : function(layout){ - if(this.layout && this.layout != layout){ - this.layout.setContainer(null); - } - this.layout = layout; - this.initItems(); - layout.setContainer(this); - }, - - afterRender: function(){ - // Render this Container, this should be done before setLayout is called which - // will hook onResize - Ext.Container.superclass.afterRender.call(this); - if(!this.layout){ - this.layout = 'auto'; - } - if(Ext.isObject(this.layout) && !this.layout.layout){ - this.layoutConfig = this.layout; - this.layout = this.layoutConfig.type; - } - if(Ext.isString(this.layout)){ - this.layout = new Ext.Container.LAYOUTS[this.layout.toLowerCase()](this.layoutConfig); - } - this.setLayout(this.layout); - - // If a CardLayout, the active item set - if(this.activeItem !== undefined && this.layout.setActiveItem){ - var item = this.activeItem; - delete this.activeItem; - this.layout.setActiveItem(item); - } - - // If we have no ownerCt, render and size all children - if(!this.ownerCt){ - this.doLayout(false, true); - } - - // This is a manually configured flag set by users in conjunction with renderTo. - // Not to be confused with the flag by the same name used in Layouts. - if(this.monitorResize === true){ - Ext.EventManager.onWindowResize(this.doLayout, this, [false]); - } - }, - - /** - *

Returns the Element to be used to contain the child Components of this Container.

- *

An implementation is provided which returns the Container's {@link #getEl Element}, but - * if there is a more complex structure to a Container, this may be overridden to return - * the element into which the {@link #layout layout} renders child Components.

- * @return {Ext.Element} The Element to render child Components into. - */ - getLayoutTarget : function(){ - return this.el; - }, - - // private - used as the key lookup function for the items collection - getComponentId : function(comp){ - return comp.getItemId(); - }, - - /** - *

Adds {@link Ext.Component Component}(s) to this Container.

- *

Description : - *

    - *
  • Fires the {@link #beforeadd} event before adding
  • - *
  • The Container's {@link #defaults default config values} will be applied - * accordingly (see {@link #defaults} for details).
  • - *
  • Fires the {@link #add} event after the component has been added.
  • - *
- *

Notes : - *

    - *
  • If the Container is already rendered when add - * is called, you may need to call {@link #doLayout} to refresh the view which causes - * any unrendered child Components to be rendered. This is required so that you can - * add multiple child components if needed while only refreshing the layout - * once. For example:
    
    -var tb = new {@link Ext.Toolbar}();
    -tb.render(document.body);  // toolbar is rendered
    -tb.add({text:'Button 1'}); // add multiple items ({@link #defaultType} for {@link Ext.Toolbar Toolbar} is 'button')
    -tb.add({text:'Button 2'});
    -tb.{@link #doLayout}();             // refresh the layout
    -     * 
  • - *
  • Warning: Containers directly managed by the BorderLayout layout manager - * may not be removed or added. See the Notes for {@link Ext.layout.BorderLayout BorderLayout} - * for more details.
  • - *
- * @param {...Object/Array} component - *

Either one or more Components to add or an Array of Components to add. See - * {@link #items} for additional information.

- * @return {Ext.Component/Array} The Components that were added. - */ - add : function(comp){ - this.initItems(); - var args = arguments.length > 1; - if(args || Ext.isArray(comp)){ - var result = []; - Ext.each(args ? arguments : comp, function(c){ - result.push(this.add(c)); - }, this); - return result; - } - var c = this.lookupComponent(this.applyDefaults(comp)); - var index = this.items.length; - if(this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false){ - this.items.add(c); - // *onAdded - c.onAdded(this, index); - this.onAdd(c); - this.fireEvent('add', this, c, index); - } - return c; - }, - - onAdd : function(c){ - // Empty template method - }, - - // private - onAdded : function(container, pos) { - //overridden here so we can cascade down, not worth creating a template method. - this.ownerCt = container; - this.initRef(); - //initialize references for child items - this.cascade(function(c){ - c.initRef(); - }); - this.fireEvent('added', this, container, pos); - }, - - /** - * Inserts a Component into this Container at a specified index. Fires the - * {@link #beforeadd} event before inserting, then fires the {@link #add} event after the - * Component has been inserted. - * @param {Number} index The index at which the Component will be inserted - * into the Container's items collection - * @param {Ext.Component} component The child Component to insert.

- * Ext uses lazy rendering, and will only render the inserted Component should - * it become necessary.

- * A Component config object may be passed in order to avoid the overhead of - * constructing a real Component object if lazy rendering might mean that the - * inserted Component will not be rendered immediately. To take advantage of - * this 'lazy instantiation', set the {@link Ext.Component#xtype} config - * property to the registered type of the Component wanted.

- * For a list of all available xtypes, see {@link Ext.Component}. - * @return {Ext.Component} component The Component (or config object) that was - * inserted with the Container's default config values applied. - */ - insert : function(index, comp) { - var args = arguments, - length = args.length, - result = [], - i, c; - - this.initItems(); - - if (length > 2) { - for (i = length - 1; i >= 1; --i) { - result.push(this.insert(index, args[i])); - } - return result; - } - - c = this.lookupComponent(this.applyDefaults(comp)); - index = Math.min(index, this.items.length); - - if (this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false) { - if (c.ownerCt == this) { - this.items.remove(c); - } - this.items.insert(index, c); - c.onAdded(this, index); - this.onAdd(c); - this.fireEvent('add', this, c, index); - } - - return c; - }, - - // private - applyDefaults : function(c){ - var d = this.defaults; - if(d){ - if(Ext.isFunction(d)){ - d = d.call(this, c); - } - if(Ext.isString(c)){ - c = Ext.ComponentMgr.get(c); - Ext.apply(c, d); - }else if(!c.events){ - Ext.applyIf(c.isAction ? c.initialConfig : c, d); - }else{ - Ext.apply(c, d); - } - } - return c; - }, - - // private - onBeforeAdd : function(item){ - if(item.ownerCt){ - item.ownerCt.remove(item, false); - } - if(this.hideBorders === true){ - item.border = (item.border === true); - } - }, - - /** - * Removes a component from this container. Fires the {@link #beforeremove} event before removing, then fires - * the {@link #remove} event after the component has been removed. - * @param {Component/String} component The component reference or id to remove. - * @param {Boolean} autoDestroy (optional) True to automatically invoke the removed Component's {@link Ext.Component#destroy} function. - * Defaults to the value of this Container's {@link #autoDestroy} config. - * @return {Ext.Component} component The Component that was removed. - */ - remove : function(comp, autoDestroy){ - this.initItems(); - var c = this.getComponent(comp); - if(c && this.fireEvent('beforeremove', this, c) !== false){ - this.doRemove(c, autoDestroy); - this.fireEvent('remove', this, c); - } - return c; - }, - - onRemove: function(c){ - // Empty template method - }, - - // private - doRemove: function(c, autoDestroy){ - var l = this.layout, - hasLayout = l && this.rendered; - - if(hasLayout){ - l.onRemove(c); - } - this.items.remove(c); - c.onRemoved(); - this.onRemove(c); - if(autoDestroy === true || (autoDestroy !== false && this.autoDestroy)){ - c.destroy(); - } - if(hasLayout){ - l.afterRemove(c); - } - }, - - /** - * Removes all components from this container. - * @param {Boolean} autoDestroy (optional) True to automatically invoke the removed Component's {@link Ext.Component#destroy} function. - * Defaults to the value of this Container's {@link #autoDestroy} config. - * @return {Array} Array of the destroyed components - */ - removeAll: function(autoDestroy){ - this.initItems(); - var item, rem = [], items = []; - this.items.each(function(i){ - rem.push(i); - }); - for (var i = 0, len = rem.length; i < len; ++i){ - item = rem[i]; - this.remove(item, autoDestroy); - if(item.ownerCt !== this){ - items.push(item); - } - } - return items; - }, - - /** - * Examines this container's {@link #items} property - * and gets a direct child component of this container. - * @param {String/Number} comp This parameter may be any of the following: - *
    - *
  • a String : representing the {@link Ext.Component#itemId itemId} - * or {@link Ext.Component#id id} of the child component
  • - *
  • a Number : representing the position of the child component - * within the {@link #items} property
  • - *
- *

For additional information see {@link Ext.util.MixedCollection#get}. - * @return Ext.Component The component (if found). - */ - getComponent : function(comp){ - if(Ext.isObject(comp)){ - comp = comp.getItemId(); - } - return this.items.get(comp); - }, - - // private - lookupComponent : function(comp){ - if(Ext.isString(comp)){ - return Ext.ComponentMgr.get(comp); - }else if(!comp.events){ - return this.createComponent(comp); - } - return comp; - }, - - // private - createComponent : function(config, defaultType){ - if (config.render) { - return config; - } - // add in ownerCt at creation time but then immediately - // remove so that onBeforeAdd can handle it - var c = Ext.create(Ext.apply({ - ownerCt: this - }, config), defaultType || this.defaultType); - delete c.initialConfig.ownerCt; - delete c.ownerCt; - return c; - }, - - /** - * @private - * We can only lay out if there is a view area in which to layout. - * display:none on the layout target, *or any of its parent elements* will mean it has no view area. - */ - canLayout : function() { - var el = this.getVisibilityEl(); - return el && el.dom && !el.isStyle("display", "none"); - }, - - /** - * Force this container's layout to be recalculated. A call to this function is required after adding a new component - * to an already rendered container, or possibly after changing sizing/position properties of child components. - * @param {Boolean} shallow (optional) True to only calc the layout of this component, and let child components auto - * calc layouts as required (defaults to false, which calls doLayout recursively for each subcontainer) - * @param {Boolean} force (optional) True to force a layout to occur, even if the item is hidden. - * @return {Ext.Container} this - */ - - doLayout : function(shallow, force){ - var rendered = this.rendered, - forceLayout = force || this.forceLayout; - - if(this.collapsed || !this.canLayout()){ - this.deferLayout = this.deferLayout || !shallow; - if(!forceLayout){ - return; - } - shallow = shallow && !this.deferLayout; - } else { - delete this.deferLayout; - } - if(rendered && this.layout){ - this.layout.layout(); - } - if(shallow !== true && this.items){ - var cs = this.items.items; - for(var i = 0, len = cs.length; i < len; i++){ - var c = cs[i]; - if(c.doLayout){ - c.doLayout(false, forceLayout); - } - } - } - if(rendered){ - this.onLayout(shallow, forceLayout); - } - // Initial layout completed - this.hasLayout = true; - delete this.forceLayout; - }, - - onLayout : Ext.emptyFn, - - // private - shouldBufferLayout: function(){ - /* - * Returns true if the container should buffer a layout. - * This is true only if the container has previously been laid out - * and has a parent container that is pending a layout. - */ - var hl = this.hasLayout; - if(this.ownerCt){ - // Only ever buffer if we've laid out the first time and we have one pending. - return hl ? !this.hasLayoutPending() : false; - } - // Never buffer initial layout - return hl; - }, - - // private - hasLayoutPending: function(){ - // Traverse hierarchy to see if any parent container has a pending layout. - var pending = false; - this.ownerCt.bubble(function(c){ - if(c.layoutPending){ - pending = true; - return false; - } - }); - return pending; - }, - - onShow : function(){ - // removes css classes that were added to hide - Ext.Container.superclass.onShow.call(this); - // If we were sized during the time we were hidden, layout. - if(Ext.isDefined(this.deferLayout)){ - delete this.deferLayout; - this.doLayout(true); - } - }, - - /** - * Returns the layout currently in use by the container. If the container does not currently have a layout - * set, a default {@link Ext.layout.ContainerLayout} will be created and set as the container's layout. - * @return {ContainerLayout} layout The container's layout - */ - getLayout : function(){ - if(!this.layout){ - var layout = new Ext.layout.AutoLayout(this.layoutConfig); - this.setLayout(layout); - } - return this.layout; - }, - - // private - beforeDestroy : function(){ - var c; - if(this.items){ - while(c = this.items.first()){ - this.doRemove(c, true); - } - } - if(this.monitorResize){ - Ext.EventManager.removeResizeListener(this.doLayout, this); - } - Ext.destroy(this.layout); - Ext.Container.superclass.beforeDestroy.call(this); - }, - - /** - * Cascades down the component/container heirarchy from this component (called first), calling the specified function with - * each component. The scope (this) of - * function call will be the scope provided or the current component. The arguments to the function - * will be the args provided or the current component. If the function returns false at any point, - * the cascade is stopped on that branch. - * @param {Function} fn The function to call - * @param {Object} scope (optional) The scope of the function (defaults to current component) - * @param {Array} args (optional) The args to call the function with (defaults to passing the current component) - * @return {Ext.Container} this - */ - cascade : function(fn, scope, args){ - if(fn.apply(scope || this, args || [this]) !== false){ - if(this.items){ - var cs = this.items.items; - for(var i = 0, len = cs.length; i < len; i++){ - if(cs[i].cascade){ - cs[i].cascade(fn, scope, args); - }else{ - fn.apply(scope || cs[i], args || [cs[i]]); - } - } - } - } - return this; - }, - - /** - * Find a component under this container at any level by id - * @param {String} id - * @deprecated Fairly useless method, since you can just use Ext.getCmp. Should be removed for 4.0 - * If you need to test if an id belongs to a container, you can use getCmp and findParent*. - * @return Ext.Component - */ - findById : function(id){ - var m = null, - ct = this; - this.cascade(function(c){ - if(ct != c && c.id === id){ - m = c; - return false; - } - }); - return m; - }, - - /** - * Find a component under this container at any level by xtype or class - * @param {String/Class} xtype The xtype string for a component, or the class of the component directly - * @param {Boolean} shallow (optional) False to check whether this Component is descended from the xtype (this is - * the default), or true to check whether this Component is directly of the specified xtype. - * @return {Array} Array of Ext.Components - */ - findByType : function(xtype, shallow){ - return this.findBy(function(c){ - return c.isXType(xtype, shallow); - }); - }, - - /** - * Find a component under this container at any level by property - * @param {String} prop - * @param {String} value - * @return {Array} Array of Ext.Components - */ - find : function(prop, value){ - return this.findBy(function(c){ - return c[prop] === value; - }); - }, - - /** - * Find a component under this container at any level by a custom function. If the passed function returns - * true, the component will be included in the results. The passed function is called with the arguments (component, this container). - * @param {Function} fn The function to call - * @param {Object} scope (optional) - * @return {Array} Array of Ext.Components - */ - findBy : function(fn, scope){ - var m = [], ct = this; - this.cascade(function(c){ - if(ct != c && fn.call(scope || c, c, ct) === true){ - m.push(c); - } - }); - return m; - }, - - /** - * Get a component contained by this container (alias for items.get(key)) - * @param {String/Number} key The index or id of the component - * @deprecated Should be removed in 4.0, since getComponent does the same thing. - * @return {Ext.Component} Ext.Component - */ - get : function(key){ - return this.getComponent(key); - } -}); - -Ext.Container.LAYOUTS = {}; -Ext.reg('container', Ext.Container); -/** - * @class Ext.layout.ContainerLayout - *

This class is intended to be extended or created via the {@link Ext.Container#layout layout} - * configuration property. See {@link Ext.Container#layout} for additional details.

- */ -Ext.layout.ContainerLayout = Ext.extend(Object, { - /** - * @cfg {String} extraCls - *

An optional extra CSS class that will be added to the container. This can be useful for adding - * customized styles to the container or any of its children using standard CSS rules. See - * {@link Ext.Component}.{@link Ext.Component#ctCls ctCls} also.

- *

Note: extraCls defaults to '' except for the following classes - * which assign a value by default: - *

    - *
  • {@link Ext.layout.AbsoluteLayout Absolute Layout} : 'x-abs-layout-item'
  • - *
  • {@link Ext.layout.Box Box Layout} : 'x-box-item'
  • - *
  • {@link Ext.layout.ColumnLayout Column Layout} : 'x-column'
  • - *
- * To configure the above Classes with an extra CSS class append to the default. For example, - * for ColumnLayout:

-     * extraCls: 'x-column custom-class'
-     * 
- *

- */ - /** - * @cfg {Boolean} renderHidden - * True to hide each contained item on render (defaults to false). - */ - - /** - * A reference to the {@link Ext.Component} that is active. For example,

-     * if(myPanel.layout.activeItem.id == 'item-1') { ... }
-     * 
- * activeItem only applies to layout styles that can display items one at a time - * (like {@link Ext.layout.AccordionLayout}, {@link Ext.layout.CardLayout} - * and {@link Ext.layout.FitLayout}). Read-only. Related to {@link Ext.Container#activeItem}. - * @type {Ext.Component} - * @property activeItem - */ - - // private - monitorResize:false, - // private - activeItem : null, - - constructor : function(config){ - this.id = Ext.id(null, 'ext-layout-'); - Ext.apply(this, config); - }, - - type: 'container', - - /* Workaround for how IE measures autoWidth elements. It prefers bottom-up measurements - whereas other browser prefer top-down. We will hide all target child elements before we measure and - put them back to get an accurate measurement. - */ - IEMeasureHack : function(target, viewFlag) { - var tChildren = target.dom.childNodes, tLen = tChildren.length, c, d = [], e, i, ret; - for (i = 0 ; i < tLen ; i++) { - c = tChildren[i]; - e = Ext.get(c); - if (e) { - d[i] = e.getStyle('display'); - e.setStyle({display: 'none'}); - } - } - ret = target ? target.getViewSize(viewFlag) : {}; - for (i = 0 ; i < tLen ; i++) { - c = tChildren[i]; - e = Ext.get(c); - if (e) { - e.setStyle({display: d[i]}); - } - } - return ret; - }, - - // Placeholder for the derived layouts - getLayoutTargetSize : Ext.EmptyFn, - - // private - layout : function(){ - var ct = this.container, target = ct.getLayoutTarget(); - if(!(this.hasLayout || Ext.isEmpty(this.targetCls))){ - target.addClass(this.targetCls); - } - this.onLayout(ct, target); - ct.fireEvent('afterlayout', ct, this); - }, - - // private - onLayout : function(ct, target){ - this.renderAll(ct, target); - }, - - // private - isValidParent : function(c, target){ - return target && c.getPositionEl().dom.parentNode == (target.dom || target); - }, - - // private - renderAll : function(ct, target){ - var items = ct.items.items, i, c, len = items.length; - for(i = 0; i < len; i++) { - c = items[i]; - if(c && (!c.rendered || !this.isValidParent(c, target))){ - this.renderItem(c, i, target); - } - } - }, - - /** - * @private - * Renders the given Component into the target Element. If the Component is already rendered, - * it is moved to the provided target instead. - * @param {Ext.Component} c The Component to render - * @param {Number} position The position within the target to render the item to - * @param {Ext.Element} target The target Element - */ - renderItem : function(c, position, target){ - if (c) { - if (!c.rendered) { - c.render(target, position); - this.configureItem(c); - } else if (!this.isValidParent(c, target)) { - if (Ext.isNumber(position)) { - position = target.dom.childNodes[position]; - } - - target.dom.insertBefore(c.getPositionEl().dom, position || null); - c.container = target; - this.configureItem(c); - } - } - }, - - // private. - // Get all rendered items to lay out. - getRenderedItems: function(ct){ - var t = ct.getLayoutTarget(), cti = ct.items.items, len = cti.length, i, c, items = []; - for (i = 0; i < len; i++) { - if((c = cti[i]).rendered && this.isValidParent(c, t) && c.shouldLayout !== false){ - items.push(c); - } - }; - return items; - }, - - /** - * @private - * Applies extraCls and hides the item if renderHidden is true - */ - configureItem: function(c){ - if (this.extraCls) { - var t = c.getPositionEl ? c.getPositionEl() : c; - t.addClass(this.extraCls); - } - - // If we are forcing a layout, do so *before* we hide so elements have height/width - if (c.doLayout && this.forceLayout) { - c.doLayout(); - } - if (this.renderHidden && c != this.activeItem) { - c.hide(); - } - }, - - onRemove: function(c){ - if(this.activeItem == c){ - delete this.activeItem; - } - if(c.rendered && this.extraCls){ - var t = c.getPositionEl ? c.getPositionEl() : c; - t.removeClass(this.extraCls); - } - }, - - afterRemove: function(c){ - if(c.removeRestore){ - c.removeMode = 'container'; - delete c.removeRestore; - } - }, - - // private - onResize: function(){ - var ct = this.container, - b; - if(ct.collapsed){ - return; - } - if(b = ct.bufferResize && ct.shouldBufferLayout()){ - if(!this.resizeTask){ - this.resizeTask = new Ext.util.DelayedTask(this.runLayout, this); - this.resizeBuffer = Ext.isNumber(b) ? b : 50; - } - ct.layoutPending = true; - this.resizeTask.delay(this.resizeBuffer); - }else{ - this.runLayout(); - } - }, - - runLayout: function(){ - var ct = this.container; - this.layout(); - ct.onLayout(); - delete ct.layoutPending; - }, - - // private - setContainer : function(ct){ - /** - * This monitorResize flag will be renamed soon as to avoid confusion - * with the Container version which hooks onWindowResize to doLayout - * - * monitorResize flag in this context attaches the resize event between - * a container and it's layout - */ - if(this.monitorResize && ct != this.container){ - var old = this.container; - if(old){ - old.un(old.resizeEvent, this.onResize, this); - } - if(ct){ - ct.on(ct.resizeEvent, this.onResize, this); - } - } - this.container = ct; - }, - - /** - * Parses a number or string representing margin sizes into an object. Supports CSS-style margin declarations - * (e.g. 10, "10", "10 10", "10 10 10" and "10 10 10 10" are all valid options and would return the same result) - * @param {Number|String} v The encoded margins - * @return {Object} An object with margin sizes for top, right, bottom and left - */ - parseMargins : function(v){ - if (Ext.isNumber(v)) { - v = v.toString(); - } - var ms = v.split(' '), - len = ms.length; - - if (len == 1) { - ms[1] = ms[2] = ms[3] = ms[0]; - } else if(len == 2) { - ms[2] = ms[0]; - ms[3] = ms[1]; - } else if(len == 3) { - ms[3] = ms[1]; - } - - return { - top :parseInt(ms[0], 10) || 0, - right :parseInt(ms[1], 10) || 0, - bottom:parseInt(ms[2], 10) || 0, - left :parseInt(ms[3], 10) || 0 - }; - }, - - /** - * The {@link Ext.Template Ext.Template} used by Field rendering layout classes (such as - * {@link Ext.layout.FormLayout}) to create the DOM structure of a fully wrapped, - * labeled and styled form Field. A default Template is supplied, but this may be - * overriden to create custom field structures. The template processes values returned from - * {@link Ext.layout.FormLayout#getTemplateArgs}. - * @property fieldTpl - * @type Ext.Template - */ - fieldTpl: (function() { - var t = new Ext.Template( - '
', - '', - '
', - '
', - '
' - ); - t.disableFormats = true; - return t.compile(); - })(), - - /* - * Destroys this layout. This is a template method that is empty by default, but should be implemented - * by subclasses that require explicit destruction to purge event handlers or remove DOM nodes. - * @protected - */ - destroy : function(){ - // Stop any buffered layout tasks - if(this.resizeTask && this.resizeTask.cancel){ - this.resizeTask.cancel(); - } - if(this.container) { - this.container.un(this.container.resizeEvent, this.onResize, this); - } - if(!Ext.isEmpty(this.targetCls)){ - var target = this.container.getLayoutTarget(); - if(target){ - target.removeClass(this.targetCls); - } - } - } -});/** - * @class Ext.layout.AutoLayout - *

The AutoLayout is the default layout manager delegated by {@link Ext.Container} to - * render any child Components when no {@link Ext.Container#layout layout} is configured into - * a {@link Ext.Container Container}.. AutoLayout provides only a passthrough of any layout calls - * to any child containers.

- */ -Ext.layout.AutoLayout = Ext.extend(Ext.layout.ContainerLayout, { - type: 'auto', - - monitorResize: true, - - onLayout : function(ct, target){ - Ext.layout.AutoLayout.superclass.onLayout.call(this, ct, target); - var cs = this.getRenderedItems(ct), len = cs.length, i, c; - for(i = 0; i < len; i++){ - c = cs[i]; - if (c.doLayout){ - // Shallow layout children - c.doLayout(true); - } - } - } -}); - -Ext.Container.LAYOUTS['auto'] = Ext.layout.AutoLayout; -/** - * @class Ext.layout.FitLayout - * @extends Ext.layout.ContainerLayout - *

This is a base class for layouts that contain a single item that automatically expands to fill the layout's - * container. This class is intended to be extended or created via the layout:'fit' {@link Ext.Container#layout} - * config, and should generally not need to be created directly via the new keyword.

- *

FitLayout does not have any direct config options (other than inherited ones). To fit a panel to a container - * using FitLayout, simply set layout:'fit' on the container and add a single panel to it. If the container has - * multiple panels, only the first one will be displayed. Example usage:

- *

-var p = new Ext.Panel({
-    title: 'Fit Layout',
-    layout:'fit',
-    items: {
-        title: 'Inner Panel',
-        html: '<p>This is the inner panel content</p>',
-        border: false
-    }
-});
-
- */ -Ext.layout.FitLayout = Ext.extend(Ext.layout.ContainerLayout, { - // private - monitorResize:true, - - type: 'fit', - - getLayoutTargetSize : function() { - var target = this.container.getLayoutTarget(); - if (!target) { - return {}; - } - // Style Sized (scrollbars not included) - return target.getStyleSize(); - }, - - // private - onLayout : function(ct, target){ - Ext.layout.FitLayout.superclass.onLayout.call(this, ct, target); - if(!ct.collapsed){ - this.setItemSize(this.activeItem || ct.items.itemAt(0), this.getLayoutTargetSize()); - } - }, - - // private - setItemSize : function(item, size){ - if(item && size.height > 0){ // display none? - item.setSize(size); - } - } -}); -Ext.Container.LAYOUTS['fit'] = Ext.layout.FitLayout;/** - * @class Ext.layout.CardLayout - * @extends Ext.layout.FitLayout - *

This layout manages multiple child Components, each fitted to the Container, where only a single child Component can be - * visible at any given time. This layout style is most commonly used for wizards, tab implementations, etc. - * This class is intended to be extended or created via the layout:'card' {@link Ext.Container#layout} config, - * and should generally not need to be created directly via the new keyword.

- *

The CardLayout's focal method is {@link #setActiveItem}. Since only one panel is displayed at a time, - * the only way to move from one Component to the next is by calling setActiveItem, passing the id or index of - * the next panel to display. The layout itself does not provide a user interface for handling this navigation, - * so that functionality must be provided by the developer.

- *

In the following example, a simplistic wizard setup is demonstrated. A button bar is added - * to the footer of the containing panel to provide navigation buttons. The buttons will be handled by a - * common navigation routine -- for this example, the implementation of that routine has been ommitted since - * it can be any type of custom logic. Note that other uses of a CardLayout (like a tab control) would require a - * completely different implementation. For serious implementations, a better approach would be to extend - * CardLayout to provide the custom functionality needed. Example usage:

- *

-var navHandler = function(direction){
-    // This routine could contain business logic required to manage the navigation steps.
-    // It would call setActiveItem as needed, manage navigation button state, handle any
-    // branching logic that might be required, handle alternate actions like cancellation
-    // or finalization, etc.  A complete wizard implementation could get pretty
-    // sophisticated depending on the complexity required, and should probably be
-    // done as a subclass of CardLayout in a real-world implementation.
-};
-
-var card = new Ext.Panel({
-    title: 'Example Wizard',
-    layout:'card',
-    activeItem: 0, // make sure the active item is set on the container config!
-    bodyStyle: 'padding:15px',
-    defaults: {
-        // applied to each contained panel
-        border:false
-    },
-    // just an example of one possible navigation scheme, using buttons
-    bbar: [
-        {
-            id: 'move-prev',
-            text: 'Back',
-            handler: navHandler.createDelegate(this, [-1]),
-            disabled: true
-        },
-        '->', // greedy spacer so that the buttons are aligned to each side
-        {
-            id: 'move-next',
-            text: 'Next',
-            handler: navHandler.createDelegate(this, [1])
-        }
-    ],
-    // the panels (or "cards") within the layout
-    items: [{
-        id: 'card-0',
-        html: '<h1>Welcome to the Wizard!</h1><p>Step 1 of 3</p>'
-    },{
-        id: 'card-1',
-        html: '<p>Step 2 of 3</p>'
-    },{
-        id: 'card-2',
-        html: '<h1>Congratulations!</h1><p>Step 3 of 3 - Complete</p>'
-    }]
-});
-
- */ -Ext.layout.CardLayout = Ext.extend(Ext.layout.FitLayout, { - /** - * @cfg {Boolean} deferredRender - * True to render each contained item at the time it becomes active, false to render all contained items - * as soon as the layout is rendered (defaults to false). If there is a significant amount of content or - * a lot of heavy controls being rendered into panels that are not displayed by default, setting this to - * true might improve performance. - */ - deferredRender : false, - - /** - * @cfg {Boolean} layoutOnCardChange - * True to force a layout of the active item when the active card is changed. Defaults to false. - */ - layoutOnCardChange : false, - - /** - * @cfg {Boolean} renderHidden @hide - */ - // private - renderHidden : true, - - type: 'card', - - /** - * Sets the active (visible) item in the layout. - * @param {String/Number} item The string component id or numeric index of the item to activate - */ - setActiveItem : function(item){ - var ai = this.activeItem, - ct = this.container; - item = ct.getComponent(item); - - // Is this a valid, different card? - if(item && ai != item){ - - // Changing cards, hide the current one - if(ai){ - ai.hide(); - if (ai.hidden !== true) { - return false; - } - ai.fireEvent('deactivate', ai); - } - - var layout = item.doLayout && (this.layoutOnCardChange || !item.rendered); - - // Change activeItem reference - this.activeItem = item; - - // The container is about to get a recursive layout, remove any deferLayout reference - // because it will trigger a redundant layout. - delete item.deferLayout; - - // Show the new component - item.show(); - - this.layout(); - - if(layout){ - item.doLayout(); - } - item.fireEvent('activate', item); - } - }, - - // private - renderAll : function(ct, target){ - if(this.deferredRender){ - this.renderItem(this.activeItem, undefined, target); - }else{ - Ext.layout.CardLayout.superclass.renderAll.call(this, ct, target); - } - } -}); -Ext.Container.LAYOUTS['card'] = Ext.layout.CardLayout; -/** - * @class Ext.layout.AnchorLayout - * @extends Ext.layout.ContainerLayout - *

This is a layout that enables anchoring of contained elements relative to the container's dimensions. - * If the container is resized, all anchored items are automatically rerendered according to their - * {@link #anchor} rules.

- *

This class is intended to be extended or created via the layout:'anchor' {@link Ext.Container#layout} - * config, and should generally not need to be created directly via the new keyword.

- *

AnchorLayout does not have any direct config options (other than inherited ones). By default, - * AnchorLayout will calculate anchor measurements based on the size of the container itself. However, the - * container using the AnchorLayout can supply an anchoring-specific config property of anchorSize. - * If anchorSize is specifed, the layout will use it as a virtual container for the purposes of calculating - * anchor measurements based on it instead, allowing the container to be sized independently of the anchoring - * logic if necessary. For example:

- *

-var viewport = new Ext.Viewport({
-    layout:'anchor',
-    anchorSize: {width:800, height:600},
-    items:[{
-        title:'Item 1',
-        html:'Content 1',
-        width:800,
-        anchor:'right 20%'
-    },{
-        title:'Item 2',
-        html:'Content 2',
-        width:300,
-        anchor:'50% 30%'
-    },{
-        title:'Item 3',
-        html:'Content 3',
-        width:600,
-        anchor:'-100 50%'
-    }]
-});
- * 
- */ -Ext.layout.AnchorLayout = Ext.extend(Ext.layout.ContainerLayout, { - /** - * @cfg {String} anchor - *

This configuation option is to be applied to child items of a container managed by - * this layout (ie. configured with layout:'anchor').


- * - *

This value is what tells the layout how an item should be anchored to the container. items - * added to an AnchorLayout accept an anchoring-specific config property of anchor which is a string - * containing two values: the horizontal anchor value and the vertical anchor value (for example, '100% 50%'). - * The following types of anchor values are supported:

- */ - - // private - monitorResize : true, - - type : 'anchor', - - /** - * @cfg {String} defaultAnchor - * - * default anchor for all child container items applied if no anchor or specific width is set on the child item. Defaults to '100%'. - * - */ - defaultAnchor : '100%', - - parseAnchorRE : /^(r|right|b|bottom)$/i, - - - getLayoutTargetSize : function() { - var target = this.container.getLayoutTarget(), ret = {}; - if (target) { - ret = target.getViewSize(); - - // IE in strict mode will return a width of 0 on the 1st pass of getViewSize. - // Use getStyleSize to verify the 0 width, the adjustment pass will then work properly - // with getViewSize - if (Ext.isIE && Ext.isStrict && ret.width == 0){ - ret = target.getStyleSize(); - } - ret.width -= target.getPadding('lr'); - ret.height -= target.getPadding('tb'); - } - return ret; - }, - - // private - onLayout : function(container, target) { - Ext.layout.AnchorLayout.superclass.onLayout.call(this, container, target); - - var size = this.getLayoutTargetSize(), - containerWidth = size.width, - containerHeight = size.height, - overflow = target.getStyle('overflow'), - components = this.getRenderedItems(container), - len = components.length, - boxes = [], - box, - anchorWidth, - anchorHeight, - component, - anchorSpec, - calcWidth, - calcHeight, - anchorsArray, - totalHeight = 0, - i, - el; - - if(containerWidth < 20 && containerHeight < 20){ - return; - } - - // find the container anchoring size - if(container.anchorSize) { - if(typeof container.anchorSize == 'number') { - anchorWidth = container.anchorSize; - } else { - anchorWidth = container.anchorSize.width; - anchorHeight = container.anchorSize.height; - } - } else { - anchorWidth = container.initialConfig.width; - anchorHeight = container.initialConfig.height; - } - - for(i = 0; i < len; i++) { - component = components[i]; - el = component.getPositionEl(); - - // If a child container item has no anchor and no specific width, set the child to the default anchor size - if (!component.anchor && component.items && !Ext.isNumber(component.width) && !(Ext.isIE6 && Ext.isStrict)){ - component.anchor = this.defaultAnchor; - } - - if(component.anchor) { - anchorSpec = component.anchorSpec; - // cache all anchor values - if(!anchorSpec){ - anchorsArray = component.anchor.split(' '); - component.anchorSpec = anchorSpec = { - right: this.parseAnchor(anchorsArray[0], component.initialConfig.width, anchorWidth), - bottom: this.parseAnchor(anchorsArray[1], component.initialConfig.height, anchorHeight) - }; - } - calcWidth = anchorSpec.right ? this.adjustWidthAnchor(anchorSpec.right(containerWidth) - el.getMargins('lr'), component) : undefined; - calcHeight = anchorSpec.bottom ? this.adjustHeightAnchor(anchorSpec.bottom(containerHeight) - el.getMargins('tb'), component) : undefined; - - if(calcWidth || calcHeight) { - boxes.push({ - component: component, - width: calcWidth || undefined, - height: calcHeight || undefined - }); - } - } - } - for (i = 0, len = boxes.length; i < len; i++) { - box = boxes[i]; - box.component.setSize(box.width, box.height); - } - - if (overflow && overflow != 'hidden' && !this.adjustmentPass) { - var newTargetSize = this.getLayoutTargetSize(); - if (newTargetSize.width != size.width || newTargetSize.height != size.height){ - this.adjustmentPass = true; - this.onLayout(container, target); - } - } - - delete this.adjustmentPass; - }, - - // private - parseAnchor : function(a, start, cstart) { - if (a && a != 'none') { - var last; - // standard anchor - if (this.parseAnchorRE.test(a)) { - var diff = cstart - start; - return function(v){ - if(v !== last){ - last = v; - return v - diff; - } - }; - // percentage - } else if(a.indexOf('%') != -1) { - var ratio = parseFloat(a.replace('%', ''))*.01; - return function(v){ - if(v !== last){ - last = v; - return Math.floor(v*ratio); - } - }; - // simple offset adjustment - } else { - a = parseInt(a, 10); - if (!isNaN(a)) { - 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 - *

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.

- *

ColumnLayout does not have any direct config options (other than inherited ones), but it does support a - * specific config property of columnWidth 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).

- *

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).

- *

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 remaining 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:

- *

-// 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
-    }]
-});
-
- */ -Ext.layout.ColumnLayout = Ext.extend(Ext.layout.ContainerLayout, { - // private - monitorResize:true, - - type: 'column', - - extraCls: 'x-column', - - scrollOffset : 0, - - // private - - targetCls: 'x-column-layout-ct', - - isValidParent : function(c, target){ - return this.innerCt && c.getPositionEl().dom.parentNode == this.innerCt.dom; - }, - - getLayoutTargetSize : function() { - var target = this.container.getLayoutTarget(), ret; - if (target) { - ret = target.getViewSize(); - - // IE in strict mode will return a width of 0 on the 1st pass of getViewSize. - // Use getStyleSize to verify the 0 width, the adjustment pass will then work properly - // with getViewSize - if (Ext.isIE && Ext.isStrict && ret.width == 0){ - ret = target.getStyleSize(); - } - - ret.width -= target.getPadding('lr'); - ret.height -= target.getPadding('tb'); - } - return ret; - }, - - renderAll : function(ct, target) { - if(!this.innerCt){ - // 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'}); - } - Ext.layout.ColumnLayout.superclass.renderAll.call(this, ct, this.innerCt); - }, - - // private - onLayout : function(ct, target){ - var cs = ct.items.items, - len = cs.length, - c, - i, - m, - margins = []; - - this.renderAll(ct, target); - - var size = this.getLayoutTargetSize(); - - if(size.width < 1 && size.height < 1){ // display none? - return; - } - - var w = size.width - this.scrollOffset, - h = size.height, - 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]; - m = c.getPositionEl().getMargins('lr'); - margins[i] = m; - if(!c.columnWidth){ - pw -= (c.getWidth() + m); - } - } - - pw = pw < 0 ? 0 : pw; - - for(i = 0; i < len; i++){ - c = cs[i]; - m = margins[i]; - if(c.columnWidth){ - c.setSize(Math.floor(c.columnWidth * pw) - m); - } - } - - // Browsers differ as to when they account for scrollbars. We need to re-measure to see if the scrollbar - // spaces were accounted for properly. If not, re-layout. - if (Ext.isIE) { - if (i = target.getStyle('overflow') && i != 'hidden' && !this.adjustmentPass) { - var ts = this.getLayoutTargetSize(); - if (ts.width != size.width){ - this.adjustmentPass = true; - this.onLayout(ct, target); - } - } - } - delete this.adjustmentPass; - } - - /** - * @property activeItem - * @hide - */ -}); - -Ext.Container.LAYOUTS['column'] = Ext.layout.ColumnLayout; -/** - * @class Ext.layout.BorderLayout - * @extends Ext.layout.ContainerLayout - *

This is a multi-pane, application-oriented UI layout style that supports multiple - * nested panels, automatic {@link Ext.layout.BorderLayout.Region#split split} bars between - * {@link Ext.layout.BorderLayout.Region#BorderLayout.Region regions} and built-in - * {@link Ext.layout.BorderLayout.Region#collapsible expanding and collapsing} of regions.

- *

This class is intended to be extended or created via the layout:'border' - * {@link Ext.Container#layout} config, and should generally not need to be created directly - * via the new keyword.

- *

BorderLayout does not have any direct config options (other than inherited ones). - * All configuration options available for customizing the BorderLayout are at the - * {@link Ext.layout.BorderLayout.Region} and {@link Ext.layout.BorderLayout.SplitRegion} - * levels.

- *

Example usage:

- *

-var myBorderPanel = new Ext.Panel({
-    {@link Ext.Component#renderTo renderTo}: document.body,
-    {@link Ext.BoxComponent#width width}: 700,
-    {@link Ext.BoxComponent#height height}: 500,
-    {@link Ext.Panel#title title}: 'Border Layout',
-    {@link Ext.Container#layout layout}: 'border',
-    {@link Ext.Container#items items}: [{
-        {@link Ext.Panel#title title}: 'South Region is resizable',
-        {@link Ext.layout.BorderLayout.Region#BorderLayout.Region region}: 'south',     // position for region
-        {@link Ext.BoxComponent#height height}: 100,
-        {@link Ext.layout.BorderLayout.Region#split split}: true,         // enable resizing
-        {@link Ext.SplitBar#minSize minSize}: 75,         // defaults to {@link Ext.layout.BorderLayout.Region#minHeight 50}
-        {@link Ext.SplitBar#maxSize maxSize}: 150,
-        {@link Ext.layout.BorderLayout.Region#margins margins}: '0 5 5 5'
-    },{
-        // xtype: 'panel' implied by default
-        {@link Ext.Panel#title title}: 'West Region is collapsible',
-        {@link Ext.layout.BorderLayout.Region#BorderLayout.Region region}:'west',
-        {@link Ext.layout.BorderLayout.Region#margins margins}: '5 0 0 5',
-        {@link Ext.BoxComponent#width width}: 200,
-        {@link Ext.layout.BorderLayout.Region#collapsible collapsible}: true,   // make collapsible
-        {@link Ext.layout.BorderLayout.Region#cmargins cmargins}: '5 5 0 5', // adjust top margin when collapsed
-        {@link Ext.Component#id id}: 'west-region-container',
-        {@link Ext.Container#layout layout}: 'fit',
-        {@link Ext.Panel#unstyled unstyled}: true
-    },{
-        {@link Ext.Panel#title title}: 'Center Region',
-        {@link Ext.layout.BorderLayout.Region#BorderLayout.Region region}: 'center',     // center region is required, no width/height specified
-        {@link Ext.Component#xtype xtype}: 'container',
-        {@link Ext.Container#layout layout}: 'fit',
-        {@link Ext.layout.BorderLayout.Region#margins margins}: '5 5 0 0'
-    }]
-});
-
- *

Notes:

- */ -Ext.layout.BorderLayout = Ext.extend(Ext.layout.ContainerLayout, { - // private - monitorResize:true, - // private - rendered : false, - - type: 'border', - - targetCls: 'x-border-layout-ct', - - getLayoutTargetSize : function() { - var target = this.container.getLayoutTarget(); - return target ? target.getViewSize() : {}; - }, - - // private - onLayout : function(ct, target){ - var collapsed, i, c, pos, items = ct.items.items, len = items.length; - if(!this.rendered){ - collapsed = []; - for(i = 0; i < len; i++) { - c = items[i]; - pos = c.region; - if(c.collapsed){ - collapsed.push(c); - } - c.collapsed = false; - if(!c.rendered){ - c.render(target, i); - c.getPositionEl().addClass('x-border-panel'); - } - 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 = this.getLayoutTargetSize(); - 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, - centerW = w, centerH = h, centerY = 0, centerX = 0, - n = this.north, s = this.south, west = this.west, e = this.east, c = this.center, - b, m, totalWidth, totalHeight; - if(!c && Ext.layout.BorderLayout.WARN !== false){ - throw 'No center region defined in BorderLayout ' + ct.id; - } - - if(n && n.isVisible()){ - b = n.getSize(); - 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()){ - b = s.getSize(); - m = s.getMargins(); - b.width = w - (m.left+m.right); - b.x = m.left; - totalHeight = (b.height + m.top + m.bottom); - b.y = h - totalHeight + m.top; - centerH -= totalHeight; - s.applyLayout(b); - } - if(west && west.isVisible()){ - b = west.getSize(); - m = west.getMargins(); - b.height = centerH - (m.top+m.bottom); - b.x = m.left; - b.y = centerY + m.top; - totalWidth = (b.width + m.left + m.right); - centerX += totalWidth; - centerW -= totalWidth; - west.applyLayout(b); - } - if(e && e.isVisible()){ - b = e.getSize(); - m = e.getMargins(); - b.height = centerH - (m.top+m.bottom); - 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){ - 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(i = 0, len = collapsed.length; i < len; i++){ - collapsed[i].collapse(false); - } - } - if(Ext.isIE && Ext.isStrict){ // workaround IE strict repainting issue - target.repaint(); - } - // Putting a border layout into an overflowed container is NOT correct and will make a second layout pass necessary. - if (i = target.getStyle('overflow') && i != 'hidden' && !this.adjustmentPass) { - var ts = this.getLayoutTargetSize(); - if (ts.width != size.width || ts.height != size.height){ - this.adjustmentPass = true; - this.onLayout(ct, target); - } - } - delete this.adjustmentPass; - }, - - destroy: function() { - var r = ['north', 'south', 'east', 'west'], i, region; - for (i = 0; i < r.length; i++) { - 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 - *

This is a region of a {@link Ext.layout.BorderLayout BorderLayout} that acts as a subcontainer - * within the layout. Each region has its own {@link Ext.layout.ContainerLayout layout} that is - * independent of other regions and the containing BorderLayout, and can be any of the - * {@link Ext.layout.ContainerLayout valid Ext layout types}.

- *

Region size is managed automatically and cannot be changed by the user -- for - * {@link #split resizable regions}, see {@link Ext.layout.BorderLayout.SplitRegion}.

- * @constructor - * Create a new Region. - * @param {Layout} layout The {@link Ext.layout.BorderLayout BorderLayout} instance that is managing this Region. - * @param {Object} config The configuration options - * @param {String} position The region position. Valid values are: north, south, - * east, west and center. Every {@link Ext.layout.BorderLayout BorderLayout} - * must have a center region for the primary content -- all other regions are optional. - */ -Ext.layout.BorderLayout.Region = function(layout, config, pos){ - Ext.apply(this, config); - this.layout = layout; - this.position = pos; - this.state = {}; - if(typeof this.margins == 'string'){ - this.margins = this.layout.parseMargins(this.margins); - } - this.margins = Ext.applyIf(this.margins || {}, this.defaultMargins); - if(this.collapsible){ - if(typeof this.cmargins == 'string'){ - this.cmargins = this.layout.parseMargins(this.cmargins); - } - if(this.collapseMode == 'mini' && !this.cmargins){ - this.cmargins = {left:0,top:0,right:0,bottom:0}; - }else{ - this.cmargins = Ext.applyIf(this.cmargins || {}, - pos == 'north' || pos == 'south' ? this.defaultNSCMargins : this.defaultEWCMargins); - } - } -}; - -Ext.layout.BorderLayout.Region.prototype = { - /** - * @cfg {Boolean} animFloat - * When a collapsed region's bar is clicked, the region's panel will be displayed as a floated - * panel that will close again once the user mouses out of that panel (or clicks out if - * {@link #autoHide} = false). Setting {@link #animFloat} = false will - * prevent the open and close of these floated panels from being animated (defaults to true). - */ - /** - * @cfg {Boolean} autoHide - * When a collapsed region's bar is clicked, the region's panel will be displayed as a floated - * panel. If autoHide = true, the panel will automatically hide after the user mouses - * out of the panel. If autoHide = false, the panel will continue to display until the - * user clicks outside of the panel (defaults to true). - */ - /** - * @cfg {String} collapseMode - * collapseMode supports two configuration values:

- *

Note: if a collapsible region does not have a title bar, then set collapseMode = - * 'mini' and {@link #split} = true in order for the region to be {@link #collapsible} - * by the user as the expand/collapse tool button (that would go in the title bar) will not be rendered.

- *

See also {@link #cmargins}.

- */ - /** - * @cfg {Object} margins - * An object containing margins to apply to the region when in the expanded state in the - * format:

-{
-    top: (top margin),
-    right: (right margin),
-    bottom: (bottom margin),
-    left: (left margin)
-}
- *

May also be a string containing space-separated, numeric margin values. The order of the - * sides associated with each value matches the way CSS processes margin values:

- *

- *

Defaults to:


-     * {top:0, right:0, bottom:0, left:0}
-     * 
- */ - /** - * @cfg {Object} cmargins - * An object containing margins to apply to the region when in the collapsed state in the - * format:

-{
-    top: (top margin),
-    right: (right margin),
-    bottom: (bottom margin),
-    left: (left margin)
-}
- *

May also be a string containing space-separated, numeric margin values. The order of the - * sides associated with each value matches the way CSS processes margin values.

- *

- */ - /** - * @cfg {Boolean} collapsible - *

true to allow the user to collapse this region (defaults to false). If - * true, an expand/collapse tool button will automatically be rendered into the title - * bar of the region, otherwise the button will not be shown.

- *

Note: that a title bar is required to display the collapse/expand toggle button -- if - * no title is specified for the region's panel, the region will only be collapsible if - * {@link #collapseMode} = 'mini' and {@link #split} = true. - */ - collapsible : false, - /** - * @cfg {Boolean} split - *

true to create a {@link Ext.layout.BorderLayout.SplitRegion SplitRegion} and - * display a 5px wide {@link Ext.SplitBar} between this region and its neighbor, allowing the user to - * resize the regions dynamically. Defaults to false creating a - * {@link Ext.layout.BorderLayout.Region Region}.


- *

Notes:

- */ - split:false, - /** - * @cfg {Boolean} floatable - * true to allow clicking a collapsed region's bar to display the region's panel floated - * above the layout, false to force the user to fully expand a collapsed region by - * clicking the expand button to see it again (defaults to true). - */ - floatable: true, - /** - * @cfg {Number} minWidth - *

The minimum allowable width in pixels for this region (defaults to 50). - * maxWidth may also be specified.


- *

Note: setting the {@link Ext.SplitBar#minSize minSize} / - * {@link Ext.SplitBar#maxSize maxSize} supersedes any specified - * minWidth / maxWidth.

- */ - minWidth:50, - /** - * @cfg {Number} minHeight - * The minimum allowable height in pixels for this region (defaults to 50) - * maxHeight may also be specified.


- *

Note: setting the {@link Ext.SplitBar#minSize minSize} / - * {@link Ext.SplitBar#maxSize maxSize} supersedes any specified - * minHeight / maxHeight.

- */ - minHeight:50, - - // private - defaultMargins : {left:0,top:0,right:0,bottom:0}, - // private - defaultNSCMargins : {left:5,top:5,right:5,bottom:5}, - // private - defaultEWCMargins : {left:5,top:0,right:5,bottom:0}, - floatingZIndex: 100, - - /** - * True if this region is collapsed. Read-only. - * @type Boolean - * @property - */ - isCollapsed : false, - - /** - * This region's panel. Read-only. - * @type Ext.Panel - * @property panel - */ - /** - * This region's layout. Read-only. - * @type Layout - * @property layout - */ - /** - * This region's layout position (north, south, east, west or center). Read-only. - * @type String - * @property position - */ - - // private - render : function(ct, p){ - this.panel = p; - p.el.enableDisplayMode(); - this.targetEl = ct; - this.el = p.el; - - var gs = p.getState, ps = this.position; - p.getState = function(){ - return Ext.apply(gs.call(p) || {}, this.state); - }.createDelegate(this); - - if(ps != 'center'){ - p.allowQueuedExpand = false; - p.on({ - beforecollapse: this.beforeCollapse, - collapse: this.onCollapse, - beforeexpand: this.beforeExpand, - expand: this.onExpand, - hide: this.onHide, - show: this.onShow, - scope: this - }); - if(this.collapsible || this.floatable){ - p.collapseEl = 'el'; - p.slideAnchor = this.getSlideAnchor(); - } - if(p.tools && p.tools.toggle){ - p.tools.toggle.addClass('x-tool-collapse-'+ps); - p.tools.toggle.addClassOnOver('x-tool-collapse-'+ps+'-over'); - } - } - }, - - // private - getCollapsedEl : function(){ - if(!this.collapsedEl){ - if(!this.toolTemplate){ - var tt = new Ext.Template( - '
 
' - ); - 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.expandToolEl = 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.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(); - var el = this.panel.getEl(); - this.originalZIndex = el.getStyle('z-index'); - 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){ - if(this.isSlid){ - this.afterSlideIn(); - } - 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', this.originalZIndex); - 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: {left: (left - * margin), top: (top margin), right: (right margin), bottom: (bottom margin)} - */ - 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: {width: (element width), - * height: (element height)} - */ - 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){ - this.autoHideSlideTask = new Ext.util.DelayedTask(this.slideIn, this); - this.autoHideHd = { - "mouseout": function(e){ - if(!e.within(this.el, true)){ - this.autoHideSlideTask.delay(500); - } - }, - "mouseover" : function(e){ - this.autoHideSlideTask.cancel(); - }, - scope : this - }; - } - this.el.on(this.autoHideHd); - this.collapsedEl.on(this.autoHideHd); - } - }, - - // private - clearAutoHide : function(){ - if(this.autoHide !== false){ - this.el.un("mouseout", this.autoHideHd.mouseout); - this.el.un("mouseover", this.autoHideHd.mouseover); - this.collapsedEl.un("mouseout", this.autoHideHd.mouseout); - this.collapsedEl.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 over the top - * of the center Region 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, dh, pc; - if(ts && ts.toggle){ - ts.toggle.hide(); - } - this.el.show(); - - // Temporarily clear the collapsed flag so we can onResize the panel on the slide - pc = this.panel.collapsed; - this.panel.collapsed = false; - - if(this.position == 'east' || this.position == 'west'){ - // Temporarily clear the deferHeight flag so we can size the height on the slide - dh = this.panel.deferHeight; - this.panel.deferHeight = false; - - this.panel.setSize(undefined, this.collapsedEl.getHeight()); - - // Put the deferHeight flag back after setSize - this.panel.deferHeight = dh; - }else{ - this.panel.setSize(this.collapsedEl.getWidth(), undefined); - } - - // Put the collapsed flag back after onResize - this.panel.collapsed = pc; - - 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; - } - }, - - destroy : function(){ - if (this.autoHideSlideTask && this.autoHideSlideTask.cancel){ - this.autoHideSlideTask.cancel(); - } - Ext.destroyMembers(this, 'miniCollapsedEl', 'collapsedEl', 'expandToolEl'); - } -}; - -/** - * @class Ext.layout.BorderLayout.SplitRegion - * @extends Ext.layout.BorderLayout.Region - *

This is a specialized type of {@link Ext.layout.BorderLayout.Region BorderLayout region} that - * has a built-in {@link Ext.SplitBar} for user resizing of regions. The movement of the split bar - * is configurable to move either {@link #tickSize smooth or incrementally}.

- * @constructor - * Create a new SplitRegion. - * @param {Layout} layout The {@link Ext.layout.BorderLayout BorderLayout} instance that is managing this Region. - * @param {Object} config The configuration options - * @param {String} position The region position. Valid values are: north, south, east, west and center. Every - * BorderLayout must have a center region for the primary content -- all other regions are optional. - */ -Ext.layout.BorderLayout.SplitRegion = function(layout, config, pos){ - Ext.layout.BorderLayout.SplitRegion.superclass.constructor.call(this, layout, config, pos); - // prevent switch - this.applyLayout = this.applyFns[pos]; -}; - -Ext.extend(Ext.layout.BorderLayout.SplitRegion, Ext.layout.BorderLayout.Region, { - /** - * @cfg {Number} tickSize - * The increment, in pixels by which to move this Region's {@link Ext.SplitBar SplitBar}. - * By default, the {@link Ext.SplitBar SplitBar} moves smoothly. - */ - /** - * @cfg {String} splitTip - * The tooltip to display when the user hovers over a - * {@link Ext.layout.BorderLayout.Region#collapsible non-collapsible} region's split bar - * (defaults to "Drag to resize."). Only applies if - * {@link #useSplitTips} = true. - */ - splitTip : "Drag to resize.", - /** - * @cfg {String} collapsibleSplitTip - * The tooltip to display when the user hovers over a - * {@link Ext.layout.BorderLayout.Region#collapsible collapsible} region's split bar - * (defaults to "Drag to resize. Double click to hide."). Only applies if - * {@link #useSplitTips} = true. - */ - collapsibleSplitTip : "Drag to resize. Double click to hide.", - /** - * @cfg {Boolean} useSplitTips - * true to display a tooltip when the user hovers over a region's split bar - * (defaults to false). The tooltip text will be the value of either - * {@link #splitTip} or {@link #collapsibleSplitTip} as appropriate. - */ - useSplitTips : false, - - // private - splitSettings : { - north : { - orientation: Ext.SplitBar.VERTICAL, - placement: Ext.SplitBar.TOP, - maxFn : 'getVMaxSize', - minProp: 'minHeight', - maxProp: 'maxHeight' - }, - south : { - orientation: Ext.SplitBar.VERTICAL, - placement: Ext.SplitBar.BOTTOM, - maxFn : 'getVMaxSize', - minProp: 'minHeight', - maxProp: 'maxHeight' - }, - east : { - orientation: Ext.SplitBar.HORIZONTAL, - placement: Ext.SplitBar.RIGHT, - maxFn : 'getHMaxSize', - minProp: 'minWidth', - maxProp: 'maxWidth' - }, - west : { - orientation: Ext.SplitBar.HORIZONTAL, - placement: Ext.SplitBar.LEFT, - maxFn : 'getHMaxSize', - minProp: 'minWidth', - maxProp: 'maxWidth' - } - }, - - // private - applyFns : { - west : function(box){ - if(this.isCollapsed){ - return this.applyLayoutCollapsed(box); - } - var sd = this.splitEl.dom, s = sd.style; - this.panel.setPosition(box.x, box.y); - var sw = sd.offsetWidth; - s.left = (box.x+box.width-sw)+'px'; - s.top = (box.y)+'px'; - s.height = Math.max(0, box.height)+'px'; - this.panel.setSize(box.width-sw, box.height); - }, - east : function(box){ - if(this.isCollapsed){ - return this.applyLayoutCollapsed(box); - } - var sd = this.splitEl.dom, s = sd.style; - var sw = sd.offsetWidth; - this.panel.setPosition(box.x+sw, box.y); - s.left = (box.x)+'px'; - s.top = (box.y)+'px'; - s.height = Math.max(0, box.height)+'px'; - this.panel.setSize(box.width-sw, box.height); - }, - north : function(box){ - if(this.isCollapsed){ - return this.applyLayoutCollapsed(box); - } - var sd = this.splitEl.dom, s = sd.style; - var sh = sd.offsetHeight; - this.panel.setPosition(box.x, box.y); - s.left = (box.x)+'px'; - s.top = (box.y+box.height-sh)+'px'; - s.width = Math.max(0, box.width)+'px'; - this.panel.setSize(box.width, box.height-sh); - }, - south : function(box){ - if(this.isCollapsed){ - return this.applyLayoutCollapsed(box); - } - var sd = this.splitEl.dom, s = sd.style; - var sh = sd.offsetHeight; - this.panel.setPosition(box.x, box.y+sh); - s.left = (box.x)+'px'; - s.top = (box.y)+'px'; - s.width = Math.max(0, box.width)+'px'; - this.panel.setSize(box.width, box.height-sh); - } - }, - - // private - render : function(ct, p){ - Ext.layout.BorderLayout.SplitRegion.superclass.render.call(this, ct, p); - - var ps = this.position; - - this.splitEl = ct.createChild({ - cls: "x-layout-split x-layout-split-"+ps, html: " ", - id: this.panel.id + '-xsplit' - }); - - if(this.collapseMode == 'mini'){ - this.miniSplitEl = this.splitEl.createChild({ - cls: "x-layout-mini x-layout-mini-"+ps, html: " " - }); - this.miniSplitEl.addClassOnOver('x-layout-mini-over'); - this.miniSplitEl.on('click', this.onCollapseClick, this, {stopEvent:true}); - } - - var s = this.splitSettings[ps]; - - this.split = new Ext.SplitBar(this.splitEl.dom, p.el, s.orientation); - this.split.tickSize = this.tickSize; - this.split.placement = s.placement; - this.split.getMaximumSize = this[s.maxFn].createDelegate(this); - this.split.minSize = this.minSize || this[s.minProp]; - this.split.on("beforeapply", this.onSplitMove, this); - this.split.useShim = this.useShim === true; - this.maxSize = this.maxSize || this[s.maxProp]; - - if(p.hidden){ - this.splitEl.hide(); - } - - if(this.useSplitTips){ - this.splitEl.dom.title = this.collapsible ? this.collapsibleSplitTip : this.splitTip; - } - if(this.collapsible){ - this.splitEl.on("dblclick", this.onCollapseClick, this); - } - }, - - //docs inherit from superclass - getSize : function(){ - if(this.isCollapsed){ - return this.collapsedEl.getSize(); - } - var s = this.panel.getSize(); - if(this.position == 'north' || this.position == 'south'){ - s.height += this.splitEl.dom.offsetHeight; - }else{ - s.width += this.splitEl.dom.offsetWidth; - } - return s; - }, - - // private - getHMaxSize : function(){ - var cmax = this.maxSize || 10000; - var center = this.layout.center; - return Math.min(cmax, (this.el.getWidth()+center.el.getWidth())-center.getMinWidth()); - }, - - // private - getVMaxSize : function(){ - var cmax = this.maxSize || 10000; - var center = this.layout.center; - return Math.min(cmax, (this.el.getHeight()+center.el.getHeight())-center.getMinHeight()); - }, - - // private - onSplitMove : function(split, newSize){ - var s = this.panel.getSize(); - this.lastSplitSize = newSize; - if(this.position == 'north' || this.position == 'south'){ - this.panel.setSize(s.width, newSize); - this.state.height = newSize; - }else{ - this.panel.setSize(newSize, s.height); - this.state.width = newSize; - } - this.layout.layout(); - this.panel.saveState(); - return false; - }, - - /** - * Returns a reference to the split bar in use by this region. - * @return {Ext.SplitBar} The split bar - */ - getSplitBar : function(){ - return this.split; - }, - - // inherit docs - destroy : function() { - Ext.destroy(this.miniSplitEl, this.split, this.splitEl); - Ext.layout.BorderLayout.SplitRegion.superclass.destroy.call(this); - } -}); - -Ext.Container.LAYOUTS['border'] = Ext.layout.BorderLayout; -/** - * @class Ext.layout.FormLayout - * @extends Ext.layout.AnchorLayout - *

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.

- * - *

This layout manager is used when a Container is configured with the layout:'form' - * {@link Ext.Container#layout layout} config option, and should generally not need to be created directly - * via the new keyword. See {@link Ext.Container#layout} for additional details.

- * - *

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.

- * - *

A {@link Ext.Container Container} using the FormLayout layout manager (e.g. - * {@link Ext.form.FormPanel} or specifying layout:'form') can also accept the following - * layout-specific config properties:

- * - *

Any Component (including Fields) managed by FormLayout accepts the following as a config option: - *

- * - *

Any Component managed by FormLayout may be rendered as a form field (with an associated label) by - * configuring it with a non-null {@link Ext.Component#fieldLabel fieldLabel}. Components configured - * in this way may be configured with the following options which affect the way the FormLayout renders them: - *

- * - *

Example usage:

- *

-// 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
-});
-
- */ -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 container 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 - */ - - /** - * @cfg {Boolean} trackLabels - * True to show/hide the field label when the field is hidden. Defaults to true. - */ - trackLabels: true, - - type: 'form', - - onRemove: function(c){ - Ext.layout.FormLayout.superclass.onRemove.call(this, c); - if(this.trackLabels){ - c.un('show', this.onFieldShow, this); - c.un('hide', this.onFieldHide, this); - } - // check for itemCt, since we may be removing a fieldset or something similar - var el = c.getPositionEl(), - ct = c.getItemCt && c.getItemCt(); - if (c.rendered && ct) { - if (el && el.dom) { - el.insertAfter(ct); - } - Ext.destroy(ct); - Ext.destroyMembers(c, 'label', 'itemCt'); - if (c.customItemCt) { - Ext.destroyMembers(c, 'getItemCt', 'customItemCt'); - } - } - }, - - // 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){ - Ext.apply(this, { - labelStyle: 'display:none', - elementStyle: 'padding-left:0;', - labelAdjust: 0 - }); - }else{ - this.labelSeparator = Ext.isDefined(ct.labelSeparator) ? ct.labelSeparator : this.labelSeparator; - ct.labelWidth = ct.labelWidth || 100; - if(Ext.isNumber(ct.labelWidth)){ - var pad = Ext.isNumber(ct.labelPad) ? ct.labelPad : 5; - Ext.apply(this, { - labelAdjust: ct.labelWidth + pad, - labelStyle: 'width:' + ct.labelWidth + 'px;', - elementStyle: 'padding-left:' + (ct.labelWidth + pad) + 'px' - }); - } - if(ct.labelAlign == 'top'){ - Ext.apply(this, { - labelStyle: 'width:auto;', - labelAdjust: 0, - elementStyle: 'padding-left:0;' - }); - } - } - }, - - // private - isHide: function(c){ - return c.hideLabel || this.container.hideLabels; - }, - - onFieldShow: function(c){ - c.getItemCt().removeClass('x-hide-' + c.hideMode); - - // Composite fields will need to layout after the container is made visible - if (c.isComposite) { - c.doLayout(); - } - }, - - onFieldHide: function(c){ - c.getItemCt().addClass('x-hide-' + c.hideMode); - }, - - //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:


-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>'
-);
-
- *

This may be specified to produce a different DOM structure when rendering form Fields.

- *

A description of the properties within the template follows:

- *

Also see {@link #getTemplateArgs}

- */ - - /** - * @private - * - */ - renderItem : function(c, position, target){ - if(c && (c.isFormField || c.fieldLabel) && c.inputType != 'hidden'){ - var args = this.getTemplateArgs(c); - if(Ext.isNumber(position)){ - position = target.dom.childNodes[position] || null; - } - if(position){ - c.itemCt = this.fieldTpl.insertBefore(position, args, true); - }else{ - c.itemCt = this.fieldTpl.append(target, args, true); - } - if(!c.getItemCt){ - // Non form fields don't have getItemCt, apply it here - // This will get cleaned up in onRemove - Ext.apply(c, { - getItemCt: function(){ - return c.itemCt; - }, - customItemCt: true - }); - } - c.label = c.getItemCt().child('label.x-form-item-label'); - if(!c.rendered){ - c.render('x-form-el-' + c.id); - }else if(!this.isValidParent(c, target)){ - Ext.fly('x-form-el-' + c.id).appendChild(c.getPositionEl()); - } - if(this.trackLabels){ - if(c.hidden){ - this.onFieldHide(c); - } - c.on({ - scope: this, - show: this.onFieldShow, - hide: this.onFieldHide - }); - } - this.configureItem(c); - }else { - Ext.layout.FormLayout.superclass.renderItem.apply(this, arguments); - } - }, - - /** - *

Provides template arguments for rendering the fully wrapped, labeled and styled form Field.

- *

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:

- * @param (Ext.form.Field} field The {@link Ext.form.Field Field} being rendered. - * @return {Object} 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, - itemCls : (field.itemCls || this.container.itemCls || '') + (field.hideLabel ? ' x-hide-label' : ''), - clearCls : field.clearCls || 'x-form-clear-left', - labelStyle : this.getLabelStyle(field.labelStyle), - elementStyle : this.elementStyle || '', - labelSeparator: noLabelSep ? '' : (Ext.isDefined(field.labelSeparator) ? field.labelSeparator : this.labelSeparator) - }; - }, - - // private - adjustWidthAnchor: function(value, c){ - if(c.label && !this.isHide(c) && (this.container.labelAlign != 'top')){ - var adjust = Ext.isIE6 || (Ext.isIE && !Ext.isStrict); - return value - this.labelAdjust + (adjust ? -3 : 0); - } - return value; - }, - - adjustHeightAnchor : function(value, c){ - if(c.label && !this.isHide(c) && (this.container.labelAlign == 'top')){ - return value - c.label.getHeight(); - } - return value; - }, - - // private - isValidParent : function(c, target){ - return target && this.container.getEl().contains(c.getPositionEl()); - } - - /** - * @property activeItem - * @hide - */ -}); - -Ext.Container.LAYOUTS['form'] = Ext.layout.FormLayout; -/** - * @class Ext.layout.AccordionLayout - * @extends Ext.layout.FitLayout - *

This is a layout that manages multiple Panels in an expandable accordion style such that only - * one Panel can be expanded at any given time. Each Panel has built-in support for expanding and collapsing.

- *

Note: Only Ext.Panels and all subclasses of Ext.Panel may be used in an accordion layout Container.

- *

This class is intended to be extended or created via the {@link Ext.Container#layout layout} - * configuration property. See {@link Ext.Container#layout} for additional details.

- *

Example usage:

- *

-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>'
-    }]
-});
-
- */ -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 - * Experimental. 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. This is NOT compatible with "animate:true" (defaults to false). - */ - activeOnTop : false, - - type: 'accordion', - - 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.setActiveItem(c, true); - }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); - }, - - onRemove: function(c){ - Ext.layout.AccordionLayout.superclass.onRemove.call(this, c); - if(c.rendered){ - c.header.removeClass('x-accordion-hd'); - } - c.un('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.setActive(p); - if(this.activeOnTop){ - p.el.dom.parentNode.insertBefore(p.el.dom, p.el.dom.parentNode.firstChild); - } - // Items have been hidden an possibly rearranged, we need to get the container size again. - this.layout(); - }, - - // private - setItemSize : function(item, size){ - if(this.fill && item){ - var hh = 0, i, ct = this.getRenderedItems(this.container), len = ct.length, p; - // Add up all the header heights - for (i = 0; i < len; i++) { - if((p = ct[i]) != item && !p.hidden){ - hh += p.header.getHeight(); - } - }; - // Subtract the header heights from the container size - size.height -= hh; - // Call setSize on the container to set the correct height. For Panels, deferedHeight - // will simply store this size for when the expansion is done. - 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){ - this.setActive(item, true); - }, - - // private - setActive : function(item, expand){ - var ai = this.activeItem; - item = this.container.getComponent(item); - if(ai != item){ - if(item.rendered && item.collapsed && expand){ - item.expand(); - }else{ - if(ai){ - ai.fireEvent('deactivate', ai); - } - this.activeItem = item; - item.fireEvent('activate', item); - } - } - } -}); -Ext.Container.LAYOUTS.accordion = Ext.layout.AccordionLayout; - -//backwards compat -Ext.layout.Accordion = Ext.layout.AccordionLayout;/** - * @class Ext.layout.TableLayout - * @extends Ext.layout.ContainerLayout - *

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.

- *

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:

- * - *

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:

- *

-// 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>'
-    }]
-});
-
- */ -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, - - type: 'table', - - targetCls: 'x-table-layout-ct', - - /** - * @cfg {Object} tableAttrs - *

An object containing properties which are added to the {@link Ext.DomHelper DomHelper} specification - * used to create the layout's <table> element. Example:


-{
-    xtype: 'panel',
-    layout: 'table',
-    layoutConfig: {
-        tableAttrs: {
-            style: {
-                width: '100%'
-            }
-        },
-        columns: 3
-    }
-}
- */ - 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){ - // Ensure we have our inner table to get cells to render into. - if(!this.table){ - this.table = target.createChild( - Ext.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true); - } - if(c && !c.rendered){ - c.render(this.getNextCell(c)); - this.configureItem(c); - }else if(c && !this.isValidParent(c, target)){ - var container = this.getNextCell(c); - container.insertBefore(c.getPositionEl().dom, null); - c.container = Ext.get(container); - this.configureItem(c); - } - }, - - // private - isValidParent : function(c, target){ - return c.getPositionEl().up('table', 5).dom.parentNode === (target.dom || target); - }, - - destroy: function(){ - delete this.table; - Ext.layout.TableLayout.superclass.destroy.call(this); - } - - /** - * @property activeItem - * @hide - */ -}); - -Ext.Container.LAYOUTS['table'] = Ext.layout.TableLayout;/** - * @class Ext.layout.AbsoluteLayout - * @extends Ext.layout.AnchorLayout - *

This is a layout that inherits the anchoring of {@link Ext.layout.AnchorLayout} and adds the - * ability for x/y positioning using the standard x and y component config options.

- *

This class is intended to be extended or created via the {@link Ext.Container#layout layout} - * configuration property. See {@link Ext.Container#layout} for additional details.

- *

Example usage:

- *

-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
-    }]
-});
-
- */ -Ext.layout.AbsoluteLayout = Ext.extend(Ext.layout.AnchorLayout, { - - extraCls: 'x-abs-layout-item', - - type: 'absolute', - - 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 - *

Base Class for HBoxLayout and VBoxLayout Classes. Generally it should not need to be used directly.

- */ -Ext.layout.BoxLayout = Ext.extend(Ext.layout.ContainerLayout, { - /** - * @cfg {Object} defaultMargins - *

If the individual contained items do not have a margins - * property specified, the default margins from this property will be - * applied to each item.

- *

This property may be specified as an object containing margins - * to apply in the format:


-{
-    top: (top margin),
-    right: (right margin),
-    bottom: (bottom margin),
-    left: (left margin)
-}
- *

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:

- *
- *

Defaults to:


-     * {top:0, right:0, bottom:0, left:0}
-     * 
- */ - defaultMargins : {left:0,top:0,right:0,bottom:0}, - /** - * @cfg {String} padding - *

Sets the padding to be applied to all child items managed by this layout.

- *

This property must be specified as a string containing - * space-separated, numeric padding values. The order of the sides associated - * with each value matches the way CSS processes padding values:

- *
- *

Defaults to: "0"

- */ - padding : '0', - // documented in subclasses - pack : 'start', - - // private - monitorResize : true, - type: 'box', - scrollOffset : 0, - extraCls : 'x-box-item', - targetCls : 'x-box-layout-ct', - innerCls : 'x-box-inner', - - constructor : function(config){ - Ext.layout.BoxLayout.superclass.constructor.call(this, config); - - if (Ext.isString(this.defaultMargins)) { - this.defaultMargins = this.parseMargins(this.defaultMargins); - } - - var handler = this.overflowHandler; - - if (typeof handler == 'string') { - handler = { - type: handler - }; - } - - var handlerType = 'none'; - if (handler && handler.type != undefined) { - handlerType = handler.type; - } - - var constructor = Ext.layout.boxOverflow[handlerType]; - if (constructor[this.type]) { - constructor = constructor[this.type]; - } - - this.overflowHandler = new constructor(this, handler); - }, - - /** - * @private - * Runs the child box calculations and caches them in childBoxCache. Subclasses can used these cached values - * when laying out - */ - onLayout: function(container, target) { - Ext.layout.BoxLayout.superclass.onLayout.call(this, container, target); - - var tSize = this.getLayoutTargetSize(), - items = this.getVisibleItems(container), - calcs = this.calculateChildBoxes(items, tSize), - boxes = calcs.boxes, - meta = calcs.meta; - - //invoke the overflow handler, if one is configured - if (tSize.width > 0) { - var handler = this.overflowHandler, - method = meta.tooNarrow ? 'handleOverflow' : 'clearOverflow'; - - var results = handler[method](calcs, tSize); - - if (results) { - if (results.targetSize) { - tSize = results.targetSize; - } - - if (results.recalculate) { - items = this.getVisibleItems(container); - calcs = this.calculateChildBoxes(items, tSize); - boxes = calcs.boxes; - } - } - } - - /** - * @private - * @property layoutTargetLastSize - * @type Object - * Private cache of the last measured size of the layout target. This should never be used except by - * BoxLayout subclasses during their onLayout run. - */ - this.layoutTargetLastSize = tSize; - - /** - * @private - * @property childBoxCache - * @type Array - * Array of the last calculated height, width, top and left positions of each visible rendered component - * within the Box layout. - */ - this.childBoxCache = calcs; - - this.updateInnerCtSize(tSize, calcs); - this.updateChildBoxes(boxes); - - // Putting a box layout into an overflowed container is NOT correct and will make a second layout pass necessary. - this.handleTargetOverflow(tSize, container, target); - }, - - /** - * Resizes and repositions each child component - * @param {Array} boxes The box measurements - */ - updateChildBoxes: function(boxes) { - for (var i = 0, length = boxes.length; i < length; i++) { - var box = boxes[i], - comp = box.component; - - if (box.dirtySize) { - comp.setSize(box.width, box.height); - } - // Don't set positions to NaN - if (isNaN(box.left) || isNaN(box.top)) { - continue; - } - - comp.setPosition(box.left, box.top); - } - }, - - /** - * @private - * Called by onRender just before the child components are sized and positioned. This resizes the innerCt - * to make sure all child items fit within it. We call this before sizing the children because if our child - * items are larger than the previous innerCt size the browser will insert scrollbars and then remove them - * again immediately afterwards, giving a performance hit. - * Subclasses should provide an implementation. - * @param {Object} currentSize The current height and width of the innerCt - * @param {Array} calculations The new box calculations of all items to be laid out - */ - updateInnerCtSize: function(tSize, calcs) { - var align = this.align, - padding = this.padding, - width = tSize.width, - height = tSize.height; - - if (this.type == 'hbox') { - var innerCtWidth = width, - innerCtHeight = calcs.meta.maxHeight + padding.top + padding.bottom; - - if (align == 'stretch') { - innerCtHeight = height; - } else if (align == 'middle') { - innerCtHeight = Math.max(height, innerCtHeight); - } - } else { - var innerCtHeight = height, - innerCtWidth = calcs.meta.maxWidth + padding.left + padding.right; - - if (align == 'stretch') { - innerCtWidth = width; - } else if (align == 'center') { - innerCtWidth = Math.max(width, innerCtWidth); - } - } - - this.innerCt.setSize(innerCtWidth || undefined, innerCtHeight || undefined); - }, - - /** - * @private - * This should be called after onLayout of any BoxLayout subclass. If the target's overflow is not set to 'hidden', - * we need to lay out a second time because the scrollbars may have modified the height and width of the layout - * target. Having a Box layout inside such a target is therefore not recommended. - * @param {Object} previousTargetSize The size and height of the layout target before we just laid out - * @param {Ext.Container} container The container - * @param {Ext.Element} target The target element - */ - handleTargetOverflow: function(previousTargetSize, container, target) { - var overflow = target.getStyle('overflow'); - - if (overflow && overflow != 'hidden' &&!this.adjustmentPass) { - var newTargetSize = this.getLayoutTargetSize(); - if (newTargetSize.width != previousTargetSize.width || newTargetSize.height != previousTargetSize.height){ - this.adjustmentPass = true; - this.onLayout(container, target); - } - } - - delete this.adjustmentPass; - }, - - // private - isValidParent : function(c, target) { - return this.innerCt && c.getPositionEl().dom.parentNode == this.innerCt.dom; - }, - - /** - * @private - * Returns all items that are both rendered and visible - * @return {Array} All matching items - */ - getVisibleItems: function(ct) { - var ct = ct || this.container, - t = ct.getLayoutTarget(), - cti = ct.items.items, - len = cti.length, - - i, c, items = []; - - for (i = 0; i < len; i++) { - if((c = cti[i]).rendered && this.isValidParent(c, t) && c.hidden !== true && c.collapsed !== true && c.shouldLayout !== false){ - items.push(c); - } - } - - return items; - }, - - // private - renderAll : function(ct, target) { - if (!this.innerCt) { - // the innerCt prevents wrapping and shuffling while the container is resizing - this.innerCt = target.createChild({cls:this.innerCls}); - this.padding = this.parseMargins(this.padding); - } - Ext.layout.BoxLayout.superclass.renderAll.call(this, ct, this.innerCt); - }, - - getLayoutTargetSize : function() { - var target = this.container.getLayoutTarget(), ret; - - if (target) { - ret = target.getViewSize(); - - // IE in strict mode will return a width of 0 on the 1st pass of getViewSize. - // Use getStyleSize to verify the 0 width, the adjustment pass will then work properly - // with getViewSize - if (Ext.isIE && Ext.isStrict && ret.width == 0){ - ret = target.getStyleSize(); - } - - ret.width -= target.getPadding('lr'); - ret.height -= target.getPadding('tb'); - } - - return ret; - }, - - // private - renderItem : function(c) { - if(Ext.isString(c.margins)){ - c.margins = this.parseMargins(c.margins); - }else if(!c.margins){ - c.margins = this.defaultMargins; - } - Ext.layout.BoxLayout.superclass.renderItem.apply(this, arguments); - }, - - /** - * @private - */ - destroy: function() { - Ext.destroy(this.overflowHandler); - - Ext.layout.BoxLayout.superclass.destroy.apply(this, arguments); - } -}); - - - -Ext.ns('Ext.layout.boxOverflow'); - -/** - * @class Ext.layout.boxOverflow.None - * @extends Object - * Base class for Box Layout overflow handlers. These specialized classes are invoked when a Box Layout - * (either an HBox or a VBox) has child items that are either too wide (for HBox) or too tall (for VBox) - * for its container. - */ - -Ext.layout.boxOverflow.None = Ext.extend(Object, { - constructor: function(layout, config) { - this.layout = layout; - - Ext.apply(this, config || {}); - }, - - handleOverflow: Ext.emptyFn, - - clearOverflow: Ext.emptyFn -}); - - -Ext.layout.boxOverflow.none = Ext.layout.boxOverflow.None; -/** - * @class Ext.layout.boxOverflow.Menu - * @extends Ext.layout.boxOverflow.None - * Description - */ -Ext.layout.boxOverflow.Menu = Ext.extend(Ext.layout.boxOverflow.None, { - /** - * @cfg afterCls - * @type String - * CSS class added to the afterCt element. This is the element that holds any special items such as scrollers, - * which must always be present at the rightmost edge of the Container - */ - afterCls: 'x-strip-right', - - /** - * @property noItemsMenuText - * @type String - * HTML fragment to render into the toolbar overflow menu if there are no items to display - */ - noItemsMenuText : '
(None)
', - - constructor: function(layout) { - Ext.layout.boxOverflow.Menu.superclass.constructor.apply(this, arguments); - - /** - * @property menuItems - * @type Array - * Array of all items that are currently hidden and should go into the dropdown menu - */ - this.menuItems = []; - }, - - /** - * @private - * Creates the beforeCt, innerCt and afterCt elements if they have not already been created - * @param {Ext.Container} container The Container attached to this Layout instance - * @param {Ext.Element} target The target Element - */ - createInnerElements: function() { - if (!this.afterCt) { - this.afterCt = this.layout.innerCt.insertSibling({cls: this.afterCls}, 'before'); - } - }, - - /** - * @private - */ - clearOverflow: function(calculations, targetSize) { - var newWidth = targetSize.width + (this.afterCt ? this.afterCt.getWidth() : 0), - items = this.menuItems; - - this.hideTrigger(); - - for (var index = 0, length = items.length; index < length; index++) { - items.pop().component.show(); - } - - return { - targetSize: { - height: targetSize.height, - width : newWidth - } - }; - }, - - /** - * @private - */ - showTrigger: function() { - this.createMenu(); - this.menuTrigger.show(); - }, - - /** - * @private - */ - hideTrigger: function() { - if (this.menuTrigger != undefined) { - this.menuTrigger.hide(); - } - }, - - /** - * @private - * Called before the overflow menu is shown. This constructs the menu's items, caching them for as long as it can. - */ - beforeMenuShow: function(menu) { - var items = this.menuItems, - len = items.length, - item, - prev; - - var needsSep = function(group, item){ - return group.isXType('buttongroup') && !(item instanceof Ext.Toolbar.Separator); - }; - - this.clearMenu(); - menu.removeAll(); - - for (var i = 0; i < len; i++) { - item = items[i].component; - - if (prev && (needsSep(item, prev) || needsSep(prev, item))) { - menu.add('-'); - } - - this.addComponentToMenu(menu, item); - prev = item; - } - - // put something so the menu isn't empty if no compatible items found - if (menu.items.length < 1) { - menu.add(this.noItemsMenuText); - } - }, - - /** - * @private - * Returns a menu config for a given component. This config is used to create a menu item - * to be added to the expander menu - * @param {Ext.Component} component The component to create the config for - * @param {Boolean} hideOnClick Passed through to the menu item - */ - createMenuConfig : function(component, hideOnClick){ - var config = Ext.apply({}, component.initialConfig), - group = component.toggleGroup; - - Ext.copyTo(config, component, [ - 'iconCls', 'icon', 'itemId', 'disabled', 'handler', 'scope', 'menu' - ]); - - Ext.apply(config, { - text : component.overflowText || component.text, - hideOnClick: hideOnClick - }); - - if (group || component.enableToggle) { - Ext.apply(config, { - group : group, - checked: component.pressed, - listeners: { - checkchange: function(item, checked){ - component.toggle(checked); - } - } - }); - } - - delete config.ownerCt; - delete config.xtype; - delete config.id; - - return config; - }, - - /** - * @private - * Adds the given Toolbar item to the given menu. Buttons inside a buttongroup are added individually. - * @param {Ext.menu.Menu} menu The menu to add to - * @param {Ext.Component} component The component to add - */ - addComponentToMenu : function(menu, component) { - if (component instanceof Ext.Toolbar.Separator) { - menu.add('-'); - - } else if (Ext.isFunction(component.isXType)) { - if (component.isXType('splitbutton')) { - menu.add(this.createMenuConfig(component, true)); - - } else if (component.isXType('button')) { - menu.add(this.createMenuConfig(component, !component.menu)); - - } else if (component.isXType('buttongroup')) { - component.items.each(function(item){ - this.addComponentToMenu(menu, item); - }, this); - } - } - }, - - /** - * @private - * Deletes the sub-menu of each item in the expander menu. Submenus are created for items such as - * splitbuttons and buttongroups, where the Toolbar item cannot be represented by a single menu item - */ - clearMenu : function(){ - var menu = this.moreMenu; - if (menu && menu.items) { - menu.items.each(function(item){ - delete item.menu; - }); - } - }, - - /** - * @private - * Creates the overflow trigger and menu used when enableOverflow is set to true and the items - * in the layout are too wide to fit in the space available - */ - createMenu: function() { - if (!this.menuTrigger) { - this.createInnerElements(); - - /** - * @private - * @property menu - * @type Ext.menu.Menu - * The expand menu - holds items for every item that cannot be shown - * because the container is currently not large enough. - */ - this.menu = new Ext.menu.Menu({ - ownerCt : this.layout.container, - listeners: { - scope: this, - beforeshow: this.beforeMenuShow - } - }); - - /** - * @private - * @property menuTrigger - * @type Ext.Button - * The expand button which triggers the overflow menu to be shown - */ - this.menuTrigger = new Ext.Button({ - iconCls : 'x-toolbar-more-icon', - cls : 'x-toolbar-more', - menu : this.menu, - renderTo: this.afterCt - }); - } - }, - - /** - * @private - */ - destroy: function() { - Ext.destroy(this.menu, this.menuTrigger); - } -}); - -Ext.layout.boxOverflow.menu = Ext.layout.boxOverflow.Menu; - - -/** - * @class Ext.layout.boxOverflow.HorizontalMenu - * @extends Ext.layout.boxOverflow.Menu - * Description - */ -Ext.layout.boxOverflow.HorizontalMenu = Ext.extend(Ext.layout.boxOverflow.Menu, { - - constructor: function() { - Ext.layout.boxOverflow.HorizontalMenu.superclass.constructor.apply(this, arguments); - - var me = this, - layout = me.layout, - origFunction = layout.calculateChildBoxes; - - layout.calculateChildBoxes = function(visibleItems, targetSize) { - var calcs = origFunction.apply(layout, arguments), - meta = calcs.meta, - items = me.menuItems; - - //calculate the width of the items currently hidden solely because there is not enough space - //to display them - var hiddenWidth = 0; - for (var index = 0, length = items.length; index < length; index++) { - hiddenWidth += items[index].width; - } - - meta.minimumWidth += hiddenWidth; - meta.tooNarrow = meta.minimumWidth > targetSize.width; - - return calcs; - }; - }, - - handleOverflow: function(calculations, targetSize) { - this.showTrigger(); - - var newWidth = targetSize.width - this.afterCt.getWidth(), - boxes = calculations.boxes, - usedWidth = 0, - recalculate = false; - - //calculate the width of all visible items and any spare width - for (var index = 0, length = boxes.length; index < length; index++) { - usedWidth += boxes[index].width; - } - - var spareWidth = newWidth - usedWidth, - showCount = 0; - - //see if we can re-show any of the hidden components - for (var index = 0, length = this.menuItems.length; index < length; index++) { - var hidden = this.menuItems[index], - comp = hidden.component, - width = hidden.width; - - if (width < spareWidth) { - comp.show(); - - spareWidth -= width; - showCount ++; - recalculate = true; - } else { - break; - } - } - - if (recalculate) { - this.menuItems = this.menuItems.slice(showCount); - } else { - for (var i = boxes.length - 1; i >= 0; i--) { - var item = boxes[i].component, - right = boxes[i].left + boxes[i].width; - - if (right >= newWidth) { - this.menuItems.unshift({ - component: item, - width : boxes[i].width - }); - - item.hide(); - } else { - break; - } - } - } - - if (this.menuItems.length == 0) { - this.hideTrigger(); - } - - return { - targetSize: { - height: targetSize.height, - width : newWidth - }, - recalculate: recalculate - }; - } -}); - -Ext.layout.boxOverflow.menu.hbox = Ext.layout.boxOverflow.HorizontalMenu;/** - * @class Ext.layout.boxOverflow.Scroller - * @extends Ext.layout.boxOverflow.None - * Description - */ -Ext.layout.boxOverflow.Scroller = Ext.extend(Ext.layout.boxOverflow.None, { - /** - * @cfg animateScroll - * @type Boolean - * True to animate the scrolling of items within the layout (defaults to true, ignored if enableScroll is false) - */ - animateScroll: true, - - /** - * @cfg scrollIncrement - * @type Number - * The number of pixels to scroll by on scroller click (defaults to 100) - */ - scrollIncrement: 100, - - /** - * @cfg wheelIncrement - * @type Number - * The number of pixels to increment on mouse wheel scrolling (defaults to 3). - */ - wheelIncrement: 3, - - /** - * @cfg scrollRepeatInterval - * @type Number - * Number of milliseconds between each scroll while a scroller button is held down (defaults to 400) - */ - scrollRepeatInterval: 400, - - /** - * @cfg scrollDuration - * @type Number - * Number of seconds that each scroll animation lasts (defaults to 0.4) - */ - scrollDuration: 0.4, - - /** - * @cfg beforeCls - * @type String - * CSS class added to the beforeCt element. This is the element that holds any special items such as scrollers, - * which must always be present at the leftmost edge of the Container - */ - beforeCls: 'x-strip-left', - - /** - * @cfg afterCls - * @type String - * CSS class added to the afterCt element. This is the element that holds any special items such as scrollers, - * which must always be present at the rightmost edge of the Container - */ - afterCls: 'x-strip-right', - - /** - * @cfg scrollerCls - * @type String - * CSS class added to both scroller elements if enableScroll is used - */ - scrollerCls: 'x-strip-scroller', - - /** - * @cfg beforeScrollerCls - * @type String - * CSS class added to the left scroller element if enableScroll is used - */ - beforeScrollerCls: 'x-strip-scroller-left', - - /** - * @cfg afterScrollerCls - * @type String - * CSS class added to the right scroller element if enableScroll is used - */ - afterScrollerCls: 'x-strip-scroller-right', - - /** - * @private - * Sets up an listener to scroll on the layout's innerCt mousewheel event - */ - createWheelListener: function() { - this.layout.innerCt.on({ - scope : this, - mousewheel: function(e) { - e.stopEvent(); - - this.scrollBy(e.getWheelDelta() * this.wheelIncrement * -1, false); - } - }); - }, - - /** - * @private - * Most of the heavy lifting is done in the subclasses - */ - handleOverflow: function(calculations, targetSize) { - this.createInnerElements(); - this.showScrollers(); - }, - - /** - * @private - */ - clearOverflow: function() { - this.hideScrollers(); - }, - - /** - * @private - * Shows the scroller elements in the beforeCt and afterCt. Creates the scrollers first if they are not already - * present. - */ - showScrollers: function() { - this.createScrollers(); - - this.beforeScroller.show(); - this.afterScroller.show(); - - this.updateScrollButtons(); - }, - - /** - * @private - * Hides the scroller elements in the beforeCt and afterCt - */ - hideScrollers: function() { - if (this.beforeScroller != undefined) { - this.beforeScroller.hide(); - this.afterScroller.hide(); - } - }, - - /** - * @private - * Creates the clickable scroller elements and places them into the beforeCt and afterCt - */ - createScrollers: function() { - if (!this.beforeScroller && !this.afterScroller) { - var before = this.beforeCt.createChild({ - cls: String.format("{0} {1} ", this.scrollerCls, this.beforeScrollerCls) - }); - - var after = this.afterCt.createChild({ - cls: String.format("{0} {1}", this.scrollerCls, this.afterScrollerCls) - }); - - before.addClassOnOver(this.beforeScrollerCls + '-hover'); - after.addClassOnOver(this.afterScrollerCls + '-hover'); - - before.setVisibilityMode(Ext.Element.DISPLAY); - after.setVisibilityMode(Ext.Element.DISPLAY); - - this.beforeRepeater = new Ext.util.ClickRepeater(before, { - interval: this.scrollRepeatInterval, - handler : this.scrollLeft, - scope : this - }); - - this.afterRepeater = new Ext.util.ClickRepeater(after, { - interval: this.scrollRepeatInterval, - handler : this.scrollRight, - scope : this - }); - - /** - * @property beforeScroller - * @type Ext.Element - * The left scroller element. Only created when needed. - */ - this.beforeScroller = before; - - /** - * @property afterScroller - * @type Ext.Element - * The left scroller element. Only created when needed. - */ - this.afterScroller = after; - } - }, - - /** - * @private - */ - destroy: function() { - Ext.destroy(this.beforeScroller, this.afterScroller, this.beforeRepeater, this.afterRepeater, this.beforeCt, this.afterCt); - }, - - /** - * @private - * Scrolls left or right by the number of pixels specified - * @param {Number} delta Number of pixels to scroll to the right by. Use a negative number to scroll left - */ - scrollBy: function(delta, animate) { - this.scrollTo(this.getScrollPosition() + delta, animate); - }, - - /** - * @private - * Normalizes an item reference, string id or numerical index into a reference to the item - * @param {Ext.Component|String|Number} item The item reference, id or index - * @return {Ext.Component} The item - */ - getItem: function(item) { - if (Ext.isString(item)) { - item = Ext.getCmp(item); - } else if (Ext.isNumber(item)) { - item = this.items[item]; - } - - return item; - }, - - /** - * @private - * @return {Object} Object passed to scrollTo when scrolling - */ - getScrollAnim: function() { - return { - duration: this.scrollDuration, - callback: this.updateScrollButtons, - scope : this - }; - }, - - /** - * @private - * Enables or disables each scroller button based on the current scroll position - */ - updateScrollButtons: function() { - if (this.beforeScroller == undefined || this.afterScroller == undefined) { - return; - } - - var beforeMeth = this.atExtremeBefore() ? 'addClass' : 'removeClass', - afterMeth = this.atExtremeAfter() ? 'addClass' : 'removeClass', - beforeCls = this.beforeScrollerCls + '-disabled', - afterCls = this.afterScrollerCls + '-disabled'; - - this.beforeScroller[beforeMeth](beforeCls); - this.afterScroller[afterMeth](afterCls); - this.scrolling = false; - }, - - /** - * @private - * Returns true if the innerCt scroll is already at its left-most point - * @return {Boolean} True if already at furthest left point - */ - atExtremeBefore: function() { - return this.getScrollPosition() === 0; - }, - - /** - * @private - * Scrolls to the left by the configured amount - */ - scrollLeft: function(animate) { - this.scrollBy(-this.scrollIncrement, animate); - }, - - /** - * @private - * Scrolls to the right by the configured amount - */ - scrollRight: function(animate) { - this.scrollBy(this.scrollIncrement, animate); - }, - - /** - * Scrolls to the given component. - * @param {String|Number|Ext.Component} item The item to scroll to. Can be a numerical index, component id - * or a reference to the component itself. - * @param {Boolean} animate True to animate the scrolling - */ - scrollToItem: function(item, animate) { - item = this.getItem(item); - - if (item != undefined) { - var visibility = this.getItemVisibility(item); - - if (!visibility.fullyVisible) { - var box = item.getBox(true, true), - newX = box.x; - - if (visibility.hiddenRight) { - newX -= (this.layout.innerCt.getWidth() - box.width); - } - - this.scrollTo(newX, animate); - } - } - }, - - /** - * @private - * For a given item in the container, return an object with information on whether the item is visible - * with the current innerCt scroll value. - * @param {Ext.Component} item The item - * @return {Object} Values for fullyVisible, hiddenLeft and hiddenRight - */ - getItemVisibility: function(item) { - var box = this.getItem(item).getBox(true, true), - itemLeft = box.x, - itemRight = box.x + box.width, - scrollLeft = this.getScrollPosition(), - scrollRight = this.layout.innerCt.getWidth() + scrollLeft; - - return { - hiddenLeft : itemLeft < scrollLeft, - hiddenRight : itemRight > scrollRight, - fullyVisible: itemLeft > scrollLeft && itemRight < scrollRight - }; - } -}); - -Ext.layout.boxOverflow.scroller = Ext.layout.boxOverflow.Scroller; - - -/** - * @class Ext.layout.boxOverflow.VerticalScroller - * @extends Ext.layout.boxOverflow.Scroller - * Description - */ -Ext.layout.boxOverflow.VerticalScroller = Ext.extend(Ext.layout.boxOverflow.Scroller, { - scrollIncrement: 75, - wheelIncrement : 2, - - handleOverflow: function(calculations, targetSize) { - Ext.layout.boxOverflow.VerticalScroller.superclass.handleOverflow.apply(this, arguments); - - return { - targetSize: { - height: targetSize.height - (this.beforeCt.getHeight() + this.afterCt.getHeight()), - width : targetSize.width - } - }; - }, - - /** - * @private - * Creates the beforeCt and afterCt elements if they have not already been created - */ - createInnerElements: function() { - var target = this.layout.innerCt; - - //normal items will be rendered to the innerCt. beforeCt and afterCt allow for fixed positioning of - //special items such as scrollers or dropdown menu triggers - if (!this.beforeCt) { - this.beforeCt = target.insertSibling({cls: this.beforeCls}, 'before'); - this.afterCt = target.insertSibling({cls: this.afterCls}, 'after'); - - this.createWheelListener(); - } - }, - - /** - * @private - * Scrolls to the given position. Performs bounds checking. - * @param {Number} position The position to scroll to. This is constrained. - * @param {Boolean} animate True to animate. If undefined, falls back to value of this.animateScroll - */ - scrollTo: function(position, animate) { - var oldPosition = this.getScrollPosition(), - newPosition = position.constrain(0, this.getMaxScrollBottom()); - - if (newPosition != oldPosition && !this.scrolling) { - if (animate == undefined) { - animate = this.animateScroll; - } - - this.layout.innerCt.scrollTo('top', newPosition, animate ? this.getScrollAnim() : false); - - if (animate) { - this.scrolling = true; - } else { - this.scrolling = false; - this.updateScrollButtons(); - } - } - }, - - /** - * Returns the current scroll position of the innerCt element - * @return {Number} The current scroll position - */ - getScrollPosition: function(){ - return parseInt(this.layout.innerCt.dom.scrollTop, 10) || 0; - }, - - /** - * @private - * Returns the maximum value we can scrollTo - * @return {Number} The max scroll value - */ - getMaxScrollBottom: function() { - return this.layout.innerCt.dom.scrollHeight - this.layout.innerCt.getHeight(); - }, - - /** - * @private - * Returns true if the innerCt scroll is already at its right-most point - * @return {Boolean} True if already at furthest right point - */ - atExtremeAfter: function() { - return this.getScrollPosition() >= this.getMaxScrollBottom(); - } -}); - -Ext.layout.boxOverflow.scroller.vbox = Ext.layout.boxOverflow.VerticalScroller; - - -/** - * @class Ext.layout.boxOverflow.HorizontalScroller - * @extends Ext.layout.boxOverflow.Scroller - * Description - */ -Ext.layout.boxOverflow.HorizontalScroller = Ext.extend(Ext.layout.boxOverflow.Scroller, { - handleOverflow: function(calculations, targetSize) { - Ext.layout.boxOverflow.HorizontalScroller.superclass.handleOverflow.apply(this, arguments); - - return { - targetSize: { - height: targetSize.height, - width : targetSize.width - (this.beforeCt.getWidth() + this.afterCt.getWidth()) - } - }; - }, - - /** - * @private - * Creates the beforeCt and afterCt elements if they have not already been created - */ - createInnerElements: function() { - var target = this.layout.innerCt; - - //normal items will be rendered to the innerCt. beforeCt and afterCt allow for fixed positioning of - //special items such as scrollers or dropdown menu triggers - if (!this.beforeCt) { - this.afterCt = target.insertSibling({cls: this.afterCls}, 'before'); - this.beforeCt = target.insertSibling({cls: this.beforeCls}, 'before'); - - this.createWheelListener(); - } - }, - - /** - * @private - * Scrolls to the given position. Performs bounds checking. - * @param {Number} position The position to scroll to. This is constrained. - * @param {Boolean} animate True to animate. If undefined, falls back to value of this.animateScroll - */ - scrollTo: function(position, animate) { - var oldPosition = this.getScrollPosition(), - newPosition = position.constrain(0, this.getMaxScrollRight()); - - if (newPosition != oldPosition && !this.scrolling) { - if (animate == undefined) { - animate = this.animateScroll; - } - - this.layout.innerCt.scrollTo('left', newPosition, animate ? this.getScrollAnim() : false); - - if (animate) { - this.scrolling = true; - } else { - this.scrolling = false; - this.updateScrollButtons(); - } - } - }, - - /** - * Returns the current scroll position of the innerCt element - * @return {Number} The current scroll position - */ - getScrollPosition: function(){ - return parseInt(this.layout.innerCt.dom.scrollLeft, 10) || 0; - }, - - /** - * @private - * Returns the maximum value we can scrollTo - * @return {Number} The max scroll value - */ - getMaxScrollRight: function() { - return this.layout.innerCt.dom.scrollWidth - this.layout.innerCt.getWidth(); - }, - - /** - * @private - * Returns true if the innerCt scroll is already at its right-most point - * @return {Boolean} True if already at furthest right point - */ - atExtremeAfter: function() { - return this.getScrollPosition() >= this.getMaxScrollRight(); - } -}); - -Ext.layout.boxOverflow.scroller.hbox = Ext.layout.boxOverflow.HorizontalScroller;/** - * @class Ext.layout.HBoxLayout - * @extends Ext.layout.BoxLayout - *

A layout that arranges items horizontally across a Container. This layout optionally divides available horizontal - * space between child items containing a numeric flex configuration.

- * This layout may also be used to set the heights of child items by configuring it with the {@link #align} option. - */ -Ext.layout.HBoxLayout = 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: - *