1// Copyright (c) 2012 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#ifndef UI_VIEWS_MOUSE_WATCHER_H_
6#define UI_VIEWS_MOUSE_WATCHER_H_
7
8#include "base/basictypes.h"
9#include "base/memory/scoped_ptr.h"
10#include "base/time/time.h"
11#include "ui/gfx/insets.h"
12#include "ui/views/views_export.h"
13
14namespace gfx {
15class Point;
16}
17
18namespace views {
19
20// MouseWatcherListener is notified when the mouse moves outside the host.
21class VIEWS_EXPORT MouseWatcherListener {
22 public:
23  virtual void MouseMovedOutOfHost() = 0;
24
25 protected:
26  virtual ~MouseWatcherListener();
27};
28
29// The MouseWatcherHost determines what region is to be monitored.
30class VIEWS_EXPORT MouseWatcherHost {
31 public:
32  // The MouseEventType can be used as a hint.
33  enum MouseEventType {
34    // The mouse moved within the window which was current when the MouseWatcher
35    // was created.
36    MOUSE_MOVE,
37    // The mouse moved exited the window which was current when the MouseWatcher
38    // was created.
39    MOUSE_EXIT
40  };
41
42  virtual ~MouseWatcherHost();
43
44  // Return false when the mouse has moved outside the monitored region.
45  virtual bool Contains(const gfx::Point& screen_point,
46                        MouseEventType type) = 0;
47};
48
49// MouseWatcher is used to watch mouse movement and notify its listener when the
50// mouse moves outside the bounds of a MouseWatcherHost.
51class VIEWS_EXPORT MouseWatcher {
52 public:
53  // Creates a new MouseWatcher. The |listener| will be notified when the |host|
54  // determines that the mouse has moved outside its monitored region.
55  // |host| will be owned by the watcher and deleted upon completion.
56  MouseWatcher(MouseWatcherHost* host, MouseWatcherListener* listener);
57  ~MouseWatcher();
58
59  // Sets the amount to delay before notifying the listener when the mouse exits
60  // the host by way of going to another window.
61  void set_notify_on_exit_time(base::TimeDelta time) {
62    notify_on_exit_time_ = time;
63  }
64
65  // Starts watching mouse movements. When the mouse moves outside the bounds of
66  // the host the listener is notified. |Start| may be invoked any number of
67  // times. If the mouse moves outside the bounds of the host the listener is
68  // notified and watcher stops watching events.
69  void Start();
70
71  // Stops watching mouse events.
72  void Stop();
73
74 private:
75  class Observer;
76
77  // Are we currently observing events?
78  bool is_observing() const { return observer_.get() != NULL; }
79
80  // Notifies the listener and stops watching events.
81  void NotifyListener();
82
83  // Host we're listening for events over.
84  scoped_ptr<MouseWatcherHost> host_;
85
86  // Our listener.
87  MouseWatcherListener* listener_;
88
89  // Does the actual work of listening for mouse events.
90  scoped_ptr<Observer> observer_;
91
92  // See description above setter.
93  base::TimeDelta notify_on_exit_time_;
94
95  DISALLOW_COPY_AND_ASSIGN(MouseWatcher);
96};
97
98}  // namespace views
99
100#endif  // UI_VIEWS_MOUSE_WATCHER_H_
101