commit extjs-2.2.1
[extjs.git] / examples / desktop / js / StartMenu.js
1 /*\r
2  * Ext JS Library 2.2.1\r
3  * Copyright(c) 2006-2009, Ext JS, LLC.\r
4  * licensing@extjs.com\r
5  * \r
6  * http://extjs.com/license\r
7  */\r
8 \r
9 /**\r
10  * @class Ext.ux.StartMenu\r
11  * @extends Ext.menu.Menu\r
12  * A start menu object.\r
13  * @constructor\r
14  * Creates a new StartMenu\r
15  * @param {Object} config Configuration options\r
16  *\r
17  * SAMPLE USAGE:\r
18  *\r
19  * this.startMenu = new Ext.ux.StartMenu({\r
20  *              iconCls: 'user',\r
21  *              height: 300,\r
22  *              shadow: true,\r
23  *              title: get_cookie('memberName'),\r
24  *              width: 300\r
25  *      });\r
26  *\r
27  * this.startMenu.add({\r
28  *              text: 'Grid Window',\r
29  *              iconCls:'icon-grid',\r
30  *              handler : this.createWindow,\r
31  *              scope: this\r
32  *      });\r
33  *\r
34  * this.startMenu.addTool({\r
35  *              text:'Logout',\r
36  *              iconCls:'logout',\r
37  *              handler:function(){ window.location = "logout.php"; },\r
38  *              scope:this\r
39  *      });\r
40  */\r
41 \r
42 Ext.namespace("Ext.ux");\r
43 \r
44 Ext.ux.StartMenu = function(config){\r
45         Ext.ux.StartMenu.superclass.constructor.call(this, config);\r
46     \r
47     var tools = this.toolItems;\r
48     this.toolItems = new Ext.util.MixedCollection();\r
49     if(tools){\r
50         this.addTool.apply(this, tools);\r
51     }\r
52 };\r
53 \r
54 Ext.extend(Ext.ux.StartMenu, Ext.menu.Menu, {\r
55     // private\r
56     render : function(){\r
57         if(this.el){\r
58             return;\r
59         }\r
60         var el = this.el = new Ext.Layer({\r
61             cls: "x-menu ux-start-menu", // this might affect item click\r
62             shadow:this.shadow,\r
63             constrain: false,\r
64             parentEl: this.parentEl || document.body,\r
65             zindex:15000\r
66         });\r
67         \r
68         var header = el.createChild({\r
69                 tag: "div",\r
70                 cls: "x-window-header x-unselectable x-panel-icon "+this.iconCls\r
71         });\r
72                 this.header = header;\r
73                 var headerText = header.createChild({\r
74                         tag: "span",\r
75                         cls: "x-window-header-text"\r
76                 });\r
77                 var tl = header.wrap({\r
78                         cls: "ux-start-menu-tl"\r
79                 });\r
80                 var tr = header.wrap({\r
81                         cls: "ux-start-menu-tr"\r
82                 });\r
83                 var tc = header.wrap({\r
84                         cls: "ux-start-menu-tc"\r
85                 });\r
86                 \r
87                 this.menuBWrap = el.createChild({\r
88                         tag: "div",\r
89                         cls: "x-window-body x-border-layout-ct ux-start-menu-body"\r
90                 });\r
91                 var ml = this.menuBWrap.wrap({\r
92                         cls: "ux-start-menu-ml"\r
93                 });\r
94                 var mc = this.menuBWrap.wrap({\r
95                         cls: "x-window-mc ux-start-menu-bwrap"\r
96                 });\r
97                 \r
98                 this.menuPanel = this.menuBWrap.createChild({\r
99                         tag: "div",\r
100                         cls: "x-panel x-border-panel ux-start-menu-apps-panel"\r
101                 });\r
102                 this.toolsPanel = this.menuBWrap.createChild({\r
103                         tag: "div",\r
104                         cls: "x-panel x-border-panel ux-start-menu-tools-panel"\r
105                 });\r
106                 \r
107                 var bwrap = ml.wrap({cls: "x-window-bwrap"});\r
108                 var bc = bwrap.createChild({\r
109                         tag: "div",\r
110                         cls: "ux-start-menu-bc"\r
111                 });\r
112                 var bl = bc.wrap({\r
113                         cls: "ux-start-menu-bl x-panel-nofooter"\r
114                 });\r
115                 var br = bc.wrap({\r
116                         cls: "ux-start-menu-br"\r
117                 });\r
118                 \r
119         this.keyNav = new Ext.menu.MenuNav(this);\r
120 \r
121         if(this.plain){\r
122             el.addClass("x-menu-plain");\r
123         }\r
124         if(this.cls){\r
125             el.addClass(this.cls);\r
126         }\r
127         // generic focus element\r
128         this.focusEl = el.createChild({\r
129             tag: "a",\r
130             cls: "x-menu-focus",\r
131             href: "#",\r
132             onclick: "return false;",\r
133             tabIndex:"-1"\r
134         });\r
135         \r
136         var ul = this.menuPanel.createChild({\r
137                 tag: "ul",\r
138                 cls: "x-menu-list"});\r
139         var toolsUl = this.toolsPanel.createChild({\r
140                 tag: "ul",\r
141                 cls: "x-menu-list"\r
142         });\r
143         \r
144         var ulListeners = {\r
145                 "click": {\r
146                         fn: this.onClick,\r
147                         scope: this\r
148                 },\r
149                 "mouseover": {\r
150                         fn: this.onMouseOver,\r
151                         scope: this\r
152                 },\r
153                 "mouseout": {\r
154                         fn: this.onMouseOut,\r
155                         scope: this\r
156                 }\r
157         };\r
158         \r
159         ul.on(ulListeners);\r
160         \r
161         this.items.each(\r
162                 function(item){\r
163                     var li = document.createElement("li");\r
164                     li.className = "x-menu-list-item";\r
165                     ul.dom.appendChild(li);\r
166                     item.render(li, this);\r
167                 }, this);\r
168 \r
169         this.ul = ul;\r
170         this.autoWidth();\r
171 \r
172         toolsUl.on(ulListeners);\r
173         \r
174         this.toolItems.each(\r
175                 function(item){\r
176                     var li = document.createElement("li");\r
177                     li.className = "x-menu-list-item";\r
178                     toolsUl.dom.appendChild(li);\r
179                     item.render(li, this);\r
180                 }, this);\r
181                 \r
182         this.toolsUl = toolsUl;\r
183         this.autoWidth();\r
184              \r
185         this.menuBWrap.setStyle('position', 'relative');  \r
186         this.menuBWrap.setHeight(this.height);\r
187         \r
188         this.menuPanel.setStyle({\r
189                 padding: '2px',\r
190                 position: 'absolute',\r
191                 overflow: 'auto'\r
192         });\r
193         \r
194         this.toolsPanel.setStyle({\r
195                 padding: '2px 4px 2px 2px',\r
196                 position: 'absolute',\r
197                 overflow: 'auto'\r
198         });\r
199         \r
200         this.setTitle(this.title);\r
201     },\r
202     \r
203     // private\r
204     findTargetItem : function(e){\r
205         var t = e.getTarget(".x-menu-list-item", this.ul,  true);\r
206         if(t && t.menuItemId){\r
207                 if(this.items.get(t.menuItemId)){\r
208                 return this.items.get(t.menuItemId);\r
209             }else{\r
210                 return this.toolItems.get(t.menuItemId);\r
211             }\r
212         }\r
213     },\r
214 \r
215     /**\r
216      * Displays this menu relative to another element\r
217      * @param {Mixed} element The element to align to\r
218      * @param {String} position (optional) The {@link Ext.Element#alignTo} anchor position to use in aligning to\r
219      * the element (defaults to this.defaultAlign)\r
220      * @param {Ext.ux.StartMenu} parentMenu (optional) This menu's parent menu, if applicable (defaults to undefined)\r
221      */\r
222     show : function(el, pos, parentMenu){\r
223         this.parentMenu = parentMenu;\r
224         if(!this.el){\r
225             this.render();\r
226         }\r
227 \r
228         this.fireEvent("beforeshow", this);\r
229         this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign), parentMenu, false);\r
230         \r
231         var tPanelWidth = 100;      \r
232         var box = this.menuBWrap.getBox();\r
233         this.menuPanel.setWidth(box.width-tPanelWidth);\r
234         this.menuPanel.setHeight(box.height);\r
235         \r
236         this.toolsPanel.setWidth(tPanelWidth);\r
237         this.toolsPanel.setX(box.x+box.width-tPanelWidth);\r
238         this.toolsPanel.setHeight(box.height);\r
239     },\r
240     \r
241     addTool : function(){\r
242         var a = arguments, l = a.length, item;\r
243         for(var i = 0; i < l; i++){\r
244             var el = a[i];\r
245             if(el.render){ // some kind of Item\r
246                 item = this.addToolItem(el);\r
247             }else if(typeof el == "string"){ // string\r
248                 if(el == "separator" || el == "-"){\r
249                     item = this.addToolSeparator();\r
250                 }else{\r
251                     item = this.addText(el);\r
252                 }\r
253             }else if(el.tagName || el.el){ // element\r
254                 item = this.addElement(el);\r
255             }else if(typeof el == "object"){ // must be menu item config?\r
256                 item = this.addToolMenuItem(el);\r
257             }\r
258         }\r
259         return item;\r
260     },\r
261     \r
262     /**\r
263      * Adds a separator bar to the Tools\r
264      * @return {Ext.menu.Item} The menu item that was added\r
265      */\r
266     addToolSeparator : function(){\r
267         return this.addToolItem(new Ext.menu.Separator({itemCls: 'ux-toolmenu-sep'}));\r
268     },\r
269 \r
270     addToolItem : function(item){\r
271         this.toolItems.add(item);\r
272         if(this.ul){\r
273             var li = document.createElement("li");\r
274             li.className = "x-menu-list-item";\r
275             this.ul.dom.appendChild(li);\r
276             item.render(li, this);\r
277             this.delayAutoWidth();\r
278         }\r
279         return item;\r
280     },\r
281 \r
282     addToolMenuItem : function(config){\r
283         if(!(config instanceof Ext.menu.Item)){\r
284             if(typeof config.checked == "boolean"){ // must be check menu item config?\r
285                 config = new Ext.menu.CheckItem(config);\r
286             }else{\r
287                 config = new Ext.menu.Item(config);\r
288             }\r
289         }\r
290         return this.addToolItem(config);\r
291     },\r
292     \r
293     setTitle : function(title, iconCls){\r
294         this.title = title;\r
295         this.header.child('span').update(title);\r
296         return this;\r
297     }\r
298 });