Upgrade to ExtJS 4.0.0 - Released 04/26/2011
[extjs.git] / src / menu / KeyNav.js
1 /**
2  * @class Ext.menu.KeyNav
3  * @private
4  */
5 Ext.define('Ext.menu.KeyNav', {
6     extend: 'Ext.util.KeyNav',
7
8     requires: ['Ext.FocusManager'],
9     
10     constructor: function(menu) {
11         var me = this;
12
13         me.menu = menu;
14         me.callParent([menu.el, {
15             down: me.down,
16             enter: me.enter,
17             esc: me.escape,
18             left: me.left,
19             right: me.right,
20             space: me.enter,
21             tab: me.tab,
22             up: me.up
23         }]);
24     },
25
26     down: function(e) {
27         var me = this,
28             fi = me.menu.focusedItem;
29
30         if (fi && e.getKey() == Ext.EventObject.DOWN && me.isWhitelisted(fi)) {
31             return true;
32         }
33         me.focusNextItem(1);
34     },
35
36     enter: function(e) {
37         var menu = this.menu;
38
39         if (menu.activeItem) {
40             menu.onClick(e);
41         }
42     },
43
44     escape: function(e) {
45         Ext.menu.Manager.hideAll();
46     },
47
48     focusNextItem: function(step) {
49         var menu = this.menu,
50             items = menu.items,
51             focusedItem = menu.focusedItem,
52             startIdx = focusedItem ? items.indexOf(focusedItem) : -1,
53             idx = startIdx + step;
54
55         while (idx != startIdx) {
56             if (idx < 0) {
57                 idx = items.length - 1;
58             } else if (idx >= items.length) {
59                 idx = 0;
60             }
61
62             var item = items.getAt(idx);
63             if (menu.canActivateItem(item)) {
64                 menu.setActiveItem(item);
65                 break;
66             }
67             idx += step;
68         }
69     },
70
71     isWhitelisted: function(item) {
72         return Ext.FocusManager.isWhitelisted(item);
73     },
74
75     left: function(e) {
76         var menu = this.menu,
77             fi = menu.focusedItem,
78             ai = menu.activeItem;
79
80         if (fi && this.isWhitelisted(fi)) {
81             return true;
82         }
83
84         menu.hide();
85         if (menu.parentMenu) {
86             menu.parentMenu.focus();
87         }
88     },
89
90     right: function(e) {
91         var menu = this.menu,
92             fi = menu.focusedItem,
93             ai = menu.activeItem,
94             am;
95
96         if (fi && this.isWhitelisted(fi)) {
97             return true;
98         }
99
100         if (ai) {
101             am = menu.activeItem.menu;
102             if (am) {
103                 ai.expandMenu(0);
104                 Ext.defer(function() {
105                     am.setActiveItem(am.items.getAt(0));
106                 }, 25);
107             }
108         }
109     },
110
111     tab: function(e) {
112         var me = this;
113
114         if (e.shiftKey) {
115             me.up(e);
116         } else {
117             me.down(e);
118         }
119     },
120
121     up: function(e) {
122         var me = this,
123             fi = me.menu.focusedItem;
124
125         if (fi && e.getKey() == Ext.EventObject.UP && me.isWhitelisted(fi)) {
126             return true;
127         }
128         me.focusNextItem(-1);
129     }
130 });