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

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

Issue 1087893003: Support longpress drag selection (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Code review Created 5 years, 7 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 2014 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/longpress_drag_selector.h"
6
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "ui/events/test/motion_event_test_utils.h"
9
10 using ui::test::MockMotionEvent;
11
12 namespace ui {
13 namespace {
14
15 const double kSlop = 10.;
16
17 } // namespace
18
19 class LongPressDragSelectorTest : public testing::Test,
20 public LongPressDragSelectorClient {
21 public:
22 LongPressDragSelectorTest()
23 : dragging_(false), active_state_changed_(false) {}
24
25 ~LongPressDragSelectorTest() override {}
26
27 void SetSelection(const gfx::PointF& start, const gfx::PointF& end) {
28 selection_start_ = start;
29 selection_end_ = end;
30 }
31
32 bool GetAndResetActiveStateChanged() {
33 bool active_state_changed = active_state_changed_;
34 active_state_changed_ = false;
35 return active_state_changed;
36 }
37
38 bool IsDragging() const { return dragging_; }
39 const gfx::PointF& DragPosition() const { return drag_position_; }
40
41 // LongPressDragSelectorClient implementation.
42 void OnDragBegin(const TouchSelectionDraggable& handler,
43 const gfx::PointF& drag_position) override {
44 dragging_ = true;
45 drag_position_ = drag_position;
46 }
47
48 void OnDragUpdate(const TouchSelectionDraggable& handler,
49 const gfx::PointF& drag_position) override {
50 drag_position_ = drag_position;
51 }
52
53 void OnDragEnd(const TouchSelectionDraggable& handler) override {
54 dragging_ = false;
55 }
56
57 bool IsWithinTapSlop(const gfx::Vector2dF& delta) const override {
58 return delta.LengthSquared() < (kSlop * kSlop);
59 }
60
61 void OnLongPressDragActiveStateChanged() override {
62 active_state_changed_ = true;
63 }
64
65 gfx::PointF GetSelectionStart() const override { return selection_start_; }
66
67 gfx::PointF GetSelectionEnd() const override { return selection_end_; }
68
69 private:
70 bool dragging_;
71 bool active_state_changed_;
72 gfx::PointF drag_position_;
73
74 gfx::PointF selection_start_;
75 gfx::PointF selection_end_;
76 };
77
78 TEST_F(LongPressDragSelectorTest, BasicDrag) {
79 LongPressDragSelector selector(this);
80 MockMotionEvent event;
81
82 // Start a touch sequence.
83 EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
84 EXPECT_FALSE(GetAndResetActiveStateChanged());
85
86 // Activate a longpress-triggered selection.
87 gfx::PointF selection_start(0, 10);
88 gfx::PointF selection_end(10, 10);
89 selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF());
90 EXPECT_TRUE(GetAndResetActiveStateChanged());
91
92 // Motion should not be consumed until a selection is detected.
93 EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
94 SetSelection(selection_start, selection_end);
95 selector.OnSelectionActivated();
96 EXPECT_FALSE(IsDragging());
97
98 // Initiate drag motion. Note that the first move event after activation is
99 // used to initialize the drag start anchor.
100 EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
101 EXPECT_FALSE(IsDragging());
102
103 // The first slop exceeding motion will start the drag. As the motion is
104 // downward, the end selection point should be moved.
105 EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop)));
106 EXPECT_TRUE(IsDragging());
107 EXPECT_EQ(selection_end, DragPosition());
108
109 // Subsequent motion will extend the selection.
110 EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2)));
111 EXPECT_TRUE(IsDragging());
112 EXPECT_EQ(selection_end + gfx::Vector2dF(0, kSlop), DragPosition());
113 EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 3)));
114 EXPECT_TRUE(IsDragging());
115 EXPECT_EQ(selection_end + gfx::Vector2dF(0, kSlop * 2), DragPosition());
116
117 // Release the touch sequence, ending the drag. The selector will never
118 // consume the start/end events, only move events after a longpress.
119 EXPECT_FALSE(selector.WillHandleTouchEvent(event.ReleasePoint()));
120 EXPECT_FALSE(IsDragging());
121 EXPECT_TRUE(GetAndResetActiveStateChanged());
122 }
123
124 TEST_F(LongPressDragSelectorTest, BasicReverseDrag) {
125 LongPressDragSelector selector(this);
126 MockMotionEvent event;
127
128 // Start a touch sequence.
129 EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
130 EXPECT_FALSE(GetAndResetActiveStateChanged());
131
132 // Activate a longpress-triggered selection.
133 gfx::PointF selection_start(0, 10);
134 gfx::PointF selection_end(10, 10);
135 selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF());
136 EXPECT_TRUE(GetAndResetActiveStateChanged());
137 SetSelection(selection_start, selection_end);
138 selector.OnSelectionActivated();
139 EXPECT_FALSE(IsDragging());
140
141 // Initiate drag motion.
142 EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
143 EXPECT_FALSE(IsDragging());
144
145 // As the initial motion is leftward, toward the selection start, the
146 // selection start should be the drag point.
147 EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, -kSlop, 0)));
148 EXPECT_TRUE(IsDragging());
149 EXPECT_EQ(selection_start, DragPosition());
150
151 EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, -kSlop)));
152 EXPECT_TRUE(IsDragging());
153 EXPECT_EQ(selection_start + gfx::Vector2dF(kSlop, -kSlop), DragPosition());
mfomitchev 2015/05/14 21:58:32 Sorry, I don't get it: we've moved by (-kSlop, -kS
jdduke (slow) 2015/05/14 22:19:28 Hmm, maybe switching from x to y coordinate is con
mfomitchev 2015/05/14 22:33:57 AH, right. For some reason I was reading this as r
154
155 // Release the touch sequence, ending the drag.
156 EXPECT_FALSE(selector.WillHandleTouchEvent(event.ReleasePoint()));
157 EXPECT_FALSE(IsDragging());
158 EXPECT_TRUE(GetAndResetActiveStateChanged());
159 }
160
161 TEST_F(LongPressDragSelectorTest, NoActiveTouch) {
162 LongPressDragSelector selector(this);
163 MockMotionEvent event;
164
165 // Activate a longpress-triggered selection.
166 gfx::PointF selection_start(0, 10);
167 gfx::PointF selection_end(10, 10);
168 selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF());
169 SetSelection(selection_start, selection_end);
170 selector.OnSelectionActivated();
171 EXPECT_FALSE(GetAndResetActiveStateChanged());
172 EXPECT_FALSE(IsDragging());
173
174 // Start a new touch sequence; it shouldn't initiate selection drag as there
175 // was no active touch sequence when the longpress selection started.
176 EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
177 EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
178 EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop)));
179 EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2)));
180 EXPECT_FALSE(IsDragging());
181 EXPECT_EQ(gfx::PointF(), DragPosition());
182 }
183
184 TEST_F(LongPressDragSelectorTest, NoLongPress) {
185 LongPressDragSelector selector(this);
186 MockMotionEvent event;
187
188 // Start a touch sequence.
189 EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
190 EXPECT_FALSE(GetAndResetActiveStateChanged());
191
192 // Activate a selection without a preceding longpress.
193 gfx::PointF selection_start(0, 10);
194 gfx::PointF selection_end(10, 10);
195 SetSelection(selection_start, selection_end);
196 selector.OnSelectionActivated();
197 EXPECT_FALSE(GetAndResetActiveStateChanged());
198 EXPECT_FALSE(IsDragging());
199
200 // Touch movement should not initiate selection drag.
201 EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
202 EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop)));
203 EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2)));
204 EXPECT_FALSE(IsDragging());
205 EXPECT_EQ(gfx::PointF(), DragPosition());
206 }
207
208 TEST_F(LongPressDragSelectorTest, NoValidLongPress) {
209 LongPressDragSelector selector(this);
210 MockMotionEvent event;
211
212 // Start a touch sequence.
213 EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
214 EXPECT_FALSE(GetAndResetActiveStateChanged());
215
216 gfx::PointF selection_start(0, 10);
217 gfx::PointF selection_end(10, 10);
218 SetSelection(selection_start, selection_end);
219
220 // Activate a longpress-triggered selection, but at a time before the current
221 // touch down event.
222 selector.OnLongPressEvent(
223 event.GetEventTime() - base::TimeDelta::FromSeconds(1), gfx::PointF());
224 selector.OnSelectionActivated();
225 EXPECT_FALSE(GetAndResetActiveStateChanged());
226 EXPECT_FALSE(IsDragging());
227
228 // Activate a longpress-triggered selection, but at a place different than the
229 // current touch down event.
230 selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF(kSlop, 0));
231 selector.OnSelectionActivated();
232 EXPECT_FALSE(GetAndResetActiveStateChanged());
233 EXPECT_FALSE(IsDragging());
234
235 // Touch movement should not initiate selection drag.
236 EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
237 EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop)));
238 EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2)));
239 EXPECT_FALSE(IsDragging());
240 EXPECT_EQ(gfx::PointF(), DragPosition());
241 }
242
243 TEST_F(LongPressDragSelectorTest, NoSelection) {
244 LongPressDragSelector selector(this);
245 MockMotionEvent event;
246
247 // Start a touch sequence.
248 EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
249 EXPECT_FALSE(GetAndResetActiveStateChanged());
250
251 // Trigger a longpress. This will notify the client that detection is active,
252 // but until there's a longpress no drag selection should occur.
253 selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF());
254 EXPECT_TRUE(GetAndResetActiveStateChanged());
255 EXPECT_FALSE(IsDragging());
256
257 // Touch movement should not initiate selection drag, as there is no active
258 // selection.
259 EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
260 EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop)));
261 EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2)));
262 EXPECT_FALSE(IsDragging());
263 EXPECT_EQ(gfx::PointF(), DragPosition());
264
265 EXPECT_FALSE(selector.WillHandleTouchEvent(event.ReleasePoint()));
266 EXPECT_TRUE(GetAndResetActiveStateChanged());
267 }
268
269 TEST_F(LongPressDragSelectorTest, NoDragMotion) {
270 LongPressDragSelector selector(this);
271 MockMotionEvent event;
272
273 // Start a touch sequence.
274 EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
275 EXPECT_FALSE(GetAndResetActiveStateChanged());
276
277 // Activate a longpress-triggered selection.
278 selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF());
279 EXPECT_TRUE(GetAndResetActiveStateChanged());
280 gfx::PointF selection_start(0, 10);
281 gfx::PointF selection_end(10, 10);
282 SetSelection(selection_start, selection_end);
283 selector.OnSelectionActivated();
284 EXPECT_FALSE(IsDragging());
285
286 // Touch movement within the slop region should not initiate selection drag.
287 EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
288 EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop / 2)));
289 EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, -kSlop / 2)));
290 EXPECT_FALSE(IsDragging());
291 EXPECT_EQ(gfx::PointF(), DragPosition());
292
293 EXPECT_FALSE(selector.WillHandleTouchEvent(event.ReleasePoint()));
294 EXPECT_TRUE(GetAndResetActiveStateChanged());
295 }
296
297 TEST_F(LongPressDragSelectorTest, SelectionDeactivated) {
298 LongPressDragSelector selector(this);
299 MockMotionEvent event;
300
301 // Start a touch sequence.
302 EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
303 EXPECT_FALSE(GetAndResetActiveStateChanged());
304
305 // Activate a longpress-triggered selection.
306 selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF());
307 EXPECT_TRUE(GetAndResetActiveStateChanged());
308 gfx::PointF selection_start(0, 10);
309 gfx::PointF selection_end(10, 10);
310 SetSelection(selection_start, selection_end);
311 selector.OnSelectionActivated();
312 EXPECT_FALSE(IsDragging());
313
314 // Start a drag selection.
315 EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
316 EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop)));
317 EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2)));
318 EXPECT_TRUE(IsDragging());
319
320 // Clearing the selection should force an end to the drag.
321 selector.OnSelectionDeactivated();
322 EXPECT_TRUE(GetAndResetActiveStateChanged());
323 EXPECT_FALSE(IsDragging());
324
325 // Subsequent motion should not be consumed.
326 EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
327 EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop)));
328 EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2)));
329 EXPECT_FALSE(IsDragging());
330 EXPECT_FALSE(selector.WillHandleTouchEvent(event.ReleasePoint()));
331 }
332
333 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698