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 "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/prefs/pref_service.h" | 8 #include "base/prefs/pref_service.h" |
9 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
10 #include "chrome/app/chrome_command_ids.h" | 10 #include "chrome/app/chrome_command_ids.h" |
11 #include "chrome/app/chrome_dll_resource.h" | 11 #include "chrome/app/chrome_dll_resource.h" |
12 #include "chrome/browser/chrome_notification_types.h" | 12 #include "chrome/browser/chrome_notification_types.h" |
13 #include "chrome/browser/profiles/profile.h" | 13 #include "chrome/browser/profiles/profile.h" |
| 14 #include "chrome/browser/profiles/profiles_state.h" |
14 #include "chrome/browser/themes/theme_properties.h" | 15 #include "chrome/browser/themes/theme_properties.h" |
15 #include "chrome/browser/ui/views/avatar_menu_button.h" | 16 #include "chrome/browser/ui/views/avatar_menu_button.h" |
16 #include "chrome/browser/ui/views/frame/browser_view.h" | 17 #include "chrome/browser/ui/views/frame/browser_view.h" |
| 18 #include "chrome/browser/ui/views/new_avatar_button.h" |
17 #include "chrome/browser/ui/views/tabs/tab.h" | 19 #include "chrome/browser/ui/views/tabs/tab.h" |
18 #include "chrome/browser/ui/views/tabs/tab_strip.h" | 20 #include "chrome/browser/ui/views/tabs/tab_strip.h" |
19 #include "chrome/common/chrome_switches.h" | 21 #include "chrome/common/chrome_switches.h" |
20 #include "chrome/common/pref_names.h" | 22 #include "chrome/common/pref_names.h" |
21 #include "content/public/browser/notification_service.h" | 23 #include "content/public/browser/notification_service.h" |
22 #include "grit/generated_resources.h" | 24 #include "grit/generated_resources.h" |
23 #include "grit/theme_resources.h" | 25 #include "grit/theme_resources.h" |
24 #include "grit/ui_resources.h" | 26 #include "grit/ui_resources.h" |
25 #include "ui/base/l10n/l10n_util.h" | 27 #include "ui/base/l10n/l10n_util.h" |
26 #include "ui/base/resource/resource_bundle_win.h" | 28 #include "ui/base/resource/resource_bundle_win.h" |
(...skipping 20 matching lines...) Expand all Loading... |
47 // 16 px at the end of the top and bottom edges triggers diagonal resizing. | 49 // 16 px at the end of the top and bottom edges triggers diagonal resizing. |
48 const int kResizeAreaCornerSize = 16; | 50 const int kResizeAreaCornerSize = 16; |
49 // The avatar ends 2 px above the bottom of the tabstrip (which, given the | 51 // The avatar ends 2 px above the bottom of the tabstrip (which, given the |
50 // way the tabstrip draws its bottom edge, will appear like a 1 px gap to the | 52 // way the tabstrip draws its bottom edge, will appear like a 1 px gap to the |
51 // user). | 53 // user). |
52 const int kAvatarBottomSpacing = 2; | 54 const int kAvatarBottomSpacing = 2; |
53 // Space between the frame border and the left edge of the avatar. | 55 // Space between the frame border and the left edge of the avatar. |
54 const int kAvatarLeftSpacing = 2; | 56 const int kAvatarLeftSpacing = 2; |
55 // Space between the right edge of the avatar and the tabstrip. | 57 // Space between the right edge of the avatar and the tabstrip. |
56 const int kAvatarRightSpacing = -2; | 58 const int kAvatarRightSpacing = -2; |
| 59 // How far the new avatar button is from the left of the minimize button. |
| 60 const int kNewAvatarButtonOffset = 5; |
57 // The content left/right images have a shadow built into them. | 61 // The content left/right images have a shadow built into them. |
58 const int kContentEdgeShadowThickness = 2; | 62 const int kContentEdgeShadowThickness = 2; |
59 // The top 3 px of the tabstrip is shadow; in maximized mode we push this off | 63 // The top 3 px of the tabstrip is shadow; in maximized mode we push this off |
60 // the top of the screen so the tabs appear flush against the screen edge. | 64 // the top of the screen so the tabs appear flush against the screen edge. |
61 const int kTabstripTopShadowThickness = 3; | 65 const int kTabstripTopShadowThickness = 3; |
62 // In restored mode, the New Tab button isn't at the same height as the caption | 66 // In restored mode, the New Tab button isn't at the same height as the caption |
63 // buttons, but the space will look cluttered if it actually slides under them, | 67 // buttons, but the space will look cluttered if it actually slides under them, |
64 // so we stop it when the gap between the two is down to 5 px. | 68 // so we stop it when the gap between the two is down to 5 px. |
65 const int kNewTabCaptionRestoredSpacing = 5; | 69 const int kNewTabCaptionRestoredSpacing = 5; |
66 // In maximized mode, where the New Tab button and the caption buttons are at | 70 // In maximized mode, where the New Tab button and the caption buttons are at |
67 // similar vertical coordinates, we need to reserve a larger, 16 px gap to avoid | 71 // similar vertical coordinates, we need to reserve a larger, 16 px gap to avoid |
68 // looking too cluttered. | 72 // looking too cluttered. |
69 const int kNewTabCaptionMaximizedSpacing = 16; | 73 const int kNewTabCaptionMaximizedSpacing = 16; |
70 // How far to indent the tabstrip from the left side of the screen when there | 74 // How far to indent the tabstrip from the left side of the screen when there |
71 // is no avatar icon. | 75 // is no avatar icon. |
72 const int kTabStripIndent = -6; | 76 const int kTabStripIndent = -6; |
73 | |
74 } // namespace | 77 } // namespace |
75 | 78 |
76 /////////////////////////////////////////////////////////////////////////////// | 79 /////////////////////////////////////////////////////////////////////////////// |
77 // GlassBrowserFrameView, public: | 80 // GlassBrowserFrameView, public: |
78 | 81 |
79 GlassBrowserFrameView::GlassBrowserFrameView(BrowserFrame* frame, | 82 GlassBrowserFrameView::GlassBrowserFrameView(BrowserFrame* frame, |
80 BrowserView* browser_view) | 83 BrowserView* browser_view) |
81 : BrowserNonClientFrameView(frame, browser_view), | 84 : BrowserNonClientFrameView(frame, browser_view), |
82 throbber_running_(false), | 85 throbber_running_(false), |
83 throbber_frame_(0) { | 86 throbber_frame_(0) { |
84 if (browser_view->ShouldShowWindowIcon()) | 87 if (browser_view->ShouldShowWindowIcon()) |
85 InitThrobberIcons(); | 88 InitThrobberIcons(); |
86 | 89 |
87 UpdateAvatarInfo(); | 90 bool is_incognito = browser_view->IsOffTheRecord() && |
| 91 !browser_view->IsGuestSession(); |
| 92 if (!is_incognito && profiles::IsNewProfileManagementEnabled()) |
| 93 UpdateNewStyleAvatarInfo(); |
| 94 else |
| 95 UpdateAvatarInfo(); |
| 96 |
88 if (!browser_view->IsOffTheRecord()) { | 97 if (!browser_view->IsOffTheRecord()) { |
89 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, | 98 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, |
90 content::NotificationService::AllSources()); | 99 content::NotificationService::AllSources()); |
91 } | 100 } |
92 } | 101 } |
93 | 102 |
94 GlassBrowserFrameView::~GlassBrowserFrameView() { | 103 GlassBrowserFrameView::~GlassBrowserFrameView() { |
95 } | 104 } |
96 | 105 |
97 /////////////////////////////////////////////////////////////////////////////// | 106 /////////////////////////////////////////////////////////////////////////////// |
98 // GlassBrowserFrameView, BrowserNonClientFrameView implementation: | 107 // GlassBrowserFrameView, BrowserNonClientFrameView implementation: |
99 | 108 |
100 gfx::Rect GlassBrowserFrameView::GetBoundsForTabStrip( | 109 gfx::Rect GlassBrowserFrameView::GetBoundsForTabStrip( |
101 views::View* tabstrip) const { | 110 views::View* tabstrip) const { |
102 int minimize_button_offset = | 111 int minimize_button_offset = |
103 std::min(frame()->GetMinimizeButtonOffset(), width()); | 112 std::min(frame()->GetMinimizeButtonOffset(), width()); |
| 113 |
| 114 // The new avatar button is optionally displayed to the left of the |
| 115 // minimize button. |
| 116 if (browser_view()->ShouldShowAvatar() && new_avatar_button()) |
| 117 minimize_button_offset -= new_avatar_button()->width(); |
| 118 |
104 int tabstrip_x = browser_view()->ShouldShowAvatar() ? | 119 int tabstrip_x = browser_view()->ShouldShowAvatar() ? |
105 (avatar_bounds_.right() + kAvatarRightSpacing) : | 120 (avatar_bounds_.right() + kAvatarRightSpacing) : |
106 NonClientBorderThickness() + kTabStripIndent; | 121 NonClientBorderThickness() + kTabStripIndent; |
107 // In RTL languages, we have moved an avatar icon left by the size of window | 122 // In RTL languages, we have moved an avatar icon left by the size of window |
108 // controls to prevent it from being rendered over them. So, we use its x | 123 // controls to prevent it from being rendered over them. So, we use its x |
109 // position to move this tab strip left when maximized. Also, we can render | 124 // position to move this tab strip left when maximized. Also, we can render |
110 // a tab strip until the left end of this window without considering the size | 125 // a tab strip until the left end of this window without considering the size |
111 // of window controls in RTL languages. | 126 // of window controls in RTL languages. |
112 if (base::i18n::IsRTL()) { | 127 if (base::i18n::IsRTL()) { |
113 if (!browser_view()->ShouldShowAvatar() && frame()->IsMaximized()) | 128 if (!browser_view()->ShouldShowAvatar() && frame()->IsMaximized()) |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 // it's in the native portion of the frame, so again Windows can figure it | 215 // it's in the native portion of the frame, so again Windows can figure it |
201 // out. | 216 // out. |
202 if (!browser_view()->IsBrowserTypeNormal() || !bounds().Contains(point)) | 217 if (!browser_view()->IsBrowserTypeNormal() || !bounds().Contains(point)) |
203 return HTNOWHERE; | 218 return HTNOWHERE; |
204 | 219 |
205 // See if the point is within the avatar menu button or within the avatar | 220 // See if the point is within the avatar menu button or within the avatar |
206 // label. | 221 // label. |
207 if (avatar_button() && avatar_button()->GetMirroredBounds().Contains(point)) | 222 if (avatar_button() && avatar_button()->GetMirroredBounds().Contains(point)) |
208 return HTCLIENT; | 223 return HTCLIENT; |
209 | 224 |
| 225 if (new_avatar_button() && |
| 226 new_avatar_button()->GetMirroredBounds().Contains(point)) |
| 227 return HTCLIENT; |
| 228 |
210 int frame_component = frame()->client_view()->NonClientHitTest(point); | 229 int frame_component = frame()->client_view()->NonClientHitTest(point); |
211 | 230 |
212 // See if we're in the sysmenu region. We still have to check the tabstrip | 231 // See if we're in the sysmenu region. We still have to check the tabstrip |
213 // first so that clicks in a tab don't get treated as sysmenu clicks. | 232 // first so that clicks in a tab don't get treated as sysmenu clicks. |
214 int nonclient_border_thickness = NonClientBorderThickness(); | 233 int nonclient_border_thickness = NonClientBorderThickness(); |
215 if (gfx::Rect(nonclient_border_thickness, GetSystemMetrics(SM_CXSIZEFRAME), | 234 if (gfx::Rect(nonclient_border_thickness, GetSystemMetrics(SM_CXSIZEFRAME), |
216 GetSystemMetrics(SM_CXSMICON), | 235 GetSystemMetrics(SM_CXSMICON), |
217 GetSystemMetrics(SM_CYSMICON)).Contains(point)) | 236 GetSystemMetrics(SM_CYSMICON)).Contains(point)) |
218 return (frame_component == HTCLIENT) ? HTCLIENT : HTSYSMENU; | 237 return (frame_component == HTCLIENT) ? HTCLIENT : HTSYSMENU; |
219 | 238 |
(...skipping 15 matching lines...) Expand all Loading... |
235 void GlassBrowserFrameView::OnPaint(gfx::Canvas* canvas) { | 254 void GlassBrowserFrameView::OnPaint(gfx::Canvas* canvas) { |
236 if (!browser_view()->IsTabStripVisible()) | 255 if (!browser_view()->IsTabStripVisible()) |
237 return; // Nothing is visible, so don't bother to paint. | 256 return; // Nothing is visible, so don't bother to paint. |
238 | 257 |
239 PaintToolbarBackground(canvas); | 258 PaintToolbarBackground(canvas); |
240 if (!frame()->IsMaximized()) | 259 if (!frame()->IsMaximized()) |
241 PaintRestoredClientEdge(canvas); | 260 PaintRestoredClientEdge(canvas); |
242 } | 261 } |
243 | 262 |
244 void GlassBrowserFrameView::Layout() { | 263 void GlassBrowserFrameView::Layout() { |
245 LayoutAvatar(); | 264 bool is_incognito = browser_view()->IsOffTheRecord() && |
| 265 !browser_view()->IsGuestSession(); |
| 266 |
| 267 if (!is_incognito && profiles::IsNewProfileManagementEnabled()) |
| 268 LayoutNewStyleAvatar(); |
| 269 else |
| 270 LayoutAvatar(); |
| 271 |
246 LayoutClientView(); | 272 LayoutClientView(); |
247 } | 273 } |
248 | 274 |
249 bool GlassBrowserFrameView::HitTestRect(const gfx::Rect& rect) const { | 275 bool GlassBrowserFrameView::HitTestRect(const gfx::Rect& rect) const { |
250 return (avatar_button() && | 276 bool hit_avatar_button = avatar_button() && |
251 avatar_button()->GetMirroredBounds().Intersects(rect)) || | 277 avatar_button()->GetMirroredBounds().Intersects(rect); |
252 !frame()->client_view()->bounds().Intersects(rect); | 278 bool hit_new_avatar_button = new_avatar_button() && |
| 279 new_avatar_button()->GetMirroredBounds().Intersects(rect); |
| 280 return hit_avatar_button || hit_new_avatar_button || |
| 281 !frame()->client_view()->bounds().Intersects(rect); |
253 } | 282 } |
254 | 283 |
255 /////////////////////////////////////////////////////////////////////////////// | 284 /////////////////////////////////////////////////////////////////////////////// |
256 // GlassBrowserFrameView, private: | 285 // GlassBrowserFrameView, private: |
257 | 286 |
258 int GlassBrowserFrameView::FrameBorderThickness() const { | 287 int GlassBrowserFrameView::FrameBorderThickness() const { |
259 return (frame()->IsMaximized() || frame()->IsFullscreen()) ? | 288 return (frame()->IsMaximized() || frame()->IsFullscreen()) ? |
260 0 : GetSystemMetrics(SM_CXSIZEFRAME); | 289 0 : GetSystemMetrics(SM_CXSIZEFRAME); |
261 } | 290 } |
262 | 291 |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 toolbar_color); | 419 toolbar_color); |
391 canvas->FillRect(gfx::Rect(client_area_bounds.x(), client_area_bottom, | 420 canvas->FillRect(gfx::Rect(client_area_bounds.x(), client_area_bottom, |
392 client_area_bounds.width(), kClientEdgeThickness), | 421 client_area_bounds.width(), kClientEdgeThickness), |
393 toolbar_color); | 422 toolbar_color); |
394 canvas->FillRect(gfx::Rect(client_area_bounds.right(), client_area_top, | 423 canvas->FillRect(gfx::Rect(client_area_bounds.right(), client_area_top, |
395 kClientEdgeThickness, | 424 kClientEdgeThickness, |
396 client_area_bottom + kClientEdgeThickness - client_area_top), | 425 client_area_bottom + kClientEdgeThickness - client_area_top), |
397 toolbar_color); | 426 toolbar_color); |
398 } | 427 } |
399 | 428 |
| 429 void GlassBrowserFrameView::LayoutNewStyleAvatar() { |
| 430 gfx::Size label_size = new_avatar_button()->GetPreferredSize(); |
| 431 int x_position = frame()->GetMinimizeButtonOffset() - |
| 432 label_size.width() - kNewAvatarButtonOffset; |
| 433 |
| 434 int caption_y = frame()->IsMaximized() ? NonClientTopBorderHeight(false) : 1; |
| 435 new_avatar_button()->SetBounds( |
| 436 x_position, |
| 437 caption_y, |
| 438 label_size.width(), |
| 439 caption_y + gfx::win::GetSystemMetricsInDIP(SM_CXMENUSIZE)); |
| 440 } |
| 441 |
400 void GlassBrowserFrameView::LayoutAvatar() { | 442 void GlassBrowserFrameView::LayoutAvatar() { |
401 // Even though the avatar is used for both incognito and profiles we always | 443 // Even though the avatar is used for both incognito and profiles we always |
402 // use the incognito icon to layout the avatar button. The profile icon | 444 // use the incognito icon to layout the avatar button. The profile icon |
403 // can be customized so we can't depend on its size to perform layout. | 445 // can be customized so we can't depend on its size to perform layout. |
404 gfx::ImageSkia incognito_icon = browser_view()->GetOTRAvatarIcon(); | 446 gfx::ImageSkia incognito_icon = browser_view()->GetOTRAvatarIcon(); |
405 | 447 |
406 int avatar_x = NonClientBorderThickness() + kAvatarLeftSpacing; | 448 int avatar_x = NonClientBorderThickness() + kAvatarLeftSpacing; |
407 // Move this avatar icon by the size of window controls to prevent it from | 449 // Move this avatar icon by the size of window controls to prevent it from |
408 // being rendered over them in RTL languages. This code also needs to adjust | 450 // being rendered over them in RTL languages. This code also needs to adjust |
409 // the width of a tab strip to avoid decreasing this size twice. (See the | 451 // the width of a tab strip to avoid decreasing this size twice. (See the |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
489 throbber_frame_ = (throbber_frame_ + 1) % kThrobberIconCount; | 531 throbber_frame_ = (throbber_frame_ + 1) % kThrobberIconCount; |
490 SendMessage(views::HWNDForWidget(frame()), WM_SETICON, | 532 SendMessage(views::HWNDForWidget(frame()), WM_SETICON, |
491 static_cast<WPARAM>(ICON_SMALL), | 533 static_cast<WPARAM>(ICON_SMALL), |
492 reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_])); | 534 reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_])); |
493 } | 535 } |
494 | 536 |
495 void GlassBrowserFrameView::Observe( | 537 void GlassBrowserFrameView::Observe( |
496 int type, | 538 int type, |
497 const content::NotificationSource& source, | 539 const content::NotificationSource& source, |
498 const content::NotificationDetails& details) { | 540 const content::NotificationDetails& details) { |
| 541 bool is_incognito = browser_view()->IsOffTheRecord() && |
| 542 !browser_view()->IsGuestSession(); |
499 switch (type) { | 543 switch (type) { |
500 case chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED: | 544 case chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED: |
501 UpdateAvatarInfo(); | 545 if (!is_incognito && profiles::IsNewProfileManagementEnabled()) |
| 546 UpdateNewStyleAvatarInfo(); |
| 547 else |
| 548 UpdateAvatarInfo(); |
502 break; | 549 break; |
503 default: | 550 default: |
504 NOTREACHED() << "Got a notification we didn't register for!"; | 551 NOTREACHED() << "Got a notification we didn't register for!"; |
505 break; | 552 break; |
506 } | 553 } |
507 } | 554 } |
508 | 555 |
509 // static | 556 // static |
510 void GlassBrowserFrameView::InitThrobberIcons() { | 557 void GlassBrowserFrameView::InitThrobberIcons() { |
511 static bool initialized = false; | 558 static bool initialized = false; |
512 if (!initialized) { | 559 if (!initialized) { |
513 for (int i = 0; i < kThrobberIconCount; ++i) { | 560 for (int i = 0; i < kThrobberIconCount; ++i) { |
514 throbber_icons_[i] = | 561 throbber_icons_[i] = |
515 ui::LoadThemeIconFromResourcesDataDLL(IDI_THROBBER_01 + i); | 562 ui::LoadThemeIconFromResourcesDataDLL(IDI_THROBBER_01 + i); |
516 DCHECK(throbber_icons_[i]); | 563 DCHECK(throbber_icons_[i]); |
517 } | 564 } |
518 initialized = true; | 565 initialized = true; |
519 } | 566 } |
520 } | 567 } |
OLD | NEW |