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

Side by Side Diff: ui/touch_selection/touch_selection_controller_aura_unittest.cc

Issue 996373002: Add Aura handles to be used in unified touch selection (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed issues with loading resources Created 5 years, 9 months 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
OLDNEW
(Empty)
1 // Copyright 2015 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 "ui/touch_selection/touch_selection_controller_aura.h"
6
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "ui/aura/test/aura_test_base.h"
9 #include "ui/aura/window.h"
10 #include "ui/events/test/event_generator.h"
11 #include "ui/touch_selection/touch_handle_drawable_aura.h"
12 #include "ui/touch_selection/touch_selection_controller_aura_test_api.h"
13 #include "ui/touch_selection/touch_selection_menu_runner.h"
14
15 namespace ui {
16 namespace {
17
18 // A mock implementation for TouchSelectionMenuRunner used in tests.
19 class TestTouchSelectionMenuRunner : public TouchSelectionMenuRunner {
20 public:
21 TestTouchSelectionMenuRunner() {}
22 ~TestTouchSelectionMenuRunner() override {}
23
24 bool is_running() const { return is_running_; }
25
26 private:
27 // TouchSelectionMenuRunner:
28 void RunMenu(TouchSelectionMenuClient* client,
29 const gfx::Rect& anchor_rect,
30 const gfx::Size& handle_image_size,
31 aura::Window* context) override {
32 is_running_ = true;
33 }
34
35 void CloseMenu() override {
36 is_running_ = false;
37 }
38
39 bool IsRunning() const override {
40 return is_running_;
41 }
42
43 bool is_running_;
44
45 DISALLOW_COPY_AND_ASSIGN(TestTouchSelectionMenuRunner);
46 };
47
48 // Convenience to make constructing a GestureEvent simpler.
49 class GestureEventForTest : public GestureEvent {
50 public:
51 GestureEventForTest(EventType type, int x, int y)
52 : GestureEvent(x, y, 0, base::TimeDelta(),
53 GestureEventDetails(type)) {}
54 };
55
56 // Convenience to make constructing a TouchEvent simpler.
57 class TouchEventForTest : public TouchEvent {
58 public:
59 TouchEventForTest(EventType type, gfx::Point location)
60 : TouchEvent(type, location, 0, base::TimeDelta()) {}
61 };
62
63 } // namespace
64
65 // A subclass of TouchSelectionControllerAura which adds some test functionality
66 // to it.
67 class TestTouchSelectionControllerAura : public TouchSelectionControllerAura {
68 public:
69 TestTouchSelectionControllerAura(TouchSelectionControllerAuraClient* client)
70 : TouchSelectionControllerAura(client),
71 test_api_(new TouchSelectionControllerAuraTestApi(this)),
72 last_drawable_(nullptr) {
73 test_api_->set_immediate_quick_menu(true);
74 }
75
76 ~TestTouchSelectionControllerAura() override {}
77
78 TouchHandleDrawable* last_drawable() const { return last_drawable_; }
79
80 TouchSelectionControllerAuraTestApi* test_api() {
81 return test_api_.get();
82 }
83
84 protected:
85 // TouchSelectionControllerAura:
86 scoped_ptr<TouchHandleDrawable> CreateDrawable() override {
87 scoped_ptr<TouchHandleDrawable> drawable =
88 TouchSelectionControllerAura::CreateDrawable();
89 last_drawable_ = drawable.get();
90 return drawable;
91 }
92
93 private:
94 scoped_ptr<TouchSelectionControllerAuraTestApi> test_api_;
95 TouchHandleDrawable* last_drawable_;
96
97 DISALLOW_COPY_AND_ASSIGN(TestTouchSelectionControllerAura);
98 };
99
100 class TouchSelectionControllerAuraTest
101 : public aura::test::AuraTestBase,
102 public TouchSelectionControllerAuraClient {
103 public:
104 TouchSelectionControllerAuraTest() {}
105 ~TouchSelectionControllerAuraTest() override {}
106
107 protected:
108 void ChangeSelection(const gfx::PointF& start_top,
109 const gfx::PointF& start_bottom,
110 const gfx::PointF& end_top,
111 const gfx::PointF& end_bottom) {
112 SelectionBound start_bound, end_bound;
113 start_bound.set_type(SelectionBound::LEFT);
114 end_bound.set_type(SelectionBound::RIGHT);
115 start_bound.SetEdge(start_top, start_bottom);
116 end_bound.SetEdge(end_top, end_bottom);
117 start_bound.set_visible(true);
118 end_bound.set_visible(true);
119 controller_->OnSelectionBoundsUpdated(start_bound, end_bound);
120 }
121
122 void ChangeInsertion(const gfx::Point& top,
123 const gfx::Point& bottom) {
124 SelectionBound bound;
125 bound.set_type(SelectionBound::CENTER);
126 bound.SetEdge(top, bottom);
127 bound.set_visible(true);
128 controller_->OnSelectionBoundsUpdated(bound, bound);
129 }
130
131 void ClearSelection() {
132 controller_->OnSelectionBoundsUpdated(SelectionBound(), SelectionBound());
133 }
134
135 void ClearInsertion() { ClearSelection(); }
136
137 aura::Window* parent_window() const { return parent_window_.get(); }
138
139 TestTouchSelectionMenuRunner* menu_runner() const {
140 return menu_runner_.get();
141 }
142
143 TestTouchSelectionControllerAura* controller() const {
144 return controller_.get();
145 }
146
147 void OnEvent(Event* event) {
148 controller_->OnEvent(event);
149 }
150
151 private:
152 // aura::test::AuraTestBase:
153 void SetUp() override {
154 AuraTestBase::SetUp();
155
156 menu_runner_.reset(new TestTouchSelectionMenuRunner());
157
158 parent_window_.reset(CreateNormalWindow(0, root_window(), nullptr));
159 parent_window_->SetBounds(gfx::Rect(0, 0, 400, 400));
160
161 controller_.reset(new TestTouchSelectionControllerAura(this));
162 }
163
164 void TearDown() override {
165 controller_.reset();
166 parent_window_.reset();
167 menu_runner_.reset();
168
169 AuraTestBase::TearDown();
170 }
171
172 // TouchSelectionControllerAuraClient:
173 EventTarget* GetEventTarget() const override {
174 return parent_window_.get();
175 }
176
177 void MoveCaret(const gfx::PointF& position) override {}
178
179 void MoveRangeSelectionExtent(const gfx::PointF& extent) override {}
180
181 void SelectBetweenCoordinates(const gfx::PointF& base,
182 const gfx::PointF& extent) override {}
183
184 aura::Window* GetParentWindow() const override {
185 return parent_window_.get();
186 }
187
188 gfx::Rect GetClientBounds() const override {
189 return parent_window_->bounds();
190 }
191
192 bool IsCommandIdEnabled(int command_id) const override { return true; }
193
194 void ExecuteCommand(int command_id, int event_flags) override {}
195
196 void OpenContextMenu(const gfx::PointF& point) override {}
197
198 scoped_ptr<aura::Window> parent_window_;
199 scoped_ptr<TestTouchSelectionControllerAura> controller_;
200 scoped_ptr<TestTouchSelectionMenuRunner> menu_runner_;
201
202 DISALLOW_COPY_AND_ASSIGN(TouchSelectionControllerAuraTest);
203 };
204
205 // Tests if touch selection quick menu is shown when touch selection is
206 // activated and hidden when touch selection is deactivated.
207 TEST_F(TouchSelectionControllerAuraTest, QuickMenuShowHide) {
208 gfx::Point top(5, 5);
209 gfx::Point bottom(5, 15);
210
211 controller()->OnSelectionEditable(true);
212 GestureEventForTest tap(ET_GESTURE_TAP, top.x(), top.y());
213 OnEvent(&tap);
214 ChangeInsertion(top, bottom);
215 EXPECT_TRUE(controller()->test_api()->is_insertion_active());
216 EXPECT_FALSE(controller()->test_api()->is_selection_active());
217 EXPECT_TRUE(menu_runner()->is_running());
218
219 ClearInsertion();
220 EXPECT_FALSE(controller()->test_api()->is_insertion_active());
221 EXPECT_FALSE(controller()->test_api()->is_selection_active());
222 EXPECT_FALSE(menu_runner()->is_running());
223 }
224
225 // Tests if touch selection quick menu is hidden during a scroll.
226 TEST_F(TouchSelectionControllerAuraTest, QuickMenuHiddenOnScroll) {
227 gfx::Point top(5, 5);
228 gfx::Point bottom(5, 15);
229
230 controller()->OnSelectionEditable(true);
231 GestureEventForTest tap(ET_GESTURE_TAP, top.x(), top.y());
232 OnEvent(&tap);
233 ChangeInsertion(top, bottom);
234 EXPECT_TRUE(controller()->test_api()->is_insertion_active());
235 EXPECT_FALSE(controller()->test_api()->is_selection_active());
236 EXPECT_TRUE(menu_runner()->is_running());
237
238 GestureEventForTest scroll_begin(ET_GESTURE_SCROLL_BEGIN, top.x(), top.y());
239 OnEvent(&scroll_begin);
240 EXPECT_TRUE(controller()->test_api()->is_insertion_active());
241 EXPECT_FALSE(controller()->test_api()->is_selection_active());
242 EXPECT_FALSE(menu_runner()->is_running());
243
244 GestureEventForTest scroll_end(ET_GESTURE_SCROLL_END, top.x(), top.y());
245 OnEvent(&scroll_end);
246 EXPECT_TRUE(controller()->test_api()->is_insertion_active());
247 EXPECT_FALSE(controller()->test_api()->is_selection_active());
248 EXPECT_TRUE(menu_runner()->is_running());
249
250 ClearInsertion();
251 EXPECT_FALSE(controller()->test_api()->is_insertion_active());
252 EXPECT_FALSE(controller()->test_api()->is_selection_active());
253 EXPECT_FALSE(menu_runner()->is_running());
254 }
255
256 // Tests if touch selection quick menu is hidden while a handle is being
257 // dragged.
258 TEST_F(TouchSelectionControllerAuraTest, QuickMenuHiddenOnHandleDrag) {
259 gfx::Point top(5, 5);
260 gfx::Point bottom(5, 15);
261
262 controller()->OnSelectionEditable(true);
263 GestureEventForTest tap(ET_GESTURE_TAP, top.x(), top.y());
264 OnEvent(&tap);
265 ChangeInsertion(top, bottom);
266 EXPECT_TRUE(controller()->test_api()->is_insertion_active());
267 EXPECT_FALSE(controller()->test_api()->is_selection_active());
268 EXPECT_TRUE(menu_runner()->is_running());
269
270 gfx::RectF handle_bounds = controller()->last_drawable()->GetVisibleBounds();
271 gfx::Point drag_point = gfx::ToRoundedPoint(handle_bounds.CenterPoint());
272
273 TouchEventForTest touch_pressed(ET_TOUCH_PRESSED, drag_point);
274 OnEvent(&touch_pressed);
275 EXPECT_TRUE(controller()->test_api()->is_insertion_active());
276 EXPECT_FALSE(controller()->test_api()->is_selection_active());
277 EXPECT_FALSE(menu_runner()->is_running());
278
279 TouchEventForTest touch_released(ET_TOUCH_RELEASED, drag_point);
280 OnEvent(&touch_released);
281 EXPECT_TRUE(controller()->test_api()->is_insertion_active());
282 EXPECT_FALSE(controller()->test_api()->is_selection_active());
283 EXPECT_TRUE(menu_runner()->is_running());
284
285 ClearInsertion();
286 EXPECT_FALSE(controller()->test_api()->is_insertion_active());
287 EXPECT_FALSE(controller()->test_api()->is_selection_active());
288 EXPECT_FALSE(menu_runner()->is_running());
289 }
290
291 // Tests if taps on selection in an editable text are handled properly.
292 TEST_F(TouchSelectionControllerAuraTest, TapOnEditableSelection) {
293 gfx::Point start_top(5, 5);
294 gfx::Point start_bottom(5, 15);
295 gfx::Point middle(15, 10);
296 gfx::Point end_top(25, 5);
297 gfx::Point end_bottom(25, 15);
298
299 controller()->OnSelectionEditable(true);
300 ChangeSelection(start_top, start_bottom, end_top, end_bottom);
301 EXPECT_FALSE(controller()->test_api()->is_insertion_active());
302 EXPECT_FALSE(controller()->test_api()->is_selection_active());
303
304 // When touch selection is inactive, tapping on selection should consume the
305 // event and activate touch selection.
306 GestureEventForTest tap1(ET_GESTURE_TAP, middle.x(), middle.y());
307 OnEvent(&tap1);
308 EXPECT_TRUE(tap1.handled());
309 EXPECT_FALSE(controller()->test_api()->is_insertion_active());
310 EXPECT_TRUE(controller()->test_api()->is_selection_active());
311
312 // When touch selection is active, tapping on selection should leave the event
313 // unhandled, so that the event can be forwarded to the renderer.
314 GestureEventForTest tap2(ET_GESTURE_TAP, middle.x(), middle.y());
315 OnEvent(&tap2);
316 EXPECT_FALSE(tap2.handled());
317 EXPECT_FALSE(controller()->test_api()->is_insertion_active());
318 EXPECT_TRUE(controller()->test_api()->is_selection_active());
319
320 ClearSelection();
321 EXPECT_FALSE(controller()->test_api()->is_insertion_active());
322 EXPECT_FALSE(controller()->test_api()->is_selection_active());
323 }
324
325 // Tests if taps on selection in a non-editable text are handled properly.
326 TEST_F(TouchSelectionControllerAuraTest, TapOnNonEditableSelection) {
327 gfx::Point start_top(5, 5);
328 gfx::Point start_bottom(5, 15);
329 gfx::Point middle(15, 10);
330 gfx::Point end_top(25, 5);
331 gfx::Point end_bottom(25, 15);
332
333 controller()->OnSelectionEditable(false);
334 ChangeSelection(start_top, start_bottom, end_top, end_bottom);
335 EXPECT_FALSE(controller()->test_api()->is_insertion_active());
336 EXPECT_FALSE(controller()->test_api()->is_selection_active());
337
338 // When touch selection is inactive, tapping on selection should consume the
339 // event and activate touch selection.
340 GestureEventForTest tap1(ET_GESTURE_TAP, middle.x(), middle.y());
341 OnEvent(&tap1);
342 EXPECT_TRUE(tap1.handled());
343 EXPECT_FALSE(controller()->test_api()->is_insertion_active());
344 EXPECT_TRUE(controller()->test_api()->is_selection_active());
345
346 // When touch selection is active, tapping on selection should consume the
347 // event to prevent it from being forwarded to the renderer.
348 GestureEventForTest tap2(ET_GESTURE_TAP, middle.x(), middle.y());
349 OnEvent(&tap2);
350 EXPECT_TRUE(tap2.handled());
351 EXPECT_FALSE(controller()->test_api()->is_insertion_active());
352 EXPECT_TRUE(controller()->test_api()->is_selection_active());
353
354 ClearSelection();
355 EXPECT_FALSE(controller()->test_api()->is_insertion_active());
356 EXPECT_FALSE(controller()->test_api()->is_selection_active());
357 }
358
359 // Tests if touch selection is deactivated on a key event.
360 TEST_F(TouchSelectionControllerAuraTest, DeactivatedOnKeyEvent) {
361 gfx::Point top(5, 5);
362 gfx::Point bottom(5, 15);
363
364 RunAllPendingInMessageLoop();
365 controller()->OnSelectionEditable(true);
366 GestureEventForTest tap(ET_GESTURE_TAP, top.x(), top.y());
367 OnEvent(&tap);
368 ChangeInsertion(top, bottom);
369 EXPECT_TRUE(controller()->test_api()->is_insertion_active());
370 EXPECT_FALSE(controller()->test_api()->is_selection_active());
371
372 test::EventGenerator generator(root_window());
373 generator.PressKey(VKEY_A, 0);
374 RunAllPendingInMessageLoop();
375 EXPECT_FALSE(controller()->test_api()->is_insertion_active());
376 EXPECT_FALSE(controller()->test_api()->is_selection_active());
377 }
378
379 // Tests if touch selection is deactivated on a mouse event.
380 TEST_F(TouchSelectionControllerAuraTest, DeactivatedOnMouseEvent) {
381 gfx::Point top(5, 5);
382 gfx::Point bottom(5, 15);
383
384 RunAllPendingInMessageLoop();
385 controller()->OnSelectionEditable(true);
386 GestureEventForTest tap(ET_GESTURE_TAP, top.x(), top.y());
387 OnEvent(&tap);
388 ChangeInsertion(top, bottom);
389 EXPECT_TRUE(controller()->test_api()->is_insertion_active());
390 EXPECT_FALSE(controller()->test_api()->is_selection_active());
391
392 test::EventGenerator generator(root_window());
393 generator.set_current_location(top);
394 RunAllPendingInMessageLoop();
395 generator.MoveMouseTo(bottom);
396 RunAllPendingInMessageLoop();
397 EXPECT_FALSE(controller()->test_api()->is_insertion_active());
398 EXPECT_FALSE(controller()->test_api()->is_selection_active());
399 }
400
401 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698