OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/automation/ui_controls.h" | |
6 #include "chrome/test/interactive_ui/view_event_test_base.h" | |
7 #include "ui/base/models/menu_model.h" | |
8 #include "views/controls/button/menu_button.h" | |
9 #include "views/controls/menu/menu_controller.h" | |
10 #include "views/controls/menu/menu_item_view.h" | |
11 #include "views/controls/menu/menu_model_adapter.h" | |
12 #include "views/controls/menu/submenu_view.h" | |
13 #include "views/controls/menu/view_menu_delegate.h" | |
14 #include "views/test/test_views_delegate.h" | |
15 #include "views/views_delegate.h" | |
16 #include "views/widget/root_view.h" | |
17 #include "views/widget/widget.h" | |
18 | |
19 namespace { | |
20 | |
21 const int kTopMenuBaseId = 100; | |
22 const int kSubMenuBaseId = 200; | |
23 | |
24 // ViewsDelegate::GetDispositionForEvent() is used by views::MenuModelAdapter. | |
25 class TestViewsDelegate : public views::ViewsDelegate { | |
26 // views::ViewsDelegate implementation | |
27 virtual ui::Clipboard* GetClipboard() const OVERRIDE { | |
28 return NULL; | |
29 } | |
30 | |
31 virtual views::View* GetDefaultParentView() OVERRIDE | |
32 { | |
33 return NULL; | |
34 } | |
35 | |
36 virtual void SaveWindowPlacement(const views::Widget* widget, | |
37 const std::wstring& window_name, | |
38 const gfx::Rect& bounds, | |
39 bool maximized) OVERRIDE { | |
40 } | |
41 | |
42 virtual bool GetSavedWindowBounds(const std::wstring& window_name, | |
43 gfx::Rect* bounds) const OVERRIDE { | |
44 return false; | |
45 } | |
46 | |
47 virtual bool GetSavedMaximizedState(const std::wstring& window_name, | |
48 bool* maximized) const OVERRIDE { | |
49 return false; | |
50 } | |
51 | |
52 virtual void NotifyAccessibilityEvent( | |
53 views::View* view, ui::AccessibilityTypes::Event event_type) OVERRIDE { | |
54 } | |
55 | |
56 virtual void NotifyMenuItemFocused( | |
57 const std::wstring& menu_name, | |
58 const std::wstring& menu_item_name, | |
59 int item_index, | |
60 int item_count, | |
61 bool has_submenu) OVERRIDE { | |
62 } | |
63 | |
64 #if defined(OS_WIN) | |
65 virtual HICON GetDefaultWindowIcon() const OVERRIDE | |
66 { | |
67 return NULL; | |
68 } | |
69 #endif | |
70 | |
71 virtual void AddRef() OVERRIDE { | |
72 } | |
73 | |
74 virtual void ReleaseRef() OVERRIDE { | |
75 } | |
76 | |
77 // Converts views::Event::flags to a WindowOpenDisposition. | |
78 virtual int GetDispositionForEvent(int event_flags) OVERRIDE { | |
79 return 0; | |
80 } | |
81 }; | |
82 | |
83 // Implement most of the ui::MenuModel pure virtuals for subclasses | |
84 // | |
85 // Exceptions: | |
86 // virtual int GetItemCount() const = 0; | |
87 // virtual ItemType GetTypeAt(int index) const = 0; | |
88 // virtual int GetCommandIdAt(int index) const = 0; | |
89 // virtual string16 GetLabelAt(int index) const = 0; | |
90 class CommonMenuModel : public ui::MenuModel { | |
91 protected: | |
92 // ui::MenuModel implementation. | |
93 virtual bool HasIcons() const OVERRIDE { | |
94 return false; | |
95 } | |
96 | |
97 virtual bool IsItemDynamicAt(int index) const OVERRIDE { | |
98 return false; | |
99 } | |
100 | |
101 virtual bool GetAcceleratorAt(int index, | |
102 ui::Accelerator* accelerator) const OVERRIDE { | |
103 return false; | |
104 } | |
105 | |
106 virtual bool IsItemCheckedAt(int index) const OVERRIDE { | |
107 return false; | |
108 } | |
109 | |
110 virtual int GetGroupIdAt(int index) const OVERRIDE { | |
111 return 0; | |
112 } | |
113 | |
114 virtual bool GetIconAt(int index, SkBitmap* icon) OVERRIDE { | |
115 return false; | |
116 } | |
117 | |
118 virtual ui::ButtonMenuItemModel* GetButtonMenuItemAt( | |
119 int index) const OVERRIDE { | |
120 return NULL; | |
121 } | |
122 | |
123 virtual bool IsEnabledAt(int index) const OVERRIDE { | |
124 return true; | |
125 } | |
126 | |
127 virtual ui::MenuModel* GetSubmenuModelAt(int index) const OVERRIDE { | |
128 return NULL; | |
129 } | |
130 | |
131 virtual void HighlightChangedTo(int index) OVERRIDE { | |
132 } | |
133 | |
134 virtual void ActivatedAt(int index) OVERRIDE { | |
135 } | |
136 | |
137 virtual void SetMenuModelDelegate(ui::MenuModelDelegate* delegate) OVERRIDE { | |
138 } | |
139 }; | |
140 | |
141 class SubMenuModel : public CommonMenuModel { | |
142 public: | |
143 SubMenuModel() : | |
sky
2011/08/02 23:08:12
: on next line.
rhashimoto
2011/08/02 23:53:37
Done.
| |
144 showing_(false) { | |
145 } | |
146 | |
147 bool showing() const { | |
148 return showing_; | |
149 } | |
150 | |
151 private: | |
152 // ui::MenuModel implementation. | |
153 virtual int GetItemCount() const OVERRIDE { | |
154 return 1; | |
155 } | |
156 | |
157 virtual ItemType GetTypeAt(int index) const OVERRIDE { | |
158 return TYPE_COMMAND; | |
159 } | |
160 | |
161 virtual int GetCommandIdAt(int index) const OVERRIDE { | |
162 return index + kSubMenuBaseId; | |
163 } | |
164 | |
165 virtual string16 GetLabelAt(int index) const OVERRIDE { | |
166 return ASCIIToUTF16("Item"); | |
167 } | |
168 | |
169 virtual void MenuWillShow() { | |
170 showing_ = true; | |
171 } | |
172 | |
173 // Called when the menu has been closed. | |
174 virtual void MenuClosed() { | |
175 showing_ = false; | |
176 } | |
177 | |
178 bool showing_; | |
179 }; | |
sky
2011/08/02 23:08:12
DISALLOW_BLAH_BLAH here and in other classes.
rhashimoto
2011/08/02 23:53:37
Done.
| |
180 | |
181 class TopMenuModel : public CommonMenuModel { | |
182 public: | |
183 TopMenuModel() { | |
184 } | |
185 | |
186 bool IsSubmenuShowing() { | |
187 return sub_menu_model_.showing(); | |
188 } | |
189 | |
190 private: | |
191 // ui::MenuModel implementation. | |
192 virtual int GetItemCount() const OVERRIDE { | |
193 return 1; | |
194 } | |
195 | |
196 virtual ItemType GetTypeAt(int index) const OVERRIDE { | |
197 return TYPE_SUBMENU; | |
198 } | |
199 | |
200 virtual int GetCommandIdAt(int index) const OVERRIDE { | |
201 return index + kTopMenuBaseId; | |
202 } | |
203 | |
204 virtual string16 GetLabelAt(int index) const OVERRIDE { | |
205 return ASCIIToUTF16("submenu"); | |
206 } | |
207 | |
208 virtual MenuModel* GetSubmenuModelAt(int index) const OVERRIDE { | |
209 return &sub_menu_model_; | |
210 } | |
211 | |
212 mutable SubMenuModel sub_menu_model_; | |
213 }; | |
214 | |
215 } // namespace | |
216 | |
217 class MenuModelAdapterTest : public ViewEventTestBase, | |
218 public views::ViewMenuDelegate { | |
219 public: | |
220 MenuModelAdapterTest() : | |
221 ViewEventTestBase(), | |
222 button_(NULL), | |
223 menu_model_adapter_(&top_menu_model_) { | |
224 old_views_delegate_ = views::ViewsDelegate::views_delegate; | |
225 views::ViewsDelegate::views_delegate = &views_delegate_; | |
226 } | |
227 | |
228 virtual ~MenuModelAdapterTest() { | |
229 views::ViewsDelegate::views_delegate = old_views_delegate_; | |
230 } | |
231 | |
232 // ViewEventTestBase implementation. | |
233 | |
234 virtual void SetUp() OVERRIDE { | |
235 button_ = new views::MenuButton(NULL, L"Menu Adapter Test", this, true); | |
236 | |
237 menu_.reset(new views::MenuItemView(&menu_model_adapter_)); | |
238 menu_model_adapter_.BuildMenu(menu_.get()); | |
239 | |
240 ViewEventTestBase::SetUp(); | |
241 } | |
242 | |
243 virtual void TearDown() OVERRIDE { | |
244 menu_.reset(NULL); | |
245 ViewEventTestBase::TearDown(); | |
246 } | |
247 | |
248 virtual views::View* CreateContentsView() OVERRIDE { | |
249 return button_; | |
250 } | |
251 | |
252 virtual gfx::Size GetPreferredSize() OVERRIDE { | |
253 return button_->GetPreferredSize(); | |
254 } | |
255 | |
256 // views::ViewMenuDelegate implementation. | |
257 virtual void RunMenu(views::View* source, const gfx::Point& pt) OVERRIDE { | |
258 gfx::Point screen_location; | |
259 views::View::ConvertPointToScreen(source, &screen_location); | |
260 gfx::Rect bounds(screen_location, source->size()); | |
261 menu_->RunMenuAt( | |
262 source->GetWidget(), | |
263 button_, | |
264 bounds, | |
265 views::MenuItemView::TOPLEFT, | |
266 true); | |
267 } | |
268 | |
269 // ui::SimpleMenuModel::Delegate implementation | |
270 virtual bool IsCommandIdChecked(int command_id) const OVERRIDE { | |
271 return false; | |
272 } | |
273 | |
274 virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE { | |
275 return true; | |
276 } | |
277 | |
278 virtual bool GetAcceleratorForCommandId( | |
279 int command_id, | |
280 ui::Accelerator* accelerator) OVERRIDE { | |
281 return false; | |
282 } | |
283 | |
284 // Performs the action associated with the specified command id. | |
285 virtual void ExecuteCommand(int command_id) OVERRIDE | |
286 { | |
287 } | |
288 | |
289 // ViewEventTestBase implementation | |
290 virtual void DoTestOnMessageLoop() OVERRIDE { | |
291 Click(button_, CreateEventTask(this, &MenuModelAdapterTest::Step1)); | |
292 } | |
293 | |
294 // Open the submenu. | |
295 void Step1() { | |
296 views::SubmenuView* topmenu = menu_->GetSubmenu(); | |
297 ASSERT_TRUE(topmenu); | |
298 ASSERT_TRUE(topmenu->IsShowing()); | |
299 ASSERT_FALSE(top_menu_model_.IsSubmenuShowing()); | |
300 | |
301 // Click the first item to open the submenu. | |
302 views::MenuItemView* item = topmenu->GetMenuItemAt(0); | |
303 ASSERT_TRUE(item); | |
304 Click(item, CreateEventTask(this, &MenuModelAdapterTest::Step2)); | |
305 } | |
306 | |
307 // Rebuild the menu which should close the submenu. | |
308 void Step2() { | |
309 views::SubmenuView* topmenu = menu_->GetSubmenu(); | |
310 ASSERT_TRUE(topmenu); | |
311 ASSERT_TRUE(topmenu->IsShowing()); | |
312 ASSERT_TRUE(top_menu_model_.IsSubmenuShowing()); | |
313 | |
314 menu_model_adapter_.BuildMenu(menu_.get()); | |
315 | |
316 MessageLoopForUI::current()->PostTask( | |
317 FROM_HERE, | |
318 CreateEventTask(this, &MenuModelAdapterTest::Step3)); | |
319 } | |
320 | |
321 // Verify that the submenu MenuModel received the close callback | |
322 // and close the menu. | |
323 void Step3() { | |
324 views::SubmenuView* topmenu = menu_->GetSubmenu(); | |
325 ASSERT_TRUE(topmenu); | |
326 ASSERT_TRUE(topmenu->IsShowing()); | |
327 ASSERT_FALSE(top_menu_model_.IsSubmenuShowing()); | |
328 | |
329 // Click the button to exit the menu. | |
330 Click(button_, CreateEventTask(this, &MenuModelAdapterTest::Step4)); | |
331 } | |
332 | |
333 // All done. | |
334 void Step4() { | |
335 views::SubmenuView* topmenu = menu_->GetSubmenu(); | |
336 ASSERT_TRUE(topmenu); | |
337 ASSERT_FALSE(topmenu->IsShowing()); | |
338 ASSERT_FALSE(top_menu_model_.IsSubmenuShowing()); | |
339 | |
340 Done(); | |
341 } | |
342 | |
343 private: | |
344 // Generate a mouse click on the specified view and post a new task. | |
345 virtual void Click(views::View* view, Task* next) { | |
346 ui_controls::MoveMouseToCenterAndPress( | |
347 view, | |
348 ui_controls::LEFT, | |
349 ui_controls::DOWN | ui_controls::UP, | |
350 next); | |
351 } | |
352 | |
353 views::ViewsDelegate* old_views_delegate_; | |
354 TestViewsDelegate views_delegate_; | |
355 | |
356 views::MenuButton* button_; | |
357 TopMenuModel top_menu_model_; | |
358 views::MenuModelAdapter menu_model_adapter_; | |
359 scoped_ptr<views::MenuItemView> menu_; | |
360 }; | |
361 | |
362 VIEW_TEST(MenuModelAdapterTest, RebuildMenu) | |
OLD | NEW |