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 |