diff options
author | jennb@chromium.org <jennb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-29 03:42:39 +0000 |
---|---|---|
committer | jennb@chromium.org <jennb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-29 03:42:39 +0000 |
commit | b9281ac4b0bbe0068d47ff83e153603734c2b264 (patch) | |
tree | a21949bfa8d1bbaf9f85d1aa59791c4bc4aa36c2 /chrome | |
parent | 27da4f022516b2db00f325e7d76a3265a90c6e4b (diff) | |
download | chromium_src-b9281ac4b0bbe0068d47ff83e153603734c2b264.zip chromium_src-b9281ac4b0bbe0068d47ff83e153603734c2b264.tar.gz chromium_src-b9281ac4b0bbe0068d47ff83e153603734c2b264.tar.bz2 |
Convert PanelMouseWatcher to have more than one observer.
BUG=None
TEST=PanelMouseWatcherTest.*
Review URL: http://codereview.chromium.org/8677031
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@111864 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/ui/panels/panel_manager.cc | 7 | ||||
-rw-r--r-- | chrome/browser/ui/panels/panel_manager.h | 7 | ||||
-rw-r--r-- | chrome/browser/ui/panels/panel_mouse_watcher.cc | 20 | ||||
-rw-r--r-- | chrome/browser/ui/panels/panel_mouse_watcher.h | 37 | ||||
-rw-r--r-- | chrome/browser/ui/panels/panel_mouse_watcher_observer.h | 24 | ||||
-rw-r--r-- | chrome/browser/ui/panels/panel_mouse_watcher_timer.cc | 27 | ||||
-rwxr-xr-x | chrome/browser/ui/panels/panel_mouse_watcher_unittest.cc | 64 | ||||
-rw-r--r-- | chrome/browser/ui/panels/panel_mouse_watcher_win.cc | 24 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 1 | ||||
-rw-r--r-- | chrome/chrome_tests.gypi | 1 |
10 files changed, 166 insertions, 46 deletions
diff --git a/chrome/browser/ui/panels/panel_manager.cc b/chrome/browser/ui/panels/panel_manager.cc index 8480676..1bdaff2 100644 --- a/chrome/browser/ui/panels/panel_manager.cc +++ b/chrome/browser/ui/panels/panel_manager.cc @@ -12,6 +12,7 @@ #include "base/message_loop.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" +#include "chrome/browser/ui/panels/panel_mouse_watcher.h" #include "chrome/browser/ui/window_sizer.h" #include "chrome/common/chrome_notification_types.h" #include "content/public/browser/notification_service.h" @@ -69,7 +70,7 @@ PanelManager::PanelManager() titlebar_action_factory_(this), auto_sizing_enabled_(true), mouse_watching_disabled_(false) { - panel_mouse_watcher_.reset(PanelMouseWatcher::Create(this)); + panel_mouse_watcher_.reset(PanelMouseWatcher::Create()); auto_hiding_desktop_bar_ = AutoHidingDesktopBar::Create(this); OnDisplayChanged(); } @@ -354,7 +355,7 @@ void PanelManager::OnPanelExpansionStateChanged( void PanelManager::IncrementMinimizedPanels() { if (!mouse_watching_disabled_ && !minimized_panel_count_) - panel_mouse_watcher_->Start(); + panel_mouse_watcher_->AddObserver(this); minimized_panel_count_++; DCHECK_LE(minimized_panel_count_, num_panels()); } @@ -363,7 +364,7 @@ void PanelManager::DecrementMinimizedPanels() { minimized_panel_count_--; DCHECK_GE(minimized_panel_count_, 0); if (!mouse_watching_disabled_ && !minimized_panel_count_) - panel_mouse_watcher_->Stop(); + panel_mouse_watcher_->RemoveObserver(this); } void PanelManager::OnPreferredWindowSizeChanged( diff --git a/chrome/browser/ui/panels/panel_manager.h b/chrome/browser/ui/panels/panel_manager.h index 5c3a92f..1417798 100644 --- a/chrome/browser/ui/panels/panel_manager.h +++ b/chrome/browser/ui/panels/panel_manager.h @@ -13,15 +13,16 @@ #include "base/memory/weak_ptr.h" #include "chrome/browser/ui/panels/auto_hiding_desktop_bar.h" #include "chrome/browser/ui/panels/panel.h" -#include "chrome/browser/ui/panels/panel_mouse_watcher.h" +#include "chrome/browser/ui/panels/panel_mouse_watcher_observer.h" #include "ui/gfx/rect.h" class Browser; class Panel; +class PanelMouseWatcher; // This class manages a set of panels. // Note that the ref count is needed by using PostTask in the implementation. -class PanelManager : public PanelMouseWatcher::Observer, +class PanelManager : public PanelMouseWatcherObserver, public AutoHidingDesktopBar::Observer { public: typedef std::vector<Panel*> Panels; @@ -79,7 +80,7 @@ class PanelManager : public PanelMouseWatcher::Observer, int GetMaxPanelHeight() const; int StartingRightPosition() const; - // Overridden from PanelMouseWatcher::Observer: + // Overridden from PanelMouseWatcherObserver: virtual void OnMouseMove(const gfx::Point& mouse_position) OVERRIDE; #ifdef UNIT_TEST diff --git a/chrome/browser/ui/panels/panel_mouse_watcher.cc b/chrome/browser/ui/panels/panel_mouse_watcher.cc index dc2ab15..b55ca76 100644 --- a/chrome/browser/ui/panels/panel_mouse_watcher.cc +++ b/chrome/browser/ui/panels/panel_mouse_watcher.cc @@ -4,15 +4,29 @@ #include "chrome/browser/ui/panels/panel_mouse_watcher.h" +#include "chrome/browser/ui/panels/panel_mouse_watcher_observer.h" #include "ui/gfx/point.h" -PanelMouseWatcher::PanelMouseWatcher(Observer* observer) - : observer_(observer) { +PanelMouseWatcher::PanelMouseWatcher() { } PanelMouseWatcher::~PanelMouseWatcher() { } +void PanelMouseWatcher::AddObserver(PanelMouseWatcherObserver* observer) { + observers_.AddObserver(observer); + if (observers_.size() == 1) + Start(); +} + +void PanelMouseWatcher::RemoveObserver(PanelMouseWatcherObserver* observer) { + DCHECK(observers_.HasObserver(observer)); + observers_.RemoveObserver(observer); + if (observers_.size() == 0) + Stop(); +} + void PanelMouseWatcher::NotifyMouseMovement(const gfx::Point& mouse_position) { - observer_->OnMouseMove(mouse_position); + FOR_EACH_OBSERVER(PanelMouseWatcherObserver, observers_, + OnMouseMove(mouse_position)); } diff --git a/chrome/browser/ui/panels/panel_mouse_watcher.h b/chrome/browser/ui/panels/panel_mouse_watcher.h index d0d6b50..5a36aad 100644 --- a/chrome/browser/ui/panels/panel_mouse_watcher.h +++ b/chrome/browser/ui/panels/panel_mouse_watcher.h @@ -4,42 +4,49 @@ #ifndef CHROME_BROWSER_UI_PANELS_PANEL_MOUSE_WATCHER_H_ #define CHROME_BROWSER_UI_PANELS_PANEL_MOUSE_WATCHER_H_ +#pragma once + +#include "base/gtest_prod_util.h" +#include "base/observer_list.h" namespace gfx { class Point; } +class PanelMouseWatcherObserver; + // This is the base class for functionality to watch for mouse movements. // The specific implementation of this abstract class differ in how they // track mouse movements. class PanelMouseWatcher { public: - // Observer interface for watching mouse movement. - class Observer { - public: - virtual ~Observer() {} - - // Called when the mouse moves. - virtual void OnMouseMove(const gfx::Point& mouse_position) = 0; - }; - // Returns an instance of the platform specific implementation. - static PanelMouseWatcher* Create(Observer* observer); + static PanelMouseWatcher* Create(); // clang gives an error asking for an out of line destructor. virtual ~PanelMouseWatcher(); - // Start/stop tracking mouse movements. - virtual void Start() = 0; - virtual void Stop() = 0; + void AddObserver(PanelMouseWatcherObserver* observer); + void RemoveObserver(PanelMouseWatcherObserver* observer); protected: - explicit PanelMouseWatcher(Observer* observer); + PanelMouseWatcher(); + // |mouse_position| is in screen coordinates. void NotifyMouseMovement(const gfx::Point& mouse_position); + // Returns true if watching mouse movements. + virtual bool IsActive() const = 0; + private: - Observer* observer_; + friend class PanelMouseWatcherTest; + FRIEND_TEST_ALL_PREFIXES(PanelMouseWatcherTest, StartStopWatching); + + // Start/stop tracking mouse movements. + virtual void Start() = 0; + virtual void Stop() = 0; + + ObserverList<PanelMouseWatcherObserver> observers_; }; #endif // CHROME_BROWSER_UI_PANELS_PANEL_MOUSE_WATCHER_H_ diff --git a/chrome/browser/ui/panels/panel_mouse_watcher_observer.h b/chrome/browser/ui/panels/panel_mouse_watcher_observer.h new file mode 100644 index 0000000..b76d7c1 --- /dev/null +++ b/chrome/browser/ui/panels/panel_mouse_watcher_observer.h @@ -0,0 +1,24 @@ +// Copyright (c) 2011 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 CHROME_BROWSER_UI_PANELS_PANEL_MOUSE_WATCHER_OBSERVER_H_ +#define CHROME_BROWSER_UI_PANELS_PANEL_MOUSE_WATCHER_OBSERVER_H_ +#pragma once + +namespace gfx { +class Point; +} + +// This observer interface should be implemented in order to receive +// notifications from PanelMouseWatcher when the mouse moves. +class PanelMouseWatcherObserver { + public: + // Called when the mouse moves. + // |mouse_position| is in screen coordinates. + virtual void OnMouseMove(const gfx::Point& mouse_position) = 0; + + protected: + virtual ~PanelMouseWatcherObserver() {} +}; +#endif // CHROME_BROWSER_UI_PANELS_PANEL_MOUSE_WATCHER_OBSERVER_H_ diff --git a/chrome/browser/ui/panels/panel_mouse_watcher_timer.cc b/chrome/browser/ui/panels/panel_mouse_watcher_timer.cc index 0dcafc3..01a7625 100644 --- a/chrome/browser/ui/panels/panel_mouse_watcher_timer.cc +++ b/chrome/browser/ui/panels/panel_mouse_watcher_timer.cc @@ -11,14 +11,14 @@ // and Mac panels implementations. class PanelMouseWatcherTimer : public PanelMouseWatcher { public: - explicit PanelMouseWatcherTimer(Observer* observer); + PanelMouseWatcherTimer(); virtual ~PanelMouseWatcherTimer(); - protected: - virtual void Start(); - virtual void Stop(); - private: + virtual void Start() OVERRIDE; + virtual void Stop() OVERRIDE; + virtual bool IsActive() const OVERRIDE; + // Specifies the rate at which we want to sample the mouse position. static const int kMousePollingIntervalMs = 250; @@ -36,30 +36,33 @@ class PanelMouseWatcherTimer : public PanelMouseWatcher { }; // static -PanelMouseWatcher* PanelMouseWatcher::Create(Observer* observer) { - return new PanelMouseWatcherTimer(observer); +PanelMouseWatcher* PanelMouseWatcher::Create() { + return new PanelMouseWatcherTimer(); } -PanelMouseWatcherTimer::PanelMouseWatcherTimer(Observer* observer) - : PanelMouseWatcher(observer) { +PanelMouseWatcherTimer::PanelMouseWatcherTimer() { } PanelMouseWatcherTimer::~PanelMouseWatcherTimer() { - DCHECK(!timer_.IsRunning()); + DCHECK(!IsActive()); } void PanelMouseWatcherTimer::Start() { - DCHECK(!timer_.IsRunning()); + DCHECK(!IsActive()); timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(kMousePollingIntervalMs), this, &PanelMouseWatcherTimer::DoWork); } void PanelMouseWatcherTimer::Stop() { - DCHECK(timer_.IsRunning()); + DCHECK(IsActive()); timer_.Stop(); } +bool PanelMouseWatcherTimer::IsActive() const { + return timer_.IsRunning(); +} + void PanelMouseWatcherTimer::DoWork() { NotifyMouseMovement(gfx::Screen::GetCursorScreenPoint()); } diff --git a/chrome/browser/ui/panels/panel_mouse_watcher_unittest.cc b/chrome/browser/ui/panels/panel_mouse_watcher_unittest.cc new file mode 100755 index 0000000..c9d2ddd --- /dev/null +++ b/chrome/browser/ui/panels/panel_mouse_watcher_unittest.cc @@ -0,0 +1,64 @@ +// Copyright (c) 2011 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 "base/memory/scoped_ptr.h" +#include "base/message_loop.h" +#include "chrome/browser/ui/panels/panel_mouse_watcher.h" +#include "chrome/browser/ui/panels/panel_mouse_watcher_observer.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/point.h" + +class TestMouseObserver : public PanelMouseWatcherObserver { + public: + // Overridden from PanelMouseWatcherObserver: + virtual void OnMouseMove(const gfx::Point& mouse_position) OVERRIDE { + ++mouse_movements_; + } + int mouse_movements_; +}; + +class PanelMouseWatcherTest : public testing::Test { +}; + +TEST_F(PanelMouseWatcherTest, StartStopWatching) { + MessageLoop loop(MessageLoop::TYPE_UI); + + scoped_ptr<PanelMouseWatcher> watcher(PanelMouseWatcher::Create()); + EXPECT_FALSE(watcher->IsActive()); + + scoped_ptr<TestMouseObserver> user1(new TestMouseObserver()); + scoped_ptr<TestMouseObserver> user2(new TestMouseObserver()); + + // No observers. + watcher->NotifyMouseMovement(gfx::Point(42, 101)); + EXPECT_EQ(0, user1->mouse_movements_); + EXPECT_EQ(0, user2->mouse_movements_); + + // Only one mouse observer. + watcher->AddObserver(user1.get()); + EXPECT_TRUE(watcher->IsActive()); + watcher->NotifyMouseMovement(gfx::Point(42, 101)); + EXPECT_GE(user1->mouse_movements_, 1); + EXPECT_EQ(0, user2->mouse_movements_); + watcher->RemoveObserver(user1.get()); + EXPECT_FALSE(watcher->IsActive()); + + // More than one mouse observer. + watcher->AddObserver(user1.get()); + EXPECT_TRUE(watcher->IsActive()); + watcher->AddObserver(user2.get()); + watcher->NotifyMouseMovement(gfx::Point(101, 42)); + EXPECT_GE(user1->mouse_movements_, 2); + EXPECT_GE(user2->mouse_movements_, 1); + + // Back to one observer. + watcher->RemoveObserver(user1.get()); + EXPECT_TRUE(watcher->IsActive()); + int saved_count = user1->mouse_movements_; + watcher->NotifyMouseMovement(gfx::Point(1, 2)); + EXPECT_EQ(saved_count, user1->mouse_movements_); + EXPECT_GE(user2->mouse_movements_, 2); + watcher->RemoveObserver(user2.get()); + EXPECT_FALSE(watcher->IsActive()); +} diff --git a/chrome/browser/ui/panels/panel_mouse_watcher_win.cc b/chrome/browser/ui/panels/panel_mouse_watcher_win.cc index 2e91011..9f42b2a 100644 --- a/chrome/browser/ui/panels/panel_mouse_watcher_win.cc +++ b/chrome/browser/ui/panels/panel_mouse_watcher_win.cc @@ -27,13 +27,14 @@ HMODULE GetCurrentModuleHandle() { class PanelMouseWatcherWin : public PanelMouseWatcher { public: - explicit PanelMouseWatcherWin(Observer* observer); + PanelMouseWatcherWin(); virtual ~PanelMouseWatcherWin(); + private: virtual void Start() OVERRIDE; virtual void Stop() OVERRIDE; + virtual bool IsActive() const OVERRIDE; - private: static LRESULT CALLBACK MouseHookProc(int code, WPARAM wparam, LPARAM lparam); static PanelMouseWatcherWin* instance_; // singleton instance @@ -45,34 +46,37 @@ class PanelMouseWatcherWin : public PanelMouseWatcher { PanelMouseWatcherWin* PanelMouseWatcherWin::instance_ = NULL; // static -PanelMouseWatcher* PanelMouseWatcher::Create(Observer* observer) { - return new PanelMouseWatcherWin(observer); +PanelMouseWatcher* PanelMouseWatcher::Create() { + return new PanelMouseWatcherWin(); } -PanelMouseWatcherWin::PanelMouseWatcherWin(Observer* observer) - : PanelMouseWatcher(observer), - mouse_hook_(NULL) { +PanelMouseWatcherWin::PanelMouseWatcherWin() + : mouse_hook_(NULL) { DCHECK(!instance_); // Only one instance ever used. instance_ = this; } PanelMouseWatcherWin::~PanelMouseWatcherWin() { - DCHECK(!mouse_hook_); + DCHECK(!IsActive()); } void PanelMouseWatcherWin::Start() { - DCHECK(!mouse_hook_); + DCHECK(!IsActive()); mouse_hook_ = ::SetWindowsHookEx( WH_MOUSE_LL, MouseHookProc, GetCurrentModuleHandle(), 0); DCHECK(mouse_hook_); } void PanelMouseWatcherWin::Stop() { - DCHECK(mouse_hook_); + DCHECK(IsActive()); ::UnhookWindowsHookEx(mouse_hook_); mouse_hook_ = NULL; } +bool PanelMouseWatcherWin::IsActive() const { + return mouse_hook_ != NULL; +} + LRESULT CALLBACK PanelMouseWatcherWin::MouseHookProc(int code, WPARAM wparam, LPARAM lparam) { diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index c26f086..9cdd3a6 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -3191,6 +3191,7 @@ 'browser/ui/panels/panel_manager.h', 'browser/ui/panels/panel_mouse_watcher.cc', 'browser/ui/panels/panel_mouse_watcher.h', + 'browser/ui/panels/panel_mouse_watcher_observer.h', 'browser/ui/panels/panel_mouse_watcher_timer.cc', 'browser/ui/panels/panel_mouse_watcher_win.cc', 'browser/ui/panels/panel_settings_menu_model.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 3f2c475..52fddbe 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1863,6 +1863,7 @@ 'browser/ui/omnibox/omnibox_view_unittest.cc', 'browser/ui/panels/auto_hiding_desktop_bar_win_unittest.cc', 'browser/ui/panels/panel_browser_window_cocoa_unittest.mm', + 'browser/ui/panels/panel_mouse_watcher_unittest.cc', 'browser/ui/search_engines/keyword_editor_controller_unittest.cc', 'browser/ui/select_file_dialog_unittest.cc', 'browser/ui/tabs/dock_info_unittest.cc', |