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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/touch_selection/longpress_drag_selector.cc ('k') | ui/touch_selection/touch_handle.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/touch_selection/longpress_drag_selector_unittest.cc
diff --git a/ui/touch_selection/longpress_drag_selector_unittest.cc b/ui/touch_selection/longpress_drag_selector_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..8c126d8022bfd51019d1d573b55e665ca1c3a541
--- /dev/null
+++ b/ui/touch_selection/longpress_drag_selector_unittest.cc
@@ -0,0 +1,333 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/touch_selection/longpress_drag_selector.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/events/test/motion_event_test_utils.h"
+
+using ui::test::MockMotionEvent;
+
+namespace ui {
+namespace {
+
+const double kSlop = 10.;
+
+} // namespace
+
+class LongPressDragSelectorTest : public testing::Test,
+ public LongPressDragSelectorClient {
+ public:
+ LongPressDragSelectorTest()
+ : dragging_(false), active_state_changed_(false) {}
+
+ ~LongPressDragSelectorTest() override {}
+
+ void SetSelection(const gfx::PointF& start, const gfx::PointF& end) {
+ selection_start_ = start;
+ selection_end_ = end;
+ }
+
+ bool GetAndResetActiveStateChanged() {
+ bool active_state_changed = active_state_changed_;
+ active_state_changed_ = false;
+ return active_state_changed;
+ }
+
+ bool IsDragging() const { return dragging_; }
+ const gfx::PointF& DragPosition() const { return drag_position_; }
+
+ // LongPressDragSelectorClient implementation.
+ void OnDragBegin(const TouchSelectionDraggable& handler,
+ const gfx::PointF& drag_position) override {
+ dragging_ = true;
+ drag_position_ = drag_position;
+ }
+
+ void OnDragUpdate(const TouchSelectionDraggable& handler,
+ const gfx::PointF& drag_position) override {
+ drag_position_ = drag_position;
+ }
+
+ void OnDragEnd(const TouchSelectionDraggable& handler) override {
+ dragging_ = false;
+ }
+
+ bool IsWithinTapSlop(const gfx::Vector2dF& delta) const override {
+ return delta.LengthSquared() < (kSlop * kSlop);
+ }
+
+ void OnLongPressDragActiveStateChanged() override {
+ active_state_changed_ = true;
+ }
+
+ gfx::PointF GetSelectionStart() const override { return selection_start_; }
+
+ gfx::PointF GetSelectionEnd() const override { return selection_end_; }
+
+ private:
+ bool dragging_;
+ bool active_state_changed_;
+ gfx::PointF drag_position_;
+
+ gfx::PointF selection_start_;
+ gfx::PointF selection_end_;
+};
+
+TEST_F(LongPressDragSelectorTest, BasicDrag) {
+ LongPressDragSelector selector(this);
+ MockMotionEvent event;
+
+ // Start a touch sequence.
+ EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
+ EXPECT_FALSE(GetAndResetActiveStateChanged());
+
+ // Activate a longpress-triggered selection.
+ gfx::PointF selection_start(0, 10);
+ gfx::PointF selection_end(10, 10);
+ selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF());
+ EXPECT_TRUE(GetAndResetActiveStateChanged());
+
+ // Motion should not be consumed until a selection is detected.
+ EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
+ SetSelection(selection_start, selection_end);
+ selector.OnSelectionActivated();
+ EXPECT_FALSE(IsDragging());
+
+ // Initiate drag motion. Note that the first move event after activation is
+ // used to initialize the drag start anchor.
+ EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
+ EXPECT_FALSE(IsDragging());
+
+ // The first slop exceeding motion will start the drag. As the motion is
+ // downward, the end selection point should be moved.
+ EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop)));
+ EXPECT_TRUE(IsDragging());
+ EXPECT_EQ(selection_end, DragPosition());
+
+ // Subsequent motion will extend the selection.
+ EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2)));
+ EXPECT_TRUE(IsDragging());
+ EXPECT_EQ(selection_end + gfx::Vector2dF(0, kSlop), DragPosition());
+ EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 3)));
+ EXPECT_TRUE(IsDragging());
+ EXPECT_EQ(selection_end + gfx::Vector2dF(0, kSlop * 2), DragPosition());
+
+ // Release the touch sequence, ending the drag. The selector will never
+ // consume the start/end events, only move events after a longpress.
+ EXPECT_FALSE(selector.WillHandleTouchEvent(event.ReleasePoint()));
+ EXPECT_FALSE(IsDragging());
+ EXPECT_TRUE(GetAndResetActiveStateChanged());
+}
+
+TEST_F(LongPressDragSelectorTest, BasicReverseDrag) {
+ LongPressDragSelector selector(this);
+ MockMotionEvent event;
+
+ // Start a touch sequence.
+ EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
+ EXPECT_FALSE(GetAndResetActiveStateChanged());
+
+ // Activate a longpress-triggered selection.
+ gfx::PointF selection_start(0, 10);
+ gfx::PointF selection_end(10, 10);
+ selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF());
+ EXPECT_TRUE(GetAndResetActiveStateChanged());
+ SetSelection(selection_start, selection_end);
+ selector.OnSelectionActivated();
+ EXPECT_FALSE(IsDragging());
+
+ // Initiate drag motion.
+ EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
+ EXPECT_FALSE(IsDragging());
+
+ // As the initial motion is leftward, toward the selection start, the
+ // selection start should be the drag point.
+ EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, -kSlop, 0)));
+ EXPECT_TRUE(IsDragging());
+ EXPECT_EQ(selection_start, DragPosition());
+
+ EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, -kSlop)));
+ EXPECT_TRUE(IsDragging());
+ EXPECT_EQ(selection_start + gfx::Vector2dF(kSlop, -kSlop), DragPosition());
+
+ // Release the touch sequence, ending the drag.
+ EXPECT_FALSE(selector.WillHandleTouchEvent(event.ReleasePoint()));
+ EXPECT_FALSE(IsDragging());
+ EXPECT_TRUE(GetAndResetActiveStateChanged());
+}
+
+TEST_F(LongPressDragSelectorTest, NoActiveTouch) {
+ LongPressDragSelector selector(this);
+ MockMotionEvent event;
+
+ // Activate a longpress-triggered selection.
+ gfx::PointF selection_start(0, 10);
+ gfx::PointF selection_end(10, 10);
+ selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF());
+ SetSelection(selection_start, selection_end);
+ selector.OnSelectionActivated();
+ EXPECT_FALSE(GetAndResetActiveStateChanged());
+ EXPECT_FALSE(IsDragging());
+
+ // Start a new touch sequence; it shouldn't initiate selection drag as there
+ // was no active touch sequence when the longpress selection started.
+ EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
+ EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
+ EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop)));
+ EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2)));
+ EXPECT_FALSE(IsDragging());
+ EXPECT_EQ(gfx::PointF(), DragPosition());
+}
+
+TEST_F(LongPressDragSelectorTest, NoLongPress) {
+ LongPressDragSelector selector(this);
+ MockMotionEvent event;
+
+ // Start a touch sequence.
+ EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
+ EXPECT_FALSE(GetAndResetActiveStateChanged());
+
+ // Activate a selection without a preceding longpress.
+ gfx::PointF selection_start(0, 10);
+ gfx::PointF selection_end(10, 10);
+ SetSelection(selection_start, selection_end);
+ selector.OnSelectionActivated();
+ EXPECT_FALSE(GetAndResetActiveStateChanged());
+ EXPECT_FALSE(IsDragging());
+
+ // Touch movement should not initiate selection drag.
+ EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
+ EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop)));
+ EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2)));
+ EXPECT_FALSE(IsDragging());
+ EXPECT_EQ(gfx::PointF(), DragPosition());
+}
+
+TEST_F(LongPressDragSelectorTest, NoValidLongPress) {
+ LongPressDragSelector selector(this);
+ MockMotionEvent event;
+
+ // Start a touch sequence.
+ EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
+ EXPECT_FALSE(GetAndResetActiveStateChanged());
+
+ gfx::PointF selection_start(0, 10);
+ gfx::PointF selection_end(10, 10);
+ SetSelection(selection_start, selection_end);
+
+ // Activate a longpress-triggered selection, but at a time before the current
+ // touch down event.
+ selector.OnLongPressEvent(
+ event.GetEventTime() - base::TimeDelta::FromSeconds(1), gfx::PointF());
+ selector.OnSelectionActivated();
+ EXPECT_FALSE(GetAndResetActiveStateChanged());
+ EXPECT_FALSE(IsDragging());
+
+ // Activate a longpress-triggered selection, but at a place different than the
+ // current touch down event.
+ selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF(kSlop, 0));
+ selector.OnSelectionActivated();
+ EXPECT_FALSE(GetAndResetActiveStateChanged());
+ EXPECT_FALSE(IsDragging());
+
+ // Touch movement should not initiate selection drag.
+ EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
+ EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop)));
+ EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2)));
+ EXPECT_FALSE(IsDragging());
+ EXPECT_EQ(gfx::PointF(), DragPosition());
+}
+
+TEST_F(LongPressDragSelectorTest, NoSelection) {
+ LongPressDragSelector selector(this);
+ MockMotionEvent event;
+
+ // Start a touch sequence.
+ EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
+ EXPECT_FALSE(GetAndResetActiveStateChanged());
+
+ // Trigger a longpress. This will notify the client that detection is active,
+ // but until there's a longpress no drag selection should occur.
+ selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF());
+ EXPECT_TRUE(GetAndResetActiveStateChanged());
+ EXPECT_FALSE(IsDragging());
+
+ // Touch movement should not initiate selection drag, as there is no active
+ // selection.
+ EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
+ EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop)));
+ EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2)));
+ EXPECT_FALSE(IsDragging());
+ EXPECT_EQ(gfx::PointF(), DragPosition());
+
+ EXPECT_FALSE(selector.WillHandleTouchEvent(event.ReleasePoint()));
+ EXPECT_TRUE(GetAndResetActiveStateChanged());
+}
+
+TEST_F(LongPressDragSelectorTest, NoDragMotion) {
+ LongPressDragSelector selector(this);
+ MockMotionEvent event;
+
+ // Start a touch sequence.
+ EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
+ EXPECT_FALSE(GetAndResetActiveStateChanged());
+
+ // Activate a longpress-triggered selection.
+ selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF());
+ EXPECT_TRUE(GetAndResetActiveStateChanged());
+ gfx::PointF selection_start(0, 10);
+ gfx::PointF selection_end(10, 10);
+ SetSelection(selection_start, selection_end);
+ selector.OnSelectionActivated();
+ EXPECT_FALSE(IsDragging());
+
+ // Touch movement within the slop region should not initiate selection drag.
+ EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
+ EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop / 2)));
+ EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, -kSlop / 2)));
+ EXPECT_FALSE(IsDragging());
+ EXPECT_EQ(gfx::PointF(), DragPosition());
+
+ EXPECT_FALSE(selector.WillHandleTouchEvent(event.ReleasePoint()));
+ EXPECT_TRUE(GetAndResetActiveStateChanged());
+}
+
+TEST_F(LongPressDragSelectorTest, SelectionDeactivated) {
+ LongPressDragSelector selector(this);
+ MockMotionEvent event;
+
+ // Start a touch sequence.
+ EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
+ EXPECT_FALSE(GetAndResetActiveStateChanged());
+
+ // Activate a longpress-triggered selection.
+ selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF());
+ EXPECT_TRUE(GetAndResetActiveStateChanged());
+ gfx::PointF selection_start(0, 10);
+ gfx::PointF selection_end(10, 10);
+ SetSelection(selection_start, selection_end);
+ selector.OnSelectionActivated();
+ EXPECT_FALSE(IsDragging());
+
+ // Start a drag selection.
+ EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
+ EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop)));
+ EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2)));
+ EXPECT_TRUE(IsDragging());
+
+ // Clearing the selection should force an end to the drag.
+ selector.OnSelectionDeactivated();
+ EXPECT_TRUE(GetAndResetActiveStateChanged());
+ EXPECT_FALSE(IsDragging());
+
+ // Subsequent motion should not be consumed.
+ EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
+ EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop)));
+ EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2)));
+ EXPECT_FALSE(IsDragging());
+ EXPECT_FALSE(selector.WillHandleTouchEvent(event.ReleasePoint()));
+}
+
+} // namespace ui
« no previous file with comments | « ui/touch_selection/longpress_drag_selector.cc ('k') | ui/touch_selection/touch_handle.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698