diff options
author | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-19 00:48:01 +0000 |
---|---|---|
committer | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-19 00:48:01 +0000 |
commit | 912b6f3be7f1e31b4107ecb8b572245d9f65ff47 (patch) | |
tree | d43a9f10d01316cc817cd7619f1561e0ed279e04 | |
parent | 7d692835b4257b2621f969037f52e1dca67d833e (diff) | |
download | chromium_src-912b6f3be7f1e31b4107ecb8b572245d9f65ff47.zip chromium_src-912b6f3be7f1e31b4107ecb8b572245d9f65ff47.tar.gz chromium_src-912b6f3be7f1e31b4107ecb8b572245d9f65ff47.tar.bz2 |
aura: Move GestureRecognizer from views into aura.
Remove deprecated GestureManager, and move the functional GestureRecognizer from views into aura.
BUG=110227
TEST=views_unittests:GestureEvent, aura_unittests:GestureRecognizerTest
Review URL: https://chromiumcodereview.appspot.com/9255019
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@118200 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | ui/aura/aura.gyp | 4 | ||||
-rw-r--r-- | ui/aura/event.cc | 22 | ||||
-rw-r--r-- | ui/aura/event.h | 25 | ||||
-rw-r--r-- | ui/aura/gestures/gesture_recognizer.cc (renamed from ui/views/touchui/gesture_recognizer.cc) | 16 | ||||
-rw-r--r-- | ui/aura/gestures/gesture_recognizer.h (renamed from ui/views/touchui/gesture_recognizer.h) | 15 | ||||
-rw-r--r-- | ui/aura/gestures/gesture_recognizer_unittest.cc | 266 | ||||
-rw-r--r-- | ui/aura/root_window.cc | 78 | ||||
-rw-r--r-- | ui/aura/root_window.h | 10 | ||||
-rw-r--r-- | ui/views/events/event.cc | 28 | ||||
-rw-r--r-- | ui/views/events/event.h | 19 | ||||
-rw-r--r-- | ui/views/events/event_aura.cc | 14 | ||||
-rw-r--r-- | ui/views/touchui/gesture_manager.cc | 58 | ||||
-rw-r--r-- | ui/views/touchui/gesture_manager.h | 56 | ||||
-rw-r--r-- | ui/views/view.h | 10 | ||||
-rw-r--r-- | ui/views/view_unittest.cc | 371 | ||||
-rw-r--r-- | ui/views/views.gyp | 4 | ||||
-rw-r--r-- | ui/views/widget/native_widget_aura.cc | 4 | ||||
-rw-r--r-- | ui/views/widget/root_view.cc | 47 | ||||
-rw-r--r-- | ui/views/widget/root_view.h | 22 |
19 files changed, 493 insertions, 576 deletions
diff --git a/ui/aura/aura.gyp b/ui/aura/aura.gyp index 90a5007..db1ad70 100644 --- a/ui/aura/aura.gyp +++ b/ui/aura/aura.gyp @@ -13,6 +13,7 @@ 'dependencies': [ '../../base/base.gyp:base', '../../base/base.gyp:base_i18n', + '../../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', '../../skia/skia.gyp:skia', '../gfx/compositor/compositor.gyp:compositor', '../ui.gyp:gfx_resources', @@ -43,6 +44,8 @@ 'client/window_move_client.h', 'client/window_types.h', 'cursor.h', + 'gestures/gesture_recognizer.cc', + 'gestures/gesture_recognizer.h', 'root_window_host.h', 'root_window_host_linux.cc', 'root_window_host_win.cc', @@ -145,6 +148,7 @@ '..', ], 'sources': [ + 'gestures/gesture_recognizer_unittest.cc', 'test/run_all_unittests.cc', 'test/test_suite.cc', 'test/test_suite.h', diff --git a/ui/aura/event.cc b/ui/aura/event.cc index 57a0f31..c62ff40 100644 --- a/ui/aura/event.cc +++ b/ui/aura/event.cc @@ -352,4 +352,26 @@ ScrollEvent::ScrollEvent(const base::NativeEvent& native_event) ui::GetScrollOffsets(native_event, &x_offset_, &y_offset_); } +GestureEvent::GestureEvent(ui::EventType type, + int x, + int y, + int flags, + base::Time time_stamp, + float delta_x, + float delta_y) + : LocatedEvent(type, gfx::Point(x, y), flags), + delta_x_(delta_x), + delta_y_(delta_y) { + // XXX: Why is aura::Event::time_stamp_ a TimeDelta instead of a Time? + set_time_stamp(base::TimeDelta::FromSeconds(time_stamp.ToDoubleT())); +} + +GestureEvent::GestureEvent(const GestureEvent& model, + Window* source, + Window* target) + : LocatedEvent(model, source, target), + delta_x_(model.delta_x_), + delta_y_(model.delta_y_) { +} + } // namespace aura diff --git a/ui/aura/event.h b/ui/aura/event.h index c840f43..9f97661 100644 --- a/ui/aura/event.h +++ b/ui/aura/event.h @@ -66,6 +66,7 @@ class AURA_EXPORT Event { void set_delete_native_event(bool delete_native_event) { delete_native_event_ = delete_native_event; } + void set_time_stamp(base::TimeDelta time_stamp) { time_stamp_ = time_stamp; } private: void operator=(const Event&); @@ -137,7 +138,7 @@ class AURA_EXPORT MouseEvent : public LocatedEvent { ui::EventType type, int flags); - // Used for synthetic events in testing. + // Used for synthetic events in testing and by the gesture recognizer. MouseEvent(ui::EventType type, const gfx::Point& location, int flags); // Compares two mouse down events and returns true if the second one should @@ -288,6 +289,28 @@ class AURA_EXPORT ScrollEvent : public MouseEvent { }; class AURA_EXPORT GestureEvent : public LocatedEvent { + public: + GestureEvent(ui::EventType type, + int x, + int y, + int flags, + base::Time time_stamp, + float delta_x, + float delta_y); + + // Create a new TouchEvent which is identical to the provided model. + // If source / target windows are provided, the model location will be + // converted from |source| coordinate system to |target| coordinate system. + GestureEvent(const GestureEvent& model, Window* source, Window* target); + + float delta_x() const { return delta_x_; } + float delta_y() const { return delta_y_; } + + private: + float delta_x_; + float delta_y_; + + DISALLOW_COPY_AND_ASSIGN(GestureEvent); }; } // namespace aura diff --git a/ui/views/touchui/gesture_recognizer.cc b/ui/aura/gestures/gesture_recognizer.cc index 112b222..8787282 100644 --- a/ui/views/touchui/gesture_recognizer.cc +++ b/ui/aura/gestures/gesture_recognizer.cc @@ -2,11 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ui/views/touchui/gesture_recognizer.h" +#include "ui/aura/gestures/gesture_recognizer.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" -#include "ui/views/events/event.h" +#include "base/time.h" +#include "ui/aura/event.h" +#include "ui/base/events.h" namespace { // TODO(Gajen): Make these configurable in sync with this CL http://code.google. @@ -19,7 +21,7 @@ const float kMinFlickSpeedSquared = 550.f * 550.f; } // namespace -namespace views { +namespace aura { //////////////////////////////////////////////////////////////////////////////// // GestureRecognizer Public: @@ -49,7 +51,7 @@ GestureRecognizer::Gestures* GestureRecognizer::ProcessTouchEventForGesture( scoped_ptr<Gestures> gestures(new Gestures()); UpdateValues(event); - switch (Signature(state_, event.identity(), event.type(), false)) { + switch (Signature(state_, event.touch_id(), event.type(), false)) { case GST_NO_GESTURE_FIRST_PRESSED: TouchDown(event, gestures.get()); break; @@ -214,11 +216,11 @@ void GestureRecognizer:: AppendScrollGestureUpdate(const TouchEvent& event, void GestureRecognizer::UpdateValues(const TouchEvent& event) { if (state_ != GS_NO_GESTURE && event.type() == ui::ET_TOUCH_MOVED) { - double interval(event.time_stamp().ToDoubleT() - last_touch_time_); + double interval(event.time_stamp().InSecondsF() - last_touch_time_); x_velocity_ = (event.x() - last_touch_position_.x()) / interval; y_velocity_ = (event.y() - last_touch_position_.y()) / interval; } - last_touch_time_ = event.time_stamp().ToDoubleT(); + last_touch_time_ = event.time_stamp().InSecondsF(); last_touch_position_ = event.location(); if (state_ == GS_NO_GESTURE) { first_touch_time_ = last_touch_time_; @@ -284,4 +286,4 @@ bool GestureRecognizer::ScrollEnd(const TouchEvent& event, Gestures* gestures) { return false; } -} // namespace views +} // namespace aura diff --git a/ui/views/touchui/gesture_recognizer.h b/ui/aura/gestures/gesture_recognizer.h index 2eeca89..4edd1b8 100644 --- a/ui/views/touchui/gesture_recognizer.h +++ b/ui/aura/gestures/gesture_recognizer.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef UI_VIEWS_TOUCHUI_GESTURE_RECOGNIZER_H_ -#define UI_VIEWS_TOUCHUI_GESTURE_RECOGNIZER_H_ +#ifndef UI_AURA_GESTURES_GESTURE_RECOGNIZER_H_ +#define UI_AURA_GESTURES_GESTURE_RECOGNIZER_H_ #pragma once #include <map> @@ -11,17 +11,16 @@ #include "base/memory/linked_ptr.h" #include "base/memory/singleton.h" +#include "ui/aura/aura_export.h" #include "ui/base/events.h" #include "ui/gfx/point.h" -#include "ui/views/views_export.h" -namespace views { -class GestureManager; +namespace aura { class TouchEvent; class GestureEvent; // A GestureRecognizer recognizes gestures from touch sequences. -class VIEWS_EXPORT GestureRecognizer { +class AURA_EXPORT GestureRecognizer { public: // Gesture state. enum GestureState { @@ -172,6 +171,6 @@ class VIEWS_EXPORT GestureRecognizer { DISALLOW_COPY_AND_ASSIGN(GestureRecognizer); }; -} // namespace views +} // namespace aura -#endif // UI_VIEWS_TOUCHUI_GESTURE_RECOGNIZER_H_ +#endif // UI_AURA_GESTURES_GESTURE_RECOGNIZER_H_ diff --git a/ui/aura/gestures/gesture_recognizer_unittest.cc b/ui/aura/gestures/gesture_recognizer_unittest.cc new file mode 100644 index 0000000..bc65b71 --- /dev/null +++ b/ui/aura/gestures/gesture_recognizer_unittest.cc @@ -0,0 +1,266 @@ +// Copyright (c) 2012 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 "testing/gtest/include/gtest/gtest.h" +#include "ui/aura/event.h" +#include "ui/aura/root_window.h" +#include "ui/aura/test/aura_test_base.h" +#include "ui/aura/test/test_window_delegate.h" +#include "ui/aura/test/test_windows.h" +#include "ui/base/hit_test.h" +#include "ui/gfx/point.h" +#include "ui/gfx/rect.h" + +namespace aura { +namespace test { + +namespace { + +// A delegate that keeps track of gesture events. +class GestureEventConsumeDelegate : public TestWindowDelegate { + public: + GestureEventConsumeDelegate() + : tap_(false), + tap_down_(false), + double_tap_(false), + scroll_begin_(false), + scroll_update_(false), + scroll_end_(false), + scroll_x_(0), + scroll_y_(0) { + } + + virtual ~GestureEventConsumeDelegate() {} + + void Reset() { + tap_ = false; + tap_down_ = false; + double_tap_ = false; + scroll_begin_ = false; + scroll_update_ = false; + scroll_end_ = false; + + scroll_x_ = 0; + scroll_y_ = 0; + } + + bool tap() const { return tap_; } + bool tap_down() const { return tap_down_; } + bool double_tap() const { return double_tap_; } + bool scroll_begin() const { return scroll_begin_; } + bool scroll_update() const { return scroll_update_; } + bool scroll_end() const { return scroll_end_; } + + float scroll_x() const { return scroll_x_; } + float scroll_y() const { return scroll_y_; } + + virtual ui::GestureStatus OnGestureEvent(GestureEvent* gesture) OVERRIDE { + switch (gesture->type()) { + case ui::ET_GESTURE_TAP: + tap_ = true; + break; + case ui::ET_GESTURE_TAP_DOWN: + tap_down_ = true; + break; + case ui::ET_GESTURE_DOUBLE_TAP: + double_tap_ = true; + break; + case ui::ET_GESTURE_SCROLL_BEGIN: + scroll_begin_ = true; + break; + case ui::ET_GESTURE_SCROLL_UPDATE: + scroll_update_ = true; + scroll_x_ += gesture->delta_x(); + scroll_y_ += gesture->delta_y(); + break; + case ui::ET_GESTURE_SCROLL_END: + scroll_end_ = true; + break; + default: + NOTREACHED(); + } + return ui::GESTURE_STATUS_CONSUMED; + } + + private: + bool tap_; + bool tap_down_; + bool double_tap_; + bool scroll_begin_; + bool scroll_update_; + bool scroll_end_; + + float scroll_x_; + float scroll_y_; + + DISALLOW_COPY_AND_ASSIGN(GestureEventConsumeDelegate); +}; + +// A delegate that ignores gesture events but keeps track of [synthetic] mouse +// events. +class GestureEventSynthDelegate : public TestWindowDelegate { + public: + GestureEventSynthDelegate() + : mouse_enter_(false), + mouse_exit_(false), + mouse_press_(false), + mouse_release_(false), + mouse_move_(false) { + } + + void Reset() { + mouse_enter_ = false; + mouse_exit_ = false; + mouse_press_ = false; + mouse_release_ = false; + mouse_move_ = false; + } + + bool mouse_enter() const { return mouse_enter_; } + bool mouse_exit() const { return mouse_exit_; } + bool mouse_press() const { return mouse_press_; } + bool mouse_move() const { return mouse_move_; } + bool mouse_release() const { return mouse_release_; } + + virtual bool OnMouseEvent(MouseEvent* event) OVERRIDE { + switch (event->type()) { + case ui::ET_MOUSE_PRESSED: + mouse_press_ = true; + break; + case ui::ET_MOUSE_RELEASED: + mouse_release_ = true; + break; + case ui::ET_MOUSE_MOVED: + mouse_move_ = true; + break; + case ui::ET_MOUSE_ENTERED: + mouse_enter_ = true; + break; + case ui::ET_MOUSE_EXITED: + mouse_exit_ = true; + break; + default: + NOTREACHED(); + } + return true; + } + + private: + bool mouse_enter_; + bool mouse_exit_; + bool mouse_press_; + bool mouse_release_; + bool mouse_move_; + + DISALLOW_COPY_AND_ASSIGN(GestureEventSynthDelegate); +}; + +} // namespace + +typedef AuraTestBase GestureRecognizerTest; + +// Check that appropriate touch events generate tap gesture events. +TEST_F(GestureRecognizerTest, GestureEventTap) { + scoped_ptr<GestureEventConsumeDelegate> delegate( + new GestureEventConsumeDelegate()); + const int kWindowWidth = 123; + const int kWindowHeight = 45; + gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); + scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( + delegate.get(), -1234, bounds, NULL)); + + delegate->Reset(); + TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), 0); + RootWindow::GetInstance()->DispatchTouchEvent(&press); + EXPECT_FALSE(delegate->tap()); + EXPECT_TRUE(delegate->tap_down()); + EXPECT_FALSE(delegate->double_tap()); + EXPECT_FALSE(delegate->scroll_begin()); + EXPECT_FALSE(delegate->scroll_update()); + EXPECT_FALSE(delegate->scroll_end()); + + // Make sure there is enough delay before the touch is released so that it is + // recognized as a tap. + delegate->Reset(); + TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), 0); + Event::TestApi test_release(&release); + test_release.set_time_stamp(press.time_stamp() + + base::TimeDelta::FromMilliseconds(50)); + RootWindow::GetInstance()->DispatchTouchEvent(&release); + EXPECT_TRUE(delegate->tap()); + EXPECT_FALSE(delegate->tap_down()); + EXPECT_FALSE(delegate->double_tap()); + EXPECT_FALSE(delegate->scroll_begin()); + EXPECT_FALSE(delegate->scroll_update()); + EXPECT_FALSE(delegate->scroll_end()); +} + +// Check that appropriate touch events generate scroll gesture events. +TEST_F(GestureRecognizerTest, GestureEventScroll) { + scoped_ptr<GestureEventConsumeDelegate> delegate( + new GestureEventConsumeDelegate()); + const int kWindowWidth = 123; + const int kWindowHeight = 45; + gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); + scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( + delegate.get(), -1234, bounds, NULL)); + + delegate->Reset(); + TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), 0); + RootWindow::GetInstance()->DispatchTouchEvent(&press); + EXPECT_FALSE(delegate->tap()); + EXPECT_TRUE(delegate->tap_down()); + EXPECT_FALSE(delegate->double_tap()); + EXPECT_FALSE(delegate->scroll_begin()); + EXPECT_FALSE(delegate->scroll_update()); + EXPECT_FALSE(delegate->scroll_end()); + + // Move the touch-point enough so that it is considered as a scroll. This + // should generate both SCROLL_BEGIN and SCROLL_UPDATE gestures. + delegate->Reset(); + TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(130, 201), 0); + RootWindow::GetInstance()->DispatchTouchEvent(&move); + EXPECT_FALSE(delegate->tap()); + EXPECT_FALSE(delegate->tap_down()); + EXPECT_FALSE(delegate->double_tap()); + EXPECT_TRUE(delegate->scroll_begin()); + EXPECT_TRUE(delegate->scroll_update()); + EXPECT_FALSE(delegate->scroll_end()); + EXPECT_EQ(29, delegate->scroll_x()); + EXPECT_EQ(0, delegate->scroll_y()); + + // Release the touch. This should end the scroll. + delegate->Reset(); + TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), 0); + Event::TestApi test_release(&release); + test_release.set_time_stamp(press.time_stamp() + + base::TimeDelta::FromMilliseconds(50)); + RootWindow::GetInstance()->DispatchTouchEvent(&release); + EXPECT_FALSE(delegate->tap()); + EXPECT_FALSE(delegate->tap_down()); + EXPECT_FALSE(delegate->double_tap()); + EXPECT_FALSE(delegate->scroll_begin()); + EXPECT_FALSE(delegate->scroll_update()); + EXPECT_TRUE(delegate->scroll_end()); +} + +// Check that unprocessed gesture events generate appropriate synthetic mouse +// events. +TEST_F(GestureRecognizerTest, GestureTapSyntheticMouse) { + scoped_ptr<GestureEventSynthDelegate> delegate( + new GestureEventSynthDelegate()); + scoped_ptr<Window> window(CreateTestWindowWithDelegate(delegate.get(), -1234, + gfx::Rect(0, 0, 123, 45), NULL)); + + delegate->Reset(); + GestureEvent tap(ui::ET_GESTURE_TAP, 20, 20, 0, base::Time::Now(), 0, 0); + RootWindow::GetInstance()->DispatchGestureEvent(&tap); + EXPECT_TRUE(delegate->mouse_enter()); + EXPECT_TRUE(delegate->mouse_press()); + EXPECT_TRUE(delegate->mouse_release()); + EXPECT_TRUE(delegate->mouse_exit()); +} + +} // namespace test +} // namespace aura diff --git a/ui/aura/root_window.cc b/ui/aura/root_window.cc index 6ce24d4..7909239 100644 --- a/ui/aura/root_window.cc +++ b/ui/aura/root_window.cc @@ -20,6 +20,7 @@ #include "ui/aura/event.h" #include "ui/aura/event_filter.h" #include "ui/aura/focus_manager.h" +#include "ui/aura/gestures/gesture_recognizer.h" #include "ui/aura/screen_aura.h" #include "ui/aura/window.h" #include "ui/aura/window_delegate.h" @@ -207,9 +208,11 @@ bool RootWindow::DispatchTouchEvent(TouchEvent* event) { touch_event_handler_ ? touch_event_handler_ : capture_window_; if (!target) target = GetEventHandlerForPoint(event->location()); + + ui::TouchStatus status = ui::TOUCH_STATUS_UNKNOWN; if (target) { TouchEvent translated_event(*event, this, target); - ui::TouchStatus status = ProcessTouchEvent(target, &translated_event); + status = ProcessTouchEvent(target, &translated_event); if (status == ui::TOUCH_STATUS_START) touch_event_handler_ = target; else if (status == ui::TOUCH_STATUS_END || @@ -218,15 +221,32 @@ bool RootWindow::DispatchTouchEvent(TouchEvent* event) { handled = status != ui::TOUCH_STATUS_UNKNOWN; } - if (!handled) { - // TODO(sad): Send the touch to the gesture recognizer. + // Get the list of GestureEvents from GestureRecognizer. + scoped_ptr<GestureRecognizer::Gestures> gestures; + gestures.reset(gesture_recognizer_->ProcessTouchEventForGesture(*event, + status)); + if (gestures.get()) { + for (unsigned int i = 0; i < gestures->size(); i++) { + GestureEvent* gesture = gestures->at(i).get(); + if (DispatchGestureEvent(gesture) != ui::GESTURE_STATUS_UNKNOWN) + handled = true; + } } return handled; } bool RootWindow::DispatchGestureEvent(GestureEvent* event) { - // TODO(sad): + event->UpdateForTransform(layer()->transform()); + Window* target = gesture_handler_ ? gesture_handler_ : capture_window_; + if (!target) + target = GetEventHandlerForPoint(event->location()); + if (target) { + GestureEvent translated_event(*event, this, target); + ui::GestureStatus status = ProcessGestureEvent(target, &translated_event); + return status != ui::GESTURE_STATUS_UNKNOWN; + } + return false; } @@ -269,6 +289,8 @@ void RootWindow::WindowDestroying(Window* window) { capture_window_ = NULL; if (touch_event_handler_ == window) touch_event_handler_ = NULL; + if (gesture_handler_ == window) + gesture_handler_ = NULL; } MessageLoop::Dispatcher* RootWindow::GetDispatcher() { @@ -312,10 +334,13 @@ void RootWindow::SetCapture(Window* window) { touch_event_handler_ = capture_window_; if (mouse_moved_handler_ || mouse_button_flags_ != 0) mouse_moved_handler_ = capture_window_; + if (gesture_handler_) + gesture_handler_ = capture_window_; } else { // When capture is lost, we must reset the event handlers. touch_event_handler_ = NULL; mouse_moved_handler_ = NULL; + gesture_handler_ = NULL; } mouse_pressed_handler_ = NULL; } @@ -355,7 +380,9 @@ RootWindow::RootWindow() mouse_pressed_handler_(NULL), mouse_moved_handler_(NULL), focused_window_(NULL), - touch_event_handler_(NULL) { + touch_event_handler_(NULL), + gesture_handler_(NULL), + gesture_recognizer_(GestureRecognizer::GetInstance()) { SetName("RootWindow"); gfx::Screen::SetInstance(screen_); host_->SetRootWindow(this); @@ -371,6 +398,8 @@ RootWindow::RootWindow() host_->GetSize()); } DCHECK(compositor_.get()); + + gesture_recognizer_->Reset(); } RootWindow::~RootWindow() { @@ -460,14 +489,49 @@ ui::GestureStatus RootWindow::ProcessGestureEvent(Window* target, EventFilters filters; GetEventFiltersToNotify(target, &filters); + ui::GestureStatus status = ui::GESTURE_STATUS_UNKNOWN; for (EventFilters::const_reverse_iterator it = filters.rbegin(); it != filters.rend(); ++it) { - ui::GestureStatus status = (*it)->PreHandleGestureEvent(target, event); + status = (*it)->PreHandleGestureEvent(target, event); if (status != ui::GESTURE_STATUS_UNKNOWN) return status; } - return target->delegate()->OnGestureEvent(event); + status = target->delegate()->OnGestureEvent(event); + if (status == ui::GESTURE_STATUS_UNKNOWN) { + // The gesture was unprocessed. Generate corresponding mouse events here + // (e.g. tap to click). + switch (event->type()) { + case ui::ET_GESTURE_TAP: { + // Tap should be processed as a click. So generate the following + // sequence of mouse events: MOUSE_ENTERED, MOUSE_PRESSED, + // MOUSE_RELEASED and MOUSE_EXITED. + ui::EventType types[] = { ui::ET_MOUSE_ENTERED, + ui::ET_MOUSE_PRESSED, + ui::ET_MOUSE_RELEASED, + ui::ET_MOUSE_EXITED, + ui::ET_UNKNOWN + }; + gesture_handler_ = target; + for (ui::EventType* type = types; *type != ui::ET_UNKNOWN; ++type) { + MouseEvent synth(*type, event->location(), event->flags()); + if (gesture_handler_->delegate()->OnMouseEvent(&synth)) + status = ui::GESTURE_STATUS_SYNTH_MOUSE; + // The window that was receiving the gestures may have closed/hidden + // itself in response to one of the synthetic events. Stop sending + // subsequent synthetic events if that happens. + if (!gesture_handler_) + break; + } + gesture_handler_ = NULL; + break; + } + default: + break; + } + } + + return status; } void RootWindow::ScheduleDraw() { diff --git a/ui/aura/root_window.h b/ui/aura/root_window.h index b4dbd2e..8e59c4f 100644 --- a/ui/aura/root_window.h +++ b/ui/aura/root_window.h @@ -40,6 +40,7 @@ class StackingClient; class ScrollEvent; class TouchEvent; class GestureEvent; +class GestureRecognizer; // RootWindow is responsible for hosting a set of windows. class AURA_EXPORT RootWindow : public ui::CompositorDelegate, @@ -151,6 +152,11 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate, void ToggleFullScreen(); #endif + // Provided only for testing: + void SetGestureRecognizerForTesting(GestureRecognizer* gr) { + gesture_recognizer_ = gr; + } + // Overridden from ui::CompositorDelegate: virtual void ScheduleDraw() OVERRIDE; @@ -229,6 +235,10 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate, Window* mouse_moved_handler_; Window* focused_window_; Window* touch_event_handler_; + Window* gesture_handler_; + + // The gesture_recognizer_ for this. + GestureRecognizer* gesture_recognizer_; DISALLOW_COPY_AND_ASSIGN(RootWindow); }; diff --git a/ui/views/events/event.cc b/ui/views/events/event.cc index e6c7a0d..a143392 100644 --- a/ui/views/events/event.cc +++ b/ui/views/events/event.cc @@ -205,25 +205,11 @@ const int MouseWheelEvent::kWheelDelta = 53; //////////////////////////////////////////////////////////////////////////////// // GestureEvent, public: -GestureEvent::GestureEvent(ui::EventType type, - int x, - int y, - int flags, - base::Time time_stamp, - float delta_x, - float delta_y) - : LocatedEvent(type, gfx::Point(x, y), flags), - delta_x_(delta_x), - delta_y_(delta_y) { - set_time_stamp(time_stamp); -} - GestureEvent::GestureEvent(const GestureEvent& model, View* source, View* target) : LocatedEvent(model, source, target), delta_x_(model.delta_x_), delta_y_(model.delta_y_) { - set_time_stamp(model.time_stamp()); } //////////////////////////////////////////////////////////////////////////////// @@ -233,7 +219,19 @@ GestureEvent::GestureEvent(const GestureEvent& model, View* root) : LocatedEvent(model, root), delta_x_(model.delta_x_), delta_y_(model.delta_y_) { - set_time_stamp(model.time_stamp()); +} + +GestureEvent::GestureEvent(ui::EventType type, int x, int y, int flags) + : LocatedEvent(type, gfx::Point(x, y), flags), + delta_x_(0), + delta_y_(0) { +} + +GestureEventForTest::GestureEventForTest(ui::EventType type, + int x, + int y, + int flags) + : GestureEvent(type, x, y, flags) { } } // namespace views diff --git a/ui/views/events/event.h b/ui/views/events/event.h index fcdb7d5..6e4e462 100644 --- a/ui/views/events/event.h +++ b/ui/views/events/event.h @@ -429,13 +429,7 @@ class VIEWS_EXPORT ScrollEvent : public MouseEvent { //////////////////////////////////////////////////////////////////////////////// class VIEWS_EXPORT GestureEvent : public LocatedEvent { public: - GestureEvent(ui::EventType type, - int x, - int y, - int flags, - base::Time time_stamp, - float delta_x, - float delta_y); + explicit GestureEvent(const NativeEvent& native_event); // Create a new GestureEvent which is identical to the provided model. // If source / target views are provided, the model location will be converted @@ -445,6 +439,9 @@ class VIEWS_EXPORT GestureEvent : public LocatedEvent { float delta_x() const { return delta_x_; } float delta_y() const { return delta_y_; } + protected: + GestureEvent(ui::EventType type, int x, int y, int flags); + private: friend class internal::RootView; @@ -456,6 +453,14 @@ class VIEWS_EXPORT GestureEvent : public LocatedEvent { DISALLOW_COPY_AND_ASSIGN(GestureEvent); }; +class VIEWS_EXPORT GestureEventForTest : public GestureEvent { + public: + GestureEventForTest(ui::EventType type, int x, int y, int flags); + + private: + DISALLOW_COPY_AND_ASSIGN(GestureEventForTest); +}; + } // namespace views #endif // UI_VIEWS_EVENTS_EVENT_H_ diff --git a/ui/views/events/event_aura.cc b/ui/views/events/event_aura.cc index 9b3af83..610752d 100644 --- a/ui/views/events/event_aura.cc +++ b/ui/views/events/event_aura.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -59,10 +59,22 @@ MouseWheelEvent::MouseWheelEvent(const NativeEvent& native_event) offset_(ui::GetMouseWheelOffset(native_event->native_event())) { } +//////////////////////////////////////////////////////////////////////////////// +// ScrollEvent, public: + ScrollEvent::ScrollEvent(const NativeEvent& native_event) : MouseEvent(native_event) { CHECK(ui::GetScrollOffsets( native_event->native_event(), &x_offset_, &y_offset_)); } +//////////////////////////////////////////////////////////////////////////////// +// GestureEvent, public: + +GestureEvent::GestureEvent(const NativeEvent& event) + : LocatedEvent(event), + delta_x_(static_cast<aura::GestureEvent*>(event)->delta_x()), + delta_y_(static_cast<aura::GestureEvent*>(event)->delta_y()) { +} + } // namespace views diff --git a/ui/views/touchui/gesture_manager.cc b/ui/views/touchui/gesture_manager.cc deleted file mode 100644 index 4dd6b0a..0000000 --- a/ui/views/touchui/gesture_manager.cc +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) 2011 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/views/touchui/gesture_manager.h" - -#ifndef NDEBUG -#include <ostream> -#endif - -#include "base/logging.h" -#include "ui/views/events/event.h" -#include "ui/views/view.h" -#include "ui/views/widget/widget.h" - -namespace views { - -GestureManager::~GestureManager() { -} - -GestureManager* GestureManager::GetInstance() { - return Singleton<GestureManager>::get(); -} - -bool GestureManager::ProcessTouchEventForGesture(const TouchEvent& event, - View* source, - ui::TouchStatus status) { - if (status != ui::TOUCH_STATUS_UNKNOWN) - return false; // The event was consumed by a touch sequence. - - // TODO(rjkroege): A realistic version of the GestureManager will - // appear in a subsequent CL. This interim version permits verifying that the - // event distribution code works by turning all touch inputs into - // mouse approximations. - - // Conver the touch-event into a mouse-event. This mouse-event gets its - // location information from the native-event, so it needs to convert the - // coordinate to the target widget. - MouseEvent mouseev(event); - Widget* source_widget = source->GetWidget(); - Widget* top_widget = source_widget->GetTopLevelWidget(); - if (source_widget != top_widget && top_widget) { - // This is necessary as TYPE_CHILD widget is still NativeWidgetGtk. - // Fix this once TYPE_CHILD is switched to NativeWidgetViews. - MouseEvent converted(mouseev, - top_widget->GetRootView(), - source_widget->GetRootView()); - source_widget->OnMouseEvent(mouseev); - } else { - source_widget->OnMouseEvent(mouseev); - } - return true; -} - -GestureManager::GestureManager() { -} - -} // namespace views diff --git a/ui/views/touchui/gesture_manager.h b/ui/views/touchui/gesture_manager.h deleted file mode 100644 index e5ec4b5..0000000 --- a/ui/views/touchui/gesture_manager.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 2011 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. - -#ifndef UI_VIEWS_TOUCHUI_GESTURE_MANAGER_H_ -#define UI_VIEWS_TOUCHUI_GESTURE_MANAGER_H_ -#pragma once - -#include "base/memory/singleton.h" -#include "ui/views/view.h" - -namespace ui { -enum TouchStatus; -} - -namespace views { -class TouchEvent; - -// A GestureManager singleton detects gestures occurring in the -// incoming feed of touch events across all of the RootViews in -// the system. In response to a given touch event, the GestureManager -// updates its internal state and optionally dispatches synthetic -// events to the invoking view. -// -class VIEWS_EXPORT GestureManager { - public: - virtual ~GestureManager(); - - static GestureManager* GetInstance(); - - // Invoked for each touch event that could contribute to the current gesture. - // Takes the event and the View that originated it and which will also - // be the target of any generated synthetic event. Finally, status - // specifies if a touch sequence is in progress or not, so that the - // GestureManager state can correctly reflect events that are handled - // already. - // Returns true if the event resulted in firing a synthetic event. - virtual bool ProcessTouchEventForGesture(const TouchEvent& event, - View* source, - ui::TouchStatus status); - - // TODO(rjkroege): Write the remainder of this class. - // It will appear in a subsequent CL. - - protected: - GestureManager(); - - private: - friend struct DefaultSingletonTraits<GestureManager>; - - DISALLOW_COPY_AND_ASSIGN(GestureManager); -}; - -} // namespace views - -#endif // UI_VIEWS_TOUCHUI_GESTURE_MANAGER_H_ diff --git a/ui/views/view.h b/ui/views/view.h index dfe1cc4..92cf372 100644 --- a/ui/views/view.h +++ b/ui/views/view.h @@ -582,7 +582,7 @@ class VIEWS_EXPORT View : public ui::LayerDelegate, // does nothing. Override as needed. virtual ui::TouchStatus OnTouchEvent(const TouchEvent& event); - // This method is invoked for each GestureEvent recognized from GestureManager + // This method is invoked for each GestureEvent created by GestureRecognizer. // Default implementation does nothing. Override as needed. virtual ui::GestureStatus OnGestureEvent(const GestureEvent& event); @@ -1257,12 +1257,12 @@ class VIEWS_EXPORT View : public ui::LayerDelegate, bool ProcessMouseDragged(const MouseEvent& event, DragInfo* drop_info); void ProcessMouseReleased(const MouseEvent& event); - // RootView will invoke this with incoming TouchEvents. Returns the - // the result of OnTouchEvent. + // RootView will invoke this with incoming TouchEvents. Returns the result + // of OnTouchEvent. ui::TouchStatus ProcessTouchEvent(const TouchEvent& event); - // GestureManager will invoke this with incoming GestureEvents. Returns the - // the result of OnGestureEvent. + // RootView will invoke this with incoming GestureEvents. Returns the result + // of OnGestureEvent. ui::GestureStatus ProcessGestureEvent(const GestureEvent& event); // Accelerators -------------------------------------------------------------- diff --git a/ui/views/view_unittest.cc b/ui/views/view_unittest.cc index 73f52e9..45e7dbd 100644 --- a/ui/views/view_unittest.cc +++ b/ui/views/view_unittest.cc @@ -29,8 +29,6 @@ #include "ui/views/focus/accelerator_handler.h" #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" @@ -41,8 +39,9 @@ #include "ui/views/test/test_views_delegate.h" #endif #if defined(USE_AURA) +#include "ui/aura/event.h" #include "ui/aura/root_window.h" -#include "ui/views/touchui/gesture_recognizer.h" +#include "ui/aura/gestures/gesture_recognizer.h" #endif #if !defined(USE_WEBKIT_COMPOSITOR) #include "ui/gfx/compositor/test/test_texture.h" @@ -252,51 +251,6 @@ class TestView : public View { std::map<ui::Accelerator, int> accelerator_count_map_; }; -// Mock instance of the GestureManager for testing. -class MockGestureManager : public GestureManager { - public: - // Reset all test state. - void Reset() { - last_touch_event_ = 0; - last_view_ = NULL; - previously_handled_flag_ = false; - dispatched_synthetic_event_ = false; - } - - bool ProcessTouchEventForGesture(const TouchEvent& event, - View* source, - ui::TouchStatus status); - MockGestureManager(); - - bool previously_handled_flag_; - int last_touch_event_; - View *last_view_; - bool dispatched_synthetic_event_; - - 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: @@ -314,23 +268,27 @@ class TestViewConsumeGesture : public TestView { virtual ~TestViewConsumeGesture() {} private: - virtual ui::TouchStatus OnTouchEvent(const TouchEvent& event) OVERRIDE; - virtual ui::GestureStatus OnGestureEvent(const GestureEvent& event) OVERRIDE; + virtual ui::GestureStatus OnGestureEvent(const GestureEvent& event) OVERRIDE { + last_gesture_event_type_ = event.type(); + location_.SetPoint(event.x(), event.y()); + return ui::GESTURE_STATUS_CONSUMED; + } DISALLOW_COPY_AND_ASSIGN(TestViewConsumeGesture); }; -// A view subclass that ignores all Gesture and touch events. -class TestViewIgnoreTouchAndGesture: public TestView { +// A view subclass that ignores all Gesture events. +class TestViewIgnoreGesture: public TestView { public: - TestViewIgnoreTouchAndGesture() : TestView() {} - virtual ~TestViewIgnoreTouchAndGesture() {} + TestViewIgnoreGesture() : TestView() {} + virtual ~TestViewIgnoreGesture() {} private: - virtual ui::TouchStatus OnTouchEvent(const TouchEvent& event) OVERRIDE; - virtual ui::GestureStatus OnGestureEvent(const GestureEvent& event) OVERRIDE; + virtual ui::GestureStatus OnGestureEvent(const GestureEvent& event) OVERRIDE { + return ui::GESTURE_STATUS_UNKNOWN; + } - DISALLOW_COPY_AND_ASSIGN(TestViewIgnoreTouchAndGesture); + DISALLOW_COPY_AND_ASSIGN(TestViewIgnoreGesture); }; //////////////////////////////////////////////////////////////////////////////// @@ -440,24 +398,6 @@ TEST_F(ViewTest, MouseEvent) { //////////////////////////////////////////////////////////////////////////////// // TouchEvent //////////////////////////////////////////////////////////////////////////////// -bool MockGestureManager::ProcessTouchEventForGesture( - const TouchEvent& event, - View* source, - ui::TouchStatus status) { - if (status != ui::TOUCH_STATUS_UNKNOWN) { - dispatched_synthetic_event_ = false; - return false; - } - last_touch_event_ = event.type(); - last_view_ = source; - previously_handled_flag_ = status != ui::TOUCH_STATUS_UNKNOWN; - dispatched_synthetic_event_ = true; - return true; -} - -MockGestureManager::MockGestureManager() { -} - ui::TouchStatus TestView::OnTouchEvent(const TouchEvent& event) { last_touch_event_type_ = event.type(); location_.SetPoint(event.x(), event.y()); @@ -482,8 +422,6 @@ ui::TouchStatus TestViewIgnoreTouch::OnTouchEvent(const TouchEvent& event) { } TEST_F(ViewTest, TouchEvent) { - MockGestureManager gm; - TestView* v1 = new TestView(); v1->SetBounds(0, 0, 300, 300); @@ -501,7 +439,6 @@ TEST_F(ViewTest, TouchEvent) { View* root = widget->GetRootView(); root->AddChildView(v1); - static_cast<internal::RootView*>(root)->SetGestureManagerForTesting(&gm); v1->AddChildView(v2); v2->AddChildView(v3); @@ -512,7 +449,6 @@ TEST_F(ViewTest, TouchEvent) { // does. v1->Reset(); v2->Reset(); - gm.Reset(); TouchEvent unhandled(ui::ET_TOUCH_MOVED, 400, @@ -525,15 +461,9 @@ TEST_F(ViewTest, TouchEvent) { EXPECT_EQ(v1->last_touch_event_type_, 0); EXPECT_EQ(v2->last_touch_event_type_, 0); - EXPECT_EQ(gm.previously_handled_flag_, false); - EXPECT_EQ(gm.last_touch_event_, ui::ET_TOUCH_MOVED); - EXPECT_EQ(gm.last_view_, root); - EXPECT_EQ(gm.dispatched_synthetic_event_, true); - // Test press, drag, release touch sequence. v1->Reset(); v2->Reset(); - gm.Reset(); TouchEvent pressed(ui::ET_TOUCH_PRESSED, 110, @@ -550,11 +480,6 @@ TEST_F(ViewTest, TouchEvent) { // Make sure v1 did not receive the event EXPECT_EQ(v1->last_touch_event_type_, 0); - // Since v2 handled the touch-event, the gesture manager should not handle it. - EXPECT_EQ(gm.last_touch_event_, 0); - EXPECT_EQ(NULL, gm.last_view_); - EXPECT_EQ(gm.previously_handled_flag_, false); - // Drag event out of bounds. Should still go to v2 v1->Reset(); v2->Reset(); @@ -572,10 +497,6 @@ TEST_F(ViewTest, TouchEvent) { // Make sure v1 did not receive the event EXPECT_EQ(v1->last_touch_event_type_, 0); - EXPECT_EQ(gm.last_touch_event_, 0); - EXPECT_EQ(NULL, gm.last_view_); - EXPECT_EQ(gm.previously_handled_flag_, false); - // Released event out of bounds. Should still go to v2 v1->Reset(); v2->Reset(); @@ -589,79 +510,24 @@ TEST_F(ViewTest, TouchEvent) { // Make sure v1 did not receive the event EXPECT_EQ(v1->last_touch_event_type_, 0); - EXPECT_EQ(gm.last_touch_event_, 0); - EXPECT_EQ(NULL, gm.last_view_); - EXPECT_EQ(gm.previously_handled_flag_, false); - widget->CloseNow(); } -//////////////////////////////////////////////////////////////////////////////// -// 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(); + TestView* v2 = new TestViewConsumeGesture(); v2->SetBounds(100, 100, 100, 100); - TestView* v3 = new TestViewConsumeGesture(); + TestView* v3 = new TestViewIgnoreGesture(); 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; @@ -670,209 +536,38 @@ TEST_F(ViewTest, GestureEvent) { 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. + // |v3| completely obscures |v2|, but all the gesture events on |v3| should + // reach |v2| because |v3| doesn't process any gesture events. However, since + // |v2| does process gesture events, gesture events on |v3| or |v2| should not + // reach |v1|. - // 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); + // Gesture on |v3| + GestureEventForTest g1(ui::ET_GESTURE_TAP, 110, 110, 0); + root->OnGestureEvent(g1); + EXPECT_EQ(ui::ET_GESTURE_TAP, v2->last_gesture_event_type_); + EXPECT_EQ(gfx::Point(10, 10), v2->location_); + EXPECT_EQ(ui::ET_UNKNOWN, v1->last_gesture_event_type_); - // 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); + // Gesture on |v1| + GestureEventForTest g2(ui::ET_GESTURE_TAP, 80, 80, 0); + root->OnGestureEvent(g2); + EXPECT_EQ(ui::ET_GESTURE_TAP, v1->last_gesture_event_type_); + EXPECT_EQ(gfx::Point(80, 80), v1->location_); + EXPECT_EQ(ui::ET_UNKNOWN, v2->last_gesture_event_type_); - // 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 diff --git a/ui/views/views.gyp b/ui/views/views.gyp index 1bee26a..64171c6 100644 --- a/ui/views/views.gyp +++ b/ui/views/views.gyp @@ -312,10 +312,6 @@ 'painter.h', 'repeat_controller.cc', 'repeat_controller.h', - 'touchui/gesture_manager.cc', - 'touchui/gesture_manager.h', - 'touchui/gesture_recognizer.cc', - 'touchui/gesture_recognizer.h', 'touchui/touch_selection_controller.cc', 'touchui/touch_selection_controller.h', 'view.cc', diff --git a/ui/views/widget/native_widget_aura.cc b/ui/views/widget/native_widget_aura.cc index f997344..13632fa 100644 --- a/ui/views/widget/native_widget_aura.cc +++ b/ui/views/widget/native_widget_aura.cc @@ -675,8 +675,8 @@ ui::TouchStatus NativeWidgetAura::OnTouchEvent(aura::TouchEvent* event) { ui::GestureStatus NativeWidgetAura::OnGestureEvent(aura::GestureEvent* event) { DCHECK(window_->IsVisible()); - // TODO(sad): - return ui::GESTURE_STATUS_UNKNOWN; + GestureEvent gesture_event(event); + return delegate_->OnGestureEvent(gesture_event); } bool NativeWidgetAura::CanFocus() { diff --git a/ui/views/widget/root_view.cc b/ui/views/widget/root_view.cc index f6ac343..efb6361 100644 --- a/ui/views/widget/root_view.cc +++ b/ui/views/widget/root_view.cc @@ -15,8 +15,6 @@ #include "ui/gfx/compositor/layer.h" #include "ui/views/focus/view_storage.h" #include "ui/views/layout/fill_layout.h" -#include "ui/views/touchui/gesture_manager.h" -#include "ui/views/touchui/gesture_recognizer.h" #include "ui/views/widget/widget.h" namespace views { @@ -39,9 +37,7 @@ RootView::RootView(Widget* widget) last_mouse_event_flags_(0), last_mouse_event_x_(-1), last_mouse_event_y_(-1), - gesture_manager_(GestureManager::GetInstance()), touch_pressed_handler_(NULL), - gesture_recognizer_(GestureRecognizer::GetInstance()), gesture_handling_view_(NULL), ALLOW_THIS_IN_INITIALIZER_LIST(focus_search_(this, false, false)), focus_traversable_parent_(NULL), @@ -340,8 +336,6 @@ ui::TouchStatus RootView::OnTouchEvent(const TouchEvent& event) { if (touch_pressed_handler_) { TouchEvent touch_event(e, this, touch_pressed_handler_); status = touch_pressed_handler_->ProcessTouchEvent(touch_event); - if (DoGestureProcessing(e, status)) - status = ui::TOUCH_STATUS_SYNTH_MOUSE; if (status == ui::TOUCH_STATUS_END) touch_pressed_handler_ = NULL; return status; @@ -352,8 +346,7 @@ ui::TouchStatus RootView::OnTouchEvent(const TouchEvent& event) { touch_pressed_handler_ && (touch_pressed_handler_ != this); touch_pressed_handler_ = touch_pressed_handler_->parent()) { if (!touch_pressed_handler_->enabled()) { - // Disabled views eat events but are treated as not handled by the - // the GestureManager. + // Disabled views eat events but are treated as not handled. status = ui::TOUCH_STATUS_UNKNOWN; break; } @@ -379,17 +372,12 @@ ui::TouchStatus RootView::OnTouchEvent(const TouchEvent& event) { if (status != ui::TOUCH_STATUS_START) touch_pressed_handler_ = NULL; - if (DoGestureProcessing(e, status)) - status = ui::TOUCH_STATUS_SYNTH_MOUSE; return status; } // Reset touch_pressed_handler_ to indicate that no processing is occurring. touch_pressed_handler_ = NULL; - // Give the touch event to the gesture manager. - if (gesture_manager_->ProcessTouchEventForGesture(e, this, status)) - status = ui::TOUCH_STATUS_SYNTH_MOUSE; return status; } @@ -402,8 +390,7 @@ ui::GestureStatus RootView::OnGestureEvent(const GestureEvent& event) { gesture_handling_view_ && (gesture_handling_view_ != this); gesture_handling_view_ = gesture_handling_view_->parent()) { if (!gesture_handling_view_->enabled()) { - // Disabled views eat events but are treated as not handled by the - // the GestureManager. + // Disabled views eat events but are treated as not handled. return ui::GESTURE_STATUS_UNKNOWN; } @@ -498,35 +485,5 @@ void RootView::SetMouseLocationAndFlags(const MouseEvent& event) { last_mouse_event_y_ = event.y(); } -bool RootView::DoGestureProcessing(const TouchEvent& event, - ui::TouchStatus status) { - if (status != ui::TOUCH_STATUS_UNKNOWN) - return false; // The event was consumed by a touch sequence. - - // Get the GestureEvent list processed from GestureRecognizer. - scoped_ptr<GestureRecognizer::Gestures> gestures; - gestures.reset(gesture_recognizer_->ProcessTouchEventForGesture(event, - status)); - bool synthetic = true; - for (unsigned int i = 0; i < gestures->size(); i++) { - GestureEvent* event = gestures->at(i).get(); - GestureEvent e(*event, this); - if (OnGestureEvent(e) == ui::GESTURE_STATUS_CONSUMED) { - // All gesture events should be consumed. - synthetic = false; - } else { - synthetic = true; - break; - } - } - if (synthetic) { - // TODO(Gajen): This should be removed in future once all views are capable - // of handling OnGestureEvent. - return gesture_manager_->ProcessTouchEventForGesture(event, this, - status); - } - return synthetic; -} - } // namespace internal } // namespace views diff --git a/ui/views/widget/root_view.h b/ui/views/widget/root_view.h index 2539676..7ae1316 100644 --- a/ui/views/widget/root_view.h +++ b/ui/views/widget/root_view.h @@ -20,8 +20,6 @@ enum TouchStatus; namespace views { class Widget; -class GestureManager; -class GestureRecognizer; // This is a views-internal API and should not be used externally. // Widget exposes this object as a View*. @@ -70,12 +68,6 @@ class VIEWS_EXPORT RootView : public View, public FocusTraversable { // it. Returns whether anyone consumed the event. bool OnKeyEvent(const KeyEvent& event); - // Provided only for testing: - void SetGestureManagerForTesting(GestureManager* g) { gesture_manager_ = g; } - void SetGestureRecognizerForTesting(GestureRecognizer* gr) { - gesture_recognizer_ = gr; - } - // Focus --------------------------------------------------------------------- // Used to set the FocusTraversable parent after the view has been created @@ -132,10 +124,6 @@ class VIEWS_EXPORT RootView : public View, public FocusTraversable { friend class View; friend class Widget; - // Required so the GestureManager can call the Process* entry points - // with synthetic events as necessary. - friend class GestureManager; - // Input --------------------------------------------------------------------- // Update the cursor given a mouse event. This is called by non mouse_move @@ -150,10 +138,6 @@ class VIEWS_EXPORT RootView : public View, public FocusTraversable { // be applied to the point prior to calling this). void SetMouseLocationAndFlags(const MouseEvent& event); - // Feeds touch event to GestureRecognizer. - // Returns true if the event resulted in firing a synthetic event. - bool DoGestureProcessing(const TouchEvent& event, ui::TouchStatus status); - ////////////////////////////////////////////////////////////////////////////// // Tree operations ----------------------------------------------------------- @@ -182,15 +166,9 @@ class VIEWS_EXPORT RootView : public View, public FocusTraversable { int last_mouse_event_x_; int last_mouse_event_y_; - // The gesture_manager_ for this. - GestureManager* gesture_manager_; - // The view currently handling touch events. View* touch_pressed_handler_; - // The gesture_recognizer_ for this. - GestureRecognizer* gesture_recognizer_; - // The view currently handling gesture events. View* gesture_handling_view_; |