Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(137)

Side by Side Diff: chrome/browser/ui/views/frame/glass_browser_frame_view.cc

Issue 2851543002: Update avatar button to MD (part 1) (Closed)
Patch Set: Rebased on CL 2868293002 [Rename new_avatar_button.* to avatar_button] Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <dwmapi.h> 7 #include <dwmapi.h>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/win/windows_version.h" 10 #include "base/win/windows_version.h"
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 namespace { 42 namespace {
43 // Thickness of the frame edge between the non-client area and the web content. 43 // Thickness of the frame edge between the non-client area and the web content.
44 const int kClientBorderThickness = 3; 44 const int kClientBorderThickness = 3;
45 // Besides the frame border, there's empty space atop the window in restored 45 // Besides the frame border, there's empty space atop the window in restored
46 // mode, to use to drag the window around. 46 // mode, to use to drag the window around.
47 const int kNonClientRestoredExtraThickness = 11; 47 const int kNonClientRestoredExtraThickness = 11;
48 // At the window corners the resize area is not actually bigger, but the 16 48 // At the window corners the resize area is not actually bigger, but the 16
49 // pixels at the end of the top and bottom edges trigger diagonal resizing. 49 // pixels at the end of the top and bottom edges trigger diagonal resizing.
50 const int kResizeCornerWidth = 16; 50 const int kResizeCornerWidth = 16;
51 // How far the profile switcher button is from the left of the minimize button. 51 // How far the profile switcher button is from the left of the minimize button.
52 const int kProfileSwitcherButtonOffset = 5; 52 const int kProfileSwitcherButtonOffset = 1;
53 // The content edge images have a shadow built into them. 53 // The content edge images have a shadow built into them.
54 const int kContentEdgeShadowThickness = 2; 54 const int kContentEdgeShadowThickness = 2;
55 // In restored mode, the New Tab button isn't at the same height as the caption 55 // In restored mode, the New Tab button isn't at the same height as the caption
56 // buttons, but the space will look cluttered if it actually slides under them, 56 // buttons, but the space will look cluttered if it actually slides under them,
57 // so we stop it when the gap between the two is down to 5 px. 57 // so we stop it when the gap between the two is down to 5 px.
58 const int kNewTabCaptionRestoredSpacing = 5; 58 const int kNewTabCaptionRestoredSpacing = 5;
59 // In maximized mode, where the New Tab button and the caption buttons are at 59 // In maximized mode, where the New Tab button and the caption buttons are at
60 // similar vertical coordinates, we need to reserve a larger, 16 px gap to avoid 60 // similar vertical coordinates, we need to reserve a larger, 16 px gap to avoid
61 // looking too cluttered. 61 // looking too cluttered.
62 const int kNewTabCaptionMaximizedSpacing = 16; 62 const int kNewTabCaptionMaximizedSpacing = 16;
63 // Height of the profile switcher button. Same as the height of the Windows 7/8
64 // caption buttons.
65 // TODO(bsep): Windows 10 caption buttons look very different and we would like
66 // the profile switcher button to match on that platform.
67 const int kProfileSwitcherButtonHeight = 20;
68 // There is a small one-pixel strip right above the caption buttons in which the 63 // There is a small one-pixel strip right above the caption buttons in which the
69 // resize border "peeks" through. 64 // resize border "peeks" through.
70 const int kCaptionButtonTopInset = 1; 65 const int kCaptionButtonTopInset = 1;
71 66
72 // Converts the |image| to a Windows icon and returns the corresponding HICON 67 // Converts the |image| to a Windows icon and returns the corresponding HICON
73 // handle. |image| is resized to desired |width| and |height| if needed. 68 // handle. |image| is resized to desired |width| and |height| if needed.
74 base::win::ScopedHICON CreateHICONFromSkBitmapSizedTo( 69 base::win::ScopedHICON CreateHICONFromSkBitmapSizedTo(
75 const gfx::ImageSkia& image, 70 const gfx::ImageSkia& image,
76 int width, 71 int width,
77 int height) { 72 int height) {
(...skipping 14 matching lines...) Expand all
92 BrowserView* browser_view) 87 BrowserView* browser_view)
93 : BrowserNonClientFrameView(frame, browser_view), 88 : BrowserNonClientFrameView(frame, browser_view),
94 window_icon_(nullptr), 89 window_icon_(nullptr),
95 window_title_(nullptr), 90 window_title_(nullptr),
96 profile_switcher_(this), 91 profile_switcher_(this),
97 minimize_button_(nullptr), 92 minimize_button_(nullptr),
98 maximize_button_(nullptr), 93 maximize_button_(nullptr),
99 restore_button_(nullptr), 94 restore_button_(nullptr),
100 close_button_(nullptr), 95 close_button_(nullptr),
101 throbber_running_(false), 96 throbber_running_(false),
102 throbber_frame_(0) { 97 throbber_frame_(0),
98 tab_strip_observer_(this) {
103 // We initialize all fields despite some of them being unused in some modes, 99 // We initialize all fields despite some of them being unused in some modes,
104 // since it's possible for modes to flip dynamically (e.g. if the user enables 100 // since it's possible for modes to flip dynamically (e.g. if the user enables
105 // a high-contrast theme). Throbber icons are only used when ShowSystemIcon() 101 // a high-contrast theme). Throbber icons are only used when ShowSystemIcon()
106 // is true. Everything else here is only used when 102 // is true. Everything else here is only used when
107 // ShouldCustomDrawSystemTitlebar() is true. 103 // ShouldCustomDrawSystemTitlebar() is true.
108 104
109 if (browser_view->ShouldShowWindowIcon()) { 105 if (browser_view->ShouldShowWindowIcon()) {
110 InitThrobberIcons(); 106 InitThrobberIcons();
111 107
112 window_icon_ = new TabIconView(this, nullptr); 108 window_icon_ = new TabIconView(this, nullptr);
(...skipping 11 matching lines...) Expand all
124 window_title_->set_id(VIEW_ID_WINDOW_TITLE); 120 window_title_->set_id(VIEW_ID_WINDOW_TITLE);
125 AddChildView(window_title_); 121 AddChildView(window_title_);
126 } 122 }
127 123
128 minimize_button_ = CreateCaptionButton(VIEW_ID_MINIMIZE_BUTTON); 124 minimize_button_ = CreateCaptionButton(VIEW_ID_MINIMIZE_BUTTON);
129 maximize_button_ = CreateCaptionButton(VIEW_ID_MAXIMIZE_BUTTON); 125 maximize_button_ = CreateCaptionButton(VIEW_ID_MAXIMIZE_BUTTON);
130 restore_button_ = CreateCaptionButton(VIEW_ID_RESTORE_BUTTON); 126 restore_button_ = CreateCaptionButton(VIEW_ID_RESTORE_BUTTON);
131 close_button_ = CreateCaptionButton(VIEW_ID_CLOSE_BUTTON); 127 close_button_ = CreateCaptionButton(VIEW_ID_CLOSE_BUTTON);
132 } 128 }
133 129
134 GlassBrowserFrameView::~GlassBrowserFrameView() {
135 }
136
137 /////////////////////////////////////////////////////////////////////////////// 130 ///////////////////////////////////////////////////////////////////////////////
138 // GlassBrowserFrameView, BrowserNonClientFrameView implementation: 131 // GlassBrowserFrameView, BrowserNonClientFrameView implementation:
139 132
140 gfx::Rect GlassBrowserFrameView::GetBoundsForTabStrip( 133 gfx::Rect GlassBrowserFrameView::GetBoundsForTabStrip(
141 views::View* tabstrip) const { 134 views::View* tabstrip) const {
142 const int x = incognito_bounds_.right() + kAvatarIconPadding; 135 const int x = incognito_bounds_.right() + kAvatarIconPadding;
143 int end_x = width() - ClientBorderThickness(false); 136 int end_x = width() - ClientBorderThickness(false);
144 if (!CaptionButtonsOnLeadingEdge()) { 137 if (!CaptionButtonsOnLeadingEdge()) {
145 end_x = std::min(MinimizeButtonX(), end_x) - 138 end_x = std::min(MinimizeButtonX(), end_x) -
146 (IsMaximized() ? kNewTabCaptionMaximizedSpacing 139 (IsMaximized() ? kNewTabCaptionMaximizedSpacing
147 : kNewTabCaptionRestoredSpacing); 140 : kNewTabCaptionRestoredSpacing);
148 141
149 // The profile switcher button is optionally displayed to the left of the 142 // The profile switcher button is optionally displayed to the left of the
150 // minimize button. 143 // minimize button.
151 if (profile_switcher_.view()) { 144 views::View* profile_switcher = GetProfileSwitcherView();
145 if (profile_switcher) {
152 const int old_end_x = end_x; 146 const int old_end_x = end_x;
153 end_x -= profile_switcher_.view()->width() + kProfileSwitcherButtonOffset; 147 end_x -= profile_switcher->width() + kProfileSwitcherButtonOffset;
154 148
155 // In non-maximized mode, allow the new tab button to slide completely 149 // In non-maximized mode, allow the new tab button to slide completely
156 // under the profile switcher button. 150 // under the profile switcher button.
157 if (!IsMaximized()) { 151 if (!IsMaximized()) {
158 end_x = std::min(end_x + GetLayoutSize(NEW_TAB_BUTTON).width() + 152 end_x = std::min(end_x + GetLayoutSize(NEW_TAB_BUTTON).width() +
159 kNewTabCaptionRestoredSpacing, 153 kNewTabCaptionRestoredSpacing,
160 old_end_x); 154 old_end_x);
161 } 155 }
162 } 156 }
163 } 157 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 min_size.set_width(std::max(min_tabstrip_area_width, min_size.width())); 204 min_size.set_width(std::max(min_tabstrip_area_width, min_size.width()));
211 } 205 }
212 206
213 return min_size; 207 return min_size;
214 } 208 }
215 209
216 views::View* GlassBrowserFrameView::GetProfileSwitcherView() const { 210 views::View* GlassBrowserFrameView::GetProfileSwitcherView() const {
217 return profile_switcher_.view(); 211 return profile_switcher_.view();
218 } 212 }
219 213
214 void GlassBrowserFrameView::OnBrowserViewInitViewsComplete() {
215 if (browser_view()->tabstrip()) {
216 DCHECK(!tab_strip_observer_.IsObserving(browser_view()->tabstrip()));
217 tab_strip_observer_.Add(browser_view()->tabstrip());
218 }
219 }
220
220 /////////////////////////////////////////////////////////////////////////////// 221 ///////////////////////////////////////////////////////////////////////////////
221 // GlassBrowserFrameView, views::NonClientFrameView implementation: 222 // GlassBrowserFrameView, views::NonClientFrameView implementation:
222 223
223 gfx::Rect GlassBrowserFrameView::GetBoundsForClientView() const { 224 gfx::Rect GlassBrowserFrameView::GetBoundsForClientView() const {
224 return client_view_bounds_; 225 return client_view_bounds_;
225 } 226 }
226 227
227 gfx::Rect GlassBrowserFrameView::GetWindowBoundsForClientBounds( 228 gfx::Rect GlassBrowserFrameView::GetWindowBoundsForClientBounds(
228 const gfx::Rect& client_bounds) const { 229 const gfx::Rect& client_bounds) const {
229 HWND hwnd = views::HWNDForWidget(frame()); 230 HWND hwnd = views::HWNDForWidget(frame());
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 const content::WebContents* current_tab = 369 const content::WebContents* current_tab =
369 browser_view()->GetActiveWebContents(); 370 browser_view()->GetActiveWebContents();
370 return current_tab && current_tab->IsLoading(); 371 return current_tab && current_tab->IsLoading();
371 } 372 }
372 373
373 gfx::ImageSkia GlassBrowserFrameView::GetFaviconForTabIconView() { 374 gfx::ImageSkia GlassBrowserFrameView::GetFaviconForTabIconView() {
374 DCHECK(ShowCustomIcon()); 375 DCHECK(ShowCustomIcon());
375 return frame()->widget_delegate()->GetWindowIcon(); 376 return frame()->widget_delegate()->GetWindowIcon();
376 } 377 }
377 378
379 void GlassBrowserFrameView::TabStripMaxXChanged(TabStrip* tab_strip) {
380 // The profile switcher button's height depends on the position of the new
381 // tab button.
382 if (browser_view()->IsRegularOrGuestSession())
383 LayoutProfileSwitcher();
384 }
385
386 void GlassBrowserFrameView::TabStripRemovedTabAt(TabStrip* tab_strip,
387 int index) {
388 // The profile switcher button may need to change height here, too.
389 // TabStripMaxXChanged is not enough when a tab other than the last tab is
390 // closed.
391 if (browser_view()->IsRegularOrGuestSession())
392 LayoutProfileSwitcher();
393 }
394
395 void GlassBrowserFrameView::TabStripDeleted(TabStrip* tab_strip) {
396 tab_strip_observer_.Remove(tab_strip);
397 }
398
378 bool GlassBrowserFrameView::IsMaximized() const { 399 bool GlassBrowserFrameView::IsMaximized() const {
379 return frame()->IsMaximized(); 400 return frame()->IsMaximized();
380 } 401 }
381 402
382 /////////////////////////////////////////////////////////////////////////////// 403 ///////////////////////////////////////////////////////////////////////////////
383 // GlassBrowserFrameView, views::View overrides: 404 // GlassBrowserFrameView, views::View overrides:
384 405
385 void GlassBrowserFrameView::OnPaint(gfx::Canvas* canvas) { 406 void GlassBrowserFrameView::OnPaint(gfx::Canvas* canvas) {
386 if (ShouldCustomDrawSystemTitlebar()) 407 if (ShouldCustomDrawSystemTitlebar())
387 PaintTitlebar(canvas); 408 PaintTitlebar(canvas);
(...skipping 11 matching lines...) Expand all
399 // must be called prior to LayoutProfileSwitcher(). 420 // must be called prior to LayoutProfileSwitcher().
400 LayoutCaptionButtons(); 421 LayoutCaptionButtons();
401 LayoutTitleBar(); 422 LayoutTitleBar();
402 } 423 }
403 if (browser_view()->IsRegularOrGuestSession()) 424 if (browser_view()->IsRegularOrGuestSession())
404 LayoutProfileSwitcher(); 425 LayoutProfileSwitcher();
405 LayoutIncognitoIcon(); 426 LayoutIncognitoIcon();
406 LayoutClientView(); 427 LayoutClientView();
407 } 428 }
408 429
430 void GlassBrowserFrameView::ChildPreferredSizeChanged(views::View* child) {
431 if (child == GetProfileSwitcherView()) {
432 // Need to layout the root view here, too, as the avatar button may change
433 // between the text and the icon when a profile is added or removed, which
434 // changes its width. This may cause it to start or stop overlapping the
435 // the tabstrip horizontally, which in turn causes it to change height, as
436 // calculated in LayoutProfileSwitcher(). Calling LayoutProfileSwitcher()
437 // is not enough here - it does not re-draw the line below the tabstrip
438 // properly when a profile is added or removed.
439 frame()->GetRootView()->Layout();
440 }
441 }
442
409 /////////////////////////////////////////////////////////////////////////////// 443 ///////////////////////////////////////////////////////////////////////////////
410 // GlassBrowserFrameView, protected: 444 // GlassBrowserFrameView, protected:
411 445
412 // BrowserNonClientFrameView: 446 // BrowserNonClientFrameView:
413 void GlassBrowserFrameView::UpdateProfileIcons() { 447 void GlassBrowserFrameView::UpdateProfileIcons() {
414 if (browser_view()->IsRegularOrGuestSession()) 448 if (browser_view()->IsRegularOrGuestSession())
415 profile_switcher_.Update(AvatarButtonStyle::NATIVE); 449 profile_switcher_.Update(AvatarButtonStyle::NATIVE);
416 else 450 else
417 UpdateProfileIndicatorIcon(); 451 UpdateProfileIndicatorIcon();
418 } 452 }
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 bottom + kClientEdgeThickness - y); 744 bottom + kClientEdgeThickness - y);
711 canvas->FillRect(side, color); 745 canvas->FillRect(side, color);
712 canvas->FillRect(gfx::Rect(x, bottom, right - x, kClientEdgeThickness), 746 canvas->FillRect(gfx::Rect(x, bottom, right - x, kClientEdgeThickness),
713 color); 747 color);
714 side.set_x(right); 748 side.set_x(right);
715 canvas->FillRect(side, color); 749 canvas->FillRect(side, color);
716 } 750 }
717 751
718 void GlassBrowserFrameView::LayoutProfileSwitcher() { 752 void GlassBrowserFrameView::LayoutProfileSwitcher() {
719 DCHECK(browser_view()->IsRegularOrGuestSession()); 753 DCHECK(browser_view()->IsRegularOrGuestSession());
720 if (!profile_switcher_.view()) 754
755 View* profile_switcher = profile_switcher_.view();
756 if (!profile_switcher)
721 return; 757 return;
722 758
723 gfx::Size label_size = profile_switcher_.view()->GetPreferredSize(); 759 gfx::Size button_size = profile_switcher->GetPreferredSize();
760 int button_width = button_size.width();
761 int button_height = button_size.height();
724 762
725 int button_x; 763 int button_x;
726 if (CaptionButtonsOnLeadingEdge()) { 764 if (CaptionButtonsOnLeadingEdge()) {
727 button_x = width() - frame()->GetMinimizeButtonOffset() + 765 button_x = width() - frame()->GetMinimizeButtonOffset() +
728 kProfileSwitcherButtonOffset; 766 kProfileSwitcherButtonOffset;
729 } else { 767 } else {
730 button_x = 768 button_x = MinimizeButtonX() - kProfileSwitcherButtonOffset - button_width;
731 MinimizeButtonX() - kProfileSwitcherButtonOffset - label_size.width();
732 } 769 }
733 770
734 int button_y = WindowTopY(); 771 int button_y = WindowTopY();
735 if (IsMaximized()) { 772 if (IsMaximized()) {
736 // In maximized mode the caption buttons appear only 19 pixels high, but 773 // In maximized mode the caption buttons appear only 19 pixels high, but
737 // their contents are aligned as if they were 20 pixels high and extended 774 // their contents are aligned as if they were 20 pixels high and extended
738 // 1 pixel off the top of the screen. We position the profile switcher 775 // 1 pixel off the top of the screen. We position the profile switcher
739 // button the same way to match. 776 // button the same way to match.
740 button_y -= 1; 777 button_y -= 1;
741 } 778 }
742 profile_switcher_.view()->SetBounds(button_x, button_y, label_size.width(), 779
743 kProfileSwitcherButtonHeight); 780 // Shrink the button height when it's atop part of the tabstrip. In RTL the
781 // new tab button is on the left, so it can never slide under the avatar
782 // button, which is still on the right [http://crbug.com/560619].
783 TabStrip* tabstrip = browser_view()->tabstrip();
784 if (tabstrip && !base::i18n::IsRTL() && tabstrip->max_x() >= button_x)
785 button_height = profile_switcher->GetMinimumSize().height();
786
787 profile_switcher->SetBounds(button_x, button_y, button_width, button_height);
744 } 788 }
745 789
746 void GlassBrowserFrameView::LayoutIncognitoIcon() { 790 void GlassBrowserFrameView::LayoutIncognitoIcon() {
747 const gfx::Size size(GetIncognitoAvatarIcon().size()); 791 const gfx::Size size(GetIncognitoAvatarIcon().size());
748 int x = ClientBorderThickness(false); 792 int x = ClientBorderThickness(false);
749 // In RTL, the icon needs to start after the caption buttons. 793 // In RTL, the icon needs to start after the caption buttons.
750 if (CaptionButtonsOnLeadingEdge()) { 794 if (CaptionButtonsOnLeadingEdge()) {
751 x = width() - frame()->GetMinimizeButtonOffset() + 795 x = width() - frame()->GetMinimizeButtonOffset() +
752 (profile_switcher_.view() ? (profile_switcher_.view()->width() + 796 (GetProfileSwitcherView() ? (GetProfileSwitcherView()->width() +
753 kProfileSwitcherButtonOffset) 797 kProfileSwitcherButtonOffset)
754 : 0); 798 : 0);
755 } 799 }
756 const int bottom = GetTopInset(false) + browser_view()->GetTabStripHeight() - 800 const int bottom = GetTopInset(false) + browser_view()->GetTabStripHeight() -
757 kAvatarIconPadding; 801 kAvatarIconPadding;
758 incognito_bounds_.SetRect( 802 incognito_bounds_.SetRect(
759 x + (profile_indicator_icon() ? kAvatarIconPadding : 0), 803 x + (profile_indicator_icon() ? kAvatarIconPadding : 0),
760 bottom - size.height(), profile_indicator_icon() ? size.width() : 0, 804 bottom - size.height(), profile_indicator_icon() ? size.width() : 0,
761 size.height()); 805 size.height());
762 if (profile_indicator_icon()) 806 if (profile_indicator_icon())
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
915 static bool initialized = false; 959 static bool initialized = false;
916 if (!initialized) { 960 if (!initialized) {
917 for (int i = 0; i < kThrobberIconCount; ++i) { 961 for (int i = 0; i < kThrobberIconCount; ++i) {
918 throbber_icons_[i] = 962 throbber_icons_[i] =
919 ui::LoadThemeIconFromResourcesDataDLL(IDI_THROBBER_01 + i); 963 ui::LoadThemeIconFromResourcesDataDLL(IDI_THROBBER_01 + i);
920 DCHECK(throbber_icons_[i]); 964 DCHECK(throbber_icons_[i]);
921 } 965 }
922 initialized = true; 966 initialized = true;
923 } 967 }
924 } 968 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698