Chromium Code Reviews| Index: chrome/browser/ui/panels/panel_manager_win.cc |
| =================================================================== |
| --- chrome/browser/ui/panels/panel_manager_win.cc (revision 0) |
| +++ chrome/browser/ui/panels/panel_manager_win.cc (revision 0) |
| @@ -0,0 +1,182 @@ |
| +// 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 "chrome/browser/ui/panels/panel_manager_win.h" |
| + |
| +#include "base/logging.h" |
| +#include "chrome/browser/ui/panels/panel.h" |
| +#include "chrome/browser/ui/panels/panel_browser_frame_view.h" |
| +#include "chrome/browser/ui/panels/panel_browser_view.h" |
| + |
| +#include <windows.h> |
| + |
| +namespace { |
| + |
| +HMODULE GetModuleHandleFromAddress(void *address) { |
| + MEMORY_BASIC_INFORMATION mbi; |
| + SIZE_T result = VirtualQuery(address, &mbi, sizeof(mbi)); |
|
dcheng
2011/06/24 08:13:18
Nit: :: -- I'm actually indifferent about this, bu
jianli
2011/06/29 01:28:12
Done.
|
| + return static_cast<HMODULE>(mbi.AllocationBase); |
| +} |
| + |
| + |
| +// Gets the handle to the currently executing module. |
| +HMODULE GetCurrentModuleHandle() { |
| + return GetModuleHandleFromAddress(GetCurrentModuleHandle); |
|
dcheng
2011/06/24 08:13:18
Nite: ::
jianli
2011/06/29 01:28:12
Done.
|
| +} |
| + |
| +} |
| + |
| +class PanelManagerMouseWatcher { |
| + public: |
| + PanelManagerMouseWatcher(int height_to_watch_on_mouse_enter, |
| + int height_to_watch_on_mouse_exit, |
| + PanelManagerWin* panel_manager); |
| + ~PanelManagerMouseWatcher(); |
| + |
| + private: |
| + static LRESULT CALLBACK MouseHookProc(int code, WPARAM wparam, LPARAM lparam); |
| + |
| + void OnMouseAction(int y); |
| + |
| + int height_to_watch_on_mouse_enter_; |
| + int height_to_watch_on_mouse_exit_; |
| + PanelManagerWin* panel_manager_; |
| + HHOOK mouse_hook_; |
| + bool mouse_in_bottom_area_; |
| +}; |
| + |
| +static PanelManagerMouseWatcher* mouse_watcher_ = NULL; |
| + |
| +PanelManagerMouseWatcher::PanelManagerMouseWatcher( |
| + int height_to_watch_on_mouse_enter, |
| + int height_to_watch_on_mouse_exit, |
| + PanelManagerWin* panel_manager) |
| + : height_to_watch_on_mouse_enter_(height_to_watch_on_mouse_enter), |
| + height_to_watch_on_mouse_exit_(height_to_watch_on_mouse_exit), |
| + panel_manager_(panel_manager), |
| + mouse_hook_(NULL), |
| + mouse_in_bottom_area_(false) { |
| + DCHECK(!mouse_watcher_); |
| + mouse_watcher_ = this; |
| + |
| + mouse_hook_ = ::SetWindowsHookEx( |
| + WH_MOUSE_LL, MouseHookProc,GetCurrentModuleHandle(), 0); |
|
dcheng
2011/06/24 08:13:18
Nit: space.
jianli
2011/06/29 01:28:12
Done.
|
| + DCHECK(mouse_hook_); |
| +} |
| + |
| +PanelManagerMouseWatcher::~PanelManagerMouseWatcher() { |
| + mouse_watcher_ = NULL; |
| + UnhookWindowsHookEx(mouse_hook_); |
|
dcheng
2011/06/24 08:13:18
Nit: ::
jianli
2011/06/29 01:28:12
Done.
|
| +} |
| + |
| +void PanelManagerMouseWatcher::OnMouseAction(int y) { |
| + int height_to_watch = mouse_in_bottom_area_ ? height_to_watch_on_mouse_exit_ |
| + : height_to_watch_on_mouse_enter_; |
| + bool mouse_in_bottom_area = |
| + y > (panel_manager_->work_area_.bottom() - height_to_watch); |
|
dcheng
2011/06/24 08:13:18
How will this interact with multiple monitors?
jianli
2011/06/29 01:28:12
We're only showing panels in primary monitor.
|
| + if (mouse_in_bottom_area == mouse_in_bottom_area_) |
| + return; |
| + mouse_in_bottom_area_ = mouse_in_bottom_area; |
| + |
| + if (mouse_in_bottom_area) |
| + panel_manager_->BringUpTitleBarForAllMinimizedPanels(); |
| + else |
| + panel_manager_->BringDownTitleBarForAllMinimizedPanels(); |
| +} |
| + |
| +LRESULT CALLBACK PanelManagerMouseWatcher::MouseHookProc(int code, |
| + WPARAM wparam, |
| + LPARAM lparam) { |
| + if (code == HC_ACTION) { |
| + MOUSEHOOKSTRUCT* hook_struct = reinterpret_cast<MOUSEHOOKSTRUCT*>(lparam); |
| + if (hook_struct) |
| + mouse_watcher_->OnMouseAction(hook_struct->pt.y); |
| + } |
| + return CallNextHookEx(NULL, code, wparam, lparam); |
|
dcheng
2011/06/24 08:13:18
Nit: ::
jianli
2011/06/29 01:28:12
Done.
|
| +} |
| + |
| +// static |
| +PanelManager* PanelManager::Create() { |
| + return new PanelManagerWin(); |
| +} |
| + |
| +PanelManagerWin::PanelManagerWin() { |
| +} |
| + |
| +PanelManagerWin::~PanelManagerWin() { |
| +} |
| + |
| +void PanelManagerWin::Remove(Panel* panel) { |
| + PanelManager::Remove(panel); |
| + |
| + // If the removed panel is the only panel that is not fully restored, we need |
| + // to check for this and stop the mouse watcher. |
| + StopMouseWatchIfNotNeeded(); |
| +} |
| + |
| +void PanelManagerWin::Minimize(Panel* panel) { |
| + PanelManager::Minimize(panel); |
| + |
| + // Starts the global mouse watch so that we can bring up or down the titlebar |
| + // when the mouse is entering or leaving the bottom 3-pixel area. |
| + EnsureMouseWatchStarted( |
| + panel->GetBounds().height(), |
| + static_cast<PanelBrowserView*>(panel->native_panel_)-> |
| + GetFrameView()->NonClientTopBorderHeight()); |
| +} |
| + |
| +void PanelManagerWin::Restore(Panel* panel, bool titlebar_only) { |
| + PanelManager::Restore(panel, titlebar_only); |
| + |
| + // If this panel is not fully restored, we still need to keep the mouse |
| + // watcher running. |
| + if (titlebar_only) |
| + return; |
| + |
| + StopMouseWatchIfNotNeeded(); |
| +} |
| + |
| +void PanelManagerWin::EnsureMouseWatchStarted( |
| + int height_to_watch_on_mouse_enter, int height_to_watch_on_mouse_exit) { |
| + if (!mouse_watcher_.get()) { |
| + mouse_watcher_.reset( |
| + new PanelManagerMouseWatcher(height_to_watch_on_mouse_enter, |
| + height_to_watch_on_mouse_exit, this)); |
| + } |
| +} |
| + |
| +void PanelManagerWin::StopMouseWatchIfNotNeeded() { |
| + // If all panels are fully restored, stop the global mouse watch. |
| + for (ActivePanels::const_iterator iter = active_panels_.begin(); |
| + iter != active_panels_.end(); ++iter) { |
| + PanelBrowserView* panel_browser_view = |
| + static_cast<PanelBrowserView*>((*iter)->native_panel_); |
| + if (panel_browser_view->expand_state() != PanelBrowserView::FULLY_RESTORED) |
| + return; |
| + } |
| + |
| + mouse_watcher_.reset(); |
| +} |
| + |
| +void PanelManagerWin::BringUpTitleBarForAllMinimizedPanels() { |
| + for (ActivePanels::const_iterator iter = active_panels_.begin(); |
| + iter != active_panels_.end(); ++iter) { |
| + PanelBrowserView* panel_browser_view = |
| + static_cast<PanelBrowserView*>((*iter)->native_panel_); |
| + if (panel_browser_view->expand_state() == PanelBrowserView::FULLY_MINIMIZED) |
| + Restore((*iter), true); |
| + } |
| +} |
| + |
| +void PanelManagerWin::BringDownTitleBarForAllMinimizedPanels() { |
| + for (ActivePanels::const_iterator iter = active_panels_.begin(); |
| + iter != active_panels_.end(); ++iter) { |
| + PanelBrowserView* panel_browser_view = |
| + static_cast<PanelBrowserView*>((*iter)->native_panel_); |
| + if (panel_browser_view->expand_state() == |
| + PanelBrowserView::TITLEBAR_RESTORED) { |
| + Minimize((*iter)); |
| + } |
| + } |
| +} |
| Property changes on: chrome\browser\ui\panels\panel_manager_win.cc |
| ___________________________________________________________________ |
| Added: svn:eol-style |
| + LF |