| Index: views/view_unittest.cc
|
| diff --git a/views/view_unittest.cc b/views/view_unittest.cc
|
| index 679754dbb89780d647c736611d763f16da3db02b..42f770c17590a01c7f4d75b630539bb498c52517 100644
|
| --- a/views/view_unittest.cc
|
| +++ b/views/view_unittest.cc
|
| @@ -44,6 +44,9 @@
|
| #if defined(USE_AURA)
|
| #include "ui/aura/desktop.h"
|
| #endif
|
| +#if defined(TOUCH_UI)
|
| +#include "views/touchui/gesture_recognizer.h"
|
| +#endif
|
|
|
| using ::testing::_;
|
|
|
| @@ -205,6 +208,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();
|
| }
|
| @@ -214,6 +219,9 @@ 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;
|
| @@ -234,6 +242,10 @@ class TestView : public View {
|
| bool last_touch_event_was_handled_;
|
| bool in_touch_sequence_;
|
|
|
| + // GestureEvent
|
| + int last_gesture_event_type_;
|
| + bool last_gesture_event_was_handled_;
|
| +
|
| // Painting.
|
| SkRect last_clip_;
|
|
|
| @@ -265,6 +277,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:
|
| @@ -275,6 +308,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
|
| ////////////////////////////////////////////////////////////////////////////////
|
| @@ -539,6 +598,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
|
| ////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|