X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/6746dc89c47ed01b165cc1152533605f97eb8e8d..f562e4c6e5fac7bcb445985b99acbea4d706e6f0:/src/panel/Panel.js diff --git a/src/panel/Panel.js b/src/panel/Panel.js index b314f306..af479cbf 100644 --- a/src/panel/Panel.js +++ b/src/panel/Panel.js @@ -13,91 +13,110 @@ If you are unsure which license is appropriate for your use, please contact the */ /** - * @class Ext.panel.Panel - * @extends Ext.panel.AbstractPanel - *
Panel is a container that has specific functionality and structural components that make - * it the perfect building block for application-oriented user interfaces.
- *Panels are, by virtue of their inheritance from {@link Ext.container.Container}, capable - * of being configured with a {@link Ext.container.Container#layout layout}, and containing child Components.
- *When either specifying child {@link Ext.Component#items items} of a Panel, or dynamically {@link Ext.container.Container#add adding} Components
- * to a Panel, remember to consider how you wish the Panel to arrange those child elements, and whether
- * those child elements need to be sized using one of Ext's built-in {@link Ext.container.Container#layout layout}
schemes. By
- * default, Panels use the {@link Ext.layout.container.Auto Auto} scheme. This simply renders
- * child components, appending them one after the other inside the Container, and does not apply any sizing
- * at all.
A Panel may also contain {@link #bbar bottom} and {@link #tbar top} toolbars, along with separate - * {@link #header}, {@link #footer} and {@link #body} sections (see {@link #frame} for additional - * information).
- *Panel also provides built-in {@link #collapsible collapsible, expandable} and {@link #closable} behavior. - * Panels can be easily dropped into any {@link Ext.container.Container Container} or layout, and the - * layout and rendering pipeline is {@link Ext.container.Container#add completely managed by the framework}.
- *Note: By default, the {@link #closable close}
header tool destroys the Panel resulting in removal of the Panel
- * and the destruction of any descendant Components. This makes the Panel object, and all its descendants unusable. To enable the close
- * tool to simply hide a Panel for later re-use, configure the Panel with {@link #closeAction closeAction: 'hide'}
.
Usually, Panels are used as constituents within an application, in which case, they would be used as child items of Containers, - * and would themselves use Ext.Components as child {@link #items}. However to illustrate simply rendering a Panel into the document, - * here's how to do it:
-Ext.create('Ext.panel.Panel', {
- title: 'Hello',
- width: 200,
- html: '<p>World!</p>',
- renderTo: document.body
-});
-
- * A more realistic scenario is a Panel created to house input fields which will not be rendered, but used as a constituent part of a Container:
-var filterPanel = Ext.create('Ext.panel.Panel', {
- bodyPadding: 5, // Don't want content to crunch against the borders
- title: 'Filters',
- items: [{
- xtype: 'datefield',
- fieldLabel: 'Start date'
- }, {
- xtype: 'datefield',
- fieldLabel: 'End date'
- }]
-});
-
- * Note that the Panel above is not configured to render into the document, nor is it configured with a size or position. In a real world scenario, - * the Container into which the Panel is added will use a {@link #layout} to render, size and position its child Components.
- *Panels will often use specific {@link #layout}s to provide an application with shape and structure by containing and arranging child - * Components:
-var resultsPanel = Ext.create('Ext.panel.Panel', {
- title: 'Results',
- width: 600,
- height: 400,
- renderTo: document.body,
- layout: {
- type: 'vbox', // Arrange child items vertically
- align: 'stretch', // Each takes up full width
- padding: 5
- },
- items: [{ // Results grid specified as a config object with an xtype of 'grid'
- xtype: 'grid',
- columns: [{header: 'Column One'}], // One header just for show. There's no data,
- store: Ext.create('Ext.data.ArrayStore', {}), // A dummy empty data store
- flex: 1 // Use 1/3 of Container's height (hint to Box layout)
- }, {
- xtype: 'splitter' // A splitter between the two child items
- }, { // Details Panel specified as a config object (no xtype defaults to 'panel').
- title: 'Details',
- bodyPadding: 5,
- items: [{
- fieldLabel: 'Data item',
- xtype: 'textfield'
- }], // An array of form fields
- flex: 2 // Use 2/3 of Container's height (hint to Box layout)
- }]
-});
-
- * The example illustrates one possible method of displaying search results. The Panel contains a grid with the resulting data arranged
- * in rows. Each selected row may be displayed in detail in the Panel below. The {@link Ext.layout.container.VBox vbox} layout is used
- * to arrange the two vertically. It is configured to stretch child items horizontally to full width. Child items may either be configured
- * with a numeric height, or with a flex
value to distribute available space proportionately.
- * This Panel itself may be a child item of, for exaple, a {@link Ext.tab.Panel} which will size its child items to fit within its - * content area.
- *Using these techniques, as long as the layout is chosen and configured correctly, an application may have any level of - * nested containment, all dynamically sized according to configuration, the user's preference and available browser size.
+ * + * A Panel may also contain {@link #bbar bottom} and {@link #tbar top} toolbars, along with separate {@link + * Ext.panel.Header header}, {@link #fbar footer} and body sections. + * + * Panel also provides built-in {@link #collapsible collapsible, expandable} and {@link #closable} behavior. Panels can + * be easily dropped into any {@link Ext.container.Container Container} or layout, and the layout and rendering pipeline + * is {@link Ext.container.Container#add completely managed by the framework}. + * + * **Note:** By default, the `{@link #closable close}` header tool _destroys_ the Panel resulting in removal of the + * Panel and the destruction of any descendant Components. This makes the Panel object, and all its descendants + * **unusable**. To enable the close tool to simply _hide_ a Panel for later re-use, configure the Panel with + * `{@link #closeAction closeAction}: 'hide'`. + * + * Usually, Panels are used as constituents within an application, in which case, they would be used as child items of + * Containers, and would themselves use Ext.Components as child {@link #items}. However to illustrate simply rendering a + * Panel into the document, here's how to do it: + * + * @example + * Ext.create('Ext.panel.Panel', { + * title: 'Hello', + * width: 200, + * html: 'World!
', + * renderTo: Ext.getBody() + * }); + * + * A more realistic scenario is a Panel created to house input fields which will not be rendered, but used as a + * constituent part of a Container: + * + * @example + * var filterPanel = Ext.create('Ext.panel.Panel', { + * bodyPadding: 5, // Don't want content to crunch against the borders + * width: 300, + * title: 'Filters', + * items: [{ + * xtype: 'datefield', + * fieldLabel: 'Start date' + * }, { + * xtype: 'datefield', + * fieldLabel: 'End date' + * }], + * renderTo: Ext.getBody() + * }); + * + * Note that the Panel above is not configured to render into the document, nor is it configured with a size or + * position. In a real world scenario, the Container into which the Panel is added will use a {@link #layout} to render, + * size and position its child Components. + * + * Panels will often use specific {@link #layout}s to provide an application with shape and structure by containing and + * arranging child Components: + * + * @example + * var resultsPanel = Ext.create('Ext.panel.Panel', { + * title: 'Results', + * width: 600, + * height: 400, + * renderTo: Ext.getBody(), + * layout: { + * type: 'vbox', // Arrange child items vertically + * align: 'stretch', // Each takes up full width + * padding: 5 + * }, + * items: [{ // Results grid specified as a config object with an xtype of 'grid' + * xtype: 'grid', + * columns: [{header: 'Column One'}], // One header just for show. There's no data, + * store: Ext.create('Ext.data.ArrayStore', {}), // A dummy empty data store + * flex: 1 // Use 1/3 of Container's height (hint to Box layout) + * }, { + * xtype: 'splitter' // A splitter between the two child items + * }, { // Details Panel specified as a config object (no xtype defaults to 'panel'). + * title: 'Details', + * bodyPadding: 5, + * items: [{ + * fieldLabel: 'Data item', + * xtype: 'textfield' + * }], // An array of form fields + * flex: 2 // Use 2/3 of Container's height (hint to Box layout) + * }] + * }); + * + * The example illustrates one possible method of displaying search results. The Panel contains a grid with the + * resulting data arranged in rows. Each selected row may be displayed in detail in the Panel below. The {@link + * Ext.layout.container.VBox vbox} layout is used to arrange the two vertically. It is configured to stretch child items + * horizontally to full width. Child items may either be configured with a numeric height, or with a `flex` value to + * distribute available space proportionately. + * + * This Panel itself may be a child item of, for exaple, a {@link Ext.tab.Panel} which will size its child items to fit + * within its content area. + * + * Using these techniques, as long as the **layout** is chosen and configured correctly, an application may have any + * level of nested containment, all dynamically sized according to configuration, the user's preference and available + * browser size. */ Ext.define('Ext.panel.Panel', { extend: 'Ext.panel.AbstractPanel', @@ -115,166 +134,182 @@ Ext.define('Ext.panel.Panel', { /** * @cfg {String} collapsedCls - * A CSS class to add to the panel's element after it has been collapsed (defaults to - *'collapsed'
).
+ * A CSS class to add to the panel's element after it has been collapsed.
*/
collapsedCls: 'collapsed',
/**
* @cfg {Boolean} animCollapse
- * true
to animate the transition when the panel is collapsed, false
to skip the
- * animation (defaults to true
if the {@link Ext.fx.Anim} class is available, otherwise false
).
- * May also be specified as the animation duration in milliseconds.
+ * `true` to animate the transition when the panel is collapsed, `false` to skip the animation (defaults to `true`
+ * if the {@link Ext.fx.Anim} class is available, otherwise `false`). May also be specified as the animation
+ * duration in milliseconds.
*/
animCollapse: Ext.enableFx,
/**
* @cfg {Number} minButtonWidth
- * Minimum width of all footer toolbar buttons in pixels (defaults to 75). If set, this will
- * be used as the default value for the {@link Ext.button.Button#minWidth} config of
- * each Button added to the footer toolbar via the {@link #fbar} or {@link #buttons} configurations.
- * It will be ignored for buttons that have a minWidth configured some other way, e.g. in their own config
- * object or via the {@link Ext.container.Container#config-defaults defaults} of their parent container.
+ * Minimum width of all footer toolbar buttons in pixels. If set, this will be used as the default
+ * value for the {@link Ext.button.Button#minWidth} config of each Button added to the **footer toolbar** via the
+ * {@link #fbar} or {@link #buttons} configurations. It will be ignored for buttons that have a minWidth configured
+ * some other way, e.g. in their own config object or via the {@link Ext.container.Container#defaults defaults} of
+ * their parent container.
*/
minButtonWidth: 75,
/**
* @cfg {Boolean} collapsed
- * true
to render the panel collapsed, false
to render it expanded (defaults to
- * false
).
+ * `true` to render the panel collapsed, `false` to render it expanded.
*/
collapsed: 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 panel's title bar, false
to render it last (defaults to true
).
+ * `true` to make sure the collapse/expand toggle button always renders first (to the left of) any other tools in
+ * the panel's title bar, `false` to render it last.
*/
collapseFirst: true,
/**
* @cfg {Boolean} hideCollapseTool
- * true
to hide the expand/collapse toggle button when {@link #collapsible} == true
,
- * false
to display it (defaults to false
).
+ * `true` to hide the expand/collapse toggle button when `{@link #collapsible} == true`, `false` to display it.
*/
hideCollapseTool: false,
/**
* @cfg {Boolean} titleCollapse
- * true
to allow expanding and collapsing the panel (when {@link #collapsible} = true
)
- * by clicking anywhere in the header bar, false
) to allow it only by clicking to tool button
- * (defaults to false
)).
+ * `true` to allow expanding and collapsing the panel (when `{@link #collapsible} = true`) by clicking anywhere in
+ * the header bar, `false`) to allow it only by clicking to tool butto).
*/
titleCollapse: false,
/**
* @cfg {String} collapseMode
- * Important: this config is only effective for {@link #collapsible} Panels which are direct child items of a {@link Ext.layout.container.Border border layout}.
- *When not a direct child item of a {@link Ext.layout.container.Border border layout}, then the Panel's header remains visible, and the body is collapsed to zero dimensions. - * If the Panel has no header, then a new header (orientated correctly depending on the {@link #collapseDirection}) will be inserted to show a the title and a re-expand tool.
- *When a child item of a {@link Ext.layout.container.Border border layout}, this config has two options: - *
undefined/omitted
header
: Important: This config is only effective for {@link #collapsible} Panels which are direct child items of a {@link Ext.layout.container.Border border layout}
- * when not using the 'header'
{@link #collapseMode}.
Optional. A Component (or config object for a Component) to show in place of this Panel when this Panel is collapsed by a - * {@link Ext.layout.container.Border border layout}. Defaults to a generated {@link Ext.panel.Header Header} - * containing a {@link Ext.panel.Tool Tool} to re-expand the Panel.
+ * @cfg {Ext.Component/Object} placeholder + * **Important: This config is only effective for {@link #collapsible} Panels which are direct child items of a + * {@link Ext.layout.container.Border border layout} when not using the `'header'` {@link #collapseMode}.** + * + * **Optional.** A Component (or config object for a Component) to show in place of this Panel when this Panel is + * collapsed by a {@link Ext.layout.container.Border border layout}. Defaults to a generated {@link Ext.panel.Header + * Header} containing a {@link Ext.panel.Tool Tool} to re-expand the Panel. */ /** * @cfg {Boolean} floatable - *Important: This config is only effective for {@link #collapsible} Panels which are direct child items of a {@link Ext.layout.container.Border border layout}.
- * true to allow clicking a collapsed Panel's {@link #placeholder} to display the 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). + * **Important: This config is only effective for {@link #collapsible} Panels which are direct child items of a + * {@link Ext.layout.container.Border border layout}.** + * + * true to allow clicking a collapsed Panel's {@link #placeholder} to display the 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. */ floatable: true, /** - * @cfg {Mixed} overlapHeader - * True to overlap the header in a panel over the framing of the panel itself. This is needed when frame:true (and is done automatically for you). Otherwise it is undefined. - * If you manually add rounded corners to a panel header which does not have frame:true, this will need to be set to true. + * @cfg {Boolean} overlapHeader + * True to overlap the header in a panel over the framing of the panel itself. This is needed when frame:true (and + * is done automatically for you). Otherwise it is undefined. If you manually add rounded corners to a panel header + * which does not have frame:true, this will need to be set to true. */ /** * @cfg {Boolean} collapsible - *True to make the panel collapsible and have an expand/collapse toggle Tool added into - * the header tool button area. False to keep the panel sized either statically, or by an owning layout manager, with no toggle Tool (defaults to false).
+ * True to make the panel collapsible and have an expand/collapse toggle Tool added into the header tool button + * area. False to keep the panel sized either statically, or by an owning layout manager, with no toggle Tool. + * * See {@link #collapseMode} and {@link #collapseDirection} */ collapsible: false, /** * @cfg {Boolean} collapseDirection - *The direction to collapse the Panel when the toggle button is clicked.
- *Defaults to the {@link #headerPosition}
- *Important: This config is ignored for {@link #collapsible} Panels which are direct child items of a {@link Ext.layout.container.Border border layout}.
- *Specify as 'top'
, 'bottom'
, 'left'
or 'right'
.
True to display the 'close' tool button and allow the user to close the window, false to
- * hide the button and disallow closing the window (defaults to false
).
By default, when close is requested by clicking the close button in the header, the {@link #close} - * method will be called. This will {@link Ext.Component#destroy destroy} the Panel and its content - * meaning that it may not be reused.
- *To make closing a Panel hide the Panel so that it may be reused, set - * {@link #closeAction} to 'hide'.
+ * True to display the 'close' tool button and allow the user to close the window, false to hide the button and + * disallow closing the window. + * + * By default, when close is requested by clicking the close button in the header, the {@link #close} method will be + * called. This will _{@link Ext.Component#destroy destroy}_ the Panel and its content meaning that it may not be + * reused. + * + * To make closing a Panel _hide_ the Panel so that it may be reused, set {@link #closeAction} to 'hide'. */ closable: false, /** * @cfg {String} closeAction - *The action to take when the close header tool is clicked: - *
'{@link #destroy}'
: Default'{@link #hide}'
: Note: This behavior has changed! setting *does* affect the {@link #close} method - * which will invoke the approriate closeAction. + * The action to take when the close header tool is clicked: + * + * - **`'{@link #destroy}'`** : + * + * {@link #destroy remove} the window from the DOM and {@link Ext.Component#destroy destroy} it and all descendant + * Components. The window will **not** be available to be redisplayed via the {@link #show} method. + * + * - **`'{@link #hide}'`** : + * + * {@link #hide} the window by setting visibility to hidden and applying negative offsets. The window will be + * available to be redisplayed via the {@link #show} method. + * + * **Note:** This behavior has changed! setting *does* affect the {@link #close} method which will invoke the + * approriate closeAction. */ closeAction: 'destroy', /** - * @cfg {Object/Array} dockedItems - * A component or series of components to be added as docked items to this panel. - * The docked items can be docked to either the top, right, left or bottom of a panel. - * This is typically used for things like toolbars or tab bars: - *
-var panel = new Ext.panel.Panel({
- dockedItems: [{
- xtype: 'toolbar',
- dock: 'top',
- items: [{
- text: 'Docked to the top'
- }]
- }]
-});
+ * @cfg {Object/Object[]} dockedItems
+ * A component or series of components to be added as docked items to this panel. The docked items can be docked to
+ * either the top, right, left or bottom of a panel. This is typically used for things like toolbars or tab bars:
+ *
+ * var panel = new Ext.panel.Panel({
+ * dockedItems: [{
+ * xtype: 'toolbar',
+ * dock: 'top',
+ * items: [{
+ * text: 'Docked to the top'
+ * }]
+ * }]
+ * });
*/
/**
- * @cfg {Boolean} preventHeader Prevent a Header from being created and shown. Defaults to false.
+ * @cfg {Boolean} preventHeader
+ * Prevent a Header from being created and shown.
*/
preventHeader: false,
/**
- * @cfg {String} headerPosition Specify as 'top'
, 'bottom'
, 'left'
or 'right'
. Defaults to 'top'
.
+ * @cfg {String} headerPosition
+ * Specify as `'top'`, `'bottom'`, `'left'` or `'right'`.
*/
headerPosition: 'top',
@@ -291,45 +326,60 @@ var panel = new Ext.panel.Panel({
frameHeader: true,
/**
- * @cfg {Array} tools
- * An array of {@link Ext.panel.Tool} configs/instances to be added to the header tool area. The tools are stored as child
- * components of the header container. They can be accessed using {@link #down} and {#query}, as well as the other
- * component methods. The toggle tool is automatically created if {@link #collapsible} is set to true.
- * Note that, apart from the toggle tool which is provided when a panel is collapsible, these - * tools only provide the visual button. Any required functionality must be provided by adding - * handlers that implement the necessary behavior.
- *Example usage:
- *
-tools:[{
- type:'refresh',
- qtip: 'Refresh form Data',
- // hidden:true,
- handler: function(event, toolEl, panel){
- // refresh logic
- }
-},
-{
- type:'help',
- qtip: 'Get Help',
- handler: function(event, toolEl, panel){
- // show help here
- }
-}]
-
+ * @cfg {Object[]/Ext.panel.Tool[]} tools
+ * An array of {@link Ext.panel.Tool} configs/instances to be added to the header tool area. The tools are stored as
+ * child components of the header container. They can be accessed using {@link #down} and {#query}, as well as the
+ * other component methods. The toggle tool is automatically created if {@link #collapsible} is set to true.
+ *
+ * Note that, apart from the toggle tool which is provided when a panel is collapsible, these tools only provide the
+ * visual button. Any required functionality must be provided by adding handlers that implement the necessary
+ * behavior.
+ *
+ * Example usage:
+ *
+ * tools:[{
+ * type:'refresh',
+ * tooltip: 'Refresh form Data',
+ * // hidden:true,
+ * handler: function(event, toolEl, panel){
+ * // refresh logic
+ * }
+ * },
+ * {
+ * type:'help',
+ * tooltip: 'Get Help',
+ * handler: function(event, toolEl, panel){
+ * // show help here
+ * }
+ * }]
*/
/**
- * @cfg {String} title
- * The title text to be used to display in the {@link Ext.panel.Header panel header} (defaults to '').
- * When a `title` is specified the {@link Ext.panel.Header} will automatically be created and displayed unless
+ * @cfg {String} [title='']
+ * The title text to be used to display in the {@link Ext.panel.Header panel header}. When a
+ * `title` is specified the {@link Ext.panel.Header} will automatically be created and displayed unless
* {@link #preventHeader} is set to `true`.
*/
+ /**
+ * @cfg {String} iconCls
+ * CSS class for icon in header. Used for displaying an icon to the left of a title.
+ */
+
initComponent: function() {
var me = this,
cls;
me.addEvents(
+
+ /**
+ * @event beforeclose
+ * Fires before the user closes the panel. Return false from any listener to stop the close event being
+ * fired
+ * @param {Ext.panel.Panel} panel The Panel object
+ */
+ 'beforeclose',
+
/**
* @event beforeexpand
* Fires before this panel is expanded. Return false to prevent the expand.
@@ -342,11 +392,13 @@ tools:[{
* @event beforecollapse
* Fires before this panel is collapsed. Return false to prevent the collapse.
* @param {Ext.panel.Panel} p The Panel being collapsed.
- * @param {String} direction. The direction of the collapse. One ofThe alignment of any buttons added to this panel. Valid values are 'right', - * 'left' and 'center' (defaults to 'right' for buttons/fbar, 'left' for other toolbar types).
- *NOTE: The newer way to specify toolbars is to use the dockedItems config, and - * instead of buttonAlign you would add the layout: { pack: 'start' | 'center' | 'end' } - * option to the dockedItem config.
- */ - /** - * @cfg {Object/Array} tbar - -Convenience method. Short for 'Top Bar'. - - tbar: [ - { xtype: 'button', text: 'Button 1' } - ] - -is equivalent to - - dockedItems: [{ - xtype: 'toolbar', - dock: 'top', - items: [ - { xtype: 'button', text: 'Button 1' } - ] - }] + * @cfg {String} buttonAlign + * The alignment of any buttons added to this panel. Valid values are 'right', 'left' and 'center' (defaults to + * 'right' for buttons/fbar, 'left' for other toolbar types). + * + * **NOTE:** The prefered way to specify toolbars is to use the dockedItems config. Instead of buttonAlign you + * would add the layout: { pack: 'start' | 'center' | 'end' } option to the dockedItem config. + */ - * @markdown + /** + * @cfg {Object/Object[]} tbar + * Convenience config. Short for 'Top Bar'. + * + * tbar: [ + * { xtype: 'button', text: 'Button 1' } + * ] + * + * is equivalent to + * + * dockedItems: [{ + * xtype: 'toolbar', + * dock: 'top', + * items: [ + * { xtype: 'button', text: 'Button 1' } + * ] + * }] */ if (me.tbar) { - me.addDocked(initToolbar(me.tbar, 'top')); + docked.push(initToolbar(me.tbar, 'top')); me.tbar = null; } /** - * @cfg {Object/Array} bbar - -Convenience method. Short for 'Bottom Bar'. - - bbar: [ - { xtype: 'button', text: 'Button 1' } - ] - -is equivalent to - - dockedItems: [{ - xtype: 'toolbar', - dock: 'bottom', - items: [ - { xtype: 'button', text: 'Button 1' } - ] - }] - - * @markdown + * @cfg {Object/Object[]} bbar + * Convenience config. Short for 'Bottom Bar'. + * + * bbar: [ + * { xtype: 'button', text: 'Button 1' } + * ] + * + * is equivalent to + * + * dockedItems: [{ + * xtype: 'toolbar', + * dock: 'bottom', + * items: [ + * { xtype: 'button', text: 'Button 1' } + * ] + * }] */ if (me.bbar) { - me.addDocked(initToolbar(me.bbar, 'bottom')); + docked.push(initToolbar(me.bbar, 'bottom')); me.bbar = null; } /** - * @cfg {Object/Array} buttons - -Convenience method used for adding buttons docked to the bottom of the panel. This is a -synonym for the {@link #fbar} config. - - buttons: [ - { text: 'Button 1' } - ] - -is equivalent to - - dockedItems: [{ - xtype: 'toolbar', - dock: 'bottom', - ui: 'footer', - defaults: {minWidth: {@link #minButtonWidth}}, - items: [ - { xtype: 'component', flex: 1 }, - { xtype: 'button', text: 'Button 1' } - ] - }] - -The {@link #minButtonWidth} is used as the default {@link Ext.button.Button#minWidth minWidth} for -each of the buttons in the buttons toolbar. - - * @markdown + * @cfg {Object/Object[]} buttons + * Convenience config used for adding buttons docked to the bottom of the panel. This is a + * synonym for the {@link #fbar} config. + * + * buttons: [ + * { text: 'Button 1' } + * ] + * + * is equivalent to + * + * dockedItems: [{ + * xtype: 'toolbar', + * dock: 'bottom', + * ui: 'footer', + * defaults: {minWidth: {@link #minButtonWidth}}, + * items: [ + * { xtype: 'component', flex: 1 }, + * { xtype: 'button', text: 'Button 1' } + * ] + * }] + * + * The {@link #minButtonWidth} is used as the default {@link Ext.button.Button#minWidth minWidth} for + * each of the buttons in the buttons toolbar. */ if (me.buttons) { me.fbar = me.buttons; @@ -614,31 +658,28 @@ each of the buttons in the buttons toolbar. } /** - * @cfg {Object/Array} fbar - -Convenience method used for adding items to the bottom of the panel. Short for Footer Bar. - - fbar: [ - { type: 'button', text: 'Button 1' } - ] - -is equivalent to - - dockedItems: [{ - xtype: 'toolbar', - dock: 'bottom', - ui: 'footer', - defaults: {minWidth: {@link #minButtonWidth}}, - items: [ - { xtype: 'component', flex: 1 }, - { xtype: 'button', text: 'Button 1' } - ] - }] - -The {@link #minButtonWidth} is used as the default {@link Ext.button.Button#minWidth minWidth} for -each of the buttons in the fbar. - - * @markdown + * @cfg {Object/Object[]} fbar + * Convenience config used for adding items to the bottom of the panel. Short for Footer Bar. + * + * fbar: [ + * { type: 'button', text: 'Button 1' } + * ] + * + * is equivalent to + * + * dockedItems: [{ + * xtype: 'toolbar', + * dock: 'bottom', + * ui: 'footer', + * defaults: {minWidth: {@link #minButtonWidth}}, + * items: [ + * { xtype: 'component', flex: 1 }, + * { xtype: 'button', text: 'Button 1' } + * ] + * }] + * + * The {@link #minButtonWidth} is used as the default {@link Ext.button.Button#minWidth minWidth} for + * each of the buttons in the fbar. */ if (me.fbar) { fbar = initToolbar(me.fbar, 'bottom', true); // only we useButtonAlign @@ -657,14 +698,13 @@ each of the buttons in the fbar. }; } - me.addDocked(fbar); + docked.push(fbar); me.fbar = null; } /** - * @cfg {Object/Array} lbar - * - * Convenience method. Short for 'Left Bar' (left-docked, vertical toolbar). + * @cfg {Object/Object[]} lbar + * Convenience config. Short for 'Left Bar' (left-docked, vertical toolbar). * * lbar: [ * { xtype: 'button', text: 'Button 1' } @@ -679,18 +719,15 @@ each of the buttons in the fbar. * { xtype: 'button', text: 'Button 1' } * ] * }] - * - * @markdown */ if (me.lbar) { - me.addDocked(initToolbar(me.lbar, 'left')); + docked.push(initToolbar(me.lbar, 'left')); me.lbar = null; } /** - * @cfg {Object/Array} rbar - * - * Convenience method. Short for 'Right Bar' (right-docked, vertical toolbar). + * @cfg {Object/Object[]} rbar + * Convenience config. Short for 'Right Bar' (right-docked, vertical toolbar). * * rbar: [ * { xtype: 'button', text: 'Button 1' } @@ -705,13 +742,20 @@ each of the buttons in the fbar. * { xtype: 'button', text: 'Button 1' } * ] * }] - * - * @markdown */ if (me.rbar) { - me.addDocked(initToolbar(me.rbar, 'right')); + docked.push(initToolbar(me.rbar, 'right')); me.rbar = null; } + + if (me.dockedItems) { + if (!Ext.isArray(me.dockedItems)) { + me.dockedItems = [me.dockedItems]; + } + me.dockedItems = me.dockedItems.concat(docked); + } else { + me.dockedItems = docked; + } }, /** @@ -722,7 +766,7 @@ each of the buttons in the fbar. initTools: function() { var me = this; - me.tools = me.tools || []; + me.tools = me.tools ? Ext.Array.clone(me.tools) : []; // Add a collapse tool unless configured to not show a collapse tool // or to not even show a header. @@ -762,17 +806,18 @@ each of the buttons in the fbar. /** * @private + * @template * Template method to be implemented in subclasses to add their tools after the collapsible tool. */ addTools: Ext.emptyFn, /** - *Closes the Panel. By default, this method, removes it from the DOM, {@link Ext.Component#destroy destroy}s - * the Panel object and all its descendant Components. The {@link #beforeclose beforeclose} - * event is fired before the close happens and will cancel the close action if it returns false.
- *
Note: This method is not affected by the {@link #closeAction} setting which - * only affects the action triggered when clicking the {@link #closable 'close' tool in the header}. - * To hide the Panel without destroying it, call {@link #hide}.
+ * Closes the Panel. By default, this method, removes it from the DOM, {@link Ext.Component#destroy destroy}s the + * Panel object and all its descendant Components. The {@link #beforeclose beforeclose} event is fired before the + * close happens and will cancel the close action if it returns false. + * + * **Note:** This method is also affected by the {@link #closeAction} setting. For more explicit control use + * {@link #destroy} and {@link #hide} methods. */ close: function() { if (this.fireEvent('beforeclose', this) !== false) { @@ -803,7 +848,12 @@ each of the buttons in the fbar. afterRender: function() { var me = this; + me.callParent(arguments); + + // Instate the collapsed state after render. We need to wait for + // this moment so that we have established at least some of our size (from our + // configured dimensions or from content via the component layout) if (me.collapsed) { me.collapsed = false; me.collapse(null, false, true); @@ -875,13 +925,52 @@ each of the buttons in the fbar. return this.body || this.frameBody || this.el; }, + // the overrides below allow for collapsed regions inside the border layout to be hidden + + // inherit docs + isVisible: function(deep){ + var me = this; + if (me.collapsed && me.placeholder) { + return me.placeholder.isVisible(deep); + } + return me.callParent(arguments); + }, + + // inherit docs + onHide: function(){ + var me = this; + if (me.collapsed && me.placeholder) { + me.placeholder.hide(); + } else { + me.callParent(arguments); + } + }, + + // inherit docs + onShow: function(){ + var me = this; + if (me.collapsed && me.placeholder) { + // force hidden back to true, since this gets set by the layout + me.hidden = true; + me.placeholder.show(); + } else { + me.callParent(arguments); + } + }, + addTool: function(tool) { - this.tools.push(tool); - var header = this.header; + var me = this, + header = me.header; + + if (Ext.isArray(tool)) { + Ext.each(tool, me.addTool, me); + return; + } + me.tools.push(tool); if (header) { header.addTool(tool); } - this.updateHeader(); + me.updateHeader(); }, getOppositeDirection: function(d) { @@ -899,15 +988,18 @@ each of the buttons in the fbar. }, /** - * Collapses the panel body so that the body becomes hidden. Docked Components parallel to the - * border towards which the collapse takes place will remain visible. Fires the {@link #beforecollapse} event which will - * cancel the collapse action if it returns false. - * @param {String} direction. The direction to collapse towards. Must be one ofIf this Panel is configured {@link #draggable}, this property will contain - * an instance of {@link Ext.dd.DragSource} which handles dragging the Panel.
- * The developer must provide implementations of the abstract methods of {@link Ext.dd.DragSource} - * in order to supply behaviour for each stage of the drag/drop process. See {@link #draggable}. - * @type Ext.dd.DragSource. - * @property dd + * @property {Ext.dd.DragSource} dd + * If this Panel is configured {@link #draggable}, this property will contain an instance of {@link + * Ext.dd.DragSource} which handles dragging the Panel. + * + * The developer must provide implementations of the abstract methods of {@link Ext.dd.DragSource} in order to + * supply behaviour for each stage of the drag/drop process. See {@link #draggable}. */ this.dd = Ext.create('Ext.panel.DD', this, Ext.isBoolean(this.draggable) ? null : this.draggable); }, @@ -1414,10 +1519,10 @@ each of the buttons in the fbar. // private - helper function for ghost ghostTools : function() { var tools = [], - origTools = this.initialConfig.tools; + headerTools = this.header.query('tool[hidden=false]'); - if (origTools) { - Ext.each(origTools, function(tool) { + if (headerTools.length) { + Ext.each(headerTools, function(tool) { // Some tools can be full components, and copying them into the ghost // actually removes them from the owning panel. You could also potentially // end up with duplicate DOM ids as well. To avoid any issues we just make @@ -1426,8 +1531,7 @@ each of the buttons in the fbar. type: tool.type }); }); - } - else { + } else { tools = [{ type: 'placeholder' }]; @@ -1439,23 +1543,19 @@ each of the buttons in the fbar. ghost: function(cls) { var me = this, ghostPanel = me.ghostPanel, - box = me.getBox(); + box = me.getBox(), + header; if (!ghostPanel) { ghostPanel = Ext.create('Ext.panel.Panel', { - renderTo: document.body, + renderTo: me.floating ? me.el.dom.parentNode : document.body, floating: { shadow: false }, frame: Ext.supports.CSS3BorderRadius ? me.frame : false, - title: me.title, overlapHeader: me.overlapHeader, headerPosition: me.headerPosition, - width: me.getWidth(), - height: me.getHeight(), - iconCls: me.iconCls, baseCls: me.baseCls, - tools: me.ghostTools(), cls: me.baseCls + '-ghost ' + (cls ||'') }); me.ghostPanel = ghostPanel; @@ -1466,6 +1566,19 @@ each of the buttons in the fbar. } else { ghostPanel.toFront(); } + header = ghostPanel.header; + // restore options + if (header) { + header.suspendLayout = true; + Ext.Array.forEach(header.query('tool'), function(tool){ + header.remove(tool); + }); + header.suspendLayout = false; + } + ghostPanel.addTool(me.ghostTools()); + ghostPanel.setTitle(me.title); + ghostPanel.setIconCls(me.iconCls); + ghostPanel.el.show(); ghostPanel.setPosition(box.x, box.y); ghostPanel.setSize(box.width, box.height); @@ -1501,5 +1614,7 @@ each of the buttons in the fbar. } this.callParent([resizable]); } +}, function(){ + this.prototype.animCollapse = Ext.enableFx; });