1 package com.vaadin.contextmenu.client;
2
3 import com.google.gwt.core.client.Scheduler;
4 import com.google.gwt.core.client.Scheduler.ScheduledCommand;
5 import com.google.gwt.event.dom.client.KeyCodes;
6 import com.google.gwt.user.client.Command;
7 import com.vaadin.client.ui.VMenuBar;
8 import com.vaadin.client.ui.VOverlay;
9
10
11
12
13
14 public class MyVMenuBar extends VMenuBar {
15
16
17 private boolean isContextMenu = true;
18
19 public MyVMenuBar() {
20 }
21
22 public MyVMenuBar(boolean subMenu, VMenuBar parentMenu) {
23 super(subMenu, parentMenu);
24 }
25
26 @Override
27 protected VOverlay createOverlay() {
28 return new MyVOverlay(true, false);
29 }
30
31
32 @Override
33 protected void showChildMenuAt(CustomMenuItem item, int top, int left) {
34 super.showChildMenuAt(item, top, left);
35 }
36
37
38 @Override
39 public boolean handleNavigation(int keycode, boolean ctrl, boolean shift) {
40
41
42 if (keycode == KeyCodes.KEY_TAB) {
43 setSelected(null);
44 hideChildren();
45 menuVisible = false;
46 return false;
47 }
48
49 if (ctrl || shift || !enabled) {
50
51 return false;
52 }
53
54 if (keycode == getNavigationLeftKey()) {
55 if (getSelected() == null) {
56
57 setSelected(items.get(items.size() - 1));
58 if (!getSelected().isSelectable()) {
59 handleNavigation(keycode, ctrl, shift);
60 }
61 } else if (visibleChildMenu == null && getParentMenu() == null) {
62
63 int idx = items.indexOf(getSelected());
64 if (idx > 0) {
65 setSelected(items.get(idx - 1));
66 } else {
67 setSelected(items.get(items.size() - 1));
68 }
69
70 if (!getSelected().isSelectable()) {
71 handleNavigation(keycode, ctrl, shift);
72 }
73 } else if (visibleChildMenu != null) {
74
75 visibleChildMenu.handleNavigation(keycode, ctrl, shift);
76
77 } else if (getParentMenu().getParentMenu() == null) {
78
79
80 if (isContextMenu) {
81 return true;
82 }
83
84
85 VMenuBar root = getParentMenu();
86
87 root.getSelected().getSubMenu().setSelected(null);
88
89 root.hideChildren(false, false);
90
91
92 int idx = root.getItems().indexOf(root.getSelected());
93 idx = idx > 0 ? idx : root.getItems().size();
94 CustomMenuItem selected = root.getItems().get(--idx);
95
96 while (selected.isSeparator() || !selected.isEnabled()) {
97 idx = idx > 0 ? idx : root.getItems().size();
98 selected = root.getItems().get(--idx);
99 }
100
101 root.setSelected(selected);
102 openMenuAndFocusFirstIfPossible(selected);
103 } else {
104 getParentMenu().getSelected().getSubMenu().setSelected(null);
105 getParentMenu().hideChildren();
106 }
107
108 return true;
109
110 } else if (keycode == getNavigationRightKey()) {
111
112 if (getSelected() == null) {
113
114 setSelected(items.get(0));
115 if (!getSelected().isSelectable()) {
116 handleNavigation(keycode, ctrl, shift);
117 }
118 } else if (visibleChildMenu == null && getParentMenu() == null) {
119
120 int idx = items.indexOf(getSelected());
121
122 if (idx < items.size() - 1) {
123 setSelected(items.get(idx + 1));
124 } else {
125 setSelected(items.get(0));
126 }
127
128 if (!getSelected().isSelectable()) {
129 handleNavigation(keycode, ctrl, shift);
130 }
131 } else if (visibleChildMenu == null
132 && getSelected().getSubMenu() != null) {
133
134
135 showChildMenu(getSelected());
136 menuVisible = true;
137 visibleChildMenu.handleNavigation(keycode, ctrl, shift);
138 } else if (visibleChildMenu == null && !isContextMenu ) {
139
140
141 VMenuBar root = getParentMenu();
142 while (root.getParentMenu() != null) {
143 root = root.getParentMenu();
144 }
145
146
147
148 root.hideChildren(false, false);
149
150
151 int idx = root.getItems().indexOf(root.getSelected());
152 idx = idx < root.getItems().size() - 1 ? idx : -1;
153 CustomMenuItem selected = root.getItems().get(++idx);
154
155 while (selected.isSeparator() || !selected.isEnabled()) {
156 idx = idx < root.getItems().size() - 1 ? idx : -1;
157 selected = root.getItems().get(++idx);
158 }
159
160 root.setSelected(selected);
161 openMenuAndFocusFirstIfPossible(selected);
162 } else if (visibleChildMenu != null) {
163
164 visibleChildMenu.handleNavigation(keycode, ctrl, shift);
165 }
166
167 return true;
168
169 } else if (keycode == getNavigationUpKey()) {
170
171 if (getSelected() == null) {
172
173 setSelected(items.get(items.size() - 1));
174 if (!getSelected().isSelectable()) {
175 handleNavigation(keycode, ctrl, shift);
176 }
177 } else if (visibleChildMenu != null) {
178
179 visibleChildMenu.handleNavigation(keycode, ctrl, shift);
180 } else {
181
182 int idx = items.indexOf(getSelected());
183 if (idx > 0) {
184 setSelected(items.get(idx - 1));
185 } else {
186 setSelected(items.get(items.size() - 1));
187 }
188
189 if (!getSelected().isSelectable()) {
190 handleNavigation(keycode, ctrl, shift);
191 }
192 }
193
194 return true;
195
196 } else if (keycode == getNavigationDownKey()) {
197
198 if (getSelected() == null) {
199
200 selectFirstItem();
201 } else if (visibleChildMenu == null && getParentMenu() == null) {
202
203
204 openMenuAndFocusFirstIfPossible(getSelected());
205 } else if (visibleChildMenu != null) {
206
207 visibleChildMenu.handleNavigation(keycode, ctrl, shift);
208 } else {
209
210 int idx = items.indexOf(getSelected());
211 if (idx < items.size() - 1) {
212 setSelected(items.get(idx + 1));
213 } else {
214 setSelected(items.get(0));
215 }
216
217 if (!getSelected().isSelectable()) {
218 handleNavigation(keycode, ctrl, shift);
219 }
220 }
221 return true;
222
223 } else if (keycode == getCloseMenuKey()) {
224 setSelected(null);
225 hideChildren();
226 menuVisible = false;
227
228 } else if (isNavigationSelectKey(keycode)) {
229 if (getSelected() == null) {
230
231 selectFirstItem();
232 } else if (visibleChildMenu != null) {
233
234 visibleChildMenu.handleNavigation(keycode, ctrl, shift);
235 menuVisible = false;
236 } else if (visibleChildMenu == null
237 && getSelected().getSubMenu() != null) {
238
239
240 openMenuAndFocusFirstIfPossible(getSelected());
241 } else {
242 final Command command = getSelected().getCommand();
243
244 setSelected(null);
245 hideParents(true);
246
247
248
249 menuVisible = false;
250
251 Scheduler.get().scheduleDeferred(new ScheduledCommand() {
252 @Override
253 public void execute() {
254 if (command != null) {
255 command.execute();
256 }
257 }
258 });
259 }
260 }
261
262 return false;
263 }
264
265 private void selectFirstItem() {
266 for (int i = 0; i < items.size(); i++) {
267 CustomMenuItem item = items.get(i);
268 if (item.isSelectable()) {
269 setSelected(item);
270 break;
271 }
272 }
273 }
274
275 private void openMenuAndFocusFirstIfPossible(CustomMenuItem menuItem) {
276 MyVMenuBar subMenu = (MyVMenuBar) menuItem.getSubMenu();
277 if (subMenu == null) {
278
279 return;
280 }
281
282 MyVMenuBar parentMenu = (MyVMenuBar) menuItem.getParentMenu();
283 parentMenu.showChildMenu(menuItem);
284
285 menuVisible = true;
286
287 subMenu.selectFirstItem();
288
289 }
290
291 public boolean isPopupShowing() {
292 return menuVisible;
293 }
294 }