OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "ui/events/platform/platform_event_source.h" |
| 6 |
| 7 #include <algorithm> |
| 8 |
| 9 #include "base/message_loop/message_loop.h" |
| 10 #include "ui/events/event.h" |
| 11 #include "ui/events/platform/platform_event_dispatcher.h" |
| 12 #include "ui/events/platform/platform_event_observer.h" |
| 13 #include "ui/events/platform/scoped_event_dispatcher.h" |
| 14 |
| 15 namespace ui { |
| 16 |
| 17 // static |
| 18 PlatformEventSource* PlatformEventSource::instance_ = NULL; |
| 19 |
| 20 PlatformEventSource::PlatformEventSource() |
| 21 : overridden_dispatcher_(NULL), |
| 22 overridden_dispatcher_restored_(false) { |
| 23 CHECK(!instance_) << "Only one platform event source can be created."; |
| 24 instance_ = this; |
| 25 } |
| 26 |
| 27 PlatformEventSource::~PlatformEventSource() { |
| 28 CHECK_EQ(this, instance_); |
| 29 instance_ = NULL; |
| 30 } |
| 31 |
| 32 PlatformEventSource* PlatformEventSource::GetInstance() { return instance_; } |
| 33 |
| 34 void PlatformEventSource::AddPlatformEventDispatcher( |
| 35 PlatformEventDispatcher* dispatcher) { |
| 36 CHECK(dispatcher); |
| 37 DCHECK(std::find(dispatchers_.begin(), dispatchers_.end(), dispatcher) == |
| 38 dispatchers_.end()); |
| 39 dispatchers_.push_back(dispatcher); |
| 40 } |
| 41 |
| 42 void PlatformEventSource::RemovePlatformEventDispatcher( |
| 43 PlatformEventDispatcher* dispatcher) { |
| 44 PlatformEventDispatcherList::iterator remove = |
| 45 std::remove(dispatchers_.begin(), dispatchers_.end(), dispatcher); |
| 46 if (remove != dispatchers_.end()) |
| 47 dispatchers_.erase(remove); |
| 48 } |
| 49 |
| 50 scoped_ptr<ScopedEventDispatcher> PlatformEventSource::OverrideDispatcher( |
| 51 PlatformEventDispatcher* dispatcher) { |
| 52 CHECK(dispatcher); |
| 53 overridden_dispatcher_restored_ = false; |
| 54 return make_scoped_ptr( |
| 55 new ScopedEventDispatcher(&overridden_dispatcher_, dispatcher)); |
| 56 } |
| 57 |
| 58 void PlatformEventSource::AddPlatformEventObserver( |
| 59 PlatformEventObserver* observer) { |
| 60 CHECK(observer); |
| 61 observers_.AddObserver(observer); |
| 62 } |
| 63 |
| 64 void PlatformEventSource::RemovePlatformEventObserver( |
| 65 PlatformEventObserver* observer) { |
| 66 observers_.RemoveObserver(observer); |
| 67 } |
| 68 |
| 69 uint32_t PlatformEventSource::DispatchEvent(PlatformEvent platform_event) { |
| 70 uint32_t action = POST_DISPATCH_PERFORM_DEFAULT; |
| 71 bool should_quit = false; |
| 72 |
| 73 if (!WillProcessEvent(platform_event)) { |
| 74 // Give the overridden dispatcher a chance to dispatch the event first. |
| 75 if (overridden_dispatcher_) |
| 76 action = overridden_dispatcher_->DispatchEvent(platform_event); |
| 77 should_quit = !!(action & POST_DISPATCH_QUIT_LOOP); |
| 78 |
| 79 if (action & POST_DISPATCH_PERFORM_DEFAULT) { |
| 80 for (PlatformEventDispatcherList::iterator i = dispatchers_.begin(); |
| 81 i != dispatchers_.end(); |
| 82 ++i) { |
| 83 PlatformEventDispatcher* dispatcher = *(i); |
| 84 if (dispatcher->CanDispatchEvent(platform_event)) |
| 85 action = dispatcher->DispatchEvent(platform_event); |
| 86 if (action & POST_DISPATCH_QUIT_LOOP) |
| 87 should_quit = true; |
| 88 if (action & POST_DISPATCH_STOP_PROPAGATION) |
| 89 break; |
| 90 } |
| 91 } |
| 92 } |
| 93 DidProcessEvent(platform_event); |
| 94 |
| 95 // Terminate the message-loop if the dispatcher requested for it. |
| 96 if (should_quit) { |
| 97 base::MessageLoop::current()->QuitNow(); |
| 98 action |= POST_DISPATCH_QUIT_LOOP; |
| 99 } |
| 100 |
| 101 // If an overridden dispatcher has been destroyed, then the platform |
| 102 // event-source should halt dispatching the current stream of events, and wait |
| 103 // until the next message-loop iteration for dispatching events. This lets any |
| 104 // nested message-loop to unwind correctly and any new dispatchers to receive |
| 105 // the correct sequence of events. |
| 106 if (overridden_dispatcher_restored_) |
| 107 action |= POST_DISPATCH_QUIT_LOOP; |
| 108 |
| 109 overridden_dispatcher_restored_ = false; |
| 110 |
| 111 return action; |
| 112 } |
| 113 |
| 114 bool PlatformEventSource::WillProcessEvent(PlatformEvent event) { |
| 115 if (observers_.might_have_observers()) { |
| 116 ObserverListBase<PlatformEventObserver>::Iterator it(observers_); |
| 117 PlatformEventObserver* obs; |
| 118 while ((obs = it.GetNext()) != NULL) { |
| 119 if (obs->WillProcessEvent(event)) |
| 120 return true; |
| 121 } |
| 122 } |
| 123 return false; |
| 124 } |
| 125 |
| 126 void PlatformEventSource::DidProcessEvent(PlatformEvent event) { |
| 127 FOR_EACH_OBSERVER(PlatformEventObserver, observers_, DidProcessEvent(event)); |
| 128 } |
| 129 |
| 130 void PlatformEventSource::OnOverriddenDispatcherRestored() { |
| 131 CHECK(overridden_dispatcher_); |
| 132 overridden_dispatcher_restored_ = true; |
| 133 } |
| 134 |
| 135 } // namespace ui |
OLD | NEW |