3 This file is part of Ext JS 4
5 Copyright (c) 2011 Sencha Inc
7 Contact: http://www.sencha.com/contact
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
16 * A specialized SplitButton that contains a menu of {@link Ext.menu.CheckItem} elements. The button automatically
17 * cycles through each menu item on click, raising the button's {@link #change} event (or calling the button's
18 * {@link #changeHandler} function, if supplied) for the active menu item. Clicking on the arrow section of the
19 * button displays the dropdown menu just like a normal SplitButton. Example usage:
22 * Ext.create('Ext.button.Cycle', {
24 * prependText: 'View as ',
25 * renderTo: Ext.getBody(),
27 * id: 'view-type-menu',
30 * iconCls: 'view-text',
34 * iconCls: 'view-html'
37 * changeHandler: function(cycleBtn, activeItem) {
38 * Ext.Msg.alert('Change View', activeItem.text);
42 Ext.define('Ext.button.Cycle', {
44 /* Begin Definitions */
46 alias: 'widget.cycle',
48 extend: 'Ext.button.Split',
49 alternateClassName: 'Ext.CycleButton',
54 * @cfg {Object[]} items
55 * An array of {@link Ext.menu.CheckItem} **config** objects to be used when creating the button's menu items (e.g.,
56 * `{text:'Foo', iconCls:'foo-icon'}`)
58 * @deprecated 4.0 Use the {@link #menu} config instead. All menu items will be created as
59 * {@link Ext.menu.CheckItem CheckItems}.
62 * @cfg {Boolean} [showText=false]
63 * True to display the active item's text as the button text. The Button will show its
64 * configured {@link #text} if this config is omitted.
67 * @cfg {String} [prependText='']
68 * A static string to prepend before the active item's text when displayed as the button's text (only applies when
72 * @cfg {Function} changeHandler
73 * A callback function that will be invoked each time the active menu item in the button's menu has changed. If this
74 * callback is not supplied, the SplitButton will instead fire the {@link #change} event on active item change. The
75 * changeHandler function will be called with the following argument list: (SplitButton this, Ext.menu.CheckItem
79 * @cfg {String} forceIcon
80 * A css class which sets an image to be used as the static icon for this button. This icon will always be displayed
81 * regardless of which item is selected in the dropdown list. This overrides the default behavior of changing the
82 * button's icon to match the selected item's icon on change.
85 * @property {Ext.menu.Menu} menu
86 * The {@link Ext.menu.Menu Menu} object used to display the {@link Ext.menu.CheckItem CheckItems} representing the
91 getButtonText: function(item) {
95 if (item && me.showText === true) {
97 text += me.prependText;
106 * Sets the button's active menu item.
107 * @param {Ext.menu.CheckItem} item The item to activate
108 * @param {Boolean} [suppressEvent=false] True to prevent the button's change event from firing.
110 setActiveItem: function(item, suppressEvent) {
113 if (!Ext.isObject(item)) {
114 item = me.menu.getComponent(item);
118 me.text = me.getButtonText(item);
119 me.iconCls = item.iconCls;
121 me.setText(me.getButtonText(item));
122 me.setIconCls(item.iconCls);
124 me.activeItem = item;
126 item.setChecked(true, false);
129 me.setIconCls(me.forceIcon);
131 if (!suppressEvent) {
132 me.fireEvent('change', me, item);
138 * Gets the currently active menu item.
139 * @return {Ext.menu.CheckItem} The active item
141 getActiveItem: function() {
142 return this.activeItem;
146 initComponent: function() {
154 * Fires after the button's active menu item has changed. Note that if a {@link #changeHandler} function is
155 * set on this CycleButton, it will be called instead on active item change and this change event will not
157 * @param {Ext.button.Cycle} this
158 * @param {Ext.menu.CheckItem} item The menu item that was selected
163 if (me.changeHandler) {
164 me.on('change', me.changeHandler, me.scope || me);
165 delete me.changeHandler;
168 // Allow them to specify a menu config which is a standard Button config.
169 // Remove direct use of "items" in 5.0.
170 items = (me.menu.items||[]).concat(me.items||[]);
171 me.menu = Ext.applyIf({
172 cls: Ext.baseCSSPrefix + 'cycle-menu',
176 // Convert all items to CheckItems
177 Ext.each(items, function(item, i) {
181 checkHandler: me.checkHandler,
183 checked: item.checked || false
185 me.menu.items.push(item);
190 me.itemCount = me.menu.items.length;
191 me.callParent(arguments);
192 me.on('click', me.toggleSelected, me);
193 me.setActiveItem(checked, me);
195 // If configured with a fixed width, the cycling will center a different child item's text each click. Prevent this.
196 if (me.width && me.showText) {
197 me.addCls(Ext.baseCSSPrefix + 'cycle-fixed-width');
202 checkHandler: function(item, pressed) {
204 this.setActiveItem(item);
209 * This is normally called internally on button click, but can be called externally to advance the button's active
210 * item programmatically to the next one in the menu. If the current item is the last one in the menu the active
211 * item will be set to the first item in the menu.
213 toggleSelected: function() {
218 checkItem = me.activeItem.next(':not([disabled])') || m.items.getAt(0);
219 checkItem.setChecked(true);