summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authordavemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-06 19:19:13 +0000
committerdavemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-06 19:19:13 +0000
commit86b1dc18859817e039361c623e3b0e4074593367 (patch)
treebb9b4613b32597b9483ac5417c5b1b5f7815988e /ui
parent9e49959b0e6e940c39359f5f05f9d5da6032a869 (diff)
downloadchromium_src-86b1dc18859817e039361c623e3b0e4074593367.zip
chromium_src-86b1dc18859817e039361c623e3b0e4074593367.tar.gz
chromium_src-86b1dc18859817e039361c623e3b0e4074593367.tar.bz2
Refactored MouseWatcher to allow regions other than Views to
be monitored. BUG=None TEST=None Review URL: https://chromiumcodereview.appspot.com/9309110 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@120583 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r--ui/views/mouse_watcher.cc80
-rw-r--r--ui/views/mouse_watcher.h59
-rw-r--r--ui/views/mouse_watcher_view_host.cc56
-rw-r--r--ui/views/mouse_watcher_view_host.h44
-rw-r--r--ui/views/views.gyp2
5 files changed, 166 insertions, 75 deletions
diff --git a/ui/views/mouse_watcher.cc b/ui/views/mouse_watcher.cc
index 1115901..4b963d9 100644
--- a/ui/views/mouse_watcher.cc
+++ b/ui/views/mouse_watcher.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.
@@ -11,12 +11,10 @@
#include "base/message_loop.h"
#include "ui/base/events.h"
#include "ui/gfx/screen.h"
-#include "ui/views/view.h"
-#include "ui/views/widget/widget.h"
namespace views {
-// Amount of time between when the mouse moves outside the view's zone and when
+// Amount of time between when the mouse moves outside the Host's zone and when
// the listener is notified.
const int kNotifyListenerTimeMs = 300;
@@ -41,7 +39,7 @@ class MouseWatcher::Observer : public MessageLoopForUI::Observer {
virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE {
// We spy on three different Windows messages here to see if the mouse has
- // moved out of the bounds of the view. The messages are:
+ // moved out of the bounds of the current view. The messages are:
//
// WM_MOUSEMOVE:
// For when the mouse moves from the view into the rest of the browser UI,
@@ -53,11 +51,11 @@ class MouseWatcher::Observer : public MessageLoopForUI::Observer {
//
switch (event.message) {
case WM_MOUSEMOVE:
- HandleGlobalMouseMoveEvent(false);
+ HandleGlobalMouseMoveEvent(MouseWatcherHost::MOUSE_MOVE);
break;
case WM_MOUSELEAVE:
case WM_NCMOUSELEAVE:
- HandleGlobalMouseMoveEvent(true);
+ HandleGlobalMouseMoveEvent(MouseWatcherHost::MOUSE_EXIT);
break;
}
}
@@ -66,11 +64,11 @@ class MouseWatcher::Observer : public MessageLoopForUI::Observer {
base::wayland::WaylandEvent* event) OVERRIDE {
switch (event->type) {
case base::wayland::WAYLAND_MOTION:
- HandleGlobalMouseMoveEvent(false);
+ HandleGlobalMouseMoveEvent(MouseWatcherHost::MOUSE_MOVE);
break;
case base::wayland::WAYLAND_POINTER_FOCUS:
if (!event->pointer_focus.state)
- HandleGlobalMouseMoveEvent(true);
+ HandleGlobalMouseMoveEvent(MouseWatcherHost::MOUSE_EXIT);
break;
default:
break;
@@ -87,10 +85,10 @@ class MouseWatcher::Observer : public MessageLoopForUI::Observer {
case ui::ET_MOUSE_MOVED:
case ui::ET_MOUSE_DRAGGED:
// DRAGGED is a special case of MOVED. See events_win.cc/events_x.cc.
- HandleGlobalMouseMoveEvent(false);
+ HandleGlobalMouseMoveEvent(MouseWatcherHost::MOUSE_MOVE);
break;
case ui::ET_MOUSE_EXITED:
- HandleGlobalMouseMoveEvent(true);
+ HandleGlobalMouseMoveEvent(MouseWatcherHost::MOUSE_EXIT);
break;
default:
break;
@@ -103,10 +101,10 @@ class MouseWatcher::Observer : public MessageLoopForUI::Observer {
virtual void DidProcessEvent(GdkEvent* event) OVERRIDE {
switch (event->type) {
case GDK_MOTION_NOTIFY:
- HandleGlobalMouseMoveEvent(false);
+ HandleGlobalMouseMoveEvent(MOUSE_MOVE);
break;
case GDK_LEAVE_NOTIFY:
- HandleGlobalMouseMoveEvent(true);
+ HandleGlobalMouseMoveEvent(MOUSE_EXIT);
break;
default:
break;
@@ -115,51 +113,26 @@ class MouseWatcher::Observer : public MessageLoopForUI::Observer {
#endif
private:
- View* view() const { return mouse_watcher_->host_; }
-
- // Returns whether or not the cursor is currently in the view's "zone" which
- // is defined as a slightly larger region than the view.
- bool IsCursorInViewZone() {
- gfx::Rect bounds = view()->GetLocalBounds();
- gfx::Point view_topleft(bounds.origin());
- View::ConvertPointToScreen(view(), &view_topleft);
- bounds.set_origin(view_topleft);
- bounds.SetRect(view_topleft.x() - mouse_watcher_->hot_zone_insets_.left(),
- view_topleft.y() - mouse_watcher_->hot_zone_insets_.top(),
- bounds.width() + mouse_watcher_->hot_zone_insets_.width(),
- bounds.height() + mouse_watcher_->hot_zone_insets_.height());
-
- gfx::Point cursor_point = gfx::Screen::GetCursorScreenPoint();
-
- return bounds.Contains(cursor_point.x(), cursor_point.y());
- }
-
- // Returns true if the mouse is over the view's window.
- bool IsMouseOverWindow() {
- Widget* widget = view()->GetWidget();
- if (!widget)
- return false;
-
- return gfx::Screen::GetWindowAtCursorScreenPoint() ==
- widget->GetNativeWindow();
- }
+ MouseWatcherHost* host() const { return mouse_watcher_->host_.get(); }
// Called from the message loop observer when a mouse movement has occurred.
- void HandleGlobalMouseMoveEvent(bool check_window) {
- bool in_view = IsCursorInViewZone();
- if (!in_view || (check_window && !IsMouseOverWindow())) {
- // Mouse moved outside the view's zone, start a timer to notify the
+ void HandleGlobalMouseMoveEvent(MouseWatcherHost::MouseEventType event_type) {
+ bool contained = host()->Contains(
+ gfx::Screen::GetCursorScreenPoint(), event_type);
+ if (!contained) {
+ // Mouse moved outside the host's zone, start a timer to notify the
// listener.
if (!notify_listener_factory_.HasWeakPtrs()) {
MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&Observer::NotifyListener,
notify_listener_factory_.GetWeakPtr()),
- !in_view ? kNotifyListenerTimeMs :
- mouse_watcher_->notify_on_exit_time_ms_);
+ event_type ==
+ MouseWatcherHost::MOUSE_MOVE ? kNotifyListenerTimeMs :
+ mouse_watcher_->notify_on_exit_time_ms_);
}
} else {
- // Mouse moved quickly out of the view and then into it again, so cancel
+ // Mouse moved quickly out of the host and then into it again, so cancel
// the timer.
notify_listener_factory_.InvalidateWeakPtrs();
}
@@ -182,12 +155,13 @@ class MouseWatcher::Observer : public MessageLoopForUI::Observer {
MouseWatcherListener::~MouseWatcherListener() {
}
-MouseWatcher::MouseWatcher(View* host,
- MouseWatcherListener* listener,
- const gfx::Insets& hot_zone_insets)
+MouseWatcherHost::~MouseWatcherHost() {
+}
+
+MouseWatcher::MouseWatcher(MouseWatcherHost* host,
+ MouseWatcherListener* listener)
: host_(host),
listener_(listener),
- hot_zone_insets_(hot_zone_insets),
notify_on_exit_time_ms_(kNotifyListenerTimeMs) {
}
@@ -205,7 +179,7 @@ void MouseWatcher::Stop() {
void MouseWatcher::NotifyListener() {
observer_.reset(NULL);
- listener_->MouseMovedOutOfView();
+ listener_->MouseMovedOutOfHost();
}
} // namespace views
diff --git a/ui/views/mouse_watcher.h b/ui/views/mouse_watcher.h
index 3ef91f3..eb82e79 100644
--- a/ui/views/mouse_watcher.h
+++ b/ui/views/mouse_watcher.h
@@ -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.
@@ -11,40 +11,58 @@
#include "ui/gfx/insets.h"
#include "ui/views/views_export.h"
-namespace views {
+namespace gfx {
+class Point;
+}
-class View;
+namespace views {
-// MouseWatcherListener is notified when the mouse moves outside the view.
+// MouseWatcherListener is notified when the mouse moves outside the host.
class VIEWS_EXPORT MouseWatcherListener {
public:
- virtual void MouseMovedOutOfView() = 0;
+ virtual void MouseMovedOutOfHost() = 0;
protected:
virtual ~MouseWatcherListener();
};
+// The MouseWatcherHost determines what region is to be monitored.
+class VIEWS_EXPORT MouseWatcherHost {
+ public:
+ // The MouseEventType can be used as a hint.
+ enum MouseEventType {
+ // The mouse moved within the window which was current when the MouseWatcher
+ // was created.
+ MOUSE_MOVE,
+ // The mouse moved exited the window which was current when the MouseWatcher
+ // was created.
+ MOUSE_EXIT
+ };
+
+ virtual ~MouseWatcherHost();
+ // Return false when the mouse has moved outside the monitored region.
+ virtual bool Contains(
+ const gfx::Point& screen_point,
+ MouseEventType type) = 0;
+};
+
// MouseWatcher is used to watch mouse movement and notify its listener when the
-// mouse moves outside the bounds of a view.
+// mouse moves outside the bounds of a MouseWatcherHost.
class VIEWS_EXPORT MouseWatcher {
public:
- // Creates a new MouseWatcher. |hot_zone_insets| is added to the bounds of
- // the view to determine the active zone. For example, if
- // |hot_zone_insets.bottom()| is 10, then the listener is not notified if
- // the y coordinate is between the origin of the view and height of the view
- // plus 10.
- MouseWatcher(views::View* host,
- MouseWatcherListener* listener,
- const gfx::Insets& hot_zone_insets);
+ // Creates a new MouseWatcher. The |listener| will be notified when the |host|
+ // determines that the mouse has moved outside its monitored region.
+ // |host| will be owned by the watcher and deleted upon completion.
+ MouseWatcher(MouseWatcherHost* host, MouseWatcherListener* listener);
~MouseWatcher();
// Sets the amount to delay before notifying the listener when the mouse exits
- // the view by way of going to another window.
+ // the host by way of going to another window.
void set_notify_on_exit_time_ms(int time) { notify_on_exit_time_ms_ = time; }
// Starts watching mouse movements. When the mouse moves outside the bounds of
- // the view the listener is notified. |Start| may be invoked any number of
- // times. If the mouse moves outside the bounds of the view the listener is
+ // the host the listener is notified. |Start| may be invoked any number of
+ // times. If the mouse moves outside the bounds of the host the listener is
// notified and watcher stops watching events.
void Start();
@@ -60,15 +78,12 @@ class VIEWS_EXPORT MouseWatcher {
// Notifies the listener and stops watching events.
void NotifyListener();
- // View we're listening for events over.
- View* host_;
+ // Host we're listening for events over.
+ scoped_ptr<MouseWatcherHost> host_;
// Our listener.
MouseWatcherListener* listener_;
- // Insets added to the bounds of the view.
- const gfx::Insets hot_zone_insets_;
-
// Does the actual work of listening for mouse events.
scoped_ptr<Observer> observer_;
diff --git a/ui/views/mouse_watcher_view_host.cc b/ui/views/mouse_watcher_view_host.cc
new file mode 100644
index 0000000..a2a917a
--- /dev/null
+++ b/ui/views/mouse_watcher_view_host.cc
@@ -0,0 +1,56 @@
+// 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 "ui/views/mouse_watcher_view_host.h"
+
+#include "ui/gfx/screen.h"
+#include "ui/views/view.h"
+#include "ui/views/widget/widget.h"
+
+namespace views {
+
+MouseWatcherViewHost::MouseWatcherViewHost(View* view,
+ const gfx::Insets& hot_zone_insets)
+ : view_(view),
+ hot_zone_insets_(hot_zone_insets) {
+}
+
+MouseWatcherViewHost::~MouseWatcherViewHost() {
+}
+
+bool MouseWatcherViewHost::Contains(
+ const gfx::Point& screen_point,
+ MouseEventType type) {
+ bool in_view = IsCursorInViewZone(screen_point);
+ if (!in_view || (type == MOUSE_EXIT && !IsMouseOverWindow()))
+ return false;
+ return true;
+}
+
+// Returns whether or not the cursor is currently in the view's "zone" which
+// is defined as a slightly larger region than the view.
+bool MouseWatcherViewHost::IsCursorInViewZone(const gfx::Point& screen_point) {
+ gfx::Rect bounds = view_->GetLocalBounds();
+ gfx::Point view_topleft(bounds.origin());
+ View::ConvertPointToScreen(view_, &view_topleft);
+ bounds.set_origin(view_topleft);
+ bounds.SetRect(view_topleft.x() - hot_zone_insets_.left(),
+ view_topleft.y() - hot_zone_insets_.top(),
+ bounds.width() + hot_zone_insets_.width(),
+ bounds.height() + hot_zone_insets_.height());
+
+ return bounds.Contains(screen_point.x(), screen_point.y());
+}
+
+// Returns true if the mouse is over the view's window.
+bool MouseWatcherViewHost::IsMouseOverWindow() {
+ Widget* widget = view_->GetWidget();
+ if (!widget)
+ return false;
+
+ return gfx::Screen::GetWindowAtCursorScreenPoint() ==
+ widget->GetNativeWindow();
+}
+
+} // namespace views
diff --git a/ui/views/mouse_watcher_view_host.h b/ui/views/mouse_watcher_view_host.h
new file mode 100644
index 0000000..d6ab3ac
--- /dev/null
+++ b/ui/views/mouse_watcher_view_host.h
@@ -0,0 +1,44 @@
+// 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.
+
+#ifndef UI_VIEWS_MOUSE_WATCHER_VIEW_HOST_H_
+#define UI_VIEWS_MOUSE_WATCHER_VIEW_HOST_H_
+#pragma once
+
+#include "ui/views/mouse_watcher.h"
+
+namespace views {
+
+class View;
+
+class VIEWS_EXPORT MouseWatcherViewHost : public MouseWatcherHost {
+ public:
+ // Creates a new MouseWatcherViewHost. |hot_zone_insets| is added to the
+ // bounds of the view to determine the active zone. For example, if
+ // |hot_zone_insets.bottom()| is 10, then the listener is not notified if
+ // the y coordinate is between the origin of the view and height of the view
+ // plus 10.
+ MouseWatcherViewHost(View* view, const gfx::Insets& hot_zone_insets);
+ virtual ~MouseWatcherViewHost();
+
+ // MouseWatcherHost.
+ virtual bool Contains(
+ const gfx::Point& screen_point,
+ MouseEventType type) OVERRIDE;
+
+ private:
+ bool IsCursorInViewZone(const gfx::Point& screen_point);
+ bool IsMouseOverWindow();
+
+ // View we're listening for events over.
+ View* view_;
+ // Insets added to the bounds of the view.
+ const gfx::Insets hot_zone_insets_;
+
+ DISALLOW_COPY_AND_ASSIGN(MouseWatcherViewHost);
+};
+
+} // namespace views
+
+#endif // UI_VIEWS_MOUSE_WATCHER_VIEW_HOST_H_
diff --git a/ui/views/views.gyp b/ui/views/views.gyp
index 76d4bca..00d3178 100644
--- a/ui/views/views.gyp
+++ b/ui/views/views.gyp
@@ -306,6 +306,8 @@
'metrics_win.cc',
'mouse_watcher.cc',
'mouse_watcher.h',
+ 'mouse_watcher_view_host.cc',
+ 'mouse_watcher_view_host.h',
'native_theme_delegate.h',
'native_theme_painter.cc',
'native_theme_painter.h',