|
OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/ui/panels/panel_manager_win.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "chrome/browser/ui/panels/panel.h" | |
9 #include "chrome/browser/ui/panels/panel_browser_frame_view.h" | |
10 #include "chrome/browser/ui/panels/panel_browser_view.h" | |
11 | |
12 #include <windows.h> | |
13 | |
14 namespace { | |
15 | |
16 HMODULE GetModuleHandleFromAddress(void *address) { | |
17 MEMORY_BASIC_INFORMATION mbi; | |
18 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.
| |
19 return static_cast<HMODULE>(mbi.AllocationBase); | |
20 } | |
21 | |
22 | |
23 // Gets the handle to the currently executing module. | |
24 HMODULE GetCurrentModuleHandle() { | |
25 return GetModuleHandleFromAddress(GetCurrentModuleHandle); | |
dcheng
2011/06/24 08:13:18
Nite: ::
jianli
2011/06/29 01:28:12
Done.
| |
26 } | |
27 | |
28 } | |
29 | |
30 class PanelManagerMouseWatcher { | |
31 public: | |
32 PanelManagerMouseWatcher(int height_to_watch_on_mouse_enter, | |
33 int height_to_watch_on_mouse_exit, | |
34 PanelManagerWin* panel_manager); | |
35 ~PanelManagerMouseWatcher(); | |
36 | |
37 private: | |
38 static LRESULT CALLBACK MouseHookProc(int code, WPARAM wparam, LPARAM lparam); | |
39 | |
40 void OnMouseAction(int y); | |
41 | |
42 int height_to_watch_on_mouse_enter_; | |
43 int height_to_watch_on_mouse_exit_; | |
44 PanelManagerWin* panel_manager_; | |
45 HHOOK mouse_hook_; | |
46 bool mouse_in_bottom_area_; | |
47 }; | |
48 | |
49 static PanelManagerMouseWatcher* mouse_watcher_ = NULL; | |
50 | |
51 PanelManagerMouseWatcher::PanelManagerMouseWatcher( | |
52 int height_to_watch_on_mouse_enter, | |
53 int height_to_watch_on_mouse_exit, | |
54 PanelManagerWin* panel_manager) | |
55 : height_to_watch_on_mouse_enter_(height_to_watch_on_mouse_enter), | |
56 height_to_watch_on_mouse_exit_(height_to_watch_on_mouse_exit), | |
57 panel_manager_(panel_manager), | |
58 mouse_hook_(NULL), | |
59 mouse_in_bottom_area_(false) { | |
60 DCHECK(!mouse_watcher_); | |
61 mouse_watcher_ = this; | |
62 | |
63 mouse_hook_ = ::SetWindowsHookEx( | |
64 WH_MOUSE_LL, MouseHookProc,GetCurrentModuleHandle(), 0); | |
dcheng
2011/06/24 08:13:18
Nit: space.
jianli
2011/06/29 01:28:12
Done.
| |
65 DCHECK(mouse_hook_); | |
66 } | |
67 | |
68 PanelManagerMouseWatcher::~PanelManagerMouseWatcher() { | |
69 mouse_watcher_ = NULL; | |
70 UnhookWindowsHookEx(mouse_hook_); | |
dcheng
2011/06/24 08:13:18
Nit: ::
jianli
2011/06/29 01:28:12
Done.
| |
71 } | |
72 | |
73 void PanelManagerMouseWatcher::OnMouseAction(int y) { | |
74 int height_to_watch = mouse_in_bottom_area_ ? height_to_watch_on_mouse_exit_ | |
75 : height_to_watch_on_mouse_enter_; | |
76 bool mouse_in_bottom_area = | |
77 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.
| |
78 if (mouse_in_bottom_area == mouse_in_bottom_area_) | |
79 return; | |
80 mouse_in_bottom_area_ = mouse_in_bottom_area; | |
81 | |
82 if (mouse_in_bottom_area) | |
83 panel_manager_->BringUpTitleBarForAllMinimizedPanels(); | |
84 else | |
85 panel_manager_->BringDownTitleBarForAllMinimizedPanels(); | |
86 } | |
87 | |
88 LRESULT CALLBACK PanelManagerMouseWatcher::MouseHookProc(int code, | |
89 WPARAM wparam, | |
90 LPARAM lparam) { | |
91 if (code == HC_ACTION) { | |
92 MOUSEHOOKSTRUCT* hook_struct = reinterpret_cast<MOUSEHOOKSTRUCT*>(lparam); | |
93 if (hook_struct) | |
94 mouse_watcher_->OnMouseAction(hook_struct->pt.y); | |
95 } | |
96 return CallNextHookEx(NULL, code, wparam, lparam); | |
dcheng
2011/06/24 08:13:18
Nit: ::
jianli
2011/06/29 01:28:12
Done.
| |
97 } | |
98 | |
99 // static | |
100 PanelManager* PanelManager::Create() { | |
101 return new PanelManagerWin(); | |
102 } | |
103 | |
104 PanelManagerWin::PanelManagerWin() { | |
105 } | |
106 | |
107 PanelManagerWin::~PanelManagerWin() { | |
108 } | |
109 | |
110 void PanelManagerWin::Remove(Panel* panel) { | |
111 PanelManager::Remove(panel); | |
112 | |
113 // If the removed panel is the only panel that is not fully restored, we need | |
114 // to check for this and stop the mouse watcher. | |
115 StopMouseWatchIfNotNeeded(); | |
116 } | |
117 | |
118 void PanelManagerWin::Minimize(Panel* panel) { | |
119 PanelManager::Minimize(panel); | |
120 | |
121 // Starts the global mouse watch so that we can bring up or down the titlebar | |
122 // when the mouse is entering or leaving the bottom 3-pixel area. | |
123 EnsureMouseWatchStarted( | |
124 panel->GetBounds().height(), | |
125 static_cast<PanelBrowserView*>(panel->native_panel_)-> | |
126 GetFrameView()->NonClientTopBorderHeight()); | |
127 } | |
128 | |
129 void PanelManagerWin::Restore(Panel* panel, bool titlebar_only) { | |
130 PanelManager::Restore(panel, titlebar_only); | |
131 | |
132 // If this panel is not fully restored, we still need to keep the mouse | |
133 // watcher running. | |
134 if (titlebar_only) | |
135 return; | |
136 | |
137 StopMouseWatchIfNotNeeded(); | |
138 } | |
139 | |
140 void PanelManagerWin::EnsureMouseWatchStarted( | |
141 int height_to_watch_on_mouse_enter, int height_to_watch_on_mouse_exit) { | |
142 if (!mouse_watcher_.get()) { | |
143 mouse_watcher_.reset( | |
144 new PanelManagerMouseWatcher(height_to_watch_on_mouse_enter, | |
145 height_to_watch_on_mouse_exit, this)); | |
146 } | |
147 } | |
148 | |
149 void PanelManagerWin::StopMouseWatchIfNotNeeded() { | |
150 // If all panels are fully restored, stop the global mouse watch. | |
151 for (ActivePanels::const_iterator iter = active_panels_.begin(); | |
152 iter != active_panels_.end(); ++iter) { | |
153 PanelBrowserView* panel_browser_view = | |
154 static_cast<PanelBrowserView*>((*iter)->native_panel_); | |
155 if (panel_browser_view->expand_state() != PanelBrowserView::FULLY_RESTORED) | |
156 return; | |
157 } | |
158 | |
159 mouse_watcher_.reset(); | |
160 } | |
161 | |
162 void PanelManagerWin::BringUpTitleBarForAllMinimizedPanels() { | |
163 for (ActivePanels::const_iterator iter = active_panels_.begin(); | |
164 iter != active_panels_.end(); ++iter) { | |
165 PanelBrowserView* panel_browser_view = | |
166 static_cast<PanelBrowserView*>((*iter)->native_panel_); | |
167 if (panel_browser_view->expand_state() == PanelBrowserView::FULLY_MINIMIZED) | |
168 Restore((*iter), true); | |
169 } | |
170 } | |
171 | |
172 void PanelManagerWin::BringDownTitleBarForAllMinimizedPanels() { | |
173 for (ActivePanels::const_iterator iter = active_panels_.begin(); | |
174 iter != active_panels_.end(); ++iter) { | |
175 PanelBrowserView* panel_browser_view = | |
176 static_cast<PanelBrowserView*>((*iter)->native_panel_); | |
177 if (panel_browser_view->expand_state() == | |
178 PanelBrowserView::TITLEBAR_RESTORED) { | |
179 Minimize((*iter)); | |
180 } | |
181 } | |
182 } | |
OLD | NEW |