[Telemetry] Reorganize key_mobile_sites pages and update their names
[chromium-blink-merge.git] / ui / views / mouse_watcher.cc
bloba55ffd5e1510f50fc8f977ab468e19d3aa3b191b
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.
5 #include "ui/views/mouse_watcher.h"
7 #include "base/bind.h"
8 #include "base/compiler_specific.h"
9 #include "base/event_types.h"
10 #include "base/memory/weak_ptr.h"
11 #include "base/message_loop/message_loop.h"
12 #include "ui/events/event.h"
13 #include "ui/events/event_constants.h"
14 #include "ui/events/event_handler.h"
15 #include "ui/events/event_utils.h"
16 #include "ui/views/event_monitor.h"
18 namespace views {
20 // Amount of time between when the mouse moves outside the Host's zone and when
21 // the listener is notified.
22 const int kNotifyListenerTimeMs = 300;
24 class MouseWatcher::Observer : public ui::EventHandler {
25 public:
26 explicit Observer(MouseWatcher* mouse_watcher)
27 : mouse_watcher_(mouse_watcher),
28 event_monitor_(views::EventMonitor::Create(this)),
29 notify_listener_factory_(this) {
32 // ui::EventHandler implementation:
33 virtual void OnMouseEvent(ui::MouseEvent* event) override {
34 switch (event->type()) {
35 case ui::ET_MOUSE_MOVED:
36 case ui::ET_MOUSE_DRAGGED:
37 HandleMouseEvent(MouseWatcherHost::MOUSE_MOVE);
38 break;
39 case ui::ET_MOUSE_EXITED:
40 HandleMouseEvent(MouseWatcherHost::MOUSE_EXIT);
41 break;
42 default:
43 break;
47 private:
48 MouseWatcherHost* host() const { return mouse_watcher_->host_.get(); }
50 // Called when a mouse event we're interested is seen.
51 void HandleMouseEvent(MouseWatcherHost::MouseEventType event_type) {
52 // It's safe to use last_mouse_location() here as this function is invoked
53 // during event dispatching.
54 if (!host()->Contains(EventMonitor::GetLastMouseLocation(), event_type)) {
55 // Mouse moved outside the host's zone, start a timer to notify the
56 // listener.
57 if (!notify_listener_factory_.HasWeakPtrs()) {
58 base::MessageLoop::current()->PostDelayedTask(
59 FROM_HERE,
60 base::Bind(&Observer::NotifyListener,
61 notify_listener_factory_.GetWeakPtr()),
62 event_type == MouseWatcherHost::MOUSE_MOVE
63 ? base::TimeDelta::FromMilliseconds(kNotifyListenerTimeMs)
64 : mouse_watcher_->notify_on_exit_time_);
66 } else {
67 // Mouse moved quickly out of the host and then into it again, so cancel
68 // the timer.
69 notify_listener_factory_.InvalidateWeakPtrs();
73 void NotifyListener() {
74 mouse_watcher_->NotifyListener();
75 // WARNING: we've been deleted.
78 private:
79 MouseWatcher* mouse_watcher_;
80 scoped_ptr<views::EventMonitor> event_monitor_;
82 // A factory that is used to construct a delayed callback to the listener.
83 base::WeakPtrFactory<Observer> notify_listener_factory_;
85 DISALLOW_COPY_AND_ASSIGN(Observer);
88 MouseWatcherListener::~MouseWatcherListener() {
91 MouseWatcherHost::~MouseWatcherHost() {
94 MouseWatcher::MouseWatcher(MouseWatcherHost* host,
95 MouseWatcherListener* listener)
96 : host_(host),
97 listener_(listener),
98 notify_on_exit_time_(base::TimeDelta::FromMilliseconds(
99 kNotifyListenerTimeMs)) {
102 MouseWatcher::~MouseWatcher() {
105 void MouseWatcher::Start() {
106 if (!is_observing())
107 observer_.reset(new Observer(this));
110 void MouseWatcher::Stop() {
111 observer_.reset(NULL);
114 void MouseWatcher::NotifyListener() {
115 observer_.reset(NULL);
116 listener_->MouseMovedOutOfHost();
119 } // namespace views