Upgrade to ExtJS 4.0.2 - Released 06/09/2011
[extjs.git] / examples / desktop / js / StartMenu.js
index ebd23b7..b34f3ff 100644 (file)
-/*\r
- * Ext JS Library 2.2.1\r
- * Copyright(c) 2006-2009, Ext JS, LLC.\r
- * licensing@extjs.com\r
- * \r
- * http://extjs.com/license\r
- */\r
-\r
-/**\r
- * @class Ext.ux.StartMenu\r
- * @extends Ext.menu.Menu\r
- * A start menu object.\r
- * @constructor\r
- * Creates a new StartMenu\r
- * @param {Object} config Configuration options\r
- *\r
- * SAMPLE USAGE:\r
- *\r
- * this.startMenu = new Ext.ux.StartMenu({\r
- *             iconCls: 'user',\r
- *             height: 300,\r
- *             shadow: true,\r
- *             title: get_cookie('memberName'),\r
- *             width: 300\r
- *     });\r
- *\r
- * this.startMenu.add({\r
- *             text: 'Grid Window',\r
- *             iconCls:'icon-grid',\r
- *             handler : this.createWindow,\r
- *             scope: this\r
- *     });\r
- *\r
- * this.startMenu.addTool({\r
- *             text:'Logout',\r
- *             iconCls:'logout',\r
- *             handler:function(){ window.location = "logout.php"; },\r
- *             scope:this\r
- *     });\r
- */\r
-\r
-Ext.namespace("Ext.ux");\r
-\r
-Ext.ux.StartMenu = function(config){\r
-       Ext.ux.StartMenu.superclass.constructor.call(this, config);\r
-    \r
-    var tools = this.toolItems;\r
-    this.toolItems = new Ext.util.MixedCollection();\r
-    if(tools){\r
-        this.addTool.apply(this, tools);\r
-    }\r
-};\r
-\r
-Ext.extend(Ext.ux.StartMenu, Ext.menu.Menu, {\r
-    // private\r
-    render : function(){\r
-        if(this.el){\r
-            return;\r
-        }\r
-        var el = this.el = new Ext.Layer({\r
-            cls: "x-menu ux-start-menu", // this might affect item click\r
-            shadow:this.shadow,\r
-            constrain: false,\r
-            parentEl: this.parentEl || document.body,\r
-            zindex:15000\r
-        });\r
-        \r
-        var header = el.createChild({\r
-               tag: "div",\r
-               cls: "x-window-header x-unselectable x-panel-icon "+this.iconCls\r
-        });\r
-               this.header = header;\r
-               var headerText = header.createChild({\r
-                       tag: "span",\r
-                       cls: "x-window-header-text"\r
-               });\r
-               var tl = header.wrap({\r
-                       cls: "ux-start-menu-tl"\r
-               });\r
-               var tr = header.wrap({\r
-                       cls: "ux-start-menu-tr"\r
-               });\r
-               var tc = header.wrap({\r
-                       cls: "ux-start-menu-tc"\r
-               });\r
-               \r
-               this.menuBWrap = el.createChild({\r
-                       tag: "div",\r
-                       cls: "x-window-body x-border-layout-ct ux-start-menu-body"\r
-               });\r
-               var ml = this.menuBWrap.wrap({\r
-                       cls: "ux-start-menu-ml"\r
-               });\r
-               var mc = this.menuBWrap.wrap({\r
-                       cls: "x-window-mc ux-start-menu-bwrap"\r
-               });\r
-               \r
-               this.menuPanel = this.menuBWrap.createChild({\r
-                       tag: "div",\r
-                       cls: "x-panel x-border-panel ux-start-menu-apps-panel"\r
-               });\r
-               this.toolsPanel = this.menuBWrap.createChild({\r
-                       tag: "div",\r
-                       cls: "x-panel x-border-panel ux-start-menu-tools-panel"\r
-               });\r
-               \r
-               var bwrap = ml.wrap({cls: "x-window-bwrap"});\r
-               var bc = bwrap.createChild({\r
-                       tag: "div",\r
-                       cls: "ux-start-menu-bc"\r
-               });\r
-               var bl = bc.wrap({\r
-                       cls: "ux-start-menu-bl x-panel-nofooter"\r
-               });\r
-               var br = bc.wrap({\r
-                       cls: "ux-start-menu-br"\r
-               });\r
-               \r
-        this.keyNav = new Ext.menu.MenuNav(this);\r
-\r
-        if(this.plain){\r
-            el.addClass("x-menu-plain");\r
-        }\r
-        if(this.cls){\r
-            el.addClass(this.cls);\r
-        }\r
-        // generic focus element\r
-        this.focusEl = el.createChild({\r
-            tag: "a",\r
-            cls: "x-menu-focus",\r
-            href: "#",\r
-            onclick: "return false;",\r
-            tabIndex:"-1"\r
-        });\r
-        \r
-        var ul = this.menuPanel.createChild({\r
-               tag: "ul",\r
-               cls: "x-menu-list"});\r
-        var toolsUl = this.toolsPanel.createChild({\r
-               tag: "ul",\r
-               cls: "x-menu-list"\r
-        });\r
-        \r
-        var ulListeners = {\r
-               "click": {\r
-                       fn: this.onClick,\r
-                       scope: this\r
-               },\r
-               "mouseover": {\r
-                       fn: this.onMouseOver,\r
-                       scope: this\r
-               },\r
-               "mouseout": {\r
-                       fn: this.onMouseOut,\r
-                       scope: this\r
-               }\r
-        };\r
-        \r
-        ul.on(ulListeners);\r
-        \r
-        this.items.each(\r
-               function(item){\r
-                   var li = document.createElement("li");\r
-                   li.className = "x-menu-list-item";\r
-                   ul.dom.appendChild(li);\r
-                   item.render(li, this);\r
-               }, this);\r
-\r
-        this.ul = ul;\r
-        this.autoWidth();\r
-\r
-        toolsUl.on(ulListeners);\r
-        \r
-        this.toolItems.each(\r
-               function(item){\r
-                   var li = document.createElement("li");\r
-                   li.className = "x-menu-list-item";\r
-                   toolsUl.dom.appendChild(li);\r
-                   item.render(li, this);\r
-               }, this);\r
-               \r
-        this.toolsUl = toolsUl;\r
-        this.autoWidth();\r
-             \r
-        this.menuBWrap.setStyle('position', 'relative');  \r
-        this.menuBWrap.setHeight(this.height);\r
-        \r
-        this.menuPanel.setStyle({\r
-               padding: '2px',\r
-               position: 'absolute',\r
-               overflow: 'auto'\r
-        });\r
-        \r
-        this.toolsPanel.setStyle({\r
-               padding: '2px 4px 2px 2px',\r
-               position: 'absolute',\r
-               overflow: 'auto'\r
-        });\r
-        \r
-        this.setTitle(this.title);\r
-    },\r
-    \r
-    // private\r
-    findTargetItem : function(e){\r
-        var t = e.getTarget(".x-menu-list-item", this.ul,  true);\r
-        if(t && t.menuItemId){\r
-               if(this.items.get(t.menuItemId)){\r
-               return this.items.get(t.menuItemId);\r
-            }else{\r
-               return this.toolItems.get(t.menuItemId);\r
-            }\r
-        }\r
-    },\r
-\r
-    /**\r
-     * Displays this menu relative to another element\r
-     * @param {Mixed} element The element to align to\r
-     * @param {String} position (optional) The {@link Ext.Element#alignTo} anchor position to use in aligning to\r
-     * the element (defaults to this.defaultAlign)\r
-     * @param {Ext.ux.StartMenu} parentMenu (optional) This menu's parent menu, if applicable (defaults to undefined)\r
-     */\r
-    show : function(el, pos, parentMenu){\r
-        this.parentMenu = parentMenu;\r
-        if(!this.el){\r
-            this.render();\r
-        }\r
-\r
-        this.fireEvent("beforeshow", this);\r
-        this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign), parentMenu, false);\r
-        \r
-        var tPanelWidth = 100;      \r
-        var box = this.menuBWrap.getBox();\r
-        this.menuPanel.setWidth(box.width-tPanelWidth);\r
-        this.menuPanel.setHeight(box.height);\r
-        \r
-        this.toolsPanel.setWidth(tPanelWidth);\r
-        this.toolsPanel.setX(box.x+box.width-tPanelWidth);\r
-        this.toolsPanel.setHeight(box.height);\r
-    },\r
-    \r
-    addTool : function(){\r
-        var a = arguments, l = a.length, item;\r
-        for(var i = 0; i < l; i++){\r
-            var el = a[i];\r
-            if(el.render){ // some kind of Item\r
-                item = this.addToolItem(el);\r
-            }else if(typeof el == "string"){ // string\r
-                if(el == "separator" || el == "-"){\r
-                    item = this.addToolSeparator();\r
-                }else{\r
-                    item = this.addText(el);\r
-                }\r
-            }else if(el.tagName || el.el){ // element\r
-                item = this.addElement(el);\r
-            }else if(typeof el == "object"){ // must be menu item config?\r
-                item = this.addToolMenuItem(el);\r
-            }\r
-        }\r
-        return item;\r
-    },\r
-    \r
-    /**\r
-     * Adds a separator bar to the Tools\r
-     * @return {Ext.menu.Item} The menu item that was added\r
-     */\r
-    addToolSeparator : function(){\r
-        return this.addToolItem(new Ext.menu.Separator({itemCls: 'ux-toolmenu-sep'}));\r
-    },\r
-\r
-    addToolItem : function(item){\r
-        this.toolItems.add(item);\r
-        if(this.ul){\r
-            var li = document.createElement("li");\r
-            li.className = "x-menu-list-item";\r
-            this.ul.dom.appendChild(li);\r
-            item.render(li, this);\r
-            this.delayAutoWidth();\r
-        }\r
-        return item;\r
-    },\r
-\r
-    addToolMenuItem : function(config){\r
-        if(!(config instanceof Ext.menu.Item)){\r
-            if(typeof config.checked == "boolean"){ // must be check menu item config?\r
-                config = new Ext.menu.CheckItem(config);\r
-            }else{\r
-                config = new Ext.menu.Item(config);\r
-            }\r
-        }\r
-        return this.addToolItem(config);\r
-    },\r
-    \r
-    setTitle : function(title, iconCls){\r
-        this.title = title;\r
-        this.header.child('span').update(title);\r
-        return this;\r
-    }\r
-});
\ No newline at end of file
+/*
+
+This file is part of Ext JS 4
+
+Copyright (c) 2011 Sencha Inc
+
+Contact:  http://www.sencha.com/contact
+
+GNU General Public License Usage
+This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file.  Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+
+If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
+
+*/
+/*!
+ * Ext JS Library 4.0
+ * Copyright(c) 2006-2011 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
+ */
+
+Ext.define('Ext.ux.desktop.StartMenu', {
+    extend: 'Ext.panel.Panel',
+
+    requires: [
+        'Ext.menu.Menu',
+        'Ext.toolbar.Toolbar'
+    ],
+
+    ariaRole: 'menu',
+
+    cls: 'x-menu ux-start-menu',
+
+    defaultAlign: 'bl-tl',
+
+    iconCls: 'user',
+
+    floating: true,
+
+    shadow: true,
+
+    // We have to hardcode a width because the internal Menu cannot drive our width.
+    // This is combined with changing the align property of the menu's layout from the
+    // typical 'stretchmax' to 'stretch' which allows the the items to fill the menu
+    // area.
+    width: 300,
+
+    initComponent: function() {
+        var me = this, menu = me.menu;
+
+        me.menu = new Ext.menu.Menu({
+            cls: 'ux-start-menu-body',
+            border: false,
+            floating: false,
+            items: menu
+        });
+        me.menu.layout.align = 'stretch';
+
+        me.items = [me.menu];
+        me.layout = 'fit';
+
+        Ext.menu.Manager.register(me);
+        me.callParent();
+        // TODO - relay menu events
+
+        me.toolbar = new Ext.toolbar.Toolbar(Ext.apply({
+            dock: 'right',
+            cls: 'ux-start-menu-toolbar',
+            vertical: true,
+            width: 100
+        }, me.toolConfig));
+
+        me.toolbar.layout.align = 'stretch';
+        me.addDocked(me.toolbar);
+
+        delete me.toolItems;
+
+        me.on('deactivate', function () {
+            me.hide();
+        });
+    },
+
+    addMenuItem: function() {
+        var cmp = this.menu;
+        cmp.add.apply(cmp, arguments);
+    },
+
+    addToolItem: function() {
+        var cmp = this.toolbar;
+        cmp.add.apply(cmp, arguments);
+    },
+
+    showBy: function(cmp, pos, off) {
+        var me = this;
+
+        if (me.floating && cmp) {
+            me.layout.autoSize = true;
+            me.show();
+
+            // Component or Element
+            cmp = cmp.el || cmp;
+
+            // Convert absolute to floatParent-relative coordinates if necessary.
+            var xy = me.el.getAlignToXY(cmp, pos || me.defaultAlign, off);
+            if (me.floatParent) {
+                var r = me.floatParent.getTargetEl().getViewRegion();
+                xy[0] -= r.x;
+                xy[1] -= r.y;
+            }
+            me.showAt(xy);
+            me.doConstrain();
+        }
+        return me;
+    }
+}); // StartMenu
+