Upgrade to ExtJS 4.0.0 - Released 04/26/2011
[extjs.git] / examples / ux / TabScrollerMenu.js
1 Ext.ns('Ext.ux');
2 /**
3  * @class Ext.ux.TabScrollerMenu
4  * @extends Object
5  * Plugin (ptype = 'tabscrollermenu') for adding a tab menu to a TabBar is the Tabs overflow.
6  * @constructor
7  * @param {Object} config Configuration options
8  * @ptype tabscrollermenu
9  */
10 Ext.define('Ext.ux.TabScrollerMenu', {
11     alias: 'plugin.tabscrollermenu',
12
13     uses: ['Ext.menu.Menu'],
14
15     /**
16      * @cfg {Number} pageSize How many items to allow per submenu.
17      */
18     pageSize: 10,
19     /**
20      * @cfg {Number} maxText How long should the title of each {@link Ext.menu.Item} be.
21      */
22     maxText: 15,
23     /**
24      * @cfg {String} menuPrefixText Text to prefix the submenus.
25      */
26     menuPrefixText: 'Items',
27     constructor: function(config) {
28         config = config || {};
29         Ext.apply(this, config);
30     },
31     //private
32     init: function(tabPanel) {
33         var me = this;
34
35         Ext.apply(tabPanel, me.parentOverrides);
36         me.tabPanel = tabPanel;
37
38         tabPanel.on({
39             render: function() {
40                 me.tabBar = tabPanel.tabBar;
41                 me.layout = me.tabBar.layout;
42                 me.layout.overflowHandler.handleOverflow = Ext.Function.bind(me.showButton, me);
43                 me.layout.overflowHandler.clearOverflow = Ext.Function.createSequence(me.layout.overflowHandler.clearOverflow, me.hideButton, me);
44             },
45             single: true
46         });
47     },
48
49     showButton: function() {
50         var me = this,
51             result = Ext.getClass(me.layout.overflowHandler).prototype.handleOverflow.apply(me.layout.overflowHandler, arguments);
52
53         if (!me.menuButton) {
54             me.menuButton = me.tabBar.body.createChild({
55                 cls: Ext.baseCSSPrefix + 'tab-tabmenu-right'
56             }, me.tabBar.body.child('.' + Ext.baseCSSPrefix + 'box-scroller-right'));
57             me.menuButton.addClsOnOver(Ext.baseCSSPrefix + 'tab-tabmenu-over');
58             me.menuButton.on('click', me.showTabsMenu, me);
59         }
60         me.menuButton.show();
61         result.targetSize.width -= me.menuButton.getWidth();
62         return result;
63     },
64
65     hideButton: function() {
66         var me = this;
67         if (me.menuButton) {
68             me.menuButton.hide();
69         }
70     },
71
72     /**
73      * Returns an the current page size (this.pageSize);
74      * @return {Number} this.pageSize The current page size.
75      */
76     getPageSize: function() {
77         return this.pageSize;
78     },
79     /**
80      * Sets the number of menu items per submenu "page size".
81      * @param {Number} pageSize The page size
82      */
83     setPageSize: function(pageSize) {
84         this.pageSize = pageSize;
85     },
86     /**
87      * Returns the current maxText length;
88      * @return {Number} this.maxText The current max text length.
89      */
90     getMaxText: function() {
91         return this.maxText;
92     },
93     /**
94      * Sets the maximum text size for each menu item.
95      * @param {Number} t The max text per each menu item.
96      */
97     setMaxText: function(t) {
98         this.maxText = t;
99     },
100     /**
101      * Returns the current menu prefix text String.;
102      * @return {String} this.menuPrefixText The current menu prefix text.
103      */
104     getMenuPrefixText: function() {
105         return this.menuPrefixText;
106     },
107     /**
108      * Sets the menu prefix text String.
109      * @param {String} t The menu prefix text.
110      */
111     setMenuPrefixText: function(t) {
112         this.menuPrefixText = t;
113     },
114
115     showTabsMenu: function(e) {
116         var me = this;
117
118         if (me.tabsMenu) {
119             me.tabsMenu.removeAll();
120         } else {
121             me.tabsMenu = Ext.create('Ext.menu.Menu');
122             me.tabPanel.on('destroy', me.tabsMenu.destroy, me.tabsMenu);
123         }
124
125         me.generateTabMenuItems();
126
127         var target = Ext.get(e.getTarget());
128         var xy = target.getXY();
129
130         //Y param + 24 pixels
131         xy[1] += 24;
132
133         me.tabsMenu.showAt(xy);
134     },
135
136     // private
137     generateTabMenuItems: function() {
138         var me = this,
139             tabPanel = me.tabPanel,
140             curActive = tabPanel.getActiveTab(),
141             totalItems = tabPanel.items.getCount(),
142             pageSize = me.getPageSize(),
143             numSubMenus = Math.floor(totalItems / pageSize),
144             remainder = totalItems % pageSize,
145             i, curPage, menuItems, x, item, start, index;
146
147         if (totalItems > pageSize) {
148
149             // Loop through all of the items and create submenus in chunks of 10
150             for (i = 0; i < numSubMenus; i++) {
151                 curPage = (i + 1) * pageSize;
152                 menuItems = [];
153
154                 for (x = 0; x < pageSize; x++) {
155                     index = x + curPage - pageSize;
156                     item = tabPanel.items.get(index);
157                     menuItems.push(me.autoGenMenuItem(item));
158                 }
159
160                 me.tabsMenu.add({
161                     text: me.getMenuPrefixText() + ' ' + (curPage - pageSize + 1) + ' - ' + curPage,
162                     menu: menuItems
163                 });
164             }
165             // remaining items
166             if (remainder > 0) {
167                 start = numSubMenus * pageSize;
168                 menuItems = [];
169                 for (i = start; i < totalItems; i++) {
170                     item = tabPanel.items.get(i);
171                     menuItems.push(me.autoGenMenuItem(item));
172                 }
173
174                 me.tabsMenu.add({
175                     text: me.menuPrefixText + ' ' + (start + 1) + ' - ' + (start + menuItems.length),
176                     menu: menuItems
177                 });
178
179             }
180         }
181         else {
182             tabPanel.items.each(function(item) {
183                 if (item.id != curActive.id && !item.hidden) {
184                     me.tabsMenu.add(me.autoGenMenuItem(item));
185                 }
186             });
187         }
188     },
189
190     // private
191     autoGenMenuItem: function(item) {
192         var maxText = this.getMaxText(),
193             text = Ext.util.Format.ellipsis(item.title, maxText);
194
195         return {
196             text: text,
197             handler: this.showTabFromMenu,
198             scope: this,
199             disabled: item.disabled,
200             tabToShow: item,
201             iconCls: item.iconCls
202         };
203     },
204
205     // private
206     showTabFromMenu: function(menuItem) {
207         this.tabPanel.setActiveTab(menuItem.tabToShow);
208     }
209 });