/** * Basic Toolbar class. Although the {@link Ext.container.Container#defaultType defaultType} for Toolbar is {@link Ext.button.Button button}, Toolbar * elements (child items for the Toolbar container) may be virtually any type of Component. Toolbar elements can be created explicitly via their * constructors, or implicitly via their xtypes, and can be {@link #add}ed dynamically. * * ## Some items have shortcut strings for creation: * * | Shortcut | xtype | Class | Description * |:---------|:--------------|:------------------------------|:--------------------------------------------------- * | `->` | `tbfill` | {@link Ext.toolbar.Fill} | begin using the right-justified button container * | `-` | `tbseparator` | {@link Ext.toolbar.Separator} | add a vertical separator bar between toolbar items * | ` ` | `tbspacer` | {@link Ext.toolbar.Spacer} | add horiztonal space between elements * * @example * Ext.create('Ext.toolbar.Toolbar', { * renderTo: document.body, * width : 500, * items: [ * { * // xtype: 'button', // default for Toolbars * text: 'Button' * }, * { * xtype: 'splitbutton', * text : 'Split Button' * }, * // begin using the right-justified button container * '->', // same as { xtype: 'tbfill' } * { * xtype : 'textfield', * name : 'field1', * emptyText: 'enter search term' * }, * // add a vertical separator bar between toolbar items * '-', // same as {xtype: 'tbseparator'} to create Ext.toolbar.Separator * 'text 1', // same as {xtype: 'tbtext', text: 'text1'} to create Ext.toolbar.TextItem * { xtype: 'tbspacer' },// same as ' ' to create Ext.toolbar.Spacer * 'text 2', * { xtype: 'tbspacer', width: 50 }, // add a 50px space * 'text 3' * ] * }); * * Toolbars have {@link #enable} and {@link #disable} methods which when called, will enable/disable all items within your toolbar. * * @example * Ext.create('Ext.toolbar.Toolbar', { * renderTo: document.body, * width : 400, * items: [ * { * text: 'Button' * }, * { * xtype: 'splitbutton', * text : 'Split Button' * }, * '->', * { * xtype : 'textfield', * name : 'field1', * emptyText: 'enter search term' * } * ] * }); * * Example * * @example * var enableBtn = Ext.create('Ext.button.Button', { * text : 'Enable All Items', * disabled: true, * scope : this, * handler : function() { * //disable the enable button and enable the disable button * enableBtn.disable(); * disableBtn.enable(); * * //enable the toolbar * toolbar.enable(); * } * }); * * var disableBtn = Ext.create('Ext.button.Button', { * text : 'Disable All Items', * scope : this, * handler : function() { * //enable the enable button and disable button * disableBtn.disable(); * enableBtn.enable(); * * //disable the toolbar * toolbar.disable(); * } * }); * * var toolbar = Ext.create('Ext.toolbar.Toolbar', { * renderTo: document.body, * width : 400, * margin : '5 0 0 0', * items : [enableBtn, disableBtn] * }); * * Adding items to and removing items from a toolbar is as simple as calling the {@link #add} and {@link #remove} methods. There is also a {@link #removeAll} method * which remove all items within the toolbar. * * @example * var toolbar = Ext.create('Ext.toolbar.Toolbar', { * renderTo: document.body, * width : 700, * items: [ * { * text: 'Example Button' * } * ] * }); * * var addedItems = []; * * Ext.create('Ext.toolbar.Toolbar', { * renderTo: document.body, * width : 700, * margin : '5 0 0 0', * items : [ * { * text : 'Add a button', * scope : this, * handler: function() { * var text = prompt('Please enter the text for your button:'); * addedItems.push(toolbar.add({ * text: text * })); * } * }, * { * text : 'Add a text item', * scope : this, * handler: function() { * var text = prompt('Please enter the text for your item:'); * addedItems.push(toolbar.add(text)); * } * }, * { * text : 'Add a toolbar seperator', * scope : this, * handler: function() { * addedItems.push(toolbar.add('-')); * } * }, * { * text : 'Add a toolbar spacer', * scope : this, * handler: function() { * addedItems.push(toolbar.add('->')); * } * }, * '->', * { * text : 'Remove last inserted item', * scope : this, * handler: function() { * if (addedItems.length) { * toolbar.remove(addedItems.pop()); * } else if (toolbar.items.length) { * toolbar.remove(toolbar.items.last()); * } else { * alert('No items in the toolbar'); * } * } * }, * { * text : 'Remove all items', * scope : this, * handler: function() { * toolbar.removeAll(); * } * } * ] * }); * * @constructor * Creates a new Toolbar * @param {Object/Object[]} config A config object or an array of buttons to <code>{@link #add}</code> * @docauthor Robert Dougan <rob@sencha.com> */ Ext.define('Ext.toolbar.Toolbar', { extend: 'Ext.container.Container', requires: [ 'Ext.toolbar.Fill', 'Ext.layout.container.HBox', 'Ext.layout.container.VBox', 'Ext.FocusManager' ], uses: [ 'Ext.toolbar.Separator' ], alias: 'widget.toolbar', alternateClassName: 'Ext.Toolbar', isToolbar: true, baseCls : Ext.baseCSSPrefix + 'toolbar', ariaRole : 'toolbar', defaultType: 'button', /** * @cfg {Boolean} vertical * Set to `true` to make the toolbar vertical. The layout will become a `vbox`. */ vertical: false, /** * @cfg {String/Object} layout * This class assigns a default layout (`layout: 'hbox'`). * Developers _may_ override this configuration option if another layout * is required (the constructor must be passed a configuration object in this * case instead of an array). * See {@link Ext.container.Container#layout} for additional information. */ /** * @cfg {Boolean} enableOverflow * Configure true to make the toolbar provide a button which activates a dropdown Menu to show * items which overflow the Toolbar's width. */ enableOverflow: false, * @cfg {String} menuTriggerCls * Configure the icon class of the overflow button. */ menuTriggerCls: Ext.baseCSSPrefix + 'toolbar-more-icon', // private trackMenus: true, itemCls: Ext.baseCSSPrefix + 'toolbar-item', initComponent: function() { var me = this, keys; // check for simplified (old-style) overflow config: if (!me.layout && me.enableOverflow) { me.layout = { overflowHandler: 'Menu' }; } if (me.dock === 'right' || me.dock === 'left') { me.vertical = true; } me.layout = Ext.applyIf(Ext.isString(me.layout) ? { type: me.layout } : me.layout || {}, { type: me.vertical ? 'vbox' : 'hbox', align: me.vertical ? 'stretchmax' : 'middle', clearInnerCtOnLayout: true }); if (me.vertical) { me.addClsWithUI('vertical'); } // @TODO: remove this hack and implement a more general solution if (me.ui === 'footer') { me.ignoreBorderManagement = true; } me.callParent(); /** * @event overflowchange * Fires after the overflow state has changed. * @param {Object} c The Container * @param {Boolean} lastOverflow overflow state */ me.addEvents('overflowchange'); // Subscribe to Ext.FocusManager for key navigation keys = me.vertical ? ['up', 'down'] : ['left', 'right']; Ext.FocusManager.subscribe(me, { keys: keys }); }, getRefItems: function(deep) { var me = this, items = me.callParent(arguments), layout = me.layout, handler; if (deep && me.enableOverflow) { handler = layout.overflowHandler; if (handler && handler.menu) { items = items.concat(handler.menu.getRefItems(deep)); } } return items; }, /** * Adds element(s) to the toolbar -- this function takes a variable number of * arguments of mixed type and adds them to the toolbar. * * **Note**: See the notes within {@link Ext.container.Container#add}. * * @param {Object...} args The following types of arguments are all valid: * - `{@link Ext.button.Button config}`: A valid button config object * - `HtmlElement`: Any standard HTML element * - `Field`: Any form field * - `Item`: Any subclass of {@link Ext.toolbar.Item} * - `String`: Any generic string (gets wrapped in a {@link Ext.toolbar.TextItem}). * Note that there are a few special strings that are treated differently as explained next. * - `'-'`: Creates a separator element * - `' '`: Creates a spacer element * - `'->'`: Creates a fill element * * @method add */ // private lookupComponent: function(c) { if (Ext.isString(c)) { var shortcut = Ext.toolbar.Toolbar.shortcuts[c]; if (shortcut) { c = { xtype: shortcut }; } else { c = { xtype: 'tbtext', text: c }; } this.applyDefaults(c); } return this.callParent(arguments); }, // private applyDefaults: function(c) { if (!Ext.isString(c)) { c = this.callParent(arguments); var d = this.internalDefaults; if (c.events) { Ext.applyIf(c.initialConfig, d); Ext.apply(c, d); } else { Ext.applyIf(c, d); } } return c; }, // private trackMenu: function(item, remove) { if (this.trackMenus && item.menu) { var method = remove ? 'mun' : 'mon', me = this; me[method](item, 'mouseover', me.onButtonOver, me); me[method](item, 'menushow', me.onButtonMenuShow, me); me[method](item, 'menuhide', me.onButtonMenuHide, me); } }, // private constructButton: function(item) { return item.events ? item : this.createComponent(item, item.split ? 'splitbutton' : this.defaultType); }, // private onBeforeAdd: function(component) { if (component.is('field') || (component.is('button') && this.ui != 'footer')) { component.ui = component.ui + '-toolbar'; } // Any separators needs to know if is vertical or not if (component instanceof Ext.toolbar.Separator) { component.setUI((this.vertical) ? 'vertical' : 'horizontal'); } this.callParent(arguments); }, // private onAdd: function(component) { this.callParent(arguments); this.trackMenu(component); if (this.disabled) { component.disable(); } }, // private onRemove: function(c) { this.callParent(arguments); this.trackMenu(c, true); }, // private onButtonOver: function(btn){ if (this.activeMenuBtn && this.activeMenuBtn != btn) { this.activeMenuBtn.hideMenu(); btn.showMenu(); this.activeMenuBtn = btn; } }, // private onButtonMenuShow: function(btn) { this.activeMenuBtn = btn; }, // private onButtonMenuHide: function(btn) { delete this.activeMenuBtn; } }, function() { this.shortcuts = { '-' : 'tbseparator', ' ' : 'tbspacer', '->': 'tbfill' }; });