TabScrollerMenu.js 6.2 KB

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