Upgrade to ExtJS 4.0.2 - Released 06/09/2011
[extjs.git] / src / menu / KeyNav.js
1 /*
2
3 This file is part of Ext JS 4
4
5 Copyright (c) 2011 Sencha Inc
6
7 Contact:  http://www.sencha.com/contact
8
9 GNU General Public License Usage
10 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.
11
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
13
14 */
15 /**
16  * @class Ext.menu.KeyNav
17  * @private
18  */
19 Ext.define('Ext.menu.KeyNav', {
20     extend: 'Ext.util.KeyNav',
21
22     requires: ['Ext.FocusManager'],
23     
24     constructor: function(menu) {
25         var me = this;
26
27         me.menu = menu;
28         me.callParent([menu.el, {
29             down: me.down,
30             enter: me.enter,
31             esc: me.escape,
32             left: me.left,
33             right: me.right,
34             space: me.enter,
35             tab: me.tab,
36             up: me.up
37         }]);
38     },
39
40     down: function(e) {
41         var me = this,
42             fi = me.menu.focusedItem;
43
44         if (fi && e.getKey() == Ext.EventObject.DOWN && me.isWhitelisted(fi)) {
45             return true;
46         }
47         me.focusNextItem(1);
48     },
49
50     enter: function(e) {
51         var menu = this.menu;
52
53         if (menu.activeItem) {
54             menu.onClick(e);
55         }
56     },
57
58     escape: function(e) {
59         Ext.menu.Manager.hideAll();
60     },
61
62     focusNextItem: function(step) {
63         var menu = this.menu,
64             items = menu.items,
65             focusedItem = menu.focusedItem,
66             startIdx = focusedItem ? items.indexOf(focusedItem) : -1,
67             idx = startIdx + step;
68
69         while (idx != startIdx) {
70             if (idx < 0) {
71                 idx = items.length - 1;
72             } else if (idx >= items.length) {
73                 idx = 0;
74             }
75
76             var item = items.getAt(idx);
77             if (menu.canActivateItem(item)) {
78                 menu.setActiveItem(item);
79                 break;
80             }
81             idx += step;
82         }
83     },
84
85     isWhitelisted: function(item) {
86         return Ext.FocusManager.isWhitelisted(item);
87     },
88
89     left: function(e) {
90         var menu = this.menu,
91             fi = menu.focusedItem,
92             ai = menu.activeItem;
93
94         if (fi && this.isWhitelisted(fi)) {
95             return true;
96         }
97
98         menu.hide();
99         if (menu.parentMenu) {
100             menu.parentMenu.focus();
101         }
102     },
103
104     right: function(e) {
105         var menu = this.menu,
106             fi = menu.focusedItem,
107             ai = menu.activeItem,
108             am;
109
110         if (fi && this.isWhitelisted(fi)) {
111             return true;
112         }
113
114         if (ai) {
115             am = menu.activeItem.menu;
116             if (am) {
117                 ai.expandMenu(0);
118                 Ext.defer(function() {
119                     am.setActiveItem(am.items.getAt(0));
120                 }, 25);
121             }
122         }
123     },
124
125     tab: function(e) {
126         var me = this;
127
128         if (e.shiftKey) {
129             me.up(e);
130         } else {
131             me.down(e);
132         }
133     },
134
135     up: function(e) {
136         var me = this,
137             fi = me.menu.focusedItem;
138
139         if (fi && e.getKey() == Ext.EventObject.UP && me.isWhitelisted(fi)) {
140             return true;
141         }
142         me.focusNextItem(-1);
143     }
144 });