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/browser/ui/views/toolbar_view.h" | 21 #include "chrome/browser/ui/views/toolbar_view.h" |
20 #include "chrome/common/chrome_switches.h" | 22 #include "chrome/common/chrome_switches.h" |
21 #include "chrome/common/pref_names.h" | 23 #include "chrome/common/pref_names.h" |
22 #include "content/public/browser/notification_service.h" | 24 #include "content/public/browser/notification_service.h" |
23 #include "grit/generated_resources.h" | 25 #include "grit/generated_resources.h" |
24 #include "grit/theme_resources.h" | 26 #include "grit/theme_resources.h" |
25 #include "grit/ui_resources.h" | 27 #include "grit/ui_resources.h" |
26 #include "ui/base/l10n/l10n_util.h" | 28 #include "ui/base/l10n/l10n_util.h" |
(...skipping 21 matching lines...) Expand all Loading... |
48 // 16 px at the end of the top and bottom edges triggers diagonal resizing. | 50 // 16 px at the end of the top and bottom edges triggers diagonal resizing. |
49 const int kResizeAreaCornerSize = 16; | 51 const int kResizeAreaCornerSize = 16; |
50 // The avatar ends 2 px above the bottom of the tabstrip (which, given the | 52 // The avatar ends 2 px above the bottom of the tabstrip (which, given the |
51 // way the tabstrip draws its bottom edge, will appear like a 1 px gap to the | 53 // way the tabstrip draws its bottom edge, will appear like a 1 px gap to the |
52 // user). | 54 // user). |
53 const int kAvatarBottomSpacing = 2; | 55 const int kAvatarBottomSpacing = 2; |
54 // Space between the frame border and the left edge of the avatar. | 56 // Space between the frame border and the left edge of the avatar. |
55 const int kAvatarLeftSpacing = 2; | 57 const int kAvatarLeftSpacing = 2; |
56 // Space between the right edge of the avatar and the tabstrip. | 58 // Space between the right edge of the avatar and the tabstrip. |
57 const int kAvatarRightSpacing = -2; | 59 const int kAvatarRightSpacing = -2; |
| 60 // How far the new avatar button is from the left of the minimize button. |
| 61 const int kNewAvatarButtonOffset = 5; |
58 // The content left/right images have a shadow built into them. | 62 // The content left/right images have a shadow built into them. |
59 const int kContentEdgeShadowThickness = 2; | 63 const int kContentEdgeShadowThickness = 2; |
60 // The top 3 px of the tabstrip is shadow; in maximized mode we push this off | 64 // The top 3 px of the tabstrip is shadow; in maximized mode we push this off |
61 // the top of the screen so the tabs appear flush against the screen edge. | 65 // the top of the screen so the tabs appear flush against the screen edge. |
62 const int kTabstripTopShadowThickness = 3; | 66 const int kTabstripTopShadowThickness = 3; |
63 // In restored mode, the New Tab button isn't at the same height as the caption | 67 // In restored mode, the New Tab button isn't at the same height as the caption |
64 // buttons, but the space will look cluttered if it actually slides under them, | 68 // buttons, but the space will look cluttered if it actually slides under them, |
65 // so we stop it when the gap between the two is down to 5 px. | 69 // so we stop it when the gap between the two is down to 5 px. |
66 const int kNewTabCaptionRestoredSpacing = 5; | 70 const int kNewTabCaptionRestoredSpacing = 5; |
67 // In maximized mode, where the New Tab button and the caption buttons are at | 71 // In maximized mode, where the New Tab button and the caption buttons are at |
(...skipping 10 matching lines...) Expand all Loading... |
78 // GlassBrowserFrameView, public: | 82 // GlassBrowserFrameView, public: |
79 | 83 |
80 GlassBrowserFrameView::GlassBrowserFrameView(BrowserFrame* frame, | 84 GlassBrowserFrameView::GlassBrowserFrameView(BrowserFrame* frame, |
81 BrowserView* browser_view) | 85 BrowserView* browser_view) |
82 : BrowserNonClientFrameView(frame, browser_view), | 86 : BrowserNonClientFrameView(frame, browser_view), |
83 throbber_running_(false), | 87 throbber_running_(false), |
84 throbber_frame_(0) { | 88 throbber_frame_(0) { |
85 if (browser_view->ShouldShowWindowIcon()) | 89 if (browser_view->ShouldShowWindowIcon()) |
86 InitThrobberIcons(); | 90 InitThrobberIcons(); |
87 | 91 |
88 UpdateAvatarInfo(); | 92 if (browser_view->IsRegularOrGuestSession() && |
| 93 profiles::IsNewProfileManagementEnabled()) |
| 94 UpdateNewStyleAvatarInfo(this, NewAvatarButton::GLASS_BUTTON); |
| 95 else |
| 96 UpdateAvatarInfo(); |
| 97 |
89 if (!browser_view->IsOffTheRecord()) { | 98 if (!browser_view->IsOffTheRecord()) { |
90 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, | 99 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, |
91 content::NotificationService::AllSources()); | 100 content::NotificationService::AllSources()); |
92 } | 101 } |
93 } | 102 } |
94 | 103 |
95 GlassBrowserFrameView::~GlassBrowserFrameView() { | 104 GlassBrowserFrameView::~GlassBrowserFrameView() { |
96 } | 105 } |
97 | 106 |
98 /////////////////////////////////////////////////////////////////////////////// | 107 /////////////////////////////////////////////////////////////////////////////// |
99 // GlassBrowserFrameView, BrowserNonClientFrameView implementation: | 108 // GlassBrowserFrameView, BrowserNonClientFrameView implementation: |
100 | 109 |
101 gfx::Rect GlassBrowserFrameView::GetBoundsForTabStrip( | 110 gfx::Rect GlassBrowserFrameView::GetBoundsForTabStrip( |
102 views::View* tabstrip) const { | 111 views::View* tabstrip) const { |
103 int minimize_button_offset = | 112 int minimize_button_offset = |
104 std::min(frame()->GetMinimizeButtonOffset(), width()); | 113 std::min(frame()->GetMinimizeButtonOffset(), width()); |
| 114 |
| 115 // The new avatar button is optionally displayed to the left of the |
| 116 // minimize button. |
| 117 if (browser_view()->ShouldShowAvatar() && new_avatar_button()) |
| 118 minimize_button_offset -= new_avatar_button()->width(); |
| 119 |
105 int tabstrip_x = browser_view()->ShouldShowAvatar() ? | 120 int tabstrip_x = browser_view()->ShouldShowAvatar() ? |
106 (avatar_bounds_.right() + kAvatarRightSpacing) : | 121 (avatar_bounds_.right() + kAvatarRightSpacing) : |
107 NonClientBorderThickness() + kTabStripIndent; | 122 NonClientBorderThickness() + kTabStripIndent; |
108 // In RTL languages, we have moved an avatar icon left by the size of window | 123 // In RTL languages, we have moved an avatar icon left by the size of window |
109 // controls to prevent it from being rendered over them. So, we use its x | 124 // controls to prevent it from being rendered over them. So, we use its x |
110 // position to move this tab strip left when maximized. Also, we can render | 125 // position to move this tab strip left when maximized. Also, we can render |
111 // a tab strip until the left end of this window without considering the size | 126 // a tab strip until the left end of this window without considering the size |
112 // of window controls in RTL languages. | 127 // of window controls in RTL languages. |
113 if (base::i18n::IsRTL()) { | 128 if (base::i18n::IsRTL()) { |
114 if (!browser_view()->ShouldShowAvatar() && frame()->IsMaximized()) | 129 if (!browser_view()->ShouldShowAvatar() && frame()->IsMaximized()) |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 // it's in the native portion of the frame, so again Windows can figure it | 218 // it's in the native portion of the frame, so again Windows can figure it |
204 // out. | 219 // out. |
205 if (!browser_view()->IsBrowserTypeNormal() || !bounds().Contains(point)) | 220 if (!browser_view()->IsBrowserTypeNormal() || !bounds().Contains(point)) |
206 return HTNOWHERE; | 221 return HTNOWHERE; |
207 | 222 |
208 // See if the point is within the avatar menu button or within the avatar | 223 // See if the point is within the avatar menu button or within the avatar |
209 // label. | 224 // label. |
210 if (avatar_button() && avatar_button()->GetMirroredBounds().Contains(point)) | 225 if (avatar_button() && avatar_button()->GetMirroredBounds().Contains(point)) |
211 return HTCLIENT; | 226 return HTCLIENT; |
212 | 227 |
| 228 if (new_avatar_button() && |
| 229 new_avatar_button()->GetMirroredBounds().Contains(point)) |
| 230 return HTCLIENT; |
| 231 |
213 int frame_component = frame()->client_view()->NonClientHitTest(point); | 232 int frame_component = frame()->client_view()->NonClientHitTest(point); |
214 | 233 |
215 // See if we're in the sysmenu region. We still have to check the tabstrip | 234 // See if we're in the sysmenu region. We still have to check the tabstrip |
216 // first so that clicks in a tab don't get treated as sysmenu clicks. | 235 // first so that clicks in a tab don't get treated as sysmenu clicks. |
217 int nonclient_border_thickness = NonClientBorderThickness(); | 236 int nonclient_border_thickness = NonClientBorderThickness(); |
218 if (gfx::Rect(nonclient_border_thickness, GetSystemMetrics(SM_CXSIZEFRAME), | 237 if (gfx::Rect(nonclient_border_thickness, GetSystemMetrics(SM_CXSIZEFRAME), |
219 GetSystemMetrics(SM_CXSMICON), | 238 GetSystemMetrics(SM_CXSMICON), |
220 GetSystemMetrics(SM_CYSMICON)).Contains(point)) | 239 GetSystemMetrics(SM_CYSMICON)).Contains(point)) |
221 return (frame_component == HTCLIENT) ? HTCLIENT : HTSYSMENU; | 240 return (frame_component == HTCLIENT) ? HTCLIENT : HTSYSMENU; |
222 | 241 |
(...skipping 14 matching lines...) Expand all Loading... |
237 | 256 |
238 void GlassBrowserFrameView::OnPaint(gfx::Canvas* canvas) { | 257 void GlassBrowserFrameView::OnPaint(gfx::Canvas* canvas) { |
239 if (browser_view()->IsToolbarVisible() && | 258 if (browser_view()->IsToolbarVisible() && |
240 browser_view()->toolbar()->ShouldPaintBackground()) | 259 browser_view()->toolbar()->ShouldPaintBackground()) |
241 PaintToolbarBackground(canvas); | 260 PaintToolbarBackground(canvas); |
242 if (!frame()->IsMaximized()) | 261 if (!frame()->IsMaximized()) |
243 PaintRestoredClientEdge(canvas); | 262 PaintRestoredClientEdge(canvas); |
244 } | 263 } |
245 | 264 |
246 void GlassBrowserFrameView::Layout() { | 265 void GlassBrowserFrameView::Layout() { |
247 LayoutAvatar(); | 266 if (browser_view()->ShouldShowAvatar()) { |
| 267 if (browser_view()->IsRegularOrGuestSession() && |
| 268 profiles::IsNewProfileManagementEnabled()) |
| 269 LayoutNewStyleAvatar(); |
| 270 else |
| 271 LayoutAvatar(); |
| 272 } |
| 273 |
248 LayoutClientView(); | 274 LayoutClientView(); |
249 } | 275 } |
250 | 276 |
251 bool GlassBrowserFrameView::HitTestRect(const gfx::Rect& rect) const { | 277 bool GlassBrowserFrameView::HitTestRect(const gfx::Rect& rect) const { |
252 return (avatar_button() && | 278 bool hit_avatar_button = avatar_button() && |
253 avatar_button()->GetMirroredBounds().Intersects(rect)) || | 279 avatar_button()->GetMirroredBounds().Intersects(rect); |
254 !frame()->client_view()->bounds().Intersects(rect); | 280 bool hit_new_avatar_button = new_avatar_button() && |
| 281 new_avatar_button()->GetMirroredBounds().Intersects(rect); |
| 282 return hit_avatar_button || hit_new_avatar_button || |
| 283 !frame()->client_view()->bounds().Intersects(rect); |
255 } | 284 } |
256 | 285 |
257 /////////////////////////////////////////////////////////////////////////////// | 286 /////////////////////////////////////////////////////////////////////////////// |
| 287 // GlassBrowserFrameView, views::ButtonListener overrides: |
| 288 void GlassBrowserFrameView::ButtonPressed(views::Button* sender, |
| 289 const ui::Event& event) { |
| 290 if (sender == new_avatar_button()) |
| 291 ShowProfileChooserViewBubble(); |
| 292 } |
| 293 |
| 294 /////////////////////////////////////////////////////////////////////////////// |
258 // GlassBrowserFrameView, private: | 295 // GlassBrowserFrameView, private: |
259 | 296 |
260 int GlassBrowserFrameView::FrameBorderThickness() const { | 297 int GlassBrowserFrameView::FrameBorderThickness() const { |
261 return (frame()->IsMaximized() || frame()->IsFullscreen()) ? | 298 return (frame()->IsMaximized() || frame()->IsFullscreen()) ? |
262 0 : GetSystemMetrics(SM_CXSIZEFRAME); | 299 0 : GetSystemMetrics(SM_CXSIZEFRAME); |
263 } | 300 } |
264 | 301 |
265 int GlassBrowserFrameView::NonClientBorderThickness() const { | 302 int GlassBrowserFrameView::NonClientBorderThickness() const { |
266 if (frame()->IsMaximized() || frame()->IsFullscreen()) | 303 if (frame()->IsMaximized() || frame()->IsFullscreen()) |
267 return 0; | 304 return 0; |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
396 toolbar_color); | 433 toolbar_color); |
397 canvas->FillRect(gfx::Rect(client_area_bounds.x(), client_area_bottom, | 434 canvas->FillRect(gfx::Rect(client_area_bounds.x(), client_area_bottom, |
398 client_area_bounds.width(), kClientEdgeThickness), | 435 client_area_bounds.width(), kClientEdgeThickness), |
399 toolbar_color); | 436 toolbar_color); |
400 canvas->FillRect(gfx::Rect(client_area_bounds.right(), client_area_top, | 437 canvas->FillRect(gfx::Rect(client_area_bounds.right(), client_area_top, |
401 kClientEdgeThickness, | 438 kClientEdgeThickness, |
402 client_area_bottom + kClientEdgeThickness - client_area_top), | 439 client_area_bottom + kClientEdgeThickness - client_area_top), |
403 toolbar_color); | 440 toolbar_color); |
404 } | 441 } |
405 | 442 |
| 443 void GlassBrowserFrameView::LayoutNewStyleAvatar() { |
| 444 if (!new_avatar_button()) |
| 445 return; |
| 446 |
| 447 gfx::Size label_size = new_avatar_button()->GetPreferredSize(); |
| 448 int button_size_with_offset = kNewAvatarButtonOffset + label_size.width(); |
| 449 |
| 450 int button_x = frame()->GetMinimizeButtonOffset() - |
| 451 kNewAvatarButtonOffset - label_size.width(); |
| 452 |
| 453 if (base::i18n::IsRTL()) |
| 454 button_x = width() - frame()->GetMinimizeButtonOffset() + |
| 455 kNewAvatarButtonOffset; |
| 456 |
| 457 int button_y = frame()->IsMaximized() ? NonClientTopBorderHeight(false) : 1; |
| 458 new_avatar_button()->SetBounds( |
| 459 button_x, |
| 460 button_y, |
| 461 label_size.width(), |
| 462 button_y + gfx::win::GetSystemMetricsInDIP(SM_CXMENUSIZE)); |
| 463 } |
| 464 |
406 void GlassBrowserFrameView::LayoutAvatar() { | 465 void GlassBrowserFrameView::LayoutAvatar() { |
407 // Even though the avatar is used for both incognito and profiles we always | 466 // Even though the avatar is used for both incognito and profiles we always |
408 // use the incognito icon to layout the avatar button. The profile icon | 467 // use the incognito icon to layout the avatar button. The profile icon |
409 // can be customized so we can't depend on its size to perform layout. | 468 // can be customized so we can't depend on its size to perform layout. |
410 gfx::ImageSkia incognito_icon = browser_view()->GetOTRAvatarIcon(); | 469 gfx::ImageSkia incognito_icon = browser_view()->GetOTRAvatarIcon(); |
411 | 470 |
412 int avatar_x = NonClientBorderThickness() + kAvatarLeftSpacing; | 471 int avatar_x = NonClientBorderThickness() + kAvatarLeftSpacing; |
413 // Move this avatar icon by the size of window controls to prevent it from | 472 // Move this avatar icon by the size of window controls to prevent it from |
414 // being rendered over them in RTL languages. This code also needs to adjust | 473 // being rendered over them in RTL languages. This code also needs to adjust |
415 // the width of a tab strip to avoid decreasing this size twice. (See the | 474 // the width of a tab strip to avoid decreasing this size twice. (See the |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
497 static_cast<WPARAM>(ICON_SMALL), | 556 static_cast<WPARAM>(ICON_SMALL), |
498 reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_])); | 557 reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_])); |
499 } | 558 } |
500 | 559 |
501 void GlassBrowserFrameView::Observe( | 560 void GlassBrowserFrameView::Observe( |
502 int type, | 561 int type, |
503 const content::NotificationSource& source, | 562 const content::NotificationSource& source, |
504 const content::NotificationDetails& details) { | 563 const content::NotificationDetails& details) { |
505 switch (type) { | 564 switch (type) { |
506 case chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED: | 565 case chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED: |
507 UpdateAvatarInfo(); | 566 if (browser_view()->IsRegularOrGuestSession() && |
| 567 profiles::IsNewProfileManagementEnabled()) |
| 568 UpdateNewStyleAvatarInfo(this, NewAvatarButton::GLASS_BUTTON); |
| 569 else |
| 570 UpdateAvatarInfo(); |
508 break; | 571 break; |
509 default: | 572 default: |
510 NOTREACHED() << "Got a notification we didn't register for!"; | 573 NOTREACHED() << "Got a notification we didn't register for!"; |
511 break; | 574 break; |
512 } | 575 } |
513 } | 576 } |
514 | 577 |
515 // static | 578 // static |
516 void GlassBrowserFrameView::InitThrobberIcons() { | 579 void GlassBrowserFrameView::InitThrobberIcons() { |
517 static bool initialized = false; | 580 static bool initialized = false; |
518 if (!initialized) { | 581 if (!initialized) { |
519 for (int i = 0; i < kThrobberIconCount; ++i) { | 582 for (int i = 0; i < kThrobberIconCount; ++i) { |
520 throbber_icons_[i] = | 583 throbber_icons_[i] = |
521 ui::LoadThemeIconFromResourcesDataDLL(IDI_THROBBER_01 + i); | 584 ui::LoadThemeIconFromResourcesDataDLL(IDI_THROBBER_01 + i); |
522 DCHECK(throbber_icons_[i]); | 585 DCHECK(throbber_icons_[i]); |
523 } | 586 } |
524 initialized = true; | 587 initialized = true; |
525 } | 588 } |
526 } | 589 } |
OLD | NEW |