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

Side by Side Diff: chrome/browser/ui/cocoa/profiles/avatar_button_controller.mm

Issue 2286993002: [Material][Mac] Update the User Account Button (Closed)
Patch Set: fixed test Created 4 years, 3 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
« no previous file with comments | « no previous file | chrome/browser/ui/cocoa/profiles/avatar_button_controller_unittest.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 #import "chrome/browser/ui/cocoa/profiles/avatar_button_controller.h" 5 #import "chrome/browser/ui/cocoa/profiles/avatar_button_controller.h"
6 6
7 #include "base/mac/foundation_util.h" 7 #include "base/mac/foundation_util.h"
8 #include "base/strings/sys_string_conversions.h" 8 #include "base/strings/sys_string_conversions.h"
9 #include "chrome/browser/browser_process.h" 9 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/profiles/profile_attributes_entry.h" 10 #include "chrome/browser/profiles/profile_attributes_entry.h"
11 #include "chrome/browser/profiles/profile_attributes_storage.h" 11 #include "chrome/browser/profiles/profile_attributes_storage.h"
12 #include "chrome/browser/profiles/profile_manager.h" 12 #include "chrome/browser/profiles/profile_manager.h"
13 #include "chrome/browser/profiles/profiles_state.h" 13 #include "chrome/browser/profiles/profiles_state.h"
14 #include "chrome/browser/themes/theme_service.h" 14 #include "chrome/browser/themes/theme_service.h"
15 #include "chrome/browser/themes/theme_service_factory.h" 15 #include "chrome/browser/themes/theme_service_factory.h"
16 #include "chrome/browser/ui/browser.h" 16 #include "chrome/browser/ui/browser.h"
17 #include "chrome/browser/ui/browser_window.h" 17 #include "chrome/browser/ui/browser_window.h"
18 #import "chrome/browser/ui/cocoa/browser_window_controller.h" 18 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
19 #import "chrome/browser/ui/cocoa/profiles/avatar_button.h" 19 #import "chrome/browser/ui/cocoa/profiles/avatar_button.h"
20 #include "chrome/grit/generated_resources.h" 20 #include "chrome/grit/generated_resources.h"
21 #include "chrome/grit/theme_resources.h" 21 #include "chrome/grit/theme_resources.h"
22 #include "components/signin/core/common/profile_management_switches.h" 22 #include "components/signin/core/common/profile_management_switches.h"
23 #include "skia/ext/skia_utils_mac.h"
23 #import "ui/base/cocoa/appkit_utils.h" 24 #import "ui/base/cocoa/appkit_utils.h"
24 #include "ui/base/l10n/l10n_util_mac.h" 25 #include "ui/base/l10n/l10n_util_mac.h"
25 #include "ui/base/material_design/material_design_controller.h" 26 #include "ui/base/material_design/material_design_controller.h"
26 #include "ui/base/nine_image_painter_factory.h" 27 #include "ui/base/nine_image_painter_factory.h"
27 #include "ui/base/resource/resource_bundle.h" 28 #include "ui/base/resource/resource_bundle.h"
28 #include "ui/gfx/color_palette.h" 29 #include "ui/gfx/color_palette.h"
29 #include "ui/gfx/image/image_skia_operations.h" 30 #include "ui/gfx/image/image_skia_operations.h"
30 #include "ui/gfx/image/image_skia_util_mac.h" 31 #include "ui/gfx/image/image_skia_util_mac.h"
31 #include "ui/gfx/paint_vector_icon.h" 32 #include "ui/gfx/paint_vector_icon.h"
32 #include "ui/gfx/vector_icons_public.h" 33 #include "ui/gfx/vector_icons_public.h"
33 34
34 namespace { 35 namespace {
35 36
36 // NSButtons have a default padding of 5px. This button should have a padding
37 // of 8px.
38 const CGFloat kButtonExtraPadding = 8 - 5;
39 const CGFloat kButtonHeight = 28;
40
41 const ui::NinePartImageIds kNormalBorderImageIds = 37 const ui::NinePartImageIds kNormalBorderImageIds =
42 IMAGE_GRID(IDR_AVATAR_NATIVE_BUTTON_NORMAL); 38 IMAGE_GRID(IDR_AVATAR_NATIVE_BUTTON_NORMAL);
43 const ui::NinePartImageIds kHoverBorderImageIds = 39 const ui::NinePartImageIds kHoverBorderImageIds =
44 IMAGE_GRID(IDR_AVATAR_NATIVE_BUTTON_HOVER); 40 IMAGE_GRID(IDR_AVATAR_NATIVE_BUTTON_HOVER);
45 const ui::NinePartImageIds kPressedBorderImageIds = 41 const ui::NinePartImageIds kPressedBorderImageIds =
46 IMAGE_GRID(IDR_AVATAR_NATIVE_BUTTON_PRESSED); 42 IMAGE_GRID(IDR_AVATAR_NATIVE_BUTTON_PRESSED);
47 const ui::NinePartImageIds kThemedBorderImageIds = 43 const ui::NinePartImageIds kThemedBorderImageIds =
48 IMAGE_GRID(IDR_AVATAR_THEMED_MAC_BUTTON_NORMAL); 44 IMAGE_GRID(IDR_AVATAR_THEMED_MAC_BUTTON_NORMAL);
49 45
50 NSImage* GetImageFromResourceID(int resourceId) { 46 NSImage* GetImageFromResourceID(int resourceId) {
51 return ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed( 47 return ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed(
52 resourceId).ToNSImage(); 48 resourceId).ToNSImage();
53 } 49 }
54 50
51 const SkColor kMaterialButtonHoverColor = SkColorSetARGB(20, 0, 0, 0);
52 const SkColor kMaterialButtonPressedColor = SkColorSetARGB(31, 0, 0, 0);
53 const SkColor kMaterialAvatarIconColor = SkColorSetRGB(0x5a, 0x5a, 0x5a);
54
55 CGFloat ButtonHeight() {
56 const CGFloat kButtonHeight = 28;
57 const CGFloat kMaterialButtonHeight = 24;
58 return ui::MaterialDesignController::IsModeMaterial() ? kMaterialButtonHeight
59 : kButtonHeight;
60 }
61
62 // NSButtons have a default padding of 5px. Non-MD buttons should have a
63 // padding of 8px. Meanwhile, MD buttons should have a padding of 6px.
64 CGFloat ButtonExtraPadding() {
65 const CGFloat kDefaultPadding = 5;
66 const CGFloat kButtonExtraPadding = 8 - kDefaultPadding;
67 const CGFloat kMaterialButtonExtraPadding = 6 - kDefaultPadding;
68
69 return ui::MaterialDesignController::IsModeMaterial()
70 ? kMaterialButtonExtraPadding
71 : kButtonExtraPadding;
72 }
73
74 // Extra padding for the MD signed out avatar button.
75 const CGFloat kMaterialSignedOutWidthPadding = 2;
76
55 } // namespace 77 } // namespace
56 78
57 // Button cell with a custom border given by a set of nine-patch image grids. 79 // Button cell with a custom border given by a set of nine-patch image grids.
58 @interface CustomThemeButtonCell : NSButtonCell { 80 @interface CustomThemeButtonCell : NSButtonCell {
59 @private 81 @private
60 BOOL isThemedWindow_; 82 BOOL isThemedWindow_;
61 BOOL hasError_; 83 BOOL hasError_;
62 } 84 }
63 - (void)setIsThemedWindow:(BOOL)isThemedWindow; 85 - (void)setIsThemedWindow:(BOOL)isThemedWindow;
64 - (void)setHasError:(BOOL)hasError withTitle:(NSString*)title; 86 - (void)setHasError:(BOOL)hasError withTitle:(NSString*)title;
65 87
66 @end 88 @end
67 89
68 @implementation CustomThemeButtonCell 90 @implementation CustomThemeButtonCell
69 - (id)initWithThemedWindow:(BOOL)isThemedWindow { 91 - (id)initWithThemedWindow:(BOOL)isThemedWindow {
70 if ((self = [super init])) { 92 if ((self = [super init])) {
71 isThemedWindow_ = isThemedWindow; 93 isThemedWindow_ = isThemedWindow;
72 hasError_ = false; 94 hasError_ = false;
73 } 95 }
74 return self; 96 return self;
75 } 97 }
76 98
77 - (NSSize)cellSize { 99 - (NSSize)cellSize {
78 NSSize buttonSize = [super cellSize]; 100 NSSize buttonSize = [super cellSize];
79 101
80 // An image and no error means we are drawing the generic button, which 102 // An image and no error means we are drawing the generic button, which
81 // is square. Otherwise, we are displaying the profile's name and an 103 // is square. Otherwise, we are displaying the profile's name and an
82 // optional authentication error icon. 104 // optional authentication error icon.
83 if ([self image] && !hasError_) { 105 if ([self image] && !hasError_) {
84 buttonSize.width = kButtonHeight; 106 buttonSize.width = ButtonHeight();
107 if (ui::MaterialDesignController::IsModeMaterial())
108 buttonSize.width += kMaterialSignedOutWidthPadding;
85 } else { 109 } else {
86 buttonSize.width += 2 * kButtonExtraPadding; 110 buttonSize.width += 2 * ButtonExtraPadding();
87 } 111 }
88 buttonSize.height = kButtonHeight; 112 buttonSize.height = ButtonHeight();
89 return buttonSize; 113 return buttonSize;
90 } 114 }
91 115
92 - (void)drawInteriorWithFrame:(NSRect)frame inView:(NSView*)controlView { 116 - (void)drawInteriorWithFrame:(NSRect)frame inView:(NSView*)controlView {
93 NSRect frameAfterPadding = NSInsetRect(frame, kButtonExtraPadding, 0); 117 NSRect frameAfterPadding = NSInsetRect(frame, ButtonExtraPadding(), 0);
94 [super drawInteriorWithFrame:frameAfterPadding inView:controlView]; 118 [super drawInteriorWithFrame:frameAfterPadding inView:controlView];
95 } 119 }
96 120
97 - (void)drawImage:(NSImage*)image 121 - (void)drawImage:(NSImage*)image
98 withFrame:(NSRect)frame 122 withFrame:(NSRect)frame
99 inView:(NSView*)controlView { 123 inView:(NSView*)controlView {
100 // The image used in the generic button case as well as the material-designed 124 // The image used in the generic button case as well as the material-designed
101 // error icon both need to be shifted down slightly to be centered correctly. 125 // error icon both need to be shifted down slightly to be centered correctly.
102 // TODO(noms): When the assets are fixed, remove this latter offset. 126 // TODO(noms): When the assets are fixed, remove this latter offset.
103 if (!hasError_ || switches::IsMaterialDesignUserMenu()) 127 if (!hasError_ || switches::IsMaterialDesignUserMenu())
104 frame = NSOffsetRect(frame, 0, 1); 128 frame = NSOffsetRect(frame, 0, 1);
105 [super drawImage:image withFrame:frame inView:controlView]; 129 [super drawImage:image withFrame:frame inView:controlView];
106 } 130 }
107 131
108 - (void)drawBezelWithFrame:(NSRect)frame 132 - (void)drawBezelWithFrame:(NSRect)frame
109 inView:(NSView*)controlView { 133 inView:(NSView*)controlView {
110 HoverState hoverState = 134 HoverState hoverState =
111 [base::mac::ObjCCastStrict<AvatarButton>(controlView) hoverState]; 135 [base::mac::ObjCCastStrict<AvatarButton>(controlView) hoverState];
112 ui::NinePartImageIds imageIds = kNormalBorderImageIds;
113 if (isThemedWindow_)
114 imageIds = kThemedBorderImageIds;
115 136
116 if (hoverState == kHoverStateMouseDown) 137 if (ui::MaterialDesignController::IsModeMaterial()) {
117 imageIds = kPressedBorderImageIds; 138 NSColor* backgroundColor = nil;
118 else if (hoverState == kHoverStateMouseOver) 139 if (hoverState == kHoverStateMouseDown) {
119 imageIds = kHoverBorderImageIds; 140 backgroundColor = skia::SkColorToSRGBNSColor(kMaterialButtonPressedColor);
120 ui::DrawNinePartImage(frame, imageIds, NSCompositeSourceOver, 1.0, true); 141 } else if (hoverState == kHoverStateMouseOver) {
142 backgroundColor = skia::SkColorToSRGBNSColor(kMaterialButtonHoverColor);
143 }
144
145 if (backgroundColor) {
146 [backgroundColor set];
147 NSBezierPath* path = [NSBezierPath bezierPathWithRoundedRect:frame
148 xRadius:2.0f
149 yRadius:2.0f];
150 [path fill];
151 }
152 } else {
153 ui::NinePartImageIds imageIds = kNormalBorderImageIds;
154 if (isThemedWindow_)
155 imageIds = kThemedBorderImageIds;
156
157 if (hoverState == kHoverStateMouseDown)
158 imageIds = kPressedBorderImageIds;
159 else if (hoverState == kHoverStateMouseOver)
160 imageIds = kHoverBorderImageIds;
161 ui::DrawNinePartImage(frame, imageIds, NSCompositeSourceOver, 1.0, true);
162 }
121 } 163 }
122 164
123 - (void)drawFocusRingMaskWithFrame:(NSRect)frame inView:(NSView*)view { 165 - (void)drawFocusRingMaskWithFrame:(NSRect)frame inView:(NSView*)view {
124 // Match the bezel's shape. 166 // Match the bezel's shape.
125 [[NSBezierPath bezierPathWithRoundedRect:NSInsetRect(frame, 2, 2) 167 [[NSBezierPath bezierPathWithRoundedRect:NSInsetRect(frame, 2, 2)
126 xRadius:2 168 xRadius:2
127 yRadius:2] fill]; 169 yRadius:2] fill];
128 } 170 }
129 171
130 - (void)setIsThemedWindow:(BOOL)isThemedWindow { 172 - (void)setIsThemedWindow:(BOOL)isThemedWindow {
(...skipping 24 matching lines...) Expand all
155 197
156 - (id)initWithBrowser:(Browser*)browser { 198 - (id)initWithBrowser:(Browser*)browser {
157 if ((self = [super initWithBrowser:browser])) { 199 if ((self = [super initWithBrowser:browser])) {
158 ThemeService* themeService = 200 ThemeService* themeService =
159 ThemeServiceFactory::GetForProfile(browser->profile()); 201 ThemeServiceFactory::GetForProfile(browser->profile());
160 isThemedWindow_ = !themeService->UsingSystemTheme(); 202 isThemedWindow_ = !themeService->UsingSystemTheme();
161 203
162 AvatarButton* avatarButton = 204 AvatarButton* avatarButton =
163 [[AvatarButton alloc] initWithFrame:NSZeroRect]; 205 [[AvatarButton alloc] initWithFrame:NSZeroRect];
164 button_.reset(avatarButton); 206 button_.reset(avatarButton);
165 base::scoped_nsobject<CustomThemeButtonCell> cell( 207
208 base::scoped_nsobject<NSButtonCell> cell(
166 [[CustomThemeButtonCell alloc] initWithThemedWindow:isThemedWindow_]); 209 [[CustomThemeButtonCell alloc] initWithThemedWindow:isThemedWindow_]);
210
167 [avatarButton setCell:cell.get()]; 211 [avatarButton setCell:cell.get()];
168 212
169 [avatarButton setWantsLayer:YES]; 213 [avatarButton setWantsLayer:YES];
170 [self setView:avatarButton]; 214 [self setView:avatarButton];
171 215
172 [avatarButton setBezelStyle:NSShadowlessSquareBezelStyle]; 216 [avatarButton setBezelStyle:NSShadowlessSquareBezelStyle];
173 [avatarButton setButtonType:NSMomentaryChangeButton]; 217 [avatarButton setButtonType:NSMomentaryChangeButton];
174 if (switches::IsMaterialDesignUserMenu()) 218 if (switches::IsMaterialDesignUserMenu())
175 [[avatarButton cell] setHighlightsBy:NSNoCellMask]; 219 [[avatarButton cell] setHighlightsBy:NSNoCellMask];
176 [avatarButton setBordered:YES]; 220 [avatarButton setBordered:YES];
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 !storage.GetAllProfilesAttributes().front()->IsAuthenticated(); 287 !storage.GetAllProfilesAttributes().front()->IsAuthenticated();
244 288
245 289
246 NSString* buttonTitle = base::SysUTF16ToNSString(useGenericButton ? 290 NSString* buttonTitle = base::SysUTF16ToNSString(useGenericButton ?
247 base::string16() : 291 base::string16() :
248 profiles::GetAvatarButtonTextForProfile(browser_->profile())); 292 profiles::GetAvatarButtonTextForProfile(browser_->profile()));
249 [[button_ cell] setHasError:hasError_ withTitle:buttonTitle]; 293 [[button_ cell] setHasError:hasError_ withTitle:buttonTitle];
250 294
251 AvatarButton* button = 295 AvatarButton* button =
252 base::mac::ObjCCastStrict<AvatarButton>(button_); 296 base::mac::ObjCCastStrict<AvatarButton>(button_);
297
253 if (useGenericButton) { 298 if (useGenericButton) {
254 [button setDefaultImage:GetImageFromResourceID( 299 if (ui::MaterialDesignController::IsModeMaterial()) {
255 IDR_AVATAR_NATIVE_BUTTON_AVATAR)]; 300 NSImage* avatarIcon = NSImageFromImageSkia(
256 [button setHoverImage:GetImageFromResourceID( 301 gfx::CreateVectorIcon(gfx::VectorIconId::USER_ACCOUNT_AVATAR, 18,
257 IDR_AVATAR_NATIVE_BUTTON_AVATAR_HOVER)]; 302 kMaterialAvatarIconColor));
258 [button setPressedImage:GetImageFromResourceID( 303 [button setDefaultImage:avatarIcon];
259 IDR_AVATAR_NATIVE_BUTTON_AVATAR_PRESSED)]; 304 [button setHoverImage:nil];
260 // This is a workaround for an issue in the HoverImageButton where the 305 [button setPressedImage:nil];
261 // button is initially sized incorrectly unless a default image is provided. 306 } else {
262 // See crbug.com/298501. 307 [button setDefaultImage:GetImageFromResourceID(
263 [button setImage:GetImageFromResourceID(IDR_AVATAR_NATIVE_BUTTON_AVATAR)]; 308 IDR_AVATAR_NATIVE_BUTTON_AVATAR)];
309 [button setHoverImage:GetImageFromResourceID(
310 IDR_AVATAR_NATIVE_BUTTON_AVATAR_HOVER)];
311 [button setPressedImage:GetImageFromResourceID(
312 IDR_AVATAR_NATIVE_BUTTON_AVATAR_PRESSED)];
313 // This is a workaround for an issue in the HoverImageButton where the
314 // button is initially sized incorrectly unless a default image is
315 // provided.
316 // See crbug.com/298501.
317 [button setImage:GetImageFromResourceID(IDR_AVATAR_NATIVE_BUTTON_AVATAR)];
318 }
264 [button setImagePosition:NSImageOnly]; 319 [button setImagePosition:NSImageOnly];
265 } else if (hasError_) { 320 } else if (hasError_) {
321 BOOL isMaterial = ui::MaterialDesignController::IsModeMaterial();
266 NSImage* errorIcon = 322 NSImage* errorIcon =
267 switches::IsMaterialDesignUserMenu() 323 isMaterial
268 ? NSImageFromImageSkia(gfx::CreateVectorIcon( 324 ? NSImageFromImageSkia(gfx::CreateVectorIcon(
269 gfx::VectorIconId::SYNC_PROBLEM, 16, gfx::kGoogleRed700)) 325 gfx::VectorIconId::SYNC_PROBLEM, 16, gfx::kGoogleRed700))
270 : GetImageFromResourceID(IDR_ICON_PROFILES_AVATAR_BUTTON_ERROR); 326 : GetImageFromResourceID(IDR_ICON_PROFILES_AVATAR_BUTTON_ERROR);
271 [button setDefaultImage:errorIcon]; 327 [button setDefaultImage:errorIcon];
272 [button setHoverImage:nil]; 328 [button setHoverImage:nil];
273 [button setPressedImage:nil]; 329 [button setPressedImage:nil];
274 [button setImage:errorIcon]; 330 [button setImage:errorIcon];
275 [button setImagePosition:switches::IsMaterialDesignUserMenu() 331 [button setImagePosition:isMaterial ? NSImageLeft : NSImageRight];
276 ? NSImageLeft
277 : NSImageRight];
278 } else { 332 } else {
279 [button setDefaultImage:nil]; 333 [button setDefaultImage:nil];
280 [button setHoverImage:nil]; 334 [button setHoverImage:nil];
281 [button setPressedImage:nil]; 335 [button setPressedImage:nil];
282 [button setImagePosition:NSNoImage]; 336 [button setImagePosition:NSNoImage];
283 } 337 }
284 338
285 base::scoped_nsobject<NSMutableParagraphStyle> paragraphStyle( 339 base::scoped_nsobject<NSMutableParagraphStyle> paragraphStyle(
286 [[NSMutableParagraphStyle alloc] init]); 340 [[NSMutableParagraphStyle alloc] init]);
287 [paragraphStyle setAlignment:NSLeftTextAlignment]; 341 [paragraphStyle setAlignment:NSLeftTextAlignment];
(...skipping 15 matching lines...) Expand all
303 layoutSubviews]; 357 layoutSubviews];
304 } 358 }
305 } 359 }
306 360
307 - (void)setErrorStatus:(BOOL)hasError { 361 - (void)setErrorStatus:(BOOL)hasError {
308 hasError_ = hasError; 362 hasError_ = hasError;
309 [self updateAvatarButtonAndLayoutParent:YES]; 363 [self updateAvatarButtonAndLayoutParent:YES];
310 } 364 }
311 365
312 @end 366 @end
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/ui/cocoa/profiles/avatar_button_controller_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698