diff options
author | davemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-06 19:19:13 +0000 |
---|---|---|
committer | davemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-06 19:19:13 +0000 |
commit | 86b1dc18859817e039361c623e3b0e4074593367 (patch) | |
tree | bb9b4613b32597b9483ac5417c5b1b5f7815988e /ui | |
parent | 9e49959b0e6e940c39359f5f05f9d5da6032a869 (diff) | |
download | chromium_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.cc | 80 | ||||
-rw-r--r-- | ui/views/mouse_watcher.h | 59 | ||||
-rw-r--r-- | ui/views/mouse_watcher_view_host.cc | 56 | ||||
-rw-r--r-- | ui/views/mouse_watcher_view_host.h | 44 | ||||
-rw-r--r-- | ui/views/views.gyp | 2 |
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', |