TabScrollerMenu.js 6.7 KB

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