Upgrade to ExtJS 4.0.0 - Released 04/26/2011
[extjs.git] / examples / ux / TabCloseMenu.js
index a3da213..a896450 100644 (file)
@@ -1,36 +1,42 @@
-/*!
- * Ext JS Library 3.3.1
- * Copyright(c) 2006-2010 Sencha Inc.
- * licensing@sencha.com
- * http://www.sencha.com/license
- */
 /**
  * @class Ext.ux.TabCloseMenu
- * @extends Object 
  * Plugin (ptype = 'tabclosemenu') for adding a close context menu to tabs. Note that the menu respects
  * the closable configuration on the tab. As such, commands like remove others and remove all will not
  * remove items that are not closable.
- * 
+ *
  * @constructor
  * @param {Object} config The configuration options
  * @ptype tabclosemenu
  */
-Ext.ux.TabCloseMenu = Ext.extend(Object, {
+Ext.define('Ext.tab.TabCloseMenu', {
+    alias: 'plugin.tabclosemenu',
+    alternateClassName: 'Ext.ux.TabCloseMenu',
+
+    mixins: {
+        observable: 'Ext.util.Observable'
+    },
+
     /**
      * @cfg {String} closeTabText
      * The text for closing the current tab. Defaults to <tt>'Close Tab'</tt>.
      */
     closeTabText: 'Close Tab',
 
+    /**
+     * @cfg {Boolean} showCloseOthers
+     * Indicates whether to show the 'Close Others' option. Defaults to <tt>true</tt>.
+     */
+    showCloseOthers: true,
+
     /**
      * @cfg {String} closeOtherTabsText
      * The text for closing all tabs except the current one. Defaults to <tt>'Close Other Tabs'</tt>.
      */
-    closeOtherTabsText: 'Close Other Tabs',
-    
+    closeOthersTabsText: 'Close Other Tabs',
+
     /**
      * @cfg {Boolean} showCloseAll
-     * Indicates whether to show the 'Close All' option. Defaults to <tt>true</tt>. 
+     * Indicates whether to show the 'Close All' option. Defaults to <tt>true</tt>.
      */
     showCloseAll: true,
 
@@ -39,112 +45,173 @@ Ext.ux.TabCloseMenu = Ext.extend(Object, {
      * <p>The text for closing all tabs. Defaults to <tt>'Close All Tabs'</tt>.
      */
     closeAllTabsText: 'Close All Tabs',
-    
-    constructor : function(config){
-        Ext.apply(this, config || {});
-    },
+
+    /**
+     * @cfg {Array} extraItemsHead
+     * An array of additional context menu items to add to the front of the context menu.
+     */
+    extraItemsHead: null,
+
+    /**
+     * @cfg {Array} extraItemsTail
+     * An array of additional context menu items to add to the end of the context menu.
+     */
+    extraItemsTail: null,
 
     //public
-    init : function(tabs){
-        this.tabs = tabs;
-        tabs.on({
+    constructor: function (config) {
+        this.addEvents(
+            'aftermenu',
+            'beforemenu');
+
+        this.mixins.observable.constructor.call(this, config);
+    },
+
+    init : function(tabpanel){
+        this.tabPanel = tabpanel;
+        this.tabBar = tabpanel.down("tabbar");
+
+        this.mon(this.tabPanel, {
+            scope: this,
+            afterlayout: this.onAfterLayout,
+            single: true
+        });
+    },
+
+    onAfterLayout: function() {
+        this.mon(this.tabBar.el, {
             scope: this,
             contextmenu: this.onContextMenu,
-            destroy: this.destroy
+            delegate: 'div.x-tab'
         });
     },
-    
-    destroy : function(){
+
+    onBeforeDestroy : function(){
         Ext.destroy(this.menu);
-        delete this.menu;
-        delete this.tabs;
-        delete this.active;    
+        this.callParent(arguments);
     },
 
     // private
-    onContextMenu : function(tabs, item, e){
-        this.active = item;
-        var m = this.createMenu(),
+    onContextMenu : function(event, target){
+        var me = this,
+            menu = me.createMenu(),
             disableAll = true,
             disableOthers = true,
-            closeAll = m.getComponent('closeall');
-        
-        m.getComponent('close').setDisabled(!item.closable);
-        tabs.items.each(function(){
-            if(this.closable){
-                disableAll = false;
-                if(this != item){
-                    disableOthers = false;
-                    return false;
+            tab = me.tabBar.getChildByElement(target),
+            index = me.tabBar.items.indexOf(tab);
+
+        me.item = me.tabPanel.getComponent(index);
+        menu.child('*[text="' + me.closeTabText + '"]').setDisabled(!me.item.closable);
+
+        if (me.showCloseAll || me.showCloseOthers) {
+            me.tabPanel.items.each(function(item) {
+                if (item.closable) {
+                    disableAll = false;
+                    if (item != me.item) {
+                        disableOthers = false;
+                        return false;
+                    }
                 }
+                return true;
+            });
+
+            if (me.showCloseAll) {
+                menu.child('*[text="' + me.closeAllTabsText + '"]').setDisabled(disableAll);
+            }
+
+            if (me.showCloseOthers) {
+                menu.child('*[text="' + me.closeOthersTabsText + '"]').setDisabled(disableOthers);
             }
-        });
-        m.getComponent('closeothers').setDisabled(disableOthers);
-        if(closeAll){
-            closeAll.setDisabled(disableAll);
         }
-        
-        e.stopEvent();
-        m.showAt(e.getPoint());
+
+        event.preventDefault();
+        me.fireEvent('beforemenu', menu, me.item, me);
+
+        menu.showAt(event.getXY());
     },
-    
-    createMenu : function(){
-        if(!this.menu){
+
+    createMenu : function() {
+        var me = this;
+
+        if (!me.menu) {
             var items = [{
-                itemId: 'close',
-                text: this.closeTabText,
-                scope: this,
-                handler: this.onClose
+                text: me.closeTabText,
+                scope: me,
+                handler: me.onClose
             }];
-            if(this.showCloseAll){
+
+            if (me.showCloseAll || me.showCloseOthers) {
                 items.push('-');
             }
-            items.push({
-                itemId: 'closeothers',
-                text: this.closeOtherTabsText,
-                scope: this,
-                handler: this.onCloseOthers
-            });
-            if(this.showCloseAll){
+
+            if (me.showCloseOthers) {
                 items.push({
-                    itemId: 'closeall',
-                    text: this.closeAllTabsText,
-                    scope: this,
-                    handler: this.onCloseAll
+                    text: me.closeOthersTabsText,
+                    scope: me,
+                    handler: me.onCloseOthers
                 });
             }
-            this.menu = new Ext.menu.Menu({
-                items: items
+
+            if (me.showCloseAll) {
+                items.push({
+                    text: me.closeAllTabsText,
+                    scope: me,
+                    handler: me.onCloseAll
+                });
+            }
+
+            if (me.extraItemsHead) {
+                items = me.extraItemsHead.concat(items);
+            }
+
+            if (me.extraItemsTail) {
+                items = items.concat(me.extraItemsTail);
+            }
+
+            me.menu = Ext.create('Ext.menu.Menu', {
+                items: items,
+                listeners: {
+                    hide: me.onHideMenu,
+                    scope: me
+                }
             });
         }
-        return this.menu;
+
+        return me.menu;
     },
-    
+
+    onHideMenu: function () {
+        var me = this;
+
+        me.item = null;
+        me.fireEvent('aftermenu', me.menu, me);
+    },
+
     onClose : function(){
-        this.tabs.remove(this.active);
+        this.tabPanel.remove(this.item);
     },
-    
+
     onCloseOthers : function(){
         this.doClose(true);
     },
-    
+
     onCloseAll : function(){
         this.doClose(false);
     },
-    
+
     doClose : function(excludeActive){
         var items = [];
-        this.tabs.items.each(function(item){
+
+        this.tabPanel.items.each(function(item){
             if(item.closable){
-                if(!excludeActive || item != this.active){
+                if(!excludeActive || item != this.item){
                     items.push(item);
-                }    
+                }
             }
         }, this);
+
         Ext.each(items, function(item){
-            this.tabs.remove(item);
+            this.tabPanel.remove(item);
         }, this);
     }
 });
-
-Ext.preg('tabclosemenu', Ext.ux.TabCloseMenu);
\ No newline at end of file