summaryrefslogtreecommitdiffstats
path: root/ui/views/view_unittest.cc
diff options
context:
space:
mode:
authorvollick@chromium.org <vollick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-17 03:28:27 +0000
committervollick@chromium.org <vollick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-17 03:28:27 +0000
commita7826751a6148308e774797db2f9842ec1cdefa1 (patch)
tree3e0385f2a6b4e65bedc14945487a0a17e913aa7c /ui/views/view_unittest.cc
parentc4b89ffbed7bb2d2cde94b5ebd6b42f72bca45db (diff)
downloadchromium_src-a7826751a6148308e774797db2f9842ec1cdefa1.zip
chromium_src-a7826751a6148308e774797db2f9842ec1cdefa1.tar.gz
chromium_src-a7826751a6148308e774797db2f9842ec1cdefa1.tar.bz2
Initial views touchui Gesture Recognizer support
This is just a merge of Gajen's patch (http://codereview.chromium.org/8364039/) with ToT. BUG=101645 TEST=views_unittest Review URL: http://codereview.chromium.org/9076002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@117869 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/views/view_unittest.cc')
-rw-r--r--ui/views/view_unittest.cc334
1 files changed, 334 insertions, 0 deletions
diff --git a/ui/views/view_unittest.cc b/ui/views/view_unittest.cc
index 44d7456..8d0d956 100644
--- a/ui/views/view_unittest.cc
+++ b/ui/views/view_unittest.cc
@@ -30,6 +30,7 @@
#include "ui/views/focus/view_storage.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/touchui/gesture_manager.h"
+#include "ui/views/touchui/gesture_recognizer.h"
#include "ui/views/view.h"
#include "ui/views/views_delegate.h"
#include "ui/views/widget/native_widget.h"
@@ -206,6 +207,8 @@ class TestView : public View {
location_.SetPoint(0, 0);
last_touch_event_type_ = 0;
last_touch_event_was_handled_ = false;
+ last_gesture_event_type_ = 0;
+ last_gesture_event_was_handled_ = false;
last_clip_.setEmpty();
accelerator_count_map_.clear();
}
@@ -215,6 +218,8 @@ class TestView : public View {
virtual bool OnMouseDragged(const MouseEvent& event) OVERRIDE;
virtual void OnMouseReleased(const MouseEvent& event) OVERRIDE;
virtual ui::TouchStatus OnTouchEvent(const TouchEvent& event) OVERRIDE;
+ // Ignores GestureEvent by default.
+ virtual ui::GestureStatus OnGestureEvent(const GestureEvent& event) OVERRIDE;
virtual void Paint(gfx::Canvas* canvas) OVERRIDE;
virtual void SchedulePaintInRect(const gfx::Rect& rect) OVERRIDE;
virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE;
@@ -230,6 +235,10 @@ class TestView : public View {
// Painting.
std::vector<gfx::Rect> scheduled_paint_rects_;
+ // GestureEvent
+ int last_gesture_event_type_;
+ bool last_gesture_event_was_handled_;
+
// TouchEvent.
int last_touch_event_type_;
bool last_touch_event_was_handled_;
@@ -266,6 +275,27 @@ class MockGestureManager : public GestureManager {
DISALLOW_COPY_AND_ASSIGN(MockGestureManager);
};
+// GestureRecognizer for testing.
+class TestGestureRecognizer : public GestureRecognizer {
+ public:
+ TestGestureRecognizer();
+
+ // Reset all test state.
+ void reset() {
+ last_touch_event_ = 0;
+ previously_handled_flag_ = false;
+ }
+
+ virtual Gestures* ProcessTouchEventForGesture(
+ const TouchEvent& event,
+ ui::TouchStatus status) OVERRIDE;
+
+ bool previously_handled_flag_;
+ int last_touch_event_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestGestureRecognizer);
+};
+
// A view subclass that ignores all touch events for testing purposes.
class TestViewIgnoreTouch : public TestView {
public:
@@ -276,6 +306,32 @@ class TestViewIgnoreTouch : public TestView {
virtual ui::TouchStatus OnTouchEvent(const TouchEvent& event) OVERRIDE;
};
+// A view subclass that consumes all Gesture events for testing purposes.
+class TestViewConsumeGesture : public TestView {
+ public:
+ TestViewConsumeGesture() : TestView() {}
+ virtual ~TestViewConsumeGesture() {}
+
+ private:
+ virtual ui::TouchStatus OnTouchEvent(const TouchEvent& event) OVERRIDE;
+ virtual ui::GestureStatus OnGestureEvent(const GestureEvent& event) OVERRIDE;
+
+ DISALLOW_COPY_AND_ASSIGN(TestViewConsumeGesture);
+};
+
+// A view subclass that ignores all Gesture and touch events.
+class TestViewIgnoreTouchAndGesture: public TestView {
+ public:
+ TestViewIgnoreTouchAndGesture() : TestView() {}
+ virtual ~TestViewIgnoreTouchAndGesture() {}
+
+ private:
+ virtual ui::TouchStatus OnTouchEvent(const TouchEvent& event) OVERRIDE;
+ virtual ui::GestureStatus OnGestureEvent(const GestureEvent& event) OVERRIDE;
+
+ DISALLOW_COPY_AND_ASSIGN(TestViewIgnoreTouchAndGesture);
+};
+
////////////////////////////////////////////////////////////////////////////////
// OnBoundsChanged
////////////////////////////////////////////////////////////////////////////////
@@ -540,6 +596,284 @@ TEST_F(ViewTest, TouchEvent) {
}
////////////////////////////////////////////////////////////////////////////////
+// GestureEvent
+////////////////////////////////////////////////////////////////////////////////
+
+GestureRecognizer::Gestures* TestGestureRecognizer::ProcessTouchEventForGesture(
+ const TouchEvent& event,
+ ui::TouchStatus status) {
+ if (status != ui::TOUCH_STATUS_UNKNOWN) {
+ return NULL;
+ }
+ last_touch_event_ = event.type();
+ previously_handled_flag_ = status != ui::TOUCH_STATUS_UNKNOWN;
+ return GestureRecognizer::ProcessTouchEventForGesture(event, status);
+}
+
+TestGestureRecognizer::TestGestureRecognizer() {
+}
+
+ui::GestureStatus TestView::OnGestureEvent(const GestureEvent& event) {
+ return ui::GESTURE_STATUS_UNKNOWN;
+}
+
+// GestureConsumer view should ignore TouchEvent for testing purposes.
+ui::TouchStatus TestViewConsumeGesture::OnTouchEvent(
+ const TouchEvent& event) {
+ return ui::TOUCH_STATUS_UNKNOWN;
+}
+
+ui::GestureStatus TestViewConsumeGesture::OnGestureEvent(
+ const GestureEvent& event) {
+ last_gesture_event_type_ = event.type();
+ location_.SetPoint(event.x(), event.y());
+ return ui::GESTURE_STATUS_CONSUMED;
+}
+
+// IgnoreTouchAndGesture view should ignore touch and Gesture event for
+// testing purposes.
+ui::TouchStatus TestViewIgnoreTouchAndGesture::OnTouchEvent(
+ const TouchEvent& event) {
+ return ui::TOUCH_STATUS_UNKNOWN;
+}
+
+ui::GestureStatus TestViewIgnoreTouchAndGesture::OnGestureEvent(
+ const GestureEvent& event) {
+ return ui::GESTURE_STATUS_UNKNOWN;
+}
+
+#if defined(TOUCH_UI)
+TEST_F(ViewTest, GestureEvent) {
+ MockGestureManager gm;
+ TestGestureRecognizer gr;
+
+ // Views hierarchy for non delivery of GestureEvent.
+ TestView* v1 = new TestViewConsumeGesture();
+ v1->SetBounds(0, 0, 300, 300);
+
+ TestView* v2 = new TestView();
+ v2->SetBounds(100, 100, 100, 100);
+
+ TestView* v3 = new TestViewConsumeGesture();
+ v3->SetBounds(0, 0, 100, 100);
+
+ // Views hierarchy for delivery of GestureEvent.
+ TestView* v4 = new TestViewConsumeGesture();
+ v4->SetBounds(200, 200, 100, 100);
+
+ scoped_ptr<Widget> widget(new Widget());
+ Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
+ params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ params.bounds = gfx::Rect(50, 50, 650, 650);
+ widget->Init(params);
+ View* root = widget->GetRootView();
+
+ root->AddChildView(v1);
+ static_cast<internal::RootView*>(root)->SetGestureManagerForTesting(&gm);
+ static_cast<internal::RootView*>(root)->SetGestureRecognizerForTesting(&gr);
+ v1->AddChildView(v2);
+ v2->AddChildView(v3);
+ v1->AddChildView(v4);
+
+ // |v3| completely obscures |v2|, but all the touch events on |v3| should
+ // reach |v2| because |v3| doesn't process any touch events, hence no gesture
+ // conversion take place.
+
+ // Both |v4| and |v1| ignore touch events, hence |v4| should recieve gesture
+ // events.
+
+ // Make sure if none of the views handle the touch event, the gesture manager
+ // does.
+ v1->Reset();
+ v2->Reset();
+ v3->Reset();
+ v4->Reset();
+ gr.reset();
+ gm.Reset();
+
+ TouchEvent unhandled(ui::ET_TOUCH_MOVED,
+ 400,
+ 400,
+ 0, /* no flags */
+ 0, /* first finger touch */
+ 1.0, 0.0, 1.0, 0.0);
+ root->OnTouchEvent(unhandled);
+
+ EXPECT_EQ(v1->last_touch_event_type_, 0);
+ EXPECT_EQ(v2->last_touch_event_type_, 0);
+ EXPECT_EQ(v4->last_touch_event_type_, 0);
+ EXPECT_EQ(v4->last_gesture_event_type_, 0);
+
+ EXPECT_EQ(gr.previously_handled_flag_, false);
+ EXPECT_EQ(gr.last_touch_event_, ui::ET_TOUCH_MOVED);
+
+ // Test press, drag, release touch sequence.
+ v1->Reset();
+ v2->Reset();
+ v3->Reset();
+ v4->Reset();
+ gr.reset();
+ gm.Reset();
+
+ TouchEvent pressed(ui::ET_TOUCH_PRESSED,
+ 110,
+ 120,
+ 0, /* no flags */
+ 0, /* first finger touch */
+ 1.0, 0.0, 1.0, 0.0);
+ v2->last_touch_event_was_handled_ = true;
+ root->OnTouchEvent(pressed);
+
+ EXPECT_EQ(v2->last_touch_event_type_, ui::ET_TOUCH_PRESSED);
+ EXPECT_EQ(v2->location_.x(), 10);
+ EXPECT_EQ(v2->location_.y(), 20);
+ // Make sure v1 did not receive the event
+ EXPECT_EQ(v1->last_touch_event_type_, 0);
+
+ // Since v2 handled the touch-event, the gesture recognizer should not
+ // handle it.
+ EXPECT_EQ(gr.last_touch_event_, 0);
+ EXPECT_EQ(gr.previously_handled_flag_, false);
+
+ // Drag event out of bounds. Should still go to v2
+ v1->Reset();
+ v2->Reset();
+ TouchEvent dragged(ui::ET_TOUCH_MOVED,
+ 50,
+ 40,
+ 0, /* no flags */
+ 0, /* first finger touch */
+ 1.0, 0.0, 1.0, 0.0);
+ root->OnTouchEvent(dragged);
+ EXPECT_EQ(v2->last_touch_event_type_, ui::ET_TOUCH_MOVED);
+ EXPECT_EQ(v2->location_.x(), -50);
+ EXPECT_EQ(v2->location_.y(), -60);
+ // Make sure v1 did not receive the event
+ EXPECT_EQ(v1->last_touch_event_type_, 0);
+
+ EXPECT_EQ(gr.last_touch_event_, 0);
+ EXPECT_EQ(gr.previously_handled_flag_, false);
+
+ // Released event out of bounds. Should still go to v2
+ v1->Reset();
+ v2->Reset();
+ TouchEvent released(ui::ET_TOUCH_RELEASED, 0, 0, 0, 0 /* first finger */,
+ 1.0, 0.0, 1.0, 0.0);
+ v2->last_touch_event_was_handled_ = true;
+ root->OnTouchEvent(released);
+ EXPECT_EQ(v2->last_touch_event_type_, ui::ET_TOUCH_RELEASED);
+ EXPECT_EQ(v2->location_.x(), -100);
+ EXPECT_EQ(v2->location_.y(), -100);
+ // Make sure v1 did not receive the event
+ EXPECT_EQ(v1->last_touch_event_type_, 0);
+
+ EXPECT_EQ(gr.last_touch_event_, 0);
+ EXPECT_EQ(gr.previously_handled_flag_, false);
+
+ // Gesture event handling test.
+ // 1) Test gesture type ui::ET_GESTURE_TAP_DOWN.
+ v1->Reset();
+ v4->Reset();
+ gr.reset();
+ gm.Reset();
+
+ TouchEvent second_pressed(ui::ET_TOUCH_PRESSED,
+ 210,
+ 220,
+ 0, /* no flags */
+ 0, /* first finger touch */
+ 1.0, 0.0, 1.0, 0.0);
+ base::Time pressed_time = second_pressed.time_stamp();
+ root->OnTouchEvent(second_pressed);
+
+ // Since v1 and V4 didn't handled touch event, the gesture manager should
+ // handle it.
+ EXPECT_EQ(gr.last_touch_event_, ui::ET_TOUCH_PRESSED);
+ EXPECT_EQ(gr.previously_handled_flag_, false);
+
+ // Check v4 should receive gesture event but not v1.
+ EXPECT_EQ(v1->last_touch_event_type_, 0);
+ EXPECT_EQ(v4->last_touch_event_type_, 0);
+ EXPECT_EQ(v4->last_gesture_event_type_, ui::ET_GESTURE_TAP_DOWN);
+ EXPECT_EQ(v4->location_.x(), 10);
+ EXPECT_EQ(v4->location_.y(), 20);
+
+ // 2) Test gesture type ui::ET_GESTURE_TAP.
+ v1->Reset();
+ v4->Reset();
+ gr.reset();
+ gm.Reset();
+
+ TouchEvent second_released(ui::ET_TOUCH_RELEASED,
+ 210,
+ 220,
+ 0, /* no flags */
+ 0, /* first finger touch */
+ 1.0, 0.0, 1.0, 0.0);
+
+ // Set touch time with-in click window.
+ second_released.set_time_stamp(base::Time::FromDoubleT(
+ pressed_time.ToDoubleT() + 0.7));
+ root->OnTouchEvent(second_released);
+
+ // Since v1 and V4 didn't handled touch event, the gesture manager should
+ // handle it.
+ EXPECT_EQ(gr.last_touch_event_, ui::ET_TOUCH_RELEASED);
+ EXPECT_EQ(gr.previously_handled_flag_, false);
+
+ // Check v4 should receive gesture event but not v1.
+ EXPECT_EQ(v1->last_touch_event_type_, 0);
+ EXPECT_EQ(v4->last_touch_event_type_, 0);
+ EXPECT_EQ(v4->last_gesture_event_type_, ui::ET_GESTURE_TAP);
+ EXPECT_EQ(v4->location_.x(), 10);
+ EXPECT_EQ(v4->location_.y(), 20);
+
+ // 3) Test Gesture to mouse conversion.
+ // Views hierarchy for delivery of mouse event in absence of Touch and
+ // Gesture handlers.
+ TestView* v5 = new TestViewIgnoreTouchAndGesture();
+ v5->SetBounds(0, 0, 300, 300);
+
+ TestView* v6 = new TestViewIgnoreTouchAndGesture();
+ v6->SetBounds(100, 100, 100, 100);
+
+ root->AddChildView(v5);
+ v5->AddChildView(v6);
+
+ v5->Reset();
+ v6->Reset();
+ gr.reset();
+ gm.Reset();
+
+ TouchEvent third_pressed(ui::ET_TOUCH_PRESSED,
+ 110,
+ 120,
+ 0, /* no flags */
+ 0, /* first finger touch */
+ 1.0, 0.0, 1.0, 0.0);
+ root->OnTouchEvent(third_pressed);
+
+ // Since v5 and V6 didn't handled touch and gesture event, gesture recognizer
+ // and manager should recieve touch event.
+ EXPECT_EQ(gr.last_touch_event_, ui::ET_TOUCH_PRESSED);
+ EXPECT_EQ(gr.previously_handled_flag_, false);
+ EXPECT_EQ(gm.previously_handled_flag_, false);
+ EXPECT_EQ(gm.last_touch_event_, ui::ET_TOUCH_PRESSED);
+ EXPECT_EQ(gm.last_view_, root);
+ EXPECT_EQ(gm.dispatched_synthetic_event_, true);
+
+ // Check v6 shouldn't recieve touch and gesture event but mouse event.
+ EXPECT_EQ(v6->last_touch_event_type_, 0);
+ EXPECT_EQ(v6->last_gesture_event_type_, 0);
+
+ // Check v5 shouldn't recieve touch, gesture and mouse event.
+ EXPECT_EQ(v5->last_touch_event_type_, 0);
+ EXPECT_EQ(v5->last_gesture_event_type_, 0);
+ widget->CloseNow();
+}
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
// Painting
////////////////////////////////////////////////////////////////////////////////