OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/ui/views/frame/glass_browser_frame_view.h" | 5 #include "chrome/browser/ui/views/frame/glass_browser_frame_view.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
10 #include "base/win/windows_version.h" | 10 #include "base/win/windows_version.h" |
(...skipping 24 matching lines...) Expand all Loading... | |
35 #include "ui/views/controls/label.h" | 35 #include "ui/views/controls/label.h" |
36 #include "ui/views/layout/layout_constants.h" | 36 #include "ui/views/layout/layout_constants.h" |
37 #include "ui/views/resources/grit/views_resources.h" | 37 #include "ui/views/resources/grit/views_resources.h" |
38 #include "ui/views/win/hwnd_util.h" | 38 #include "ui/views/win/hwnd_util.h" |
39 #include "ui/views/window/client_view.h" | 39 #include "ui/views/window/client_view.h" |
40 | 40 |
41 HICON GlassBrowserFrameView::throbber_icons_[ | 41 HICON GlassBrowserFrameView::throbber_icons_[ |
42 GlassBrowserFrameView::kThrobberIconCount]; | 42 GlassBrowserFrameView::kThrobberIconCount]; |
43 | 43 |
44 namespace { | 44 namespace { |
45 // Size of client edge drawn inside the outer frame borders. | 45 // Thickness of the border in the client area that separates it from the |
46 const int kNonClientBorderThicknessPreWin10 = 3; | 46 // non-client area. Not to be confused with kClientEdgeThickness, which is the |
47 const int kNonClientBorderThicknessWin10 = 1; | 47 // thickness of the border between the web content and our frame border. |
48 const int kClientBorderThicknessPreWin10 = 3; | |
49 const int kClientBorderThicknessWin10 = 1; | |
48 // Besides the frame border, there's empty space atop the window in restored | 50 // Besides the frame border, there's empty space atop the window in restored |
49 // mode, to use to drag the window around. | 51 // mode, to use to drag the window around. |
50 const int kNonClientRestoredExtraThickness = 11; | 52 const int kNonClientRestoredExtraThickness = 11; |
51 // In the window corners, the resize areas don't actually expand bigger, but the | 53 // In the window corners the resize area is not actually bigger, but the 16 |
52 // 16 px at the end of the top and bottom edges triggers diagonal resizing. | 54 // pixels at the end of the top edges trigger diagonal resizing. |
53 const int kResizeCornerWidth = 16; | 55 const int kResizeCornerWidth = 16; |
54 // How far the new avatar button is from the left of the minimize button. | 56 // How far the profile switcher button is from the left of the minimize button. |
55 const int kNewAvatarButtonOffset = 5; | 57 const int kProfileSwitcherButtonOffset = 5; |
56 // The content edge images have a shadow built into them. | 58 // The content edge images have a shadow built into them. |
57 const int kContentEdgeShadowThickness = 2; | 59 const int kContentEdgeShadowThickness = 2; |
58 // In restored mode, the New Tab button isn't at the same height as the caption | 60 // In restored mode, the New Tab button isn't at the same height as the caption |
59 // buttons, but the space will look cluttered if it actually slides under them, | 61 // buttons, but the space will look cluttered if it actually slides under them, |
60 // so we stop it when the gap between the two is down to 5 px. | 62 // so we stop it when the gap between the two is down to 5 px. |
61 const int kNewTabCaptionRestoredSpacing = 5; | 63 const int kNewTabCaptionRestoredSpacing = 5; |
62 // In maximized mode, where the New Tab button and the caption buttons are at | 64 // In maximized mode, where the New Tab button and the caption buttons are at |
63 // similar vertical coordinates, we need to reserve a larger, 16 px gap to avoid | 65 // similar vertical coordinates, we need to reserve a larger, 16 px gap to avoid |
64 // looking too cluttered. | 66 // looking too cluttered. |
65 const int kNewTabCaptionMaximizedSpacing = 16; | 67 const int kNewTabCaptionMaximizedSpacing = 16; |
68 // Height of the profile switcher button. Same as the height of the Windows 7/8 | |
69 // caption buttons but doesn't change for 10 where the caption buttons are much | |
70 // bigger. | |
71 const int kProfileSwitcherButtonHeightRestored = 20; | |
72 const int kProfileSwitcherButtonHeightMaximized = 19; | |
66 | 73 |
67 // Converts the |image| to a Windows icon and returns the corresponding HICON | 74 // Converts the |image| to a Windows icon and returns the corresponding HICON |
68 // handle. |image| is resized to desired |width| and |height| if needed. | 75 // handle. |image| is resized to desired |width| and |height| if needed. |
69 base::win::ScopedHICON CreateHICONFromSkBitmapSizedTo( | 76 base::win::ScopedHICON CreateHICONFromSkBitmapSizedTo( |
70 const gfx::ImageSkia& image, | 77 const gfx::ImageSkia& image, |
71 int width, | 78 int width, |
72 int height) { | 79 int height) { |
73 return IconUtil::CreateHICONFromSkBitmap( | 80 return IconUtil::CreateHICONFromSkBitmap( |
74 width == image.width() && height == image.height() | 81 width == image.width() && height == image.height() |
75 ? *image.bitmap() | 82 ? *image.bitmap() |
(...skipping 19 matching lines...) Expand all Loading... | |
95 | 102 |
96 GlassBrowserFrameView::~GlassBrowserFrameView() { | 103 GlassBrowserFrameView::~GlassBrowserFrameView() { |
97 } | 104 } |
98 | 105 |
99 /////////////////////////////////////////////////////////////////////////////// | 106 /////////////////////////////////////////////////////////////////////////////// |
100 // GlassBrowserFrameView, BrowserNonClientFrameView implementation: | 107 // GlassBrowserFrameView, BrowserNonClientFrameView implementation: |
101 | 108 |
102 gfx::Rect GlassBrowserFrameView::GetBoundsForTabStrip( | 109 gfx::Rect GlassBrowserFrameView::GetBoundsForTabStrip( |
103 views::View* tabstrip) const { | 110 views::View* tabstrip) const { |
104 // In maximized RTL windows, don't let the tabstrip overlap the caption area, | 111 // In maximized RTL windows, don't let the tabstrip overlap the caption area, |
105 // or the alpha-blending it does will make things like the new avatar button | 112 // or the alpha-blending it does will make things like the profile switcher |
106 // look glitchy. | 113 // button look glitchy. |
107 const int offset = | 114 const int offset = |
108 (ui::MaterialDesignController::IsModeMaterial() || !base::i18n::IsRTL() || | 115 (ui::MaterialDesignController::IsModeMaterial() || |
109 !frame()->IsMaximized()) ? | 116 !RTLModeAndCaptionButtonsOnRight() || !frame()->IsMaximized()) |
110 GetLayoutInsets(AVATAR_ICON).right() : 0; | 117 ? GetLayoutInsets(AVATAR_ICON).right() |
118 : 0; | |
111 const int x = incognito_bounds_.right() + offset; | 119 const int x = incognito_bounds_.right() + offset; |
112 int end_x = width() - NonClientBorderThickness(false); | 120 int end_x = width() - ClientBorderThickness(false); |
113 if (!base::i18n::IsRTL()) { | 121 if (!RTLModeAndCaptionButtonsOnRight()) { |
114 end_x = std::min(frame()->GetMinimizeButtonOffset(), end_x) - | 122 end_x = std::min(frame()->GetMinimizeButtonOffset(), end_x) - |
115 (frame()->IsMaximized() ? | 123 (frame()->IsMaximized() ? |
116 kNewTabCaptionMaximizedSpacing : kNewTabCaptionRestoredSpacing); | 124 kNewTabCaptionMaximizedSpacing : kNewTabCaptionRestoredSpacing); |
117 | 125 |
118 // The new avatar button is optionally displayed to the left of the | 126 // The profile switcher button is optionally displayed to the left of the |
119 // minimize button. | 127 // minimize button. |
120 if (profile_switcher_.view()) { | 128 if (profile_switcher_.view()) { |
121 const int old_end_x = end_x; | 129 const int old_end_x = end_x; |
122 end_x -= profile_switcher_.view()->width() + kNewAvatarButtonOffset; | 130 end_x -= profile_switcher_.view()->width() + kProfileSwitcherButtonOffset; |
123 | 131 |
124 // In non-maximized mode, allow the new tab button to slide completely | 132 // In non-maximized mode, allow the new tab button to slide completely |
125 // under the avatar button. | 133 // under the profile switcher button. |
126 if (!frame()->IsMaximized()) { | 134 if (!frame()->IsMaximized()) { |
127 end_x = std::min(end_x + GetLayoutSize(NEW_TAB_BUTTON).width() + | 135 end_x = std::min(end_x + GetLayoutSize(NEW_TAB_BUTTON).width() + |
128 kNewTabCaptionRestoredSpacing, | 136 kNewTabCaptionRestoredSpacing, |
129 old_end_x); | 137 old_end_x); |
130 } | 138 } |
131 } | 139 } |
132 } | 140 } |
133 return gfx::Rect(x, NonClientTopBorderHeight(false), std::max(0, end_x - x), | 141 return gfx::Rect(x, NonClientTopHeight(false), std::max(0, end_x - x), |
134 tabstrip->GetPreferredSize().height()); | 142 tabstrip->GetPreferredSize().height()); |
135 } | 143 } |
136 | 144 |
137 int GlassBrowserFrameView::GetTopInset(bool restored) const { | 145 int GlassBrowserFrameView::GetTopInset(bool restored) const { |
138 return GetClientAreaInsets(restored).top(); | 146 return GetClientAreaInsets(restored).top(); |
139 } | 147 } |
140 | 148 |
141 int GlassBrowserFrameView::GetThemeBackgroundXInset() const { | 149 int GlassBrowserFrameView::GetThemeBackgroundXInset() const { |
142 return 0; | 150 return 0; |
143 } | 151 } |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
209 } | 217 } |
210 | 218 |
211 int GlassBrowserFrameView::NonClientHitTest(const gfx::Point& point) { | 219 int GlassBrowserFrameView::NonClientHitTest(const gfx::Point& point) { |
212 // If the browser isn't in normal mode, we haven't customized the frame, so | 220 // If the browser isn't in normal mode, we haven't customized the frame, so |
213 // Windows can figure this out. If the point isn't within our bounds, then | 221 // Windows can figure this out. If the point isn't within our bounds, then |
214 // it's in the native portion of the frame, so again Windows can figure it | 222 // it's in the native portion of the frame, so again Windows can figure it |
215 // out. | 223 // out. |
216 if (!browser_view()->IsBrowserTypeNormal() || !bounds().Contains(point)) | 224 if (!browser_view()->IsBrowserTypeNormal() || !bounds().Contains(point)) |
217 return HTNOWHERE; | 225 return HTNOWHERE; |
218 | 226 |
219 // See if the point is within the incognito icon or the new avatar menu. | 227 // See if the point is within the incognito icon or the profile switcher menu. |
220 if ((avatar_button() && | 228 if ((avatar_button() && |
221 avatar_button()->GetMirroredBounds().Contains(point)) || | 229 avatar_button()->GetMirroredBounds().Contains(point)) || |
222 (profile_switcher_.view() && | 230 (profile_switcher_.view() && |
223 profile_switcher_.view()->GetMirroredBounds().Contains(point))) | 231 profile_switcher_.view()->GetMirroredBounds().Contains(point))) |
224 return HTCLIENT; | 232 return HTCLIENT; |
225 | 233 |
226 int frame_component = frame()->client_view()->NonClientHitTest(point); | 234 int frame_component = frame()->client_view()->NonClientHitTest(point); |
227 | 235 |
228 // See if we're in the sysmenu region. We still have to check the tabstrip | 236 // See if we're in the sysmenu region. We still have to check the tabstrip |
229 // first so that clicks in a tab don't get treated as sysmenu clicks. | 237 // first so that clicks in a tab don't get treated as sysmenu clicks. |
230 int nonclient_border_thickness = NonClientBorderThickness(false); | 238 int client_border_thickness = ClientBorderThickness(false); |
231 if (gfx::Rect(nonclient_border_thickness, | 239 if (gfx::Rect(client_border_thickness, |
232 gfx::win::GetSystemMetricsInDIP(SM_CYSIZEFRAME), | 240 gfx::win::GetSystemMetricsInDIP(SM_CYSIZEFRAME), |
233 gfx::win::GetSystemMetricsInDIP(SM_CXSMICON), | 241 gfx::win::GetSystemMetricsInDIP(SM_CXSMICON), |
234 gfx::win::GetSystemMetricsInDIP(SM_CYSMICON)).Contains(point)) | 242 gfx::win::GetSystemMetricsInDIP(SM_CYSMICON)) |
243 .Contains(point)) | |
235 return (frame_component == HTCLIENT) ? HTCLIENT : HTSYSMENU; | 244 return (frame_component == HTCLIENT) ? HTCLIENT : HTSYSMENU; |
236 | 245 |
237 if (frame_component != HTNOWHERE) | 246 if (frame_component != HTNOWHERE) |
238 return frame_component; | 247 return frame_component; |
239 | 248 |
240 int frame_top_border_height = FrameTopBorderHeight(false); | 249 int top_border_thickness = NonClientTopBorderThickness(false); |
241 // We want the resize corner behavior to apply to the kResizeCornerWidth | 250 // We want the resize corner behavior to apply to the kResizeCornerWidth |
242 // pixels at each end of the top and bottom edges. Because |point|'s x | 251 // pixels at each end of the top and bottom edges. Because |point|'s x |
243 // coordinate is based on the DWM-inset portion of the window (so, it's 0 at | 252 // coordinate is based on the DWM-inset portion of the window (so, it's 0 at |
244 // the first pixel inside the left DWM margin), we need to subtract the DWM | 253 // the first pixel inside the left DWM margin), we need to subtract the DWM |
245 // margin thickness, which we calculate as the total frame border thickness | 254 // margin thickness, which we calculate as the total frame border thickness |
246 // minus the nonclient border thickness. | 255 // minus the nonclient border thickness. |
247 const int dwm_margin = FrameBorderThickness() - nonclient_border_thickness; | 256 const int dwm_margin = NonClientBorderThickness() - client_border_thickness; |
248 int window_component = GetHTComponentForFrame(point, frame_top_border_height, | 257 int window_component = GetHTComponentForFrame( |
249 nonclient_border_thickness, frame_top_border_height, | 258 point, top_border_thickness, client_border_thickness, |
250 kResizeCornerWidth - dwm_margin, frame()->widget_delegate()->CanResize()); | 259 top_border_thickness, kResizeCornerWidth - dwm_margin, |
260 frame()->widget_delegate()->CanResize()); | |
251 // Fall back to the caption if no other component matches. | 261 // Fall back to the caption if no other component matches. |
252 return (window_component == HTNOWHERE) ? HTCAPTION : window_component; | 262 return (window_component == HTNOWHERE) ? HTCAPTION : window_component; |
253 } | 263 } |
254 | 264 |
255 /////////////////////////////////////////////////////////////////////////////// | 265 /////////////////////////////////////////////////////////////////////////////// |
256 // GlassBrowserFrameView, views::View overrides: | 266 // GlassBrowserFrameView, views::View overrides: |
257 | 267 |
258 void GlassBrowserFrameView::OnPaint(gfx::Canvas* canvas) { | 268 void GlassBrowserFrameView::OnPaint(gfx::Canvas* canvas) { |
259 if (!browser_view()->IsTabStripVisible()) | 269 if (!browser_view()->IsTabStripVisible()) |
260 return; | 270 return; |
261 if (IsToolbarVisible()) | 271 if (IsToolbarVisible()) |
262 PaintToolbarBackground(canvas); | 272 PaintToolbarBackground(canvas); |
263 if (!frame()->IsMaximized()) | 273 if (!frame()->IsMaximized()) |
264 PaintClientEdge(canvas); | 274 PaintClientEdge(canvas); |
265 } | 275 } |
266 | 276 |
267 void GlassBrowserFrameView::Layout() { | 277 void GlassBrowserFrameView::Layout() { |
268 if (browser_view()->IsRegularOrGuestSession()) | 278 if (browser_view()->IsRegularOrGuestSession()) |
269 LayoutNewStyleAvatar(); | 279 LayoutProfileSwitcher(); |
270 LayoutIncognitoIcon(); | 280 LayoutIncognitoIcon(); |
271 LayoutClientView(); | 281 LayoutClientView(); |
272 } | 282 } |
273 | 283 |
274 /////////////////////////////////////////////////////////////////////////////// | 284 /////////////////////////////////////////////////////////////////////////////// |
275 // GlassBrowserFrameView, protected: | 285 // GlassBrowserFrameView, protected: |
276 | 286 |
277 // BrowserNonClientFrameView: | 287 // BrowserNonClientFrameView: |
278 void GlassBrowserFrameView::UpdateAvatar() { | 288 void GlassBrowserFrameView::UpdateAvatar() { |
279 if (browser_view()->IsRegularOrGuestSession()) | 289 if (browser_view()->IsRegularOrGuestSession()) |
280 profile_switcher_.Update(AvatarButtonStyle::NATIVE); | 290 profile_switcher_.Update(AvatarButtonStyle::NATIVE); |
281 else | 291 else |
282 UpdateOldAvatarButton(); | 292 UpdateOldAvatarButton(); |
283 } | 293 } |
284 | 294 |
285 /////////////////////////////////////////////////////////////////////////////// | 295 /////////////////////////////////////////////////////////////////////////////// |
286 // GlassBrowserFrameView, private: | 296 // GlassBrowserFrameView, private: |
287 | 297 |
288 // views::NonClientFrameView: | 298 // views::NonClientFrameView: |
289 bool GlassBrowserFrameView::DoesIntersectRect(const views::View* target, | 299 bool GlassBrowserFrameView::DoesIntersectRect(const views::View* target, |
290 const gfx::Rect& rect) const { | 300 const gfx::Rect& rect) const { |
291 CHECK_EQ(target, this); | 301 CHECK_EQ(target, this); |
292 bool hit_incognito_icon = avatar_button() && | 302 bool hit_incognito_icon = avatar_button() && |
293 avatar_button()->GetMirroredBounds().Intersects(rect); | 303 avatar_button()->GetMirroredBounds().Intersects(rect); |
294 bool hit_new_avatar_button = | 304 bool hit_profile_switcher_button = |
295 profile_switcher_.view() && | 305 profile_switcher_.view() && |
296 profile_switcher_.view()->GetMirroredBounds().Intersects(rect); | 306 profile_switcher_.view()->GetMirroredBounds().Intersects(rect); |
297 return hit_incognito_icon || hit_new_avatar_button || | 307 return hit_incognito_icon || hit_profile_switcher_button || |
298 !frame()->client_view()->bounds().Intersects(rect); | 308 !frame()->client_view()->bounds().Intersects(rect); |
299 } | 309 } |
300 | 310 |
301 int GlassBrowserFrameView::FrameBorderThickness() const { | 311 int GlassBrowserFrameView::ClientBorderThickness(bool restored) const { |
312 if ((frame()->IsMaximized() || frame()->IsFullscreen()) && !restored) | |
313 return 0; | |
314 | |
315 return (base::win::GetVersion() < base::win::VERSION_WIN10) | |
316 ? kClientBorderThicknessPreWin10 | |
317 : kClientBorderThicknessWin10; | |
318 } | |
319 | |
320 int GlassBrowserFrameView::NonClientBorderThickness() const { | |
302 return (frame()->IsMaximized() || frame()->IsFullscreen()) ? | 321 return (frame()->IsMaximized() || frame()->IsFullscreen()) ? |
303 0 : gfx::win::GetSystemMetricsInDIP(SM_CXSIZEFRAME); | 322 0 : gfx::win::GetSystemMetricsInDIP(SM_CXSIZEFRAME); |
304 } | 323 } |
305 | 324 |
306 int GlassBrowserFrameView::FrameTopBorderHeight(bool restored) const { | 325 int GlassBrowserFrameView::NonClientTopBorderThickness(bool restored) const { |
307 // We'd like to use FrameBorderThickness() here, but the maximized Aero glass | 326 // Distinct from NonClientBorderThickness() because Windows gives maximized |
308 // frame has a 0 frame border around most edges and a CYSIZEFRAME-thick border | 327 // windows an offscreen CYSIZEFRAME-thick region around the edges. The |
309 // at the top (see AeroGlassFrame::OnGetMinMaxInfo()). | 328 // left/right/bottom edges don't worry about this because we cancel them out |
329 // with client insets in BrowserNonClientFrameView::GetClientAreaInsets so the | |
330 // offscreen area is non-client. However because we want to push away the top | |
331 // part of the glass's gradient in Windows 7 we set the top client inset to 0. | |
332 // Thus we must compensate here to avoid having UI elements drift off the top | |
333 // of the screen. | |
Peter Kasting
2016/04/13 01:00:22
Huh. The wording here suggests that this is not a
Bret
2016/04/13 22:19:47
Oh hmm you're right, for this comment I'm mixing u
Peter Kasting
2016/04/15 00:20:51
Yeah, the opaque frame was written first, and the
Bret
2016/04/15 23:07:08
Okay I went back to what opaque was doing and call
| |
310 return (frame()->IsFullscreen() && !restored) ? | 334 return (frame()->IsFullscreen() && !restored) ? |
311 0 : gfx::win::GetSystemMetricsInDIP(SM_CYSIZEFRAME); | 335 0 : gfx::win::GetSystemMetricsInDIP(SM_CYSIZEFRAME); |
312 } | 336 } |
313 | 337 |
314 int GlassBrowserFrameView::NonClientBorderThickness(bool restored) const { | 338 int GlassBrowserFrameView::NonClientTopHeight(bool restored) const { |
315 if ((frame()->IsMaximized() || frame()->IsFullscreen()) && !restored) | |
316 return 0; | |
317 | |
318 return (base::win::GetVersion() < base::win::VERSION_WIN10) | |
319 ? kNonClientBorderThicknessPreWin10 | |
320 : kNonClientBorderThicknessWin10; | |
321 } | |
322 | |
323 int GlassBrowserFrameView::NonClientTopBorderHeight(bool restored) const { | |
324 if (frame()->IsFullscreen() && !restored) | 339 if (frame()->IsFullscreen() && !restored) |
325 return 0; | 340 return 0; |
326 | 341 |
327 const int top = FrameTopBorderHeight(restored); | 342 const int top = NonClientTopBorderThickness(restored); |
328 // The tab top inset is equal to the height of any shadow region above the | 343 // The tab top inset is equal to the height of any shadow region above the |
329 // tabs, plus a 1 px top stroke. In maximized mode, we want to push the | 344 // tabs, plus a 1 px top stroke. In maximized mode, we want to push the |
330 // shadow region off the top of the screen but leave the top stroke. | 345 // shadow region off the top of the screen but leave the top stroke. |
331 // Annoyingly, the pre-MD layout uses different heights for the hit-test | 346 // Annoyingly, the pre-MD layout uses different heights for the hit-test |
332 // exclusion region (which we want here, since we're trying to size the border | 347 // exclusion region (which we want here, since we're trying to size the border |
333 // so that the region above the tab's hit-test zone matches) versus the shadow | 348 // so that the region above the tab's hit-test zone matches) versus the shadow |
334 // thickness. | 349 // thickness. |
335 const int exclusion = GetLayoutConstant(TAB_TOP_EXCLUSION_HEIGHT); | 350 const int exclusion = GetLayoutConstant(TAB_TOP_EXCLUSION_HEIGHT); |
336 return (frame()->IsMaximized() && !restored) ? | 351 return (frame()->IsMaximized() && !restored) ? |
337 (top - GetLayoutInsets(TAB).top() + 1) : | 352 (top - GetLayoutInsets(TAB).top() + 1) : |
338 (top + kNonClientRestoredExtraThickness - exclusion); | 353 (top + kNonClientRestoredExtraThickness - exclusion); |
339 } | 354 } |
340 | 355 |
356 int GlassBrowserFrameView::CaptionButtonY() const { | |
357 // Windows draws its caption buttons at the top of the screen for maximized | |
358 // windows, and 1 px from the top of the window when restored. | |
359 return frame()->IsMaximized() ? NonClientTopBorderThickness(false) : 1; | |
360 } | |
361 | |
341 bool GlassBrowserFrameView::IsToolbarVisible() const { | 362 bool GlassBrowserFrameView::IsToolbarVisible() const { |
342 return browser_view()->IsToolbarVisible() && | 363 return browser_view()->IsToolbarVisible() && |
343 !browser_view()->toolbar()->GetPreferredSize().IsEmpty(); | 364 !browser_view()->toolbar()->GetPreferredSize().IsEmpty(); |
344 } | 365 } |
345 | 366 |
367 bool GlassBrowserFrameView::RTLModeAndCaptionButtonsOnRight() const { | |
368 return base::i18n::IsRTL(); | |
369 } | |
370 | |
346 void GlassBrowserFrameView::PaintToolbarBackground(gfx::Canvas* canvas) const { | 371 void GlassBrowserFrameView::PaintToolbarBackground(gfx::Canvas* canvas) const { |
347 gfx::Rect toolbar_bounds(browser_view()->GetToolbarBounds()); | 372 gfx::Rect toolbar_bounds(browser_view()->GetToolbarBounds()); |
348 if (toolbar_bounds.IsEmpty()) | 373 if (toolbar_bounds.IsEmpty()) |
349 return; | 374 return; |
350 gfx::Point toolbar_origin(toolbar_bounds.origin()); | 375 gfx::Point toolbar_origin(toolbar_bounds.origin()); |
351 ConvertPointToTarget(browser_view(), this, &toolbar_origin); | 376 ConvertPointToTarget(browser_view(), this, &toolbar_origin); |
352 toolbar_bounds.set_origin(toolbar_origin); | 377 toolbar_bounds.set_origin(toolbar_origin); |
353 | 378 |
354 const ui::ThemeProvider* tp = GetThemeProvider(); | 379 const ui::ThemeProvider* tp = GetThemeProvider(); |
355 const gfx::ImageSkia* const bg = tp->GetImageSkiaNamed(IDR_THEME_TOOLBAR); | 380 const gfx::ImageSkia* const bg = tp->GetImageSkiaNamed(IDR_THEME_TOOLBAR); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
442 // Pre-Material Design, the client edge images start below the toolbar. In MD | 467 // Pre-Material Design, the client edge images start below the toolbar. In MD |
443 // the client edge images start at the top of the toolbar. | 468 // the client edge images start at the top of the toolbar. |
444 gfx::Rect client_bounds = CalculateClientAreaBounds(); | 469 gfx::Rect client_bounds = CalculateClientAreaBounds(); |
445 const int x = client_bounds.x(); | 470 const int x = client_bounds.x(); |
446 const bool md = ui::MaterialDesignController::IsModeMaterial(); | 471 const bool md = ui::MaterialDesignController::IsModeMaterial(); |
447 const gfx::Rect toolbar_bounds(browser_view()->GetToolbarBounds()); | 472 const gfx::Rect toolbar_bounds(browser_view()->GetToolbarBounds()); |
448 const int y = | 473 const int y = |
449 client_bounds.y() + (md ? toolbar_bounds.y() : toolbar_bounds.bottom()); | 474 client_bounds.y() + (md ? toolbar_bounds.y() : toolbar_bounds.bottom()); |
450 const int w = client_bounds.width(); | 475 const int w = client_bounds.width(); |
451 const int right = client_bounds.right(); | 476 const int right = client_bounds.right(); |
452 const int bottom = std::max(y, height() - NonClientBorderThickness(false)); | 477 const int bottom = std::max(y, height() - ClientBorderThickness(false)); |
453 const int height = bottom - y; | 478 const int height = bottom - y; |
454 | 479 |
455 // Draw the client edge images. For non-MD, we fill the toolbar color | 480 // Draw the client edge images. For non-MD, we fill the toolbar color |
456 // underneath these images so they will lighten/darken it appropriately to | 481 // underneath these images so they will lighten/darken it appropriately to |
457 // create a "3D shaded" effect. For MD, where we want a flatter appearance, | 482 // create a "3D shaded" effect. For MD, where we want a flatter appearance, |
458 // we do the filling afterwards so the user sees the unmodified toolbar color. | 483 // we do the filling afterwards so the user sees the unmodified toolbar color. |
459 const ui::ThemeProvider* tp = GetThemeProvider(); | 484 const ui::ThemeProvider* tp = GetThemeProvider(); |
460 const SkColor toolbar_color = tp->GetColor(ThemeProperties::COLOR_TOOLBAR); | 485 const SkColor toolbar_color = tp->GetColor(ThemeProperties::COLOR_TOOLBAR); |
461 if (!md) | 486 if (!md) |
462 FillClientEdgeRects(x, y, right, bottom, toolbar_color, canvas); | 487 FillClientEdgeRects(x, y, right, bottom, toolbar_color, canvas); |
(...skipping 22 matching lines...) Expand all Loading... | |
485 gfx::Canvas* canvas) const { | 510 gfx::Canvas* canvas) const { |
486 gfx::Rect side(x - kClientEdgeThickness, y, kClientEdgeThickness, | 511 gfx::Rect side(x - kClientEdgeThickness, y, kClientEdgeThickness, |
487 bottom + kClientEdgeThickness - y); | 512 bottom + kClientEdgeThickness - y); |
488 canvas->FillRect(side, color); | 513 canvas->FillRect(side, color); |
489 canvas->FillRect(gfx::Rect(x, bottom, right - x, kClientEdgeThickness), | 514 canvas->FillRect(gfx::Rect(x, bottom, right - x, kClientEdgeThickness), |
490 color); | 515 color); |
491 side.set_x(right); | 516 side.set_x(right); |
492 canvas->FillRect(side, color); | 517 canvas->FillRect(side, color); |
493 } | 518 } |
494 | 519 |
495 void GlassBrowserFrameView::LayoutNewStyleAvatar() { | 520 void GlassBrowserFrameView::LayoutProfileSwitcher() { |
496 DCHECK(browser_view()->IsRegularOrGuestSession()); | 521 DCHECK(browser_view()->IsRegularOrGuestSession()); |
497 if (!profile_switcher_.view()) | 522 if (!profile_switcher_.view()) |
498 return; | 523 return; |
499 | 524 |
500 gfx::Size label_size = profile_switcher_.view()->GetPreferredSize(); | 525 gfx::Size label_size = profile_switcher_.view()->GetPreferredSize(); |
501 | 526 |
502 int button_x = frame()->GetMinimizeButtonOffset() - | 527 int button_x = frame()->GetMinimizeButtonOffset() - |
503 kNewAvatarButtonOffset - label_size.width(); | 528 kProfileSwitcherButtonOffset - label_size.width(); |
504 if (base::i18n::IsRTL()) | 529 if (RTLModeAndCaptionButtonsOnRight()) |
505 button_x = width() - frame()->GetMinimizeButtonOffset() + | 530 button_x = width() - frame()->GetMinimizeButtonOffset() + |
506 kNewAvatarButtonOffset; | 531 kProfileSwitcherButtonOffset; |
507 | 532 |
508 // The caption button position and size is confusing. In maximized mode, the | 533 const int button_y = CaptionButtonY(); |
509 // caption buttons are SM_CYMENUSIZE pixels high and are placed | 534 const int button_h = frame()->IsMaximized() |
510 // FrameTopBorderHeight() pixels from the top of the window; all those top | 535 ? kProfileSwitcherButtonHeightMaximized |
511 // border pixels are offscreen, so this result in caption buttons flush with | 536 : kProfileSwitcherButtonHeightRestored; |
512 // the top of the screen. In restored mode, the caption buttons are first | 537 profile_switcher_.view()->SetBounds(button_x, button_y, label_size.width(), |
513 // placed just below a 2 px border at the top of the window (which is the | 538 button_h); |
514 // first two pixels' worth of FrameTopBorderHeight()), then extended upwards | |
515 // one extra pixel to overlap part of this border. | |
516 // | |
517 // To match both of these, we size the button as if it's always the extra one | |
518 // pixel in height, then we place it at the correct position in restored mode, | |
519 // or one pixel above the top of the screen in maximized mode. | |
520 int button_y = frame()->IsMaximized() ? (FrameTopBorderHeight(false) - 1) : 1; | |
521 profile_switcher_.view()->SetBounds( | |
522 button_x, button_y, label_size.width(), | |
523 gfx::win::GetSystemMetricsInDIP(SM_CYMENUSIZE) + 1); | |
524 } | 539 } |
525 | 540 |
526 void GlassBrowserFrameView::LayoutIncognitoIcon() { | 541 void GlassBrowserFrameView::LayoutIncognitoIcon() { |
527 const bool md = ui::MaterialDesignController::IsModeMaterial(); | 542 const bool md = ui::MaterialDesignController::IsModeMaterial(); |
528 const gfx::Insets insets(GetLayoutInsets(AVATAR_ICON)); | 543 const gfx::Insets insets(GetLayoutInsets(AVATAR_ICON)); |
529 const gfx::Size size(GetOTRAvatarIcon().size()); | 544 const gfx::Size size(GetOTRAvatarIcon().size()); |
530 int x = NonClientBorderThickness(false); | 545 int x = ClientBorderThickness(false); |
531 // In RTL, the icon needs to start after the caption buttons. | 546 // In RTL, the icon needs to start after the caption buttons. |
532 if (base::i18n::IsRTL()) { | 547 if (RTLModeAndCaptionButtonsOnRight()) { |
533 x = width() - frame()->GetMinimizeButtonOffset() + | 548 x = width() - frame()->GetMinimizeButtonOffset() + |
534 (profile_switcher_.view() | 549 (profile_switcher_.view() ? (profile_switcher_.view()->width() + |
535 ? (profile_switcher_.view()->width() + kNewAvatarButtonOffset) | 550 kProfileSwitcherButtonOffset) |
536 : 0); | 551 : 0); |
537 } else if (!md && !avatar_button() && IsToolbarVisible() && | 552 } else if (!md && !avatar_button() && IsToolbarVisible() && |
538 (base::win::GetVersion() < base::win::VERSION_WIN10)) { | 553 (base::win::GetVersion() < base::win::VERSION_WIN10)) { |
539 // In non-MD before Win 10, the toolbar has a rounded corner that we don't | 554 // In non-MD before Win 10, the toolbar has a rounded corner that we don't |
540 // want the tabstrip to overlap. | 555 // want the tabstrip to overlap. |
541 x += browser_view()->GetToolbarBounds().x() - kContentEdgeShadowThickness + | 556 x += browser_view()->GetToolbarBounds().x() - kContentEdgeShadowThickness + |
542 GetThemeProvider()->GetImageSkiaNamed( | 557 GetThemeProvider()->GetImageSkiaNamed( |
543 IDR_CONTENT_TOP_LEFT_CORNER)->width(); | 558 IDR_CONTENT_TOP_LEFT_CORNER)->width(); |
544 } | 559 } |
545 const int bottom = GetTopInset(false) + browser_view()->GetTabStripHeight() - | 560 const int bottom = GetTopInset(false) + browser_view()->GetTabStripHeight() - |
546 insets.bottom(); | 561 insets.bottom(); |
547 const int y = (md || !frame()->IsMaximized()) ? | 562 const int y = (md || !frame()->IsMaximized()) |
548 (bottom - size.height()) : FrameTopBorderHeight(false); | 563 ? (bottom - size.height()) |
564 : NonClientTopBorderThickness(false); | |
549 incognito_bounds_.SetRect(x + (avatar_button() ? insets.left() : 0), y, | 565 incognito_bounds_.SetRect(x + (avatar_button() ? insets.left() : 0), y, |
550 avatar_button() ? size.width() : 0, bottom - y); | 566 avatar_button() ? size.width() : 0, bottom - y); |
551 if (avatar_button()) | 567 if (avatar_button()) |
552 avatar_button()->SetBoundsRect(incognito_bounds_); | 568 avatar_button()->SetBoundsRect(incognito_bounds_); |
553 } | 569 } |
554 | 570 |
555 void GlassBrowserFrameView::LayoutClientView() { | 571 void GlassBrowserFrameView::LayoutClientView() { |
556 client_view_bounds_ = CalculateClientAreaBounds(); | 572 client_view_bounds_ = CalculateClientAreaBounds(); |
557 } | 573 } |
558 | 574 |
559 gfx::Insets GlassBrowserFrameView::GetClientAreaInsets(bool restored) const { | 575 gfx::Insets GlassBrowserFrameView::GetClientAreaInsets(bool restored) const { |
560 if (!browser_view()->IsTabStripVisible()) | 576 if (!browser_view()->IsTabStripVisible()) |
561 return gfx::Insets(); | 577 return gfx::Insets(); |
562 | 578 |
563 const int top_height = NonClientTopBorderHeight(restored); | 579 const int top_height = NonClientTopHeight(restored); |
564 const int border_thickness = NonClientBorderThickness(restored); | 580 const int border_thickness = ClientBorderThickness(restored); |
565 return gfx::Insets(top_height, | 581 return gfx::Insets(top_height, |
566 border_thickness, | 582 border_thickness, |
567 border_thickness, | 583 border_thickness, |
568 border_thickness); | 584 border_thickness); |
569 } | 585 } |
570 | 586 |
571 gfx::Rect GlassBrowserFrameView::CalculateClientAreaBounds() const { | 587 gfx::Rect GlassBrowserFrameView::CalculateClientAreaBounds() const { |
572 gfx::Rect bounds(GetLocalBounds()); | 588 gfx::Rect bounds(GetLocalBounds()); |
573 bounds.Inset(GetClientAreaInsets(false)); | 589 bounds.Inset(GetClientAreaInsets(false)); |
574 return bounds; | 590 return bounds; |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
648 static bool initialized = false; | 664 static bool initialized = false; |
649 if (!initialized) { | 665 if (!initialized) { |
650 for (int i = 0; i < kThrobberIconCount; ++i) { | 666 for (int i = 0; i < kThrobberIconCount; ++i) { |
651 throbber_icons_[i] = | 667 throbber_icons_[i] = |
652 ui::LoadThemeIconFromResourcesDataDLL(IDI_THROBBER_01 + i); | 668 ui::LoadThemeIconFromResourcesDataDLL(IDI_THROBBER_01 + i); |
653 DCHECK(throbber_icons_[i]); | 669 DCHECK(throbber_icons_[i]); |
654 } | 670 } |
655 initialized = true; | 671 initialized = true; |
656 } | 672 } |
657 } | 673 } |
OLD | NEW |