| 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 |