commit extjs-2.2.1
[extjs.git] / source / widgets / menu / MenuMgr.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.menu.MenuMgr\r
11  * Provides a common registry of all menu items on a page so that they can be easily accessed by id.\r
12  * @singleton\r
13  */\r
14 Ext.menu.MenuMgr = function(){\r
15    var menus, active, groups = {}, attached = false, lastShow = new Date();\r
16 \r
17    // private - called when first menu is created\r
18    function init(){\r
19        menus = {};\r
20        active = new Ext.util.MixedCollection();\r
21        Ext.getDoc().addKeyListener(27, function(){\r
22            if(active.length > 0){\r
23                hideAll();\r
24            }\r
25        });\r
26    }\r
27 \r
28    // private\r
29    function hideAll(){\r
30        if(active && active.length > 0){\r
31            var c = active.clone();\r
32            c.each(function(m){\r
33                m.hide();\r
34            });\r
35        }\r
36    }\r
37 \r
38    // private\r
39    function onHide(m){\r
40        active.remove(m);\r
41        if(active.length < 1){\r
42            Ext.getDoc().un("mousedown", onMouseDown);\r
43            attached = false;\r
44        }\r
45    }\r
46 \r
47    // private\r
48    function onShow(m){\r
49        var last = active.last();\r
50        lastShow = new Date();\r
51        active.add(m);\r
52        if(!attached){\r
53            Ext.getDoc().on("mousedown", onMouseDown);\r
54            attached = true;\r
55        }\r
56        if(m.parentMenu){\r
57           m.getEl().setZIndex(parseInt(m.parentMenu.getEl().getStyle("z-index"), 10) + 3);\r
58           m.parentMenu.activeChild = m;\r
59        }else if(last && last.isVisible()){\r
60           m.getEl().setZIndex(parseInt(last.getEl().getStyle("z-index"), 10) + 3);\r
61        }\r
62    }\r
63 \r
64    // private\r
65    function onBeforeHide(m){\r
66        if(m.activeChild){\r
67            m.activeChild.hide();\r
68        }\r
69        if(m.autoHideTimer){\r
70            clearTimeout(m.autoHideTimer);\r
71            delete m.autoHideTimer;\r
72        }\r
73    }\r
74 \r
75    // private\r
76    function onBeforeShow(m){\r
77        var pm = m.parentMenu;\r
78        if(!pm && !m.allowOtherMenus){\r
79            hideAll();\r
80        }else if(pm && pm.activeChild){\r
81            pm.activeChild.hide();\r
82        }\r
83    }\r
84 \r
85    // private\r
86    function onMouseDown(e){\r
87        if(lastShow.getElapsed() > 50 && active.length > 0 && !e.getTarget(".x-menu")){\r
88            hideAll();\r
89        }\r
90    }\r
91 \r
92    // private\r
93    function onBeforeCheck(mi, state){\r
94        if(state){\r
95            var g = groups[mi.group];\r
96            for(var i = 0, l = g.length; i < l; i++){\r
97                if(g[i] != mi){\r
98                    g[i].setChecked(false);\r
99                }\r
100            }\r
101        }\r
102    }\r
103 \r
104    return {\r
105 \r
106        /**\r
107         * Hides all menus that are currently visible\r
108         */\r
109        hideAll : function(){\r
110             hideAll();  \r
111        },\r
112 \r
113        // private\r
114        register : function(menu){\r
115            if(!menus){\r
116                init();\r
117            }\r
118            menus[menu.id] = menu;\r
119            menu.on("beforehide", onBeforeHide);\r
120            menu.on("hide", onHide);\r
121            menu.on("beforeshow", onBeforeShow);\r
122            menu.on("show", onShow);\r
123            var g = menu.group;\r
124            if(g && menu.events["checkchange"]){\r
125                if(!groups[g]){\r
126                    groups[g] = [];\r
127                }\r
128                groups[g].push(menu);\r
129                menu.on("checkchange", onCheck);\r
130            }\r
131        },\r
132 \r
133         /**\r
134          * Returns a {@link Ext.menu.Menu} object\r
135          * @param {String/Object} menu The string menu id, an existing menu object reference, or a Menu config that will\r
136          * be used to generate and return a new Menu instance.\r
137          * @return {Ext.menu.Menu} The specified menu, or null if none are found\r
138          */\r
139        get : function(menu){\r
140            if(typeof menu == "string"){ // menu id\r
141                if(!menus){  // not initialized, no menus to return\r
142                    return null;\r
143                }\r
144                return menus[menu];\r
145            }else if(menu.events){  // menu instance\r
146                return menu;\r
147            }else if(typeof menu.length == 'number'){ // array of menu items?\r
148                return new Ext.menu.Menu({items:menu});\r
149            }else{ // otherwise, must be a config\r
150                return new Ext.menu.Menu(menu);\r
151            }\r
152        },\r
153 \r
154        // private\r
155        unregister : function(menu){\r
156            delete menus[menu.id];\r
157            menu.un("beforehide", onBeforeHide);\r
158            menu.un("hide", onHide);\r
159            menu.un("beforeshow", onBeforeShow);\r
160            menu.un("show", onShow);\r
161            var g = menu.group;\r
162            if(g && menu.events["checkchange"]){\r
163                groups[g].remove(menu);\r
164                menu.un("checkchange", onCheck);\r
165            }\r
166        },\r
167 \r
168        // private\r
169        registerCheckable : function(menuItem){\r
170            var g = menuItem.group;\r
171            if(g){\r
172                if(!groups[g]){\r
173                    groups[g] = [];\r
174                }\r
175                groups[g].push(menuItem);\r
176                menuItem.on("beforecheckchange", onBeforeCheck);\r
177            }\r
178        },\r
179 \r
180        // private\r
181        unregisterCheckable : function(menuItem){\r
182            var g = menuItem.group;\r
183            if(g){\r
184                groups[g].remove(menuItem);\r
185                menuItem.un("beforecheckchange", onBeforeCheck);\r
186            }\r
187        },\r
188 \r
189        getCheckedItem : function(groupId){\r
190            var g = groups[groupId];\r
191            if(g){\r
192                for(var i = 0, l = g.length; i < l; i++){\r
193                    if(g[i].checked){\r
194                        return g[i];\r
195                    }\r
196                }\r
197            }\r
198            return null;\r
199        },\r
200 \r
201        setCheckedItem : function(groupId, itemId){\r
202            var g = groups[groupId];\r
203            if(g){\r
204                for(var i = 0, l = g.length; i < l; i++){\r
205                    if(g[i].id == itemId){\r
206                        g[i].setChecked(true);\r
207                    }\r
208                }\r
209            }\r
210            return null;\r
211        }\r
212    };\r
213 }();\r