TabScrollerMenu.js 6.4 KB

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