OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/opaque_browser_frame_view.h" | 5 #include "chrome/browser/ui/views/frame/opaque_browser_frame_view.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
10 #include "chrome/browser/prefs/pref_service.h" | 10 #include "chrome/browser/prefs/pref_service.h" |
11 #include "chrome/browser/profiles/profile.h" | 11 #include "chrome/browser/profiles/profile.h" |
12 #include "chrome/browser/themes/theme_service.h" | 12 #include "chrome/browser/themes/theme_service.h" |
13 #include "chrome/browser/ui/profile_menu_model.h" | |
14 #include "chrome/browser/ui/views/avatar_menu_button.h" | |
15 #include "chrome/browser/ui/views/frame/browser_frame.h" | 13 #include "chrome/browser/ui/views/frame/browser_frame.h" |
16 #include "chrome/browser/ui/views/frame/browser_view.h" | 14 #include "chrome/browser/ui/views/frame/browser_view.h" |
| 15 #include "chrome/browser/ui/views/profile_menu_button.h" |
| 16 #include "chrome/browser/ui/views/profile_tag_view.h" |
17 #include "chrome/browser/ui/views/tabs/tab_strip.h" | 17 #include "chrome/browser/ui/views/tabs/tab_strip.h" |
18 #include "chrome/browser/ui/views/toolbar_view.h" | 18 #include "chrome/browser/ui/views/toolbar_view.h" |
19 #include "chrome/common/chrome_switches.h" | 19 #include "chrome/common/chrome_switches.h" |
20 #include "chrome/common/pref_names.h" | 20 #include "chrome/common/pref_names.h" |
21 #include "content/browser/tab_contents/tab_contents.h" | 21 #include "content/browser/tab_contents/tab_contents.h" |
22 #include "content/common/notification_service.h" | 22 #include "content/common/notification_service.h" |
23 #include "grit/app_resources.h" | 23 #include "grit/app_resources.h" |
24 #include "grit/chromium_strings.h" | 24 #include "grit/chromium_strings.h" |
25 #include "grit/generated_resources.h" | 25 #include "grit/generated_resources.h" |
26 #include "grit/theme_resources.h" | 26 #include "grit/theme_resources.h" |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 // The titlebar has a 2 px 3D edge along the top and bottom. | 67 // The titlebar has a 2 px 3D edge along the top and bottom. |
68 const int kTitlebarTopAndBottomEdgeThickness = 2; | 68 const int kTitlebarTopAndBottomEdgeThickness = 2; |
69 // The icon is inset 2 px from the left frame border. | 69 // The icon is inset 2 px from the left frame border. |
70 const int kIconLeftSpacing = 2; | 70 const int kIconLeftSpacing = 2; |
71 // The icon never shrinks below 16 px on a side. | 71 // The icon never shrinks below 16 px on a side. |
72 const int kIconMinimumSize = 16; | 72 const int kIconMinimumSize = 16; |
73 // There is a 4 px gap between the icon and the title text. | 73 // There is a 4 px gap between the icon and the title text. |
74 const int kIconTitleSpacing = 4; | 74 const int kIconTitleSpacing = 4; |
75 // There is a 5 px gap between the title text and the caption buttons. | 75 // There is a 5 px gap between the title text and the caption buttons. |
76 const int kTitleLogoSpacing = 5; | 76 const int kTitleLogoSpacing = 5; |
77 // The avatar ends 2 px above the bottom of the tabstrip (which, given the | 77 // The OTR avatar ends 2 px above the bottom of the tabstrip (which, given the |
78 // way the tabstrip draws its bottom edge, will appear like a 1 px gap to the | 78 // way the tabstrip draws its bottom edge, will appear like a 1 px gap to the |
79 // user). | 79 // user). |
80 const int kAvatarBottomSpacing = 2; | 80 const int kOTRBottomSpacing = 2; |
81 // There are 2 px on each side of the avatar (between the frame border and | 81 // There are 2 px on each side of the OTR avatar (between the frame border and |
82 // it on the left, and between it and the tabstrip on the right). | 82 // it on the left, and between it and the tabstrip on the right). |
83 const int kAvatarSideSpacing = 2; | 83 const int kOTRSideSpacing = 2; |
84 // The top 1 px of the tabstrip is shadow; in maximized mode we push this off | 84 // The top 1 px of the tabstrip is shadow; in maximized mode we push this off |
85 // the top of the screen so the tabs appear flush against the screen edge. | 85 // the top of the screen so the tabs appear flush against the screen edge. |
86 const int kTabstripTopShadowThickness = 1; | 86 const int kTabstripTopShadowThickness = 1; |
87 // In restored mode, the New Tab button isn't at the same height as the caption | 87 // In restored mode, the New Tab button isn't at the same height as the caption |
88 // buttons, but the space will look cluttered if it actually slides under them, | 88 // buttons, but the space will look cluttered if it actually slides under them, |
89 // so we stop it when the gap between the two is down to 5 px. | 89 // so we stop it when the gap between the two is down to 5 px. |
90 const int kNewTabCaptionRestoredSpacing = 5; | 90 const int kNewTabCaptionRestoredSpacing = 5; |
91 // In maximized mode, where the New Tab button and the caption buttons are at | 91 // In maximized mode, where the New Tab button and the caption buttons are at |
92 // similar vertical coordinates, we need to reserve a larger, 16 px gap to avoid | 92 // similar vertical coordinates, we need to reserve a larger, 16 px gap to avoid |
93 // looking too cluttered. | 93 // looking too cluttered. |
94 const int kNewTabCaptionMaximizedSpacing = 16; | 94 const int kNewTabCaptionMaximizedSpacing = 16; |
95 // How far to indent the tabstrip from the left side of the screen when there | 95 // How far to indent the tabstrip from the left side of the screen when there |
96 // is no avatar icon. | 96 // is no OTR icon. |
97 const int kTabStripIndent = 1; | 97 const int kTabStripIndent = 1; |
98 // Inset from the top of the toolbar/tabstrip to the shadow. Used only for | 98 // Inset from the top of the toolbar/tabstrip to the shadow. Used only for |
99 // vertical tabs. | 99 // vertical tabs. |
100 const int kVerticalTabBorderInset = 3; | 100 const int kVerticalTabBorderInset = 3; |
| 101 // Y position for profile tag inside the frame. |
| 102 const int kProfileTagYPosition = 1; |
101 | 103 |
102 // Converts |bounds| from |src|'s coordinate system to |dst|, and checks if | 104 // Converts |bounds| from |src|'s coordinate system to |dst|, and checks if |
103 // |pt| is contained within. | 105 // |pt| is contained within. |
104 bool ConvertedContainsCheck(gfx::Rect bounds, const views::View* src, | 106 bool ConvertedContainsCheck(gfx::Rect bounds, const views::View* src, |
105 const views::View* dst, const gfx::Point& pt) { | 107 const views::View* dst, const gfx::Point& pt) { |
106 DCHECK(src); | 108 DCHECK(src); |
107 DCHECK(dst); | 109 DCHECK(dst); |
108 gfx::Point origin(bounds.origin()); | 110 gfx::Point origin(bounds.origin()); |
109 views::View::ConvertPointToView(src, dst, &origin); | 111 views::View::ConvertPointToView(src, dst, &origin); |
110 bounds.set_origin(origin); | 112 bounds.set_origin(origin); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 AddChildView(close_button_); | 193 AddChildView(close_button_); |
192 | 194 |
193 // Initializing the TabIconView is expensive, so only do it if we need to. | 195 // Initializing the TabIconView is expensive, so only do it if we need to. |
194 if (browser_view_->ShouldShowWindowIcon()) { | 196 if (browser_view_->ShouldShowWindowIcon()) { |
195 window_icon_ = new TabIconView(this); | 197 window_icon_ = new TabIconView(this); |
196 window_icon_->set_is_light(true); | 198 window_icon_->set_is_light(true); |
197 AddChildView(window_icon_); | 199 AddChildView(window_icon_); |
198 window_icon_->Update(); | 200 window_icon_->Update(); |
199 } | 201 } |
200 | 202 |
201 if (browser_view_->ShouldShowAvatar()) { | 203 // If multi-profile is enabled set up profile button and login notifications. |
202 ui::MenuModel* menu_model = browser_view_->IsOffTheRecord() ? | |
203 NULL : new ProfileMenuModel; | |
204 // AvatarMenuButton takes ownership of |menu_model|. | |
205 avatar_button_.reset(new AvatarMenuButton(std::wstring(), menu_model)); | |
206 AddChildView(avatar_button_.get()); | |
207 | |
208 if (browser_view_->IsOffTheRecord()) { | |
209 avatar_button_->SetIcon(browser_view_->GetOTRAvatarIcon()); | |
210 } else { | |
211 // TODO(sail) Get the avatar icon assigned to this profile. | |
212 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | |
213 avatar_button_->SetIcon(*rb.GetBitmapNamed(IDR_PROFILE_AVATAR_1)); | |
214 // TODO(sail) Also need to call SetHoverIcon() and SetPushedIcon(). | |
215 } | |
216 } | |
217 | |
218 // If multi-profile is enabled set up login notifications. | |
219 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); | 204 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); |
220 if (browser_command_line.HasSwitch(switches::kMultiProfiles) && | 205 if (browser_command_line.HasSwitch(switches::kMultiProfiles) && |
221 !browser_view->IsOffTheRecord()) { | 206 !browser_view_->ShouldShowOffTheRecordAvatar()) { |
222 RegisterLoginNotifications(); | 207 RegisterLoginNotifications(); |
| 208 profile_button_.reset(new ProfileMenuButton(std::wstring(), |
| 209 browser_view_->browser()->profile())); |
| 210 profile_button_->SetVisible(false); |
| 211 profile_tag_.reset(new ProfileTagView(frame_, profile_button_.get())); |
| 212 profile_tag_->SetVisible(false); |
| 213 AddChildView(profile_tag_.get()); |
| 214 AddChildView(profile_button_.get()); |
223 } | 215 } |
224 } | 216 } |
225 | 217 |
226 OpaqueBrowserFrameView::~OpaqueBrowserFrameView() { | 218 OpaqueBrowserFrameView::~OpaqueBrowserFrameView() { |
227 } | 219 } |
228 | 220 |
229 /////////////////////////////////////////////////////////////////////////////// | 221 /////////////////////////////////////////////////////////////////////////////// |
230 // OpaqueBrowserFrameView, protected: | 222 // OpaqueBrowserFrameView, protected: |
231 | 223 |
232 int OpaqueBrowserFrameView::GetReservedHeight() const { | 224 int OpaqueBrowserFrameView::GetReservedHeight() const { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 if (!tabstrip) | 262 if (!tabstrip) |
271 return gfx::Rect(); | 263 return gfx::Rect(); |
272 | 264 |
273 if (browser_view_->UseVerticalTabs()) { | 265 if (browser_view_->UseVerticalTabs()) { |
274 gfx::Size ps = tabstrip->GetPreferredSize(); | 266 gfx::Size ps = tabstrip->GetPreferredSize(); |
275 return gfx::Rect(NonClientBorderThickness(), | 267 return gfx::Rect(NonClientBorderThickness(), |
276 NonClientTopBorderHeight(false, false), ps.width(), | 268 NonClientTopBorderHeight(false, false), ps.width(), |
277 browser_view_->height()); | 269 browser_view_->height()); |
278 } | 270 } |
279 | 271 |
280 int tabstrip_x = browser_view_->ShouldShowAvatar() ? | 272 int tabstrip_x = browser_view_->ShouldShowOffTheRecordAvatar() ? |
281 (avatar_bounds_.right() + kAvatarSideSpacing) : | 273 (otr_avatar_bounds_.right() + kOTRSideSpacing) : |
282 NonClientBorderThickness() + kTabStripIndent; | 274 NonClientBorderThickness() + kTabStripIndent; |
283 | 275 |
284 int maximized_spacing = kNewTabCaptionMaximizedSpacing; | 276 int maximized_spacing = |
| 277 kNewTabCaptionMaximizedSpacing + |
| 278 (show_profile_button() && profile_button_->IsVisible() ? |
| 279 profile_button_->GetPreferredSize().width() + |
| 280 ProfileMenuButton::kProfileTagHorizontalSpacing : 0); |
285 int tabstrip_width = minimize_button_->x() - tabstrip_x - | 281 int tabstrip_width = minimize_button_->x() - tabstrip_x - |
286 (frame_->IsMaximized() ? | 282 (frame_->IsMaximized() ? |
287 maximized_spacing : kNewTabCaptionRestoredSpacing); | 283 maximized_spacing : kNewTabCaptionRestoredSpacing); |
288 return gfx::Rect(tabstrip_x, GetHorizontalTabStripVerticalOffset(false), | 284 return gfx::Rect(tabstrip_x, GetHorizontalTabStripVerticalOffset(false), |
289 std::max(0, tabstrip_width), tabstrip->GetPreferredSize().height()); | 285 std::max(0, tabstrip_width), tabstrip->GetPreferredSize().height()); |
290 } | 286 } |
291 | 287 |
292 int OpaqueBrowserFrameView::GetHorizontalTabStripVerticalOffset( | 288 int OpaqueBrowserFrameView::GetHorizontalTabStripVerticalOffset( |
293 bool restored) const { | 289 bool restored) const { |
294 return NonClientTopBorderHeight(restored, true) + ((!restored && | 290 return NonClientTopBorderHeight(restored, true) + ((!restored && |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 return gfx::Rect(std::max(0, client_bounds.x() - border_thickness), | 333 return gfx::Rect(std::max(0, client_bounds.x() - border_thickness), |
338 std::max(0, client_bounds.y() - top_height), | 334 std::max(0, client_bounds.y() - top_height), |
339 client_bounds.width() + (2 * border_thickness), | 335 client_bounds.width() + (2 * border_thickness), |
340 client_bounds.height() + top_height + border_thickness); | 336 client_bounds.height() + top_height + border_thickness); |
341 } | 337 } |
342 | 338 |
343 int OpaqueBrowserFrameView::NonClientHitTest(const gfx::Point& point) { | 339 int OpaqueBrowserFrameView::NonClientHitTest(const gfx::Point& point) { |
344 if (!bounds().Contains(point)) | 340 if (!bounds().Contains(point)) |
345 return HTNOWHERE; | 341 return HTNOWHERE; |
346 | 342 |
347 // See if the point is within the avatar menu button. | 343 int frame_component = |
348 if (avatar_button_.get() && | 344 frame_->client_view()->NonClientHitTest(point); |
349 avatar_button_->GetMirroredBounds().Contains(point)) | |
350 return HTCLIENT; | |
351 | |
352 int frame_component = frame_->client_view()->NonClientHitTest(point); | |
353 | 345 |
354 // See if we're in the sysmenu region. We still have to check the tabstrip | 346 // See if we're in the sysmenu region. We still have to check the tabstrip |
355 // first so that clicks in a tab don't get treated as sysmenu clicks. | 347 // first so that clicks in a tab don't get treated as sysmenu clicks. |
356 gfx::Rect sysmenu_rect(IconBounds()); | 348 gfx::Rect sysmenu_rect(IconBounds()); |
357 // In maximized mode we extend the rect to the screen corner to take advantage | 349 // In maximized mode we extend the rect to the screen corner to take advantage |
358 // of Fitts' Law. | 350 // of Fitts' Law. |
359 if (frame_->IsMaximized()) | 351 if (frame_->IsMaximized()) |
360 sysmenu_rect.SetRect(0, 0, sysmenu_rect.right(), sysmenu_rect.bottom()); | 352 sysmenu_rect.SetRect(0, 0, sysmenu_rect.right(), sysmenu_rect.bottom()); |
361 sysmenu_rect.set_x(GetMirroredXForRect(sysmenu_rect)); | 353 sysmenu_rect.set_x(GetMirroredXForRect(sysmenu_rect)); |
362 if (sysmenu_rect.Contains(point)) | 354 if (sysmenu_rect.Contains(point)) |
363 return (frame_component == HTCLIENT) ? HTCLIENT : HTSYSMENU; | 355 return (frame_component == HTCLIENT) ? HTCLIENT : HTSYSMENU; |
364 | 356 |
365 if (frame_component != HTNOWHERE) | 357 if (frame_component != HTNOWHERE) |
366 return frame_component; | 358 return frame_component; |
367 | 359 |
368 // Then see if the point is within any of the window controls. | 360 // Then see if the point is within any of the window controls. |
369 if (close_button_->IsVisible() && | 361 if (close_button_->IsVisible() && |
370 close_button_->GetMirroredBounds().Contains(point)) | 362 close_button_->GetMirroredBounds().Contains(point)) |
371 return HTCLOSE; | 363 return HTCLOSE; |
372 if (restore_button_->IsVisible() && | 364 if (restore_button_->IsVisible() && |
373 restore_button_->GetMirroredBounds().Contains(point)) | 365 restore_button_->GetMirroredBounds().Contains(point)) |
374 return HTMAXBUTTON; | 366 return HTMAXBUTTON; |
375 if (maximize_button_->IsVisible() && | 367 if (maximize_button_->IsVisible() && |
376 maximize_button_->GetMirroredBounds().Contains(point)) | 368 maximize_button_->GetMirroredBounds().Contains(point)) |
377 return HTMAXBUTTON; | 369 return HTMAXBUTTON; |
378 if (minimize_button_->IsVisible() && | 370 if (minimize_button_->IsVisible() && |
379 minimize_button_->GetMirroredBounds().Contains(point)) | 371 minimize_button_->GetMirroredBounds().Contains(point)) |
380 return HTMINBUTTON; | 372 return HTMINBUTTON; |
381 | 373 |
| 374 // See if the point is within the profile menu button. |
| 375 if (show_profile_button() && profile_button_->IsVisible() && |
| 376 profile_button_->GetMirroredBounds().Contains(point)) |
| 377 return HTCLIENT; |
| 378 |
382 views::WindowDelegate* delegate = frame_->window_delegate(); | 379 views::WindowDelegate* delegate = frame_->window_delegate(); |
383 if (!delegate) { | 380 if (!delegate) { |
384 LOG(WARNING) << "delegate is NULL, returning safe default."; | 381 LOG(WARNING) << "delegate is NULL, returning safe default."; |
385 return HTCAPTION; | 382 return HTCAPTION; |
386 } | 383 } |
387 int window_component = GetHTComponentForFrame(point, TopResizeHeight(), | 384 int window_component = GetHTComponentForFrame(point, TopResizeHeight(), |
388 NonClientBorderThickness(), kResizeAreaCornerSize, kResizeAreaCornerSize, | 385 NonClientBorderThickness(), kResizeAreaCornerSize, kResizeAreaCornerSize, |
389 delegate->CanResize()); | 386 delegate->CanResize()); |
390 // Fall back to the caption if no other component matches. | 387 // Fall back to the caption if no other component matches. |
391 return (window_component == HTNOWHERE) ? HTCAPTION : window_component; | 388 return (window_component == HTNOWHERE) ? HTCAPTION : window_component; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 return; // Nothing is visible, so don't bother to paint. | 421 return; // Nothing is visible, so don't bother to paint. |
425 | 422 |
426 if (frame_->IsMaximized()) | 423 if (frame_->IsMaximized()) |
427 PaintMaximizedFrameBorder(canvas); | 424 PaintMaximizedFrameBorder(canvas); |
428 else | 425 else |
429 PaintRestoredFrameBorder(canvas); | 426 PaintRestoredFrameBorder(canvas); |
430 PaintTitleBar(canvas); | 427 PaintTitleBar(canvas); |
431 if (browser_view_->IsToolbarVisible() || | 428 if (browser_view_->IsToolbarVisible() || |
432 browser_view_->UseCompactNavigationBar()) | 429 browser_view_->UseCompactNavigationBar()) |
433 PaintToolbarBackground(canvas); | 430 PaintToolbarBackground(canvas); |
| 431 if (browser_view_->ShouldShowOffTheRecordAvatar()) |
| 432 PaintOTRAvatar(canvas); |
434 if (!frame_->IsMaximized()) | 433 if (!frame_->IsMaximized()) |
435 PaintRestoredClientEdge(canvas); | 434 PaintRestoredClientEdge(canvas); |
436 } | 435 } |
437 | 436 |
438 void OpaqueBrowserFrameView::Layout() { | 437 void OpaqueBrowserFrameView::Layout() { |
439 LayoutWindowControls(); | 438 LayoutWindowControls(); |
440 LayoutTitleBar(); | 439 LayoutTitleBar(); |
441 LayoutAvatar(); | 440 LayoutOTRAvatar(); |
| 441 LayoutProfileTag(); |
442 client_view_bounds_ = CalculateClientAreaBounds(width(), height()); | 442 client_view_bounds_ = CalculateClientAreaBounds(width(), height()); |
443 } | 443 } |
444 | 444 |
445 bool OpaqueBrowserFrameView::HitTest(const gfx::Point& l) const { | 445 bool OpaqueBrowserFrameView::HitTest(const gfx::Point& l) const { |
446 // If the point is outside the bounds of the client area, claim it. | 446 // If the point is outside the bounds of the client area, claim it. |
447 bool in_nonclient = NonClientFrameView::HitTest(l); | 447 bool in_nonclient = NonClientFrameView::HitTest(l); |
448 if (in_nonclient) | 448 if (in_nonclient) |
449 return in_nonclient; | 449 return in_nonclient; |
450 | 450 |
451 // Otherwise claim it only if it's in a non-tab portion of the tabstrip. | 451 // Otherwise claim it only if it's in a non-tab portion of the tabstrip. |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
517 | 517 |
518 /////////////////////////////////////////////////////////////////////////////// | 518 /////////////////////////////////////////////////////////////////////////////// |
519 // OpaqueBrowserFrameView, protected: | 519 // OpaqueBrowserFrameView, protected: |
520 | 520 |
521 void OpaqueBrowserFrameView::Observe(NotificationType type, | 521 void OpaqueBrowserFrameView::Observe(NotificationType type, |
522 const NotificationSource& source, | 522 const NotificationSource& source, |
523 const NotificationDetails& details) { | 523 const NotificationDetails& details) { |
524 DCHECK_EQ(NotificationType::PREF_CHANGED, type.value); | 524 DCHECK_EQ(NotificationType::PREF_CHANGED, type.value); |
525 std::string* name = Details<std::string>(details).ptr(); | 525 std::string* name = Details<std::string>(details).ptr(); |
526 if (prefs::kGoogleServicesUsername == *name) | 526 if (prefs::kGoogleServicesUsername == *name) |
527 LayoutAvatar(); | 527 LayoutProfileTag(); |
528 } | 528 } |
529 | 529 |
530 /////////////////////////////////////////////////////////////////////////////// | 530 /////////////////////////////////////////////////////////////////////////////// |
531 // OpaqueBrowserFrameView, private: | 531 // OpaqueBrowserFrameView, private: |
532 | 532 |
533 int OpaqueBrowserFrameView::FrameBorderThickness(bool restored) const { | 533 int OpaqueBrowserFrameView::FrameBorderThickness(bool restored) const { |
534 return (!restored && (frame_->IsMaximized() || frame_->IsFullscreen())) ? | 534 return (!restored && (frame_->IsMaximized() || frame_->IsFullscreen())) ? |
535 0 : kFrameBorderThickness; | 535 0 : kFrameBorderThickness; |
536 } | 536 } |
537 | 537 |
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
918 toolbar_right->height() - bottom_edge_height, toolbar_right->width(), | 918 toolbar_right->height() - bottom_edge_height, toolbar_right->width(), |
919 bottom_edge_height, right_x, bottom_y, toolbar_right->width(), | 919 bottom_edge_height, right_x, bottom_y, toolbar_right->width(), |
920 bottom_edge_height, false); | 920 bottom_edge_height, false); |
921 | 921 |
922 // Draw the content/toolbar separator. | 922 // Draw the content/toolbar separator. |
923 canvas->FillRectInt(ResourceBundle::toolbar_separator_color, | 923 canvas->FillRectInt(ResourceBundle::toolbar_separator_color, |
924 x + kClientEdgeThickness, toolbar_bounds.bottom() - kClientEdgeThickness, | 924 x + kClientEdgeThickness, toolbar_bounds.bottom() - kClientEdgeThickness, |
925 w - (2 * kClientEdgeThickness), kClientEdgeThickness); | 925 w - (2 * kClientEdgeThickness), kClientEdgeThickness); |
926 } | 926 } |
927 | 927 |
| 928 void OpaqueBrowserFrameView::PaintOTRAvatar(gfx::Canvas* canvas) { |
| 929 // In RTL mode, the avatar icon should be looking the opposite direction. |
| 930 canvas->Save(); |
| 931 if (base::i18n::IsRTL()) { |
| 932 canvas->TranslateInt(width(), 0); |
| 933 canvas->ScaleInt(-1, 1); |
| 934 } |
| 935 |
| 936 SkBitmap otr_avatar_icon = browser_view_->GetOTRAvatarIcon(); |
| 937 int w = otr_avatar_bounds_.width(); |
| 938 int h = otr_avatar_bounds_.height(); |
| 939 canvas->DrawBitmapInt(otr_avatar_icon, 0, |
| 940 // Bias the rounding to select a region that's lower rather than higher, |
| 941 // as the shadows at the image top mean the apparent center is below the |
| 942 // real center. |
| 943 ((otr_avatar_icon.height() - otr_avatar_bounds_.height()) + 1) / 2, w, h, |
| 944 otr_avatar_bounds_.x(), otr_avatar_bounds_.y(), w, h, false); |
| 945 |
| 946 canvas->Restore(); |
| 947 } |
| 948 |
928 void OpaqueBrowserFrameView::PaintRestoredClientEdge(gfx::Canvas* canvas) { | 949 void OpaqueBrowserFrameView::PaintRestoredClientEdge(gfx::Canvas* canvas) { |
929 ui::ThemeProvider* tp = GetThemeProvider(); | 950 ui::ThemeProvider* tp = GetThemeProvider(); |
930 int client_area_top = frame_->client_view()->y(); | 951 int client_area_top = frame_->client_view()->y(); |
931 int image_top = client_area_top; | 952 int image_top = client_area_top; |
932 | 953 |
933 gfx::Rect client_area_bounds = CalculateClientAreaBounds(width(), height()); | 954 gfx::Rect client_area_bounds = CalculateClientAreaBounds(width(), height()); |
934 SkColor toolbar_color = tp->GetColor(ThemeService::COLOR_TOOLBAR); | 955 SkColor toolbar_color = tp->GetColor(ThemeService::COLOR_TOOLBAR); |
935 | 956 |
936 if (browser_view_->IsToolbarVisible() || | 957 if (browser_view_->IsToolbarVisible() || |
937 browser_view_->UseCompactNavigationBar()) { | 958 browser_view_->UseCompactNavigationBar()) { |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1106 // vertical midline rather than below. This compensates for how the icon is | 1127 // vertical midline rather than below. This compensates for how the icon is |
1107 // already biased downwards (see IconBounds()) and helps prevent descenders | 1128 // already biased downwards (see IconBounds()) and helps prevent descenders |
1108 // on the title from overlapping the 3D edge at the bottom of the titlebar. | 1129 // on the title from overlapping the 3D edge at the bottom of the titlebar. |
1109 title_bounds_.SetRect(title_x, | 1130 title_bounds_.SetRect(title_x, |
1110 icon_bounds.y() + ((icon_bounds.height() - title_height - 1) / 2), | 1131 icon_bounds.y() + ((icon_bounds.height() - title_height - 1) / 2), |
1111 std::max(0, minimize_button_->x() - kTitleLogoSpacing - title_x), | 1132 std::max(0, minimize_button_->x() - kTitleLogoSpacing - title_x), |
1112 title_height); | 1133 title_height); |
1113 } | 1134 } |
1114 } | 1135 } |
1115 | 1136 |
1116 void OpaqueBrowserFrameView::LayoutAvatar() { | 1137 void OpaqueBrowserFrameView::LayoutOTRAvatar() { |
1117 // Even though the avatar is used for both incognito and profiles we always | 1138 SkBitmap otr_avatar_icon = browser_view_->GetOTRAvatarIcon(); |
1118 // use the incognito icon to layout the avatar button. | 1139 int otr_bottom, otr_restored_y; |
1119 SkBitmap incognito_icon = browser_view_->GetOTRAvatarIcon(); | 1140 if (browser_view_->UseVerticalTabs()) { |
| 1141 otr_bottom = NonClientTopBorderHeight(false, false) - kOTRBottomSpacing; |
| 1142 otr_restored_y = kFrameShadowThickness; |
| 1143 } else { |
| 1144 otr_bottom = GetHorizontalTabStripVerticalOffset(false) + |
| 1145 browser_view_->GetTabStripHeight() - kOTRBottomSpacing; |
| 1146 otr_restored_y = otr_bottom - otr_avatar_icon.height(); |
| 1147 } |
| 1148 int otr_y = frame_->IsMaximized() ? |
| 1149 (NonClientTopBorderHeight(false, true) + kTabstripTopShadowThickness) : |
| 1150 otr_restored_y; |
| 1151 otr_avatar_bounds_.SetRect(NonClientBorderThickness() + kOTRSideSpacing, |
| 1152 otr_y, otr_avatar_icon.width(), |
| 1153 browser_view_->ShouldShowOffTheRecordAvatar() ? (otr_bottom - otr_y) : 0); |
| 1154 } |
1120 | 1155 |
1121 int avatar_bottom, avatar_restored_y; | 1156 void OpaqueBrowserFrameView::LayoutProfileTag() { |
1122 if (browser_view_->UseVerticalTabs()) { | 1157 if (!show_profile_button()) |
1123 avatar_bottom = NonClientTopBorderHeight(false, false) - | 1158 return; |
1124 kAvatarBottomSpacing; | 1159 |
1125 avatar_restored_y = kFrameShadowThickness; | 1160 string16 profile_name = UTF8ToUTF16(browser_view_->browser()->profile()-> |
| 1161 GetPrefs()->GetString(prefs::kGoogleServicesUsername)); |
| 1162 if (!profile_name.empty()) { |
| 1163 profile_button_->SetText(UTF16ToWideHack(profile_name)); |
1126 } else { | 1164 } else { |
1127 avatar_bottom = GetHorizontalTabStripVerticalOffset(false) + | 1165 profile_button_->SetText(UTF16ToWideHack(l10n_util::GetStringUTF16( |
1128 browser_view_->GetTabStripHeight() - kAvatarBottomSpacing; | 1166 IDS_PROFILES_NOT_SIGNED_IN_MENU))); |
1129 avatar_restored_y = avatar_bottom - incognito_icon.height(); | |
1130 } | 1167 } |
1131 int avatar_y = frame_->IsMaximized() ? | 1168 profile_button_->SetTextShadowColors(ProfileMenuButton::kDarkTextShadow, |
1132 (NonClientTopBorderHeight(false, true) + kTabstripTopShadowThickness) : | 1169 ProfileMenuButton::kDarkTextShadow); |
1133 avatar_restored_y; | 1170 profile_button_->ClearMaxTextSize(); |
1134 avatar_bounds_.SetRect(NonClientBorderThickness() + kAvatarSideSpacing, | 1171 profile_button_->SetVisible(true); |
1135 avatar_y, incognito_icon.width(), | 1172 int x_tag = |
1136 browser_view_->ShouldShowAvatar() ? (avatar_bottom - avatar_y) : 0); | 1173 // The x position of minimize button in the frame |
| 1174 minimize_button_->x() - |
| 1175 // - the space between the minimize button and the profile button |
| 1176 ProfileMenuButton::kProfileTagHorizontalSpacing - |
| 1177 // - the width of the profile button |
| 1178 profile_button_->GetPreferredSize().width(); |
| 1179 // Adjust for different default font sizes on different Windows platforms. |
| 1180 int y_tag = profile_button_->font().GetHeight() < 14 ? 2 : 0; |
| 1181 int maximized = frame_->IsMaximized(); |
| 1182 profile_button_->SetBounds( |
| 1183 x_tag, |
| 1184 maximized ? 0 : y_tag, |
| 1185 profile_button_->GetPreferredSize().width(), |
| 1186 profile_button_->GetPreferredSize().height()); |
1137 | 1187 |
1138 if (avatar_button_.get()) | 1188 if (!profile_name.empty()) { |
1139 avatar_button_->SetBoundsRect(avatar_bounds_); | 1189 profile_tag_->SetVisible(true); |
| 1190 profile_tag_->SetBounds( |
| 1191 x_tag, |
| 1192 maximized ? 0 : kProfileTagYPosition, |
| 1193 profile_button_->GetPreferredSize().width(), |
| 1194 ProfileTagView::kProfileTagHeight); |
| 1195 } else { |
| 1196 profile_tag_->SetVisible(false); |
| 1197 } |
1140 } | 1198 } |
1141 | 1199 |
1142 gfx::Rect OpaqueBrowserFrameView::CalculateClientAreaBounds(int width, | 1200 gfx::Rect OpaqueBrowserFrameView::CalculateClientAreaBounds(int width, |
1143 int height) const { | 1201 int height) const { |
1144 int top_height = NonClientTopBorderHeight(false, false); | 1202 int top_height = NonClientTopBorderHeight(false, false); |
1145 int border_thickness = NonClientBorderThickness(); | 1203 int border_thickness = NonClientBorderThickness(); |
1146 return gfx::Rect(border_thickness, top_height, | 1204 return gfx::Rect(border_thickness, top_height, |
1147 std::max(0, width - (2 * border_thickness)), | 1205 std::max(0, width - (2 * border_thickness)), |
1148 std::max(0, height - GetReservedHeight() - | 1206 std::max(0, height - GetReservedHeight() - |
1149 top_height - border_thickness)); | 1207 top_height - border_thickness)); |
1150 } | 1208 } |
1151 | 1209 |
1152 void OpaqueBrowserFrameView::RegisterLoginNotifications() { | 1210 void OpaqueBrowserFrameView::RegisterLoginNotifications() { |
1153 PrefService* pref_service = browser_view_->browser()->profile()->GetPrefs(); | 1211 PrefService* pref_service = browser_view_->browser()->profile()->GetPrefs(); |
1154 DCHECK(pref_service); | 1212 DCHECK(pref_service); |
1155 username_pref_.Init(prefs::kGoogleServicesUsername, pref_service, this); | 1213 username_pref_.Init(prefs::kGoogleServicesUsername, pref_service, this); |
1156 } | 1214 } |
OLD | NEW |