+ * @markdown
+ */
+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`.
+ * (defaults to `false`)
+ */
+ 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
+ * Defaults to false. 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,
+
+ // 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'
+ });
+
+ 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
+ });
+ },
+
+ /**
+ * 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 {Mixed} arg1 The following types of arguments are all valid:
+ *
+ * - {@link Ext.button.Button} config: A valid button config object (equivalent to {@link #addButton})
+ * - HtmlElement: Any standard HTML element (equivalent to {@link #addElement})
+ * - Field: Any form field (equivalent to {@link #addField})
+ * - Item: Any subclass of {@link Ext.toolbar.Item} (equivalent to {@link #addItem})
+ * - String: Any generic string (gets wrapped in a {@link Ext.toolbar.TextItem}, equivalent to {@link #addText}).
+ * Note that there are a few special strings that are treated differently as explained next.
+ * - '-': Creates a separator element (equivalent to {@link #addSeparator})
+ * - ' ': Creates a spacer element (equivalent to {@link #addSpacer})
+ * - '->': Creates a fill element (equivalent to {@link #addFill})
+ *
+ * @param {Mixed} arg2
+ * @param {Mixed} etc.
+ * @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, 'menutriggerover', me.onButtonTriggerOver, 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
+ onButtonTriggerOver: 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'
+ };
+});
\ No newline at end of file