OLD | NEW |
---|---|
(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 | |
OLD | NEW |