diff options
author | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-11 05:56:51 +0000 |
---|---|---|
committer | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-11 05:56:51 +0000 |
commit | 1eeb971326a2a38b782443ae1857f37f5d74eb07 (patch) | |
tree | 8ed8afb1c8c044717d6dcedbd4ac407ee47cda1c /ui | |
parent | 8af40c7f4612fab5e348ef866d93a05b79e2d035 (diff) | |
download | chromium_src-1eeb971326a2a38b782443ae1857f37f5d74eb07.zip chromium_src-1eeb971326a2a38b782443ae1857f37f5d74eb07.tar.gz chromium_src-1eeb971326a2a38b782443ae1857f37f5d74eb07.tar.bz2 |
events: Inlcude the event-phase and event-result in Event.
An event-handler can be installed on a target as both a pre-target and a post-target handler.
In such cases, it will be necessary to know the phase of the event-dispatch. So add EventPhase.
Also, from a handler, it may be necessary to know whether the event has been handled by any other
handlers before this. So include EventResult in the event too.
BUG=none.
Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=155825
Review URL: https://chromiumcodereview.appspot.com/10916210
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@155957 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r-- | ui/base/events/event.cc | 12 | ||||
-rw-r--r-- | ui/base/events/event.h | 9 | ||||
-rw-r--r-- | ui/base/events/event_constants.h | 9 | ||||
-rw-r--r-- | ui/base/events/event_dispatcher.cc | 11 | ||||
-rw-r--r-- | ui/base/events/event_dispatcher.h | 19 | ||||
-rw-r--r-- | ui/base/events/event_dispatcher_unittest.cc | 79 |
6 files changed, 106 insertions, 33 deletions
diff --git a/ui/base/events/event.cc b/ui/base/events/event.cc index f288107..a2190ff 100644 --- a/ui/base/events/event.cc +++ b/ui/base/events/event.cc @@ -74,7 +74,9 @@ Event::Event(EventType type, int flags) time_stamp_(base::Time::NowFromSystemTime() - base::Time()), flags_(flags), delete_native_event_(false), - target_(NULL) { + target_(NULL), + phase_(EP_PREDISPATCH), + result_(ER_UNHANDLED) { Init(); } @@ -85,7 +87,9 @@ Event::Event(const base::NativeEvent& native_event, time_stamp_(EventTimeFromNative(native_event)), flags_(flags), delete_native_event_(false), - target_(NULL) { + target_(NULL), + phase_(EP_PREDISPATCH), + result_(ER_UNHANDLED) { InitWithNativeEvent(native_event); } @@ -95,7 +99,9 @@ Event::Event(const Event& copy) time_stamp_(copy.time_stamp_), flags_(copy.flags_), delete_native_event_(false), - target_(NULL) { + target_(NULL), + phase_(EP_PREDISPATCH), + result_(ER_UNHANDLED) { #if defined(USE_X11) if (native_event_) delete_native_event_ = true; diff --git a/ui/base/events/event.h b/ui/base/events/event.h index 89831f2..4d8ad63 100644 --- a/ui/base/events/event.h +++ b/ui/base/events/event.h @@ -33,6 +33,11 @@ class UI_EXPORT Event { event_->target_ = target; } + void set_phase(EventPhase phase) { event_->phase_ = phase; } + void set_result(int result) { + event_->result_ = static_cast<EventResult>(result); + } + private: DispatcherApi(); Event* event_; @@ -65,6 +70,8 @@ class UI_EXPORT Event { void set_flags(int flags) { flags_ = flags; } EventTarget* target() const { return target_; } + EventPhase phase() const { return phase_; } + EventResult result() const { return result_; } // The following methods return true if the respective keys were pressed at // the time the event was created. @@ -171,6 +178,8 @@ class UI_EXPORT Event { int flags_; bool delete_native_event_; EventTarget* target_; + EventPhase phase_; + EventResult result_; }; class UI_EXPORT LocatedEvent : public Event { diff --git a/ui/base/events/event_constants.h b/ui/base/events/event_constants.h index 91d0be5..43a0e90 100644 --- a/ui/base/events/event_constants.h +++ b/ui/base/events/event_constants.h @@ -105,6 +105,15 @@ enum EventResult { // propagated to other handlers. }; +// Phase of the event dispatch. +enum EventPhase { + EP_PREDISPATCH, + EP_PRETARGET, + EP_TARGET, + EP_POSTTARGET, + EP_POSTDISPATCH +}; + enum TouchStatus { TOUCH_STATUS_UNKNOWN = 0, // Unknown touch status. This is used to indicate // that the touch event was not handled. diff --git a/ui/base/events/event_dispatcher.cc b/ui/base/events/event_dispatcher.cc index ec9c5ac..23bad57 100644 --- a/ui/base/events/event_dispatcher.cc +++ b/ui/base/events/event_dispatcher.cc @@ -44,4 +44,15 @@ EventResult EventDispatcher::DispatchEventToSingleHandler(EventHandler* handler, return handler->OnGestureEvent(event); } +//////////////////////////////////////////////////////////////////////////////// +// EventDispatcher::ScopedDispatchHelper + +EventDispatcher::ScopedDispatchHelper::ScopedDispatchHelper(Event* event) + : Event::DispatcherApi(event) { +} + +EventDispatcher::ScopedDispatchHelper::~ScopedDispatchHelper() { + set_phase(EP_POSTDISPATCH); +} + } // namespace ui diff --git a/ui/base/events/event_dispatcher.h b/ui/base/events/event_dispatcher.h index 48aa5d4..55cab11 100644 --- a/ui/base/events/event_dispatcher.h +++ b/ui/base/events/event_dispatcher.h @@ -33,12 +33,13 @@ class UI_EXPORT EventDispatcher { if (!target || !target->CanAcceptEvents()) return ER_UNHANDLED; - Event::DispatcherApi dispatcher(event); - dispatcher.set_target(target); + ScopedDispatchHelper dispatch_helper(event); + dispatch_helper.set_target(target); EventHandlerList list; target->GetPreTargetHandlers(&list); ProcessPreTargetList(&list); + dispatch_helper.set_phase(EP_PRETARGET); int result = DispatchEventToEventHandlers(list, event); if (result & ER_CONSUMED) return result; @@ -49,7 +50,9 @@ class UI_EXPORT EventDispatcher { // this layer, however it should not be processed in the next layer of // abstraction. if (CanDispatchToTarget(target)) { + dispatch_helper.set_phase(EP_TARGET); result |= DispatchEventToSingleHandler(target, event); + dispatch_helper.set_result(event->result() | result); if (result & ER_CONSUMED) return result; } @@ -60,17 +63,29 @@ class UI_EXPORT EventDispatcher { list.clear(); target->GetPostTargetHandlers(&list); ProcessPostTargetList(&list); + dispatch_helper.set_phase(EP_POSTTARGET); result |= DispatchEventToEventHandlers(list, event); return result; } private: + class UI_EXPORT ScopedDispatchHelper : public NON_EXPORTED_BASE( + Event::DispatcherApi) { + public: + explicit ScopedDispatchHelper(Event* event); + virtual ~ScopedDispatchHelper(); + private: + DISALLOW_COPY_AND_ASSIGN(ScopedDispatchHelper); + }; + template<class T> int DispatchEventToEventHandlers(EventHandlerList& list, T* event) { int result = ER_UNHANDLED; + Event::DispatcherApi dispatch_helper(event); for (EventHandlerList::const_iterator it = list.begin(), end = list.end(); it != end; ++it) { result |= DispatchEventToSingleHandler((*it), event); + dispatch_helper.set_result(event->result() | result); if (result & ER_CONSUMED) return result; } diff --git a/ui/base/events/event_dispatcher_unittest.cc b/ui/base/events/event_dispatcher_unittest.cc index 3cdeccfd..4f7b1a7 100644 --- a/ui/base/events/event_dispatcher_unittest.cc +++ b/ui/base/events/event_dispatcher_unittest.cc @@ -10,26 +10,6 @@ namespace ui { namespace { -class TestEventDispatcher : public EventDispatcher { - public: - TestEventDispatcher() {} - virtual ~TestEventDispatcher() {} - - private: - // Overridden from EventDispatcher: - virtual bool CanDispatchToTarget(EventTarget* target) OVERRIDE { - return true; - } - - virtual void ProcessPreTargetList(EventHandlerList* list) OVERRIDE { - } - - virtual void ProcessPostTargetList(EventHandlerList* list) OVERRIDE { - } - - DISALLOW_COPY_AND_ASSIGN(TestEventDispatcher); -}; - class TestTarget : public EventTarget { public: TestTarget() : parent_(NULL) {} @@ -67,50 +47,80 @@ class TestEventHandler : public EventHandler { public: TestEventHandler(int id) : id_(id), - event_result_(ER_UNHANDLED) { + event_result_(ER_UNHANDLED), + expected_phase_(EP_PREDISPATCH) { } virtual ~TestEventHandler() {} - void ReceivedEventForTarget(EventTarget* target) { - static_cast<TestTarget*>(target)->AddHandlerId(id_); + void ReceivedEvent(Event* event) { + EXPECT_EQ(expected_phase_, event->phase()); + static_cast<TestTarget*>(event->target())->AddHandlerId(id_); } void set_event_result(EventResult result) { event_result_ = result; } + void set_expected_phase(EventPhase phase) { expected_phase_ = phase; } private: // Overridden from EventHandler: virtual EventResult OnKeyEvent(KeyEvent* event) OVERRIDE { - ReceivedEventForTarget(event->target()); + ReceivedEvent(event); return event_result_; } virtual EventResult OnMouseEvent(MouseEvent* event) OVERRIDE { - ReceivedEventForTarget(event->target()); + ReceivedEvent(event); return event_result_; } virtual EventResult OnScrollEvent(ScrollEvent* event) OVERRIDE { - ReceivedEventForTarget(event->target()); + ReceivedEvent(event); return event_result_; } virtual TouchStatus OnTouchEvent(TouchEvent* event) OVERRIDE { - ReceivedEventForTarget(event->target()); + ReceivedEvent(event); return ui::TOUCH_STATUS_UNKNOWN; } virtual EventResult OnGestureEvent(GestureEvent* event) OVERRIDE { - ReceivedEventForTarget(event->target()); + ReceivedEvent(event); return event_result_; } int id_; EventResult event_result_; + EventPhase expected_phase_; DISALLOW_COPY_AND_ASSIGN(TestEventHandler); }; +class TestEventDispatcher : public EventDispatcher { + public: + TestEventDispatcher() {} + virtual ~TestEventDispatcher() {} + + private: + // Overridden from EventDispatcher: + virtual bool CanDispatchToTarget(EventTarget* target) OVERRIDE { + return true; + } + + virtual void ProcessPreTargetList(EventHandlerList* list) OVERRIDE { + for (EventHandlerList::iterator i = list->begin(); i != list->end(); ++i) { + static_cast<TestEventHandler*>(*i)->set_expected_phase(EP_PRETARGET); + } + } + + virtual void ProcessPostTargetList(EventHandlerList* list) OVERRIDE { + for (EventHandlerList::iterator i = list->begin(); i != list->end(); ++i) { + static_cast<TestEventHandler*>(*i)->set_expected_phase(EP_POSTTARGET); + } + } + + DISALLOW_COPY_AND_ASSIGN(TestEventDispatcher); +}; + } // namespace TEST(EventDispatcherTest, EventDispatchOrder) { @@ -135,6 +145,7 @@ TEST(EventDispatcherTest, EventDispatchOrder) { MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(3, 4), gfx::Point(3, 4), 0); + Event::DispatcherApi event_mod(&mouse); int result = dispatcher.ProcessEvent(&child, &mouse); EXPECT_FALSE(result & ER_CONSUMED); EXPECT_FALSE(result & ER_HANDLED); @@ -145,9 +156,13 @@ TEST(EventDispatcherTest, EventDispatchOrder) { child.handler_list()); child.Reset(); + event_mod.set_phase(EP_PREDISPATCH); + event_mod.set_result(ER_UNHANDLED); h1.set_event_result(ER_HANDLED); result = dispatcher.ProcessEvent(&child, &mouse); + EXPECT_EQ(result, mouse.result()); + EXPECT_EQ(EP_POSTDISPATCH, mouse.phase()); EXPECT_FALSE(result & ER_CONSUMED); EXPECT_TRUE(result & ER_HANDLED); EXPECT_EQ( @@ -155,10 +170,14 @@ TEST(EventDispatcherTest, EventDispatchOrder) { child.handler_list()); child.Reset(); + event_mod.set_phase(EP_PREDISPATCH); + event_mod.set_result(ER_UNHANDLED); int nexpected[] = { 1, 2, 3, 4, 5 }; h5.set_event_result(ER_CONSUMED); result = dispatcher.ProcessEvent(&child, &mouse); + EXPECT_EQ(result, mouse.result()); + EXPECT_EQ(EP_POSTDISPATCH, mouse.phase()); EXPECT_TRUE(result & ER_CONSUMED); EXPECT_TRUE(result & ER_HANDLED); EXPECT_EQ( @@ -166,10 +185,14 @@ TEST(EventDispatcherTest, EventDispatchOrder) { child.handler_list()); child.Reset(); + event_mod.set_phase(EP_PREDISPATCH); + event_mod.set_result(ER_UNHANDLED); int exp[] = { 1 }; h1.set_event_result(ER_CONSUMED); result = dispatcher.ProcessEvent(&child, &mouse); + EXPECT_EQ(EP_POSTDISPATCH, mouse.phase()); + EXPECT_EQ(result, mouse.result()); EXPECT_TRUE(result & ER_CONSUMED); EXPECT_FALSE(result & ER_HANDLED); EXPECT_EQ( |