TabCloseMenu.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /**
  2. * Plugin for adding a close context menu to tabs. Note that the menu respects
  3. * the closable configuration on the tab. As such, commands like remove others
  4. * and remove all will not remove items that are not closable.
  5. */
  6. Ext.define('Ext.ux.TabCloseMenu', {
  7. extend: 'Ext.plugin.Abstract',
  8. alias: 'plugin.tabclosemenu',
  9. mixins: {
  10. observable: 'Ext.util.Observable'
  11. },
  12. /**
  13. * @cfg {String} closeTabText
  14. * The text for closing the current tab.
  15. */
  16. closeTabText: '关闭',
  17. /**
  18. * @cfg {Boolean} showCloseOthers
  19. * Indicates whether to show the 'Close Others' option.
  20. */
  21. showCloseOthers: true,
  22. /**
  23. * @cfg {String} closeOthersTabsText
  24. * The text for closing all tabs except the current one.
  25. */
  26. closeOthersTabsText: '关闭其他',
  27. /**
  28. * @cfg {Boolean} showCloseAll
  29. * Indicates whether to show the 'Close All' option.
  30. */
  31. showCloseAll: true,
  32. /**
  33. * @cfg {String} closeAllTabsText
  34. * The text for closing all tabs.
  35. */
  36. closeAllTabsText: '关闭全部',
  37. /**
  38. * @cfg {Array} extraItemsHead
  39. * An array of additional context menu items to add to the front of the context menu.
  40. */
  41. extraItemsHead: null,
  42. /**
  43. * @cfg {Array} extraItemsTail
  44. * An array of additional context menu items to add to the end of the context menu.
  45. */
  46. extraItemsTail: null,
  47. //public
  48. constructor: function (config) {
  49. this.callParent([config]);
  50. this.mixins.observable.constructor.call(this, config);
  51. },
  52. init: function (tabpanel) {
  53. this.tabPanel = tabpanel;
  54. this.tabBar = tabpanel.down("tabbar");
  55. this.mon(this.tabPanel, {
  56. scope: this,
  57. afterlayout: this.onAfterLayout,
  58. single: true
  59. });
  60. },
  61. onAfterLayout: function () {
  62. this.mon(this.tabBar.el, {
  63. scope: this,
  64. contextmenu: this.onContextMenu,
  65. delegate: '.x-tab'
  66. });
  67. },
  68. destroy: function () {
  69. Ext.destroy(this.menu);
  70. this.callParent();
  71. },
  72. /**
  73. * @private
  74. */
  75. onContextMenu: function (event, target) {
  76. var me = this,
  77. menu = me.createMenu(),
  78. disableAll = true,
  79. disableOthers = true,
  80. tab = me.tabBar.getChildByElement(target),
  81. index = me.tabBar.items.indexOf(tab);
  82. me.item = me.tabPanel.getComponent(index);
  83. menu.child('#close').setDisabled(!me.item.closable);
  84. if (me.showCloseAll || me.showCloseOthers) {
  85. me.tabPanel.items.each(function (item) {
  86. if (item.closable) {
  87. disableAll = false;
  88. if (item !== me.item) {
  89. disableOthers = false;
  90. return false;
  91. }
  92. }
  93. return true;
  94. });
  95. if (me.showCloseAll) {
  96. menu.child('#closeAll').setDisabled(disableAll);
  97. }
  98. if (me.showCloseOthers) {
  99. menu.child('#closeOthers').setDisabled(disableOthers);
  100. }
  101. }
  102. event.preventDefault();
  103. me.fireEvent('beforemenu', menu, me.item, me);
  104. menu.showAt(event.getXY());
  105. },
  106. createMenu: function () {
  107. var me = this;
  108. if (!me.menu) {
  109. var items = [{
  110. itemId: 'close',
  111. text: me.closeTabText,
  112. scope: me,
  113. handler: me.onClose
  114. }];
  115. if (me.showCloseAll || me.showCloseOthers) {
  116. items.push('-');
  117. }
  118. if (me.showCloseOthers) {
  119. items.push({
  120. itemId: 'closeOthers',
  121. text: me.closeOthersTabsText,
  122. scope: me,
  123. handler: me.onCloseOthers
  124. });
  125. }
  126. if (me.showCloseAll) {
  127. items.push({
  128. itemId: 'closeAll',
  129. text: me.closeAllTabsText,
  130. scope: me,
  131. handler: me.onCloseAll
  132. });
  133. }
  134. if (me.extraItemsHead) {
  135. items = me.extraItemsHead.concat(items);
  136. }
  137. if (me.extraItemsTail) {
  138. items = items.concat(me.extraItemsTail);
  139. }
  140. me.menu = Ext.create('Ext.menu.Menu', {
  141. items: items,
  142. listeners: {
  143. hide: me.onHideMenu,
  144. scope: me
  145. }
  146. });
  147. }
  148. return me.menu;
  149. },
  150. onHideMenu: function () {
  151. var me = this;
  152. me.fireEvent('aftermenu', me.menu, me);
  153. },
  154. onClose: function () {
  155. this.tabPanel.remove(this.item);
  156. },
  157. onCloseOthers: function () {
  158. this.doClose(true);
  159. },
  160. onCloseAll: function () {
  161. this.doClose(false);
  162. },
  163. doClose: function (excludeActive) {
  164. var items = [];
  165. this.tabPanel.items.each(function (item) {
  166. if (item.closable) {
  167. if (!excludeActive || item !== this.item) {
  168. items.push(item);
  169. }
  170. }
  171. }, this);
  172. Ext.suspendLayouts();
  173. Ext.Array.forEach(items, function (item) {
  174. this.tabPanel.remove(item);
  175. }, this);
  176. Ext.resumeLayouts(true);
  177. }
  178. });