Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(236)

Side by Side Diff: ui/views/controls/button/menu_button_unittest.cc

Issue 639893003: Unify MenuButton Pushed state logic (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update Formatting Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/views/controls/button/menu_button.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/views/controls/button/menu_button.h" 5 #include "ui/views/controls/button/menu_button.h"
6 6
7 #include "base/memory/scoped_ptr.h" 7 #include "base/memory/scoped_ptr.h"
8 #include "base/strings/utf_string_conversions.h" 8 #include "base/strings/utf_string_conversions.h"
9 #include "ui/base/dragdrop/drag_drop_types.h"
9 #include "ui/events/test/event_generator.h" 10 #include "ui/events/test/event_generator.h"
10 #include "ui/views/controls/button/menu_button_listener.h" 11 #include "ui/views/controls/button/menu_button_listener.h"
12 #include "ui/views/drag_controller.h"
11 #include "ui/views/test/views_test_base.h" 13 #include "ui/views/test/views_test_base.h"
12 14
15 #if defined(USE_AURA)
16 #include "ui/events/event.h"
17 #include "ui/events/event_handler.h"
18 #include "ui/wm/public/drag_drop_client.h"
19 #endif
20
13 using base::ASCIIToUTF16; 21 using base::ASCIIToUTF16;
14 22
15 namespace views { 23 namespace views {
16 24
17 class MenuButtonTest : public ViewsTestBase { 25 class MenuButtonTest : public ViewsTestBase {
18 public: 26 public:
19 MenuButtonTest() : widget_(NULL), button_(NULL) {} 27 MenuButtonTest() : widget_(nullptr), button_(nullptr) {}
20 virtual ~MenuButtonTest() {} 28 virtual ~MenuButtonTest() {}
21 29
22 virtual void TearDown() override { 30 void TearDown() override {
23 if (widget_ && !widget_->IsClosed()) 31 if (widget_ && !widget_->IsClosed())
24 widget_->Close(); 32 widget_->Close();
25 33
26 ViewsTestBase::TearDown(); 34 ViewsTestBase::TearDown();
27 } 35 }
28 36
29 Widget* widget() { return widget_; } 37 Widget* widget() { return widget_; }
30 MenuButton* button() { return button_; } 38 MenuButton* button() { return button_; }
31 39
32 protected: 40 protected:
33 // Creates a MenuButton with no button listener. 41 // Creates a MenuButton with no button listener.
34 void CreateMenuButtonWithNoListener() { 42 void CreateMenuButtonWithNoListener() { CreateMenuButton(nullptr, nullptr); }
35 CreateMenuButton(NULL, NULL);
36 }
37 43
38 // Creates a MenuButton with a ButtonListener. In this case, the MenuButton 44 // Creates a MenuButton with a ButtonListener. In this case, the MenuButton
39 // acts like a regular button. 45 // acts like a regular button.
40 void CreateMenuButtonWithButtonListener(ButtonListener* button_listener) { 46 void CreateMenuButtonWithButtonListener(ButtonListener* button_listener) {
41 CreateMenuButton(button_listener, NULL); 47 CreateMenuButton(button_listener, nullptr);
42 } 48 }
43 49
44 // Creates a MenuButton with a MenuButtonListener. In this case, when the 50 // Creates a MenuButton with a MenuButtonListener. In this case, when the
45 // MenuButton is pushed, it notifies the MenuButtonListener to open a 51 // MenuButton is pushed, it notifies the MenuButtonListener to open a
46 // drop-down menu. 52 // drop-down menu.
47 void CreateMenuButtonWithMenuButtonListener( 53 void CreateMenuButtonWithMenuButtonListener(
48 MenuButtonListener* menu_button_listener) { 54 MenuButtonListener* menu_button_listener) {
49 CreateMenuButton(NULL, menu_button_listener); 55 CreateMenuButton(nullptr, menu_button_listener);
50 } 56 }
51 57
52 private: 58 private:
53 void CreateMenuButton(ButtonListener* button_listener, 59 void CreateMenuButton(ButtonListener* button_listener,
54 MenuButtonListener* menu_button_listener) { 60 MenuButtonListener* menu_button_listener) {
55 CreateWidget(); 61 CreateWidget();
56 62
57 const base::string16 label(ASCIIToUTF16("button")); 63 const base::string16 label(ASCIIToUTF16("button"));
58 button_ = 64 button_ =
59 new MenuButton(button_listener, label, menu_button_listener, false); 65 new MenuButton(button_listener, label, menu_button_listener, false);
(...skipping 13 matching lines...) Expand all
73 widget_->Init(params); 79 widget_->Init(params);
74 } 80 }
75 81
76 Widget* widget_; 82 Widget* widget_;
77 MenuButton* button_; 83 MenuButton* button_;
78 }; 84 };
79 85
80 class TestButtonListener : public ButtonListener { 86 class TestButtonListener : public ButtonListener {
81 public: 87 public:
82 TestButtonListener() 88 TestButtonListener()
83 : last_sender_(NULL), 89 : last_sender_(nullptr),
84 last_sender_state_(Button::STATE_NORMAL), 90 last_sender_state_(Button::STATE_NORMAL),
85 last_event_type_(ui::ET_UNKNOWN) {} 91 last_event_type_(ui::ET_UNKNOWN) {}
86 virtual ~TestButtonListener() {} 92 virtual ~TestButtonListener() {}
87 93
88 virtual void ButtonPressed(Button* sender, const ui::Event& event) override { 94 void ButtonPressed(Button* sender, const ui::Event& event) override {
89 last_sender_ = sender; 95 last_sender_ = sender;
90 CustomButton* custom_button = CustomButton::AsCustomButton(sender); 96 CustomButton* custom_button = CustomButton::AsCustomButton(sender);
91 DCHECK(custom_button); 97 DCHECK(custom_button);
92 last_sender_state_ = custom_button->state(); 98 last_sender_state_ = custom_button->state();
93 last_event_type_ = event.type(); 99 last_event_type_ = event.type();
94 } 100 }
95 101
96 Button* last_sender() { return last_sender_; } 102 Button* last_sender() { return last_sender_; }
97 Button::ButtonState last_sender_state() { return last_sender_state_; } 103 Button::ButtonState last_sender_state() { return last_sender_state_; }
98 ui::EventType last_event_type() { return last_event_type_; } 104 ui::EventType last_event_type() { return last_event_type_; }
99 105
100 private: 106 private:
101 Button* last_sender_; 107 Button* last_sender_;
102 Button::ButtonState last_sender_state_; 108 Button::ButtonState last_sender_state_;
103 ui::EventType last_event_type_; 109 ui::EventType last_event_type_;
104 110
105 DISALLOW_COPY_AND_ASSIGN(TestButtonListener); 111 DISALLOW_COPY_AND_ASSIGN(TestButtonListener);
106 }; 112 };
107 113
108 class TestMenuButtonListener : public MenuButtonListener { 114 class TestMenuButtonListener : public MenuButtonListener {
109 public: 115 public:
110 TestMenuButtonListener() {} 116 TestMenuButtonListener()
117 : last_source_(nullptr), last_source_state_(Button::STATE_NORMAL) {}
111 virtual ~TestMenuButtonListener() {} 118 virtual ~TestMenuButtonListener() {}
112 119
113 virtual void OnMenuButtonClicked(View* source, 120 void OnMenuButtonClicked(View* source, const gfx::Point& /*point*/) override {
114 const gfx::Point& /*point*/) override {
115 last_source_ = source; 121 last_source_ = source;
116 CustomButton* custom_button = CustomButton::AsCustomButton(source); 122 CustomButton* custom_button = CustomButton::AsCustomButton(source);
117 DCHECK(custom_button); 123 DCHECK(custom_button);
118 last_source_state_ = custom_button->state(); 124 last_source_state_ = custom_button->state();
119 } 125 }
120 126
121 View* last_source() { return last_source_; } 127 View* last_source() { return last_source_; }
122 Button::ButtonState last_source_state() { return last_source_state_; } 128 Button::ButtonState last_source_state() { return last_source_state_; }
123 129
124 private: 130 private:
125 View* last_source_; 131 View* last_source_;
126 Button::ButtonState last_source_state_; 132 Button::ButtonState last_source_state_;
127 }; 133 };
128 134
135 // Basic implementation of a DragController, to test input behaviour for
136 // MenuButtons that can be dragged.
137 class TestDragController : public DragController {
138 public:
139 TestDragController() {}
140 virtual ~TestDragController() {}
141
142 void WriteDragDataForView(View* sender,
143 const gfx::Point& press_pt,
144 ui::OSExchangeData* data) override {}
145
146 int GetDragOperationsForView(View* sender, const gfx::Point& p) override {
147 return ui::DragDropTypes::DRAG_MOVE;
148 }
149
150 bool CanStartDragForView(View* sender,
151 const gfx::Point& press_pt,
152 const gfx::Point& p) override {
153 return true;
154 }
155
156 private:
157 DISALLOW_COPY_AND_ASSIGN(TestDragController);
158 };
159
160 #if defined(USE_AURA)
161 // Basic implementation of a DragDropClient, tracking the state of the drag
162 // operation. While dragging addition mouse events are consumed, preventing the
163 // target view from receiving them.
164 class TestDragDropClient : public aura::client::DragDropClient,
165 public ui::EventHandler {
166 public:
167 TestDragDropClient();
168 virtual ~TestDragDropClient();
169
170 // aura::client::DragDropClient:
171 int StartDragAndDrop(const ui::OSExchangeData& data,
172 aura::Window* root_window,
173 aura::Window* source_window,
174 const gfx::Point& root_location,
175 int operation,
176 ui::DragDropTypes::DragEventSource source) override;
177 void DragUpdate(aura::Window* target, const ui::LocatedEvent& event) override;
178 void Drop(aura::Window* target, const ui::LocatedEvent& event) override;
179 void DragCancel() override;
180 bool IsDragDropInProgress() override;
181
182 // ui::EventHandler:
183 void OnMouseEvent(ui::MouseEvent* event) override;
184
185 private:
186 // True while receiving ui::LocatedEvents for drag operations.
187 bool drag_in_progress_;
188
189 // Target window where drag operations are occuring.
190 aura::Window* target_;
191
192 DISALLOW_COPY_AND_ASSIGN(TestDragDropClient);
193 };
194
195 TestDragDropClient::TestDragDropClient()
196 : drag_in_progress_(false), target_(nullptr) {
197 }
198
199 TestDragDropClient::~TestDragDropClient() {
200 }
201
202 int TestDragDropClient::StartDragAndDrop(
203 const ui::OSExchangeData& data,
204 aura::Window* root_window,
205 aura::Window* source_window,
206 const gfx::Point& root_location,
207 int operation,
208 ui::DragDropTypes::DragEventSource source) {
209 if (IsDragDropInProgress())
210 return ui::DragDropTypes::DRAG_NONE;
211 drag_in_progress_ = true;
212 target_ = root_window;
213 return operation;
214 }
215
216 void TestDragDropClient::DragUpdate(aura::Window* target,
217 const ui::LocatedEvent& event) {
218 }
219
220 void TestDragDropClient::Drop(aura::Window* target,
221 const ui::LocatedEvent& event) {
222 drag_in_progress_ = false;
223 }
224
225 void TestDragDropClient::DragCancel() {
226 drag_in_progress_ = false;
227 }
228
229 bool TestDragDropClient::IsDragDropInProgress() {
230 return drag_in_progress_;
231 }
232
233 void TestDragDropClient::OnMouseEvent(ui::MouseEvent* event) {
234 if (!IsDragDropInProgress())
235 return;
236 switch (event->type()) {
237 case ui::ET_MOUSE_DRAGGED:
238 DragUpdate(target_, *event);
239 event->StopPropagation();
240 break;
241 case ui::ET_MOUSE_RELEASED:
242 Drop(target_, *event);
243 event->StopPropagation();
244 break;
245 default:
246 break;
247 }
248 }
249 #endif // defined(USE_AURA)
250
129 // Tests if the listener is notified correctly, when a mouse click happens on a 251 // Tests if the listener is notified correctly, when a mouse click happens on a
130 // MenuButton that has a regular ButtonListener. 252 // MenuButton that has a regular ButtonListener.
131 TEST_F(MenuButtonTest, ActivateNonDropDownOnMouseClick) { 253 TEST_F(MenuButtonTest, ActivateNonDropDownOnMouseClick) {
132 scoped_ptr<TestButtonListener> button_listener(new TestButtonListener); 254 TestButtonListener button_listener;
133 CreateMenuButtonWithButtonListener(button_listener.get()); 255 CreateMenuButtonWithButtonListener(&button_listener);
134 256
135 ui::test::EventGenerator generator(GetContext(), widget()->GetNativeWindow()); 257 ui::test::EventGenerator generator(GetContext(), widget()->GetNativeWindow());
136 258
137 generator.set_current_location(gfx::Point(10, 10)); 259 generator.set_current_location(gfx::Point(10, 10));
138 generator.ClickLeftButton(); 260 generator.ClickLeftButton();
139 261
140 // Check that MenuButton has notified the listener on mouse-released event, 262 // Check that MenuButton has notified the listener on mouse-released event,
141 // while it was in hovered state. 263 // while it was in hovered state.
142 EXPECT_EQ(button(), button_listener->last_sender()); 264 EXPECT_EQ(button(), button_listener.last_sender());
143 EXPECT_EQ(ui::ET_MOUSE_RELEASED, button_listener->last_event_type()); 265 EXPECT_EQ(ui::ET_MOUSE_RELEASED, button_listener.last_event_type());
144 EXPECT_EQ(Button::STATE_HOVERED, button_listener->last_sender_state()); 266 EXPECT_EQ(Button::STATE_HOVERED, button_listener.last_sender_state());
145 } 267 }
146 268
147 // Tests if the listener is notified correctly when a gesture tap happens on a 269 // Tests if the listener is notified correctly when a gesture tap happens on a
148 // MenuButton that has a regular ButtonListener. 270 // MenuButton that has a regular ButtonListener.
149 TEST_F(MenuButtonTest, ActivateNonDropDownOnGestureTap) { 271 TEST_F(MenuButtonTest, ActivateNonDropDownOnGestureTap) {
150 scoped_ptr<TestButtonListener> button_listener(new TestButtonListener); 272 TestButtonListener button_listener;
151 CreateMenuButtonWithButtonListener(button_listener.get()); 273 CreateMenuButtonWithButtonListener(&button_listener);
152 274
153 ui::test::EventGenerator generator(GetContext(), widget()->GetNativeWindow()); 275 ui::test::EventGenerator generator(GetContext(), widget()->GetNativeWindow());
154 generator.GestureTapAt(gfx::Point(10, 10)); 276 generator.GestureTapAt(gfx::Point(10, 10));
155 277
156 // Check that MenuButton has notified the listener on gesture tap event, while 278 // Check that MenuButton has notified the listener on gesture tap event, while
157 // it was in hovered state. 279 // it was in hovered state.
158 EXPECT_EQ(button(), button_listener->last_sender()); 280 EXPECT_EQ(button(), button_listener.last_sender());
159 EXPECT_EQ(ui::ET_GESTURE_TAP, button_listener->last_event_type()); 281 EXPECT_EQ(ui::ET_GESTURE_TAP, button_listener.last_event_type());
160 EXPECT_EQ(Button::STATE_HOVERED, button_listener->last_sender_state()); 282 EXPECT_EQ(Button::STATE_HOVERED, button_listener.last_sender_state());
161 } 283 }
162 284
163 // Tests if the listener is notified correctly when a mouse click happens on a 285 // Tests if the listener is notified correctly when a mouse click happens on a
164 // MenuButton that has a MenuButtonListener. 286 // MenuButton that has a MenuButtonListener.
165 TEST_F(MenuButtonTest, ActivateDropDownOnMouseClick) { 287 TEST_F(MenuButtonTest, ActivateDropDownOnMouseClick) {
166 scoped_ptr<TestMenuButtonListener> menu_button_listener( 288 TestMenuButtonListener menu_button_listener;
167 new TestMenuButtonListener); 289 CreateMenuButtonWithMenuButtonListener(&menu_button_listener);
168 CreateMenuButtonWithMenuButtonListener(menu_button_listener.get());
169 290
170 ui::test::EventGenerator generator(GetContext(), widget()->GetNativeWindow()); 291 ui::test::EventGenerator generator(GetContext(), widget()->GetNativeWindow());
171 292
172 generator.set_current_location(gfx::Point(10, 10)); 293 generator.set_current_location(gfx::Point(10, 10));
173 generator.ClickLeftButton(); 294 generator.ClickLeftButton();
174 295
175 // Check that MenuButton has notified the listener, while it was in pressed 296 // Check that MenuButton has notified the listener, while it was in pressed
176 // state. 297 // state.
177 EXPECT_EQ(button(), menu_button_listener->last_source()); 298 EXPECT_EQ(button(), menu_button_listener.last_source());
178 EXPECT_EQ(Button::STATE_PRESSED, menu_button_listener->last_source_state()); 299 EXPECT_EQ(Button::STATE_PRESSED, menu_button_listener.last_source_state());
179 } 300 }
180 301
181 // Tests if the listener is notified correctly when a gesture tap happens on a 302 // Tests if the listener is notified correctly when a gesture tap happens on a
182 // MenuButton that has a MenuButtonListener. 303 // MenuButton that has a MenuButtonListener.
183 TEST_F(MenuButtonTest, ActivateDropDownOnGestureTap) { 304 TEST_F(MenuButtonTest, ActivateDropDownOnGestureTap) {
184 scoped_ptr<TestMenuButtonListener> menu_button_listener( 305 TestMenuButtonListener menu_button_listener;
185 new TestMenuButtonListener); 306 CreateMenuButtonWithMenuButtonListener(&menu_button_listener);
186 CreateMenuButtonWithMenuButtonListener(menu_button_listener.get());
187 307
188 ui::test::EventGenerator generator(GetContext(), widget()->GetNativeWindow()); 308 ui::test::EventGenerator generator(GetContext(), widget()->GetNativeWindow());
189 generator.GestureTapAt(gfx::Point(10, 10)); 309 generator.GestureTapAt(gfx::Point(10, 10));
190 310
191 // Check that MenuButton has notified the listener, while it was in pressed 311 // Check that MenuButton has notified the listener, while it was in pressed
192 // state. 312 // state.
193 EXPECT_EQ(button(), menu_button_listener->last_source()); 313 EXPECT_EQ(button(), menu_button_listener.last_source());
194 EXPECT_EQ(Button::STATE_PRESSED, menu_button_listener->last_source_state()); 314 EXPECT_EQ(Button::STATE_PRESSED, menu_button_listener.last_source_state());
195 } 315 }
196 316
197 // Test that the MenuButton stays pressed while there are any PressedLocks. 317 // Test that the MenuButton stays pressed while there are any PressedLocks.
198 TEST_F(MenuButtonTest, MenuButtonPressedLock) { 318 TEST_F(MenuButtonTest, MenuButtonPressedLock) {
199 CreateMenuButtonWithNoListener(); 319 CreateMenuButtonWithNoListener();
200 320
201 // Move the mouse over the button; the button should be in a hovered state. 321 // Move the mouse over the button; the button should be in a hovered state.
202 ui::test::EventGenerator generator(GetContext(), widget()->GetNativeWindow()); 322 ui::test::EventGenerator generator(GetContext(), widget()->GetNativeWindow());
203 generator.MoveMouseTo(gfx::Point(10, 10)); 323 generator.MoveMouseTo(gfx::Point(10, 10));
204 EXPECT_EQ(Button::STATE_HOVERED, button()->state()); 324 EXPECT_EQ(Button::STATE_HOVERED, button()->state());
(...skipping 18 matching lines...) Expand all
223 343
224 // Reseting the final lock should return the button's state to normal... 344 // Reseting the final lock should return the button's state to normal...
225 pressed_lock2.reset(); 345 pressed_lock2.reset();
226 EXPECT_EQ(Button::STATE_NORMAL, button()->state()); 346 EXPECT_EQ(Button::STATE_NORMAL, button()->state());
227 347
228 // ...And it should respond to mouse movement again. 348 // ...And it should respond to mouse movement again.
229 generator.MoveMouseTo(gfx::Point(10, 10)); 349 generator.MoveMouseTo(gfx::Point(10, 10));
230 EXPECT_EQ(Button::STATE_HOVERED, button()->state()); 350 EXPECT_EQ(Button::STATE_HOVERED, button()->state());
231 } 351 }
232 352
353 // Test that the MenuButton does not become pressed if it can be dragged, until
354 // a release occurs.
355 TEST_F(MenuButtonTest, DraggableMenuButtonActivatesOnRelease) {
356 TestMenuButtonListener menu_button_listener;
357 CreateMenuButtonWithMenuButtonListener(&menu_button_listener);
358 TestDragController drag_controller;
359 button()->set_drag_controller(&drag_controller);
360
361 ui::test::EventGenerator generator(GetContext(), widget()->GetNativeWindow());
362
363 generator.set_current_location(gfx::Point(10, 10));
364 generator.PressLeftButton();
365 EXPECT_EQ(nullptr, menu_button_listener.last_source());
366
367 generator.ReleaseLeftButton();
368 EXPECT_EQ(button(), menu_button_listener.last_source());
369 EXPECT_EQ(Button::STATE_PRESSED, menu_button_listener.last_source_state());
370 }
371
372 #if defined(USE_AURA)
373 // Tests that the MenuButton does not become pressed if it can be dragged, and a
374 // DragDropClient is processing the events.
375 TEST_F(MenuButtonTest, DraggableMenuButtonDoesNotActivateOnDrag) {
376 TestMenuButtonListener menu_button_listener;
377 CreateMenuButtonWithMenuButtonListener(&menu_button_listener);
378 TestDragController drag_controller;
379 button()->set_drag_controller(&drag_controller);
380
381 TestDragDropClient drag_client;
382 SetDragDropClient(GetContext(), &drag_client);
383 button()->PrependPreTargetHandler(&drag_client);
384
385 ui::test::EventGenerator generator(GetContext(), widget()->GetNativeWindow());
386 generator.set_current_location(gfx::Point(10, 10));
387 generator.DragMouseBy(10, 0);
388 EXPECT_EQ(nullptr, menu_button_listener.last_source());
389 EXPECT_EQ(Button::STATE_NORMAL, menu_button_listener.last_source_state());
390 }
391 #endif
392
233 } // namespace views 393 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/controls/button/menu_button.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698