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

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: Rebase 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 // LongPressDragSelectorClient implementation.
mfomitchev 2015/05/13 20:52:25 Can we put the LongPressDragSelectorClient methods
jdduke (slow) 2015/05/14 18:29:26 Done.
28 void OnDragBegin(const TouchSelectionDraggable& handler,
29 const gfx::PointF& drag_position) override {
30 dragging_ = true;
31 drag_position_ = drag_position;
32 }
33
34 void OnDragUpdate(const TouchSelectionDraggable& handler,
35 const gfx::PointF& drag_position) override {
36 drag_position_ = drag_position;
37 }
38
39 void OnDragEnd(const TouchSelectionDraggable& handler) override {
40 dragging_ = false;
41 }
42
43 bool IsWithinTapSlop(const gfx::Vector2dF& delta) const override {
44 return delta.LengthSquared() < (kSlop * kSlop);
45 }
46
47 void OnLongPressDragActiveStateChanged() override {
48 active_state_changed_ = true;
49 }
50
51 gfx::PointF GetSelectionStart() const override { return selection_start_; }
52
53 gfx::PointF GetSelectionEnd() const override { return selection_end_; }
54
55 void SetSelection(const gfx::PointF& start, const gfx::PointF& end) {
56 selection_start_ = start;
57 selection_end_ = end;
58 }
59
60 bool GetAndResetActiveStateChanged() {
61 bool active_state_changed = active_state_changed_;
62 active_state_changed_ = false;
63 return active_state_changed;
64 }
65
66 bool IsDragging() const { return dragging_; }
67 const gfx::PointF& DragPosition() const { return drag_position_; }
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. The motion is downward, so the end selection point
mfomitchev 2015/05/13 20:52:25 The comment about downward motion would probably f
jdduke (slow) 2015/05/14 18:29:26 Done.
99 // should be moved. Note that the first move event after activation is used to
100 // initialize the drag start anchor.
101 EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
102 EXPECT_FALSE(IsDragging());
103
104 // The first slop exceeding motion will start the drag.
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. The initial motion is leftward, toward the selection
142 // start, so that should be the drag point.
143 EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, kSlop, 0)));
mfomitchev 2015/05/13 20:52:25 I don't get it - kSlop is greater than 0, so why i
jdduke (slow) 2015/05/14 18:29:26 Yeah, the comment is in a bad position, I'll chang
144 EXPECT_FALSE(IsDragging());
145
146 EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
147 EXPECT_TRUE(IsDragging());
148 EXPECT_EQ(selection_start, DragPosition());
149
150 EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, -kSlop)));
151 EXPECT_TRUE(IsDragging());
152 EXPECT_EQ(selection_start + gfx::Vector2dF(0, -kSlop), DragPosition());
153
154 // Release the touch sequence, ending the drag.
155 EXPECT_FALSE(selector.WillHandleTouchEvent(event.ReleasePoint()));
156 EXPECT_FALSE(IsDragging());
157 EXPECT_TRUE(GetAndResetActiveStateChanged());
158 }
159
160 TEST_F(LongPressDragSelectorTest, NoActiveTouch) {
161 LongPressDragSelector selector(this);
162 MockMotionEvent event;
163
164 // Activate a longpress-triggered selection.
165 gfx::PointF selection_start(0, 10);
166 gfx::PointF selection_end(10, 10);
167 selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF());
168 SetSelection(selection_start, selection_end);
169 selector.OnSelectionActivated();
170 EXPECT_FALSE(GetAndResetActiveStateChanged());
171 EXPECT_FALSE(IsDragging());
172
173 // Start a new touch sequence; it shouldn't initiate selection drag as there
174 // was no active touch sequence when the longpress selection started.
175 EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
176 EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
177 EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop)));
178 EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2)));
179 EXPECT_FALSE(IsDragging());
180 EXPECT_EQ(gfx::PointF(), DragPosition());
181 }
182
183 TEST_F(LongPressDragSelectorTest, NoLongPress) {
184 LongPressDragSelector selector(this);
185 MockMotionEvent event;
186
187 // Start a touch sequence.
188 EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
189 EXPECT_FALSE(GetAndResetActiveStateChanged());
190
191 // Activate a selection without a preceding longpress.
192 gfx::PointF selection_start(0, 10);
193 gfx::PointF selection_end(10, 10);
194 SetSelection(selection_start, selection_end);
195 selector.OnSelectionActivated();
196 EXPECT_FALSE(GetAndResetActiveStateChanged());
197 EXPECT_FALSE(IsDragging());
198
199 // Touch movement should not initiate selection drag.
200 EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
201 EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop)));
202 EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2)));
203 EXPECT_FALSE(IsDragging());
204 EXPECT_EQ(gfx::PointF(), DragPosition());
205 }
206
207 TEST_F(LongPressDragSelectorTest, NoValidLongPress) {
208 LongPressDragSelector selector(this);
209 MockMotionEvent event;
210
211 // Start a touch sequence.
212 EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
213 EXPECT_FALSE(GetAndResetActiveStateChanged());
214
215 gfx::PointF selection_start(0, 10);
216 gfx::PointF selection_end(10, 10);
217 SetSelection(selection_start, selection_end);
218
219 // Activate a longpress-triggered selection, but at a time different than the
mfomitchev 2015/05/13 20:52:25 different -> before ?
jdduke (slow) 2015/05/14 18:29:26 Done.
220 // current touch down event.
221 selector.OnLongPressEvent(
222 event.GetEventTime() - base::TimeDelta::FromSeconds(1), gfx::PointF());
223 selector.OnSelectionActivated();
224 EXPECT_FALSE(GetAndResetActiveStateChanged());
225 EXPECT_FALSE(IsDragging());
226
227 // Activate a longpress-triggered selection, but at a place different than the
228 // current touch down event.
229 selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF(kSlop * 2, 0));
mfomitchev 2015/05/13 20:52:25 Can we do kSlop here instead of kSlop * 2?
jdduke (slow) 2015/05/14 18:29:26 Done.
230 selector.OnSelectionActivated();
231 EXPECT_FALSE(GetAndResetActiveStateChanged());
232 EXPECT_FALSE(IsDragging());
233
234 // Touch movement should not initiate selection drag.
235 EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
236 EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop)));
237 EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2)));
238 EXPECT_FALSE(IsDragging());
239 EXPECT_EQ(gfx::PointF(), DragPosition());
240 }
241
242 TEST_F(LongPressDragSelectorTest, NoSelection) {
243 LongPressDragSelector selector(this);
244 MockMotionEvent event;
245
246 // Start a touch sequence.
247 EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
248 EXPECT_FALSE(GetAndResetActiveStateChanged());
249
250 // Trigger a longpress. This will notify the client that detection is active,
251 // but until there's a longpress no drag selection should occur.
252 selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF());
253 EXPECT_TRUE(GetAndResetActiveStateChanged());
254 EXPECT_FALSE(IsDragging());
255
256 // Touch movement should not initiate selection drag, as there is no active
257 // selection.
258 EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
259 EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop)));
260 EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2)));
261 EXPECT_FALSE(IsDragging());
262 EXPECT_EQ(gfx::PointF(), DragPosition());
263
264 EXPECT_FALSE(selector.WillHandleTouchEvent(event.ReleasePoint()));
265 EXPECT_TRUE(GetAndResetActiveStateChanged());
266 }
267
268 TEST_F(LongPressDragSelectorTest, NoDragMotion) {
269 LongPressDragSelector selector(this);
270 MockMotionEvent event;
271
272 // Start a touch sequence.
273 EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
274 EXPECT_FALSE(GetAndResetActiveStateChanged());
275
276 // Activate a longpress-triggered selection.
277 selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF());
278 EXPECT_TRUE(GetAndResetActiveStateChanged());
279 gfx::PointF selection_start(0, 10);
280 gfx::PointF selection_end(10, 10);
281 SetSelection(selection_start, selection_end);
282 selector.OnSelectionActivated();
283 EXPECT_FALSE(IsDragging());
284
285 // Touch movement within the slop region should not initiate selection drag.
286 EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
287 EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop / 2)));
288 EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, -kSlop / 2)));
289 EXPECT_FALSE(IsDragging());
290 EXPECT_EQ(gfx::PointF(), DragPosition());
291
292 EXPECT_FALSE(selector.WillHandleTouchEvent(event.ReleasePoint()));
293 EXPECT_TRUE(GetAndResetActiveStateChanged());
294 }
295
296 TEST_F(LongPressDragSelectorTest, SelectionDeactivated) {
297 LongPressDragSelector selector(this);
298 MockMotionEvent event;
299
300 // Start a touch sequence.
301 EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
302 EXPECT_FALSE(GetAndResetActiveStateChanged());
303
304 // Activate a longpress-triggered selection.
305 selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF());
306 EXPECT_TRUE(GetAndResetActiveStateChanged());
307 gfx::PointF selection_start(0, 10);
308 gfx::PointF selection_end(10, 10);
309 SetSelection(selection_start, selection_end);
310 selector.OnSelectionActivated();
311 EXPECT_FALSE(IsDragging());
312
313 // Start a drag selection.
314 EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
315 EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop)));
316 EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2)));
317 EXPECT_TRUE(IsDragging());
318
319 // Clearing the selection should force an end to the drag.
320 selector.OnSelectionDeactivated();
321 EXPECT_TRUE(GetAndResetActiveStateChanged());
322 EXPECT_FALSE(IsDragging());
323
324 // Subsequent motion should not be consumed.
325 EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
326 EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop)));
327 EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2)));
328 EXPECT_FALSE(IsDragging());
329 EXPECT_FALSE(selector.WillHandleTouchEvent(event.ReleasePoint()));
330 }
331
332 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698