OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/views/frame/aero_glass_frame.h" | 5 #include "chrome/browser/views/frame/browser_frame.h" |
6 | 6 |
7 #include <dwmapi.h> | 7 #include <dwmapi.h> |
8 | 8 |
9 #include "chrome/browser/browser_list.h" | 9 #include "chrome/browser/browser_list.h" |
10 #include "chrome/browser/views/frame/browser_view.h" | 10 #include "chrome/browser/views/frame/browser_view.h" |
11 #include "chrome/browser/views/frame/aero_glass_non_client_view.h" | 11 #include "chrome/browser/views/frame/glass_browser_frame_view.h" |
| 12 #include "chrome/browser/views/frame/opaque_browser_frame_view.h" |
12 #include "chrome/common/resource_bundle.h" | 13 #include "chrome/common/resource_bundle.h" |
| 14 #include "chrome/common/win_util.h" |
13 #include "chrome/views/window_delegate.h" | 15 #include "chrome/views/window_delegate.h" |
14 #include "grit/theme_resources.h" | 16 #include "grit/theme_resources.h" |
15 | 17 |
16 // static | 18 // static |
17 | |
18 static const int kClientEdgeThickness = 3; | 19 static const int kClientEdgeThickness = 3; |
19 | 20 |
20 HICON AeroGlassFrame::throbber_icons_[AeroGlassFrame::kThrobberIconCount]; | 21 /////////////////////////////////////////////////////////////////////////////// |
| 22 // BrowserFrame, public: |
21 | 23 |
22 /////////////////////////////////////////////////////////////////////////////// | 24 BrowserFrame::BrowserFrame(BrowserView* browser_view) |
23 // AeroGlassFrame, public: | |
24 | |
25 AeroGlassFrame::AeroGlassFrame(BrowserView* browser_view) | |
26 : Window(browser_view), | 25 : Window(browser_view), |
27 browser_view_(browser_view), | 26 browser_view_(browser_view), |
28 frame_initialized_(false), | 27 frame_initialized_(false) { |
29 throbber_running_(false), | |
30 throbber_frame_(0) { | |
31 non_client_view_ = new AeroGlassNonClientView(this, browser_view); | |
32 browser_view_->set_frame(this); | 28 browser_view_->set_frame(this); |
33 | 29 non_client_view_->SetFrameView(CreateFrameViewForWindow()); |
34 if (window_delegate()->ShouldShowWindowIcon()) | |
35 InitThrobberIcons(); | |
36 } | 30 } |
37 | 31 |
38 AeroGlassFrame::~AeroGlassFrame() { | 32 BrowserFrame::~BrowserFrame() { |
39 } | 33 } |
40 | 34 |
41 void AeroGlassFrame::Init() { | 35 void BrowserFrame::Init() { |
42 Window::Init(NULL, gfx::Rect()); | 36 Window::Init(NULL, gfx::Rect()); |
43 } | 37 } |
44 | 38 |
45 int AeroGlassFrame::GetMinimizeButtonOffset() const { | 39 int BrowserFrame::GetMinimizeButtonOffset() const { |
46 TITLEBARINFOEX titlebar_info; | 40 TITLEBARINFOEX titlebar_info; |
47 titlebar_info.cbSize = sizeof(TITLEBARINFOEX); | 41 titlebar_info.cbSize = sizeof(TITLEBARINFOEX); |
48 SendMessage(GetHWND(), WM_GETTITLEBARINFOEX, 0, (WPARAM)&titlebar_info); | 42 SendMessage(GetHWND(), WM_GETTITLEBARINFOEX, 0, (WPARAM)&titlebar_info); |
49 | 43 |
50 CPoint minimize_button_corner(titlebar_info.rgrect[2].left, | 44 CPoint minimize_button_corner(titlebar_info.rgrect[2].left, |
51 titlebar_info.rgrect[2].top); | 45 titlebar_info.rgrect[2].top); |
52 MapWindowPoints(HWND_DESKTOP, GetHWND(), &minimize_button_corner, 1); | 46 MapWindowPoints(HWND_DESKTOP, GetHWND(), &minimize_button_corner, 1); |
53 | 47 |
54 return minimize_button_corner.x; | 48 return minimize_button_corner.x; |
55 } | 49 } |
56 | 50 |
57 /////////////////////////////////////////////////////////////////////////////// | 51 gfx::Rect BrowserFrame::GetBoundsForTabStrip(TabStrip* tabstrip) const { |
58 // AeroGlassFrame, BrowserFrame implementation: | 52 return browser_frame_view_->GetBoundsForTabStrip(tabstrip); |
59 | |
60 gfx::Rect AeroGlassFrame::GetWindowBoundsForClientBounds( | |
61 const gfx::Rect& client_bounds) { | |
62 RECT rect = client_bounds.ToRECT(); | |
63 AdjustWindowRectEx(&rect, window_style(), FALSE, window_ex_style()); | |
64 return gfx::Rect(rect); | |
65 } | 53 } |
66 | 54 |
67 gfx::Rect AeroGlassFrame::GetBoundsForTabStrip(TabStrip* tabstrip) const { | 55 void BrowserFrame::UpdateThrobber(bool running) { |
68 return GetAeroGlassNonClientView()->GetBoundsForTabStrip(tabstrip); | 56 browser_frame_view_->UpdateThrobber(running); |
69 } | |
70 | |
71 void AeroGlassFrame::UpdateThrobber(bool running) { | |
72 if (throbber_running_) { | |
73 if (running) { | |
74 DisplayNextThrobberFrame(); | |
75 } else { | |
76 StopThrobber(); | |
77 } | |
78 } else if (running) { | |
79 StartThrobber(); | |
80 } | |
81 } | |
82 | |
83 views::Window* AeroGlassFrame::GetWindow() { | |
84 return this; | |
85 } | |
86 | |
87 const views::Window* AeroGlassFrame::GetWindow() const { | |
88 return this; | |
89 } | 57 } |
90 | 58 |
91 /////////////////////////////////////////////////////////////////////////////// | 59 /////////////////////////////////////////////////////////////////////////////// |
92 // AeroGlassFrame, views::WidgetWin overrides: | 60 // BrowserFrame, views::WidgetWin overrides: |
93 | 61 |
94 bool AeroGlassFrame::AcceleratorPressed(views::Accelerator* accelerator) { | 62 bool BrowserFrame::AcceleratorPressed(views::Accelerator* accelerator) { |
95 return browser_view_->AcceleratorPressed(*accelerator); | 63 return browser_view_->AcceleratorPressed(*accelerator); |
96 } | 64 } |
97 | 65 |
98 bool AeroGlassFrame::GetAccelerator(int cmd_id, | 66 bool BrowserFrame::GetAccelerator(int cmd_id, views::Accelerator* accelerator) { |
99 views::Accelerator* accelerator) { | |
100 return browser_view_->GetAccelerator(cmd_id, accelerator); | 67 return browser_view_->GetAccelerator(cmd_id, accelerator); |
101 } | 68 } |
102 | 69 |
103 void AeroGlassFrame::OnInitMenuPopup(HMENU menu, UINT position, | 70 void BrowserFrame::OnEndSession(BOOL ending, UINT logoff) { |
| 71 BrowserList::WindowsSessionEnding(); |
| 72 } |
| 73 |
| 74 void BrowserFrame::OnEnterSizeMove() { |
| 75 browser_view_->WindowMoveOrResizeStarted(); |
| 76 } |
| 77 |
| 78 void BrowserFrame::OnInitMenuPopup(HMENU menu, UINT position, |
104 BOOL is_system_menu) { | 79 BOOL is_system_menu) { |
105 browser_view_->PrepareToRunSystemMenu(menu); | 80 browser_view_->PrepareToRunSystemMenu(menu); |
106 } | 81 } |
107 | 82 |
108 void AeroGlassFrame::OnEnterSizeMove() { | 83 LRESULT BrowserFrame::OnMouseActivate(HWND window, UINT hittest_code, |
109 browser_view_->WindowMoveOrResizeStarted(); | |
110 } | |
111 | |
112 void AeroGlassFrame::OnEndSession(BOOL ending, UINT logoff) { | |
113 BrowserList::WindowsSessionEnding(); | |
114 } | |
115 | |
116 LRESULT AeroGlassFrame::OnMouseActivate(HWND window, UINT hittest_code, | |
117 UINT message) { | 84 UINT message) { |
118 return browser_view_->ActivateAppModalDialog() ? MA_NOACTIVATEANDEAT | 85 return browser_view_->ActivateAppModalDialog() ? MA_NOACTIVATEANDEAT |
119 : MA_ACTIVATE; | 86 : MA_ACTIVATE; |
120 } | 87 } |
121 | 88 |
122 void AeroGlassFrame::OnMove(const CPoint& point) { | 89 void BrowserFrame::OnMove(const CPoint& point) { |
123 browser_view_->WindowMoved(); | 90 browser_view_->WindowMoved(); |
124 } | 91 } |
125 | 92 |
126 void AeroGlassFrame::OnMoving(UINT param, const RECT* new_bounds) { | 93 void BrowserFrame::OnMoving(UINT param, const RECT* new_bounds) { |
127 browser_view_->WindowMoved(); | 94 browser_view_->WindowMoved(); |
128 } | 95 } |
129 | 96 |
130 LRESULT AeroGlassFrame::OnNCActivate(BOOL active) { | 97 LRESULT BrowserFrame::OnNCActivate(BOOL active) { |
131 if (browser_view_->ActivateAppModalDialog()) | 98 if (browser_view_->ActivateAppModalDialog()) |
132 return TRUE; | 99 return TRUE; |
133 | 100 |
134 if (!frame_initialized_) { | 101 // Perform first time initialization of the DWM frame insets, only if we're |
| 102 // using the native frame. |
| 103 if (non_client_view_->UseNativeFrame() && !frame_initialized_) { |
135 if (browser_view_->IsBrowserTypeNormal()) { | 104 if (browser_view_->IsBrowserTypeNormal()) { |
136 ::SetWindowPos(GetHWND(), NULL, 0, 0, 0, 0, | 105 ::SetWindowPos(GetHWND(), NULL, 0, 0, 0, 0, |
137 SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED); | 106 SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED); |
138 UpdateDWMFrame(); | 107 UpdateDWMFrame(); |
139 } | 108 } |
140 frame_initialized_ = true; | 109 frame_initialized_ = true; |
141 } | 110 } |
142 browser_view_->ActivationChanged(!!active); | 111 browser_view_->ActivationChanged(!!active); |
143 SetMsgHandled(false); | 112 return Window::OnNCActivate(active); |
144 return TRUE; | |
145 } | 113 } |
146 | 114 |
147 LRESULT AeroGlassFrame::OnNCCalcSize(BOOL mode, LPARAM l_param) { | 115 LRESULT BrowserFrame::OnNCCalcSize(BOOL mode, LPARAM l_param) { |
148 if (!browser_view_->IsBrowserTypeNormal() || !mode) { | 116 // We don't adjust the client area unless we're a tabbed browser window and |
149 SetMsgHandled(FALSE); | 117 // are using the native frame. |
150 return 0; | 118 if (!non_client_view_->UseNativeFrame() || |
| 119 !browser_view_->IsBrowserTypeNormal() || !mode) { |
| 120 return Window::OnNCCalcSize(mode, l_param); |
151 } | 121 } |
152 | 122 |
153 // In fullscreen mode, we make the whole window client area. | 123 // In fullscreen mode, we make the whole window client area. |
154 if (!browser_view_->IsFullscreen()) { | 124 if (!browser_view_->IsFullscreen()) { |
155 NCCALCSIZE_PARAMS* params = reinterpret_cast<NCCALCSIZE_PARAMS*>(l_param); | 125 NCCALCSIZE_PARAMS* params = reinterpret_cast<NCCALCSIZE_PARAMS*>(l_param); |
156 int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME); | 126 int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME); |
157 params->rgrc[0].left += (border_thickness - kClientEdgeThickness); | 127 params->rgrc[0].left += (border_thickness - kClientEdgeThickness); |
158 params->rgrc[0].right -= (border_thickness - kClientEdgeThickness); | 128 params->rgrc[0].right -= (border_thickness - kClientEdgeThickness); |
159 params->rgrc[0].bottom -= (border_thickness - kClientEdgeThickness); | 129 params->rgrc[0].bottom -= (border_thickness - kClientEdgeThickness); |
160 } | 130 } |
161 | 131 |
162 UpdateDWMFrame(); | 132 UpdateDWMFrame(); |
163 | 133 |
164 SetMsgHandled(TRUE); | 134 SetMsgHandled(TRUE); |
165 return 0; | 135 return 0; |
166 } | 136 } |
167 | 137 |
168 LRESULT AeroGlassFrame::OnNCHitTest(const CPoint& pt) { | 138 LRESULT BrowserFrame::OnNCHitTest(const CPoint& pt) { |
169 LRESULT result; | 139 // Only do DWM hit-testing when we are using the native frame. |
170 if (DwmDefWindowProc(GetHWND(), WM_NCHITTEST, 0, MAKELPARAM(pt.x, pt.y), | 140 if (non_client_view_->UseNativeFrame()) { |
171 &result)) { | 141 LRESULT result; |
172 return result; | 142 if (DwmDefWindowProc(GetHWND(), WM_NCHITTEST, 0, MAKELPARAM(pt.x, pt.y), |
| 143 &result)) { |
| 144 return result; |
| 145 } |
173 } | 146 } |
174 return Window::OnNCHitTest(pt); | 147 return Window::OnNCHitTest(pt); |
175 } | 148 } |
176 | 149 |
177 /////////////////////////////////////////////////////////////////////////////// | 150 /////////////////////////////////////////////////////////////////////////////// |
178 // AeroGlassFrame, views::CustomFrameWindow overrides: | 151 // BrowserFrame, views::CustomFrameWindow overrides: |
179 | 152 |
180 int AeroGlassFrame::GetShowState() const { | 153 int BrowserFrame::GetShowState() const { |
181 return browser_view_->GetShowState(); | 154 return browser_view_->GetShowState(); |
182 } | 155 } |
183 | 156 |
| 157 views::NonClientFrameView* BrowserFrame::CreateFrameViewForWindow() { |
| 158 if (non_client_view_->UseNativeFrame()) |
| 159 browser_frame_view_ = new GlassBrowserFrameView(this, browser_view_); |
| 160 else |
| 161 browser_frame_view_ = new OpaqueBrowserFrameView(this, browser_view_); |
| 162 return browser_frame_view_; |
| 163 } |
| 164 |
| 165 void BrowserFrame::UpdateFrameAfterFrameChange() { |
| 166 Window::UpdateFrameAfterFrameChange(); |
| 167 UpdateDWMFrame(); |
| 168 } |
| 169 |
184 /////////////////////////////////////////////////////////////////////////////// | 170 /////////////////////////////////////////////////////////////////////////////// |
185 // AeroGlassFrame, private: | 171 // BrowserFrame, private: |
186 | 172 |
187 void AeroGlassFrame::UpdateDWMFrame() { | 173 void BrowserFrame::UpdateDWMFrame() { |
188 // Nothing to do yet. | 174 // Nothing to do yet. |
189 if (!client_view()) | 175 if (!client_view()) |
190 return; | 176 return; |
191 | 177 |
192 // In fullscreen mode, we don't extend glass into the client area at all, | 178 // In fullscreen mode, we don't extend glass into the client area at all, |
193 // because the GDI-drawn text in the web content composited over it will | 179 // because the GDI-drawn text in the web content composited over it will |
194 // become semi-transparent over any glass area. | 180 // become semi-transparent over any glass area. |
195 MARGINS margins = { 0 }; | 181 MARGINS margins = { 0 }; |
196 if (!browser_view_->IsFullscreen()) { | 182 if (!browser_view_->IsFullscreen()) { |
197 margins.cxLeftWidth = kClientEdgeThickness + 1; | 183 margins.cxLeftWidth = kClientEdgeThickness + 1; |
198 margins.cxRightWidth = kClientEdgeThickness + 1; | 184 margins.cxRightWidth = kClientEdgeThickness + 1; |
199 margins.cyTopHeight = | 185 margins.cyTopHeight = |
200 GetBoundsForTabStrip(browser_view_->tabstrip()).bottom(); | 186 GetBoundsForTabStrip(browser_view_->tabstrip()).bottom(); |
201 margins.cyBottomHeight = kClientEdgeThickness + 1; | 187 margins.cyBottomHeight = kClientEdgeThickness + 1; |
202 } | 188 } |
203 DwmExtendFrameIntoClientArea(GetHWND(), &margins); | 189 DwmExtendFrameIntoClientArea(GetHWND(), &margins); |
204 } | 190 } |
205 | 191 |
206 AeroGlassNonClientView* AeroGlassFrame::GetAeroGlassNonClientView() const { | |
207 // We can safely assume that this conversion is true. | |
208 return static_cast<AeroGlassNonClientView*>(non_client_view_); | |
209 } | |
210 | |
211 void AeroGlassFrame::StartThrobber() { | |
212 if (!throbber_running_) { | |
213 throbber_running_ = true; | |
214 throbber_frame_ = 0; | |
215 InitThrobberIcons(); | |
216 ::SendMessage(GetHWND(), WM_SETICON, static_cast<WPARAM>(ICON_SMALL), | |
217 reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_])); | |
218 } | |
219 } | |
220 | |
221 void AeroGlassFrame::StopThrobber() { | |
222 if (throbber_running_) | |
223 throbber_running_ = false; | |
224 } | |
225 | |
226 void AeroGlassFrame::DisplayNextThrobberFrame() { | |
227 throbber_frame_ = (throbber_frame_ + 1) % kThrobberIconCount; | |
228 ::SendMessage(GetHWND(), WM_SETICON, static_cast<WPARAM>(ICON_SMALL), | |
229 reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_])); | |
230 } | |
231 | |
232 // static | |
233 void AeroGlassFrame::InitThrobberIcons() { | |
234 static bool initialized = false; | |
235 if (!initialized) { | |
236 ResourceBundle &rb = ResourceBundle::GetSharedInstance(); | |
237 for (int i = 0; i < kThrobberIconCount; ++i) { | |
238 throbber_icons_[i] = rb.LoadThemeIcon(IDR_THROBBER_01 + i); | |
239 DCHECK(throbber_icons_[i]); | |
240 } | |
241 initialized = true; | |
242 } | |
243 } | |
OLD | NEW |