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

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

Issue 235833002: [Mac] Redesign the avatar bubble UI (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix unittest broken by rebase Created 6 years, 8 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 | Annotate | Revision Log
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 <Cocoa/Cocoa.h> 5 #import <Cocoa/Cocoa.h>
6 6
7 #import "chrome/browser/ui/cocoa/profiles/profile_chooser_controller.h" 7 #import "chrome/browser/ui/cocoa/profiles/profile_chooser_controller.h"
8 8
9 #include "base/mac/bundle_locations.h" 9 #include "base/mac/bundle_locations.h"
10 #include "base/prefs/pref_service.h" 10 #include "base/prefs/pref_service.h"
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 #include "ui/base/l10n/l10n_util_mac.h" 58 #include "ui/base/l10n/l10n_util_mac.h"
59 #include "ui/base/resource/resource_bundle.h" 59 #include "ui/base/resource/resource_bundle.h"
60 #include "ui/gfx/image/image.h" 60 #include "ui/gfx/image/image.h"
61 #include "ui/gfx/text_elider.h" 61 #include "ui/gfx/text_elider.h"
62 #include "ui/native_theme/native_theme.h" 62 #include "ui/native_theme/native_theme.h"
63 63
64 namespace { 64 namespace {
65 65
66 // Constants taken from the Windows/Views implementation at: 66 // Constants taken from the Windows/Views implementation at:
67 // chrome/browser/ui/views/profile_chooser_view.cc 67 // chrome/browser/ui/views/profile_chooser_view.cc
68 const int kLargeImageSide = 64; 68 const int kLargeImageSide = 88;
69 const int kSmallImageSide = 32; 69 const int kSmallImageSide = 32;
70 const CGFloat kFixedMenuWidth = 250; 70 const CGFloat kFixedMenuWidth = 250;
71 71
72 const CGFloat kVerticalSpacing = 20.0; 72 const CGFloat kVerticalSpacing = 16.0;
73 const CGFloat kSmallVerticalSpacing = 10.0; 73 const CGFloat kSmallVerticalSpacing = 10.0;
74 const CGFloat kHorizontalSpacing = 20.0; 74 const CGFloat kHorizontalSpacing = 16.0;
75 const CGFloat kTitleFontSize = 15.0; 75 const CGFloat kTitleFontSize = 15.0;
76 const CGFloat kTextFontSize = 12.0; 76 const CGFloat kTextFontSize = 12.0;
77 const CGFloat kProfileButtonHeight = 30; 77 const CGFloat kProfileButtonHeight = 30;
78 const int kOverlayHeight = 20; // Height of the "Change" avatar photo overlay. 78 const int kOverlayHeight = 20; // Height of the "Change" avatar photo overlay.
79 const int kBezelThickness = 3; // Width of the bezel on an NSButton. 79 const int kBezelThickness = 3; // Width of the bezel on an NSButton.
80 const int kImageTitleSpacing = 10; 80 const int kImageTitleSpacing = 10;
81 const int kBlueButtonHeight = 30; 81 const int kBlueButtonHeight = 30;
82 82
83 // Fixed size for embedded sign in pages as defined in Gaia. 83 // Fixed size for embedded sign in pages as defined in Gaia.
84 const CGFloat kFixedGaiaViewWidth = 360; 84 const CGFloat kFixedGaiaViewWidth = 360;
85 const CGFloat kFixedGaiaViewHeight = 400; 85 const CGFloat kFixedGaiaViewHeight = 400;
86 86
87 // Fixed size for the account removal view. 87 // Fixed size for the account removal view.
88 const CGFloat kFixedAccountRemovalViewWidth = 280; 88 const CGFloat kFixedAccountRemovalViewWidth = 280;
89 89
90 // Maximum number of times to show the tutorial in the profile avatar bubble. 90 // Maximum number of times to show the tutorial in the profile avatar bubble.
91 const int kProfileAvatarTutorialShowMax = 5; 91 const int kProfileAvatarTutorialShowMax = 5;
92 92
93 // The tag number for the primary account. 93 // The tag number for the primary account.
94 const int kPrimaryProfileTag = -1; 94 const int kPrimaryProfileTag = -1;
95 95
96 gfx::Image CreateProfileImage(const gfx::Image& icon, int imageSize) { 96 gfx::Image CreateProfileImage(const gfx::Image& icon, int imageSize) {
97 return profiles::GetSizedAvatarIconWithBorder( 97 return profiles::GetSizedAvatarIcon(
98 icon, true /* image is a square */, 98 icon, true /* image is a square */,
99 imageSize + profiles::kAvatarIconPadding, 99 imageSize + profiles::kAvatarIconPadding,
100 imageSize + profiles::kAvatarIconPadding); 100 imageSize + profiles::kAvatarIconPadding);
101 } 101 }
102 102
103 // Updates the window size and position. 103 // Updates the window size and position.
104 void SetWindowSize(NSWindow* window, NSSize size) { 104 void SetWindowSize(NSWindow* window, NSSize size) {
105 NSRect frame = [window frame]; 105 NSRect frame = [window frame];
106 frame.origin.x += frame.size.width - size.width; 106 frame.origin.x += frame.size.width - size.width;
107 frame.origin.y += frame.size.height - size.height; 107 frame.origin.y += frame.size.height - size.height;
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 @implementation EditableProfileNameButton 476 @implementation EditableProfileNameButton
477 - (id)initWithFrame:(NSRect)frameRect 477 - (id)initWithFrame:(NSRect)frameRect
478 profile:(Profile*)profile 478 profile:(Profile*)profile
479 profileName:(NSString*)profileName 479 profileName:(NSString*)profileName
480 editingAllowed:(BOOL)editingAllowed { 480 editingAllowed:(BOOL)editingAllowed {
481 if ((self = [super initWithFrame:frameRect])) { 481 if ((self = [super initWithFrame:frameRect])) {
482 profile_ = profile; 482 profile_ = profile;
483 483
484 [self setBordered:NO]; 484 [self setBordered:NO];
485 [self setFont:[NSFont labelFontOfSize:kTitleFontSize]]; 485 [self setFont:[NSFont labelFontOfSize:kTitleFontSize]];
486 [self setAlignment:NSLeftTextAlignment]; 486 [self setAlignment:NSCenterTextAlignment];
487 [[self cell] setLineBreakMode:NSLineBreakByTruncatingTail]; 487 [[self cell] setLineBreakMode:NSLineBreakByTruncatingTail];
488 [self setTitle:profileName]; 488 [self setTitle:profileName];
489 489
490 if (editingAllowed) { 490 if (editingAllowed) {
491 // Show an "edit" pencil icon when hovering over. 491 // Show an "edit" pencil icon when hovering over. In the default state,
492 // we need to create an empty placeholder of the correct size, so that
493 // the text doesn't jump around when the hovered icon appears.
492 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); 494 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
493 [self setHoverImage: 495 NSImage* hoverImage = rb->GetNativeImageNamed(
494 rb->GetNativeImageNamed(IDR_ICON_PROFILES_EDIT_HOVER).AsNSImage()]; 496 IDR_ICON_PROFILES_EDIT_HOVER).AsNSImage();
497 NSImage* placeholder = [[NSImage alloc] initWithSize:[hoverImage size]];
498 [self setDefaultImage:placeholder];
499 [self setHoverImage:hoverImage];
495 [self setAlternateImage: 500 [self setAlternateImage:
496 rb->GetNativeImageNamed(IDR_ICON_PROFILES_EDIT_PRESSED).AsNSImage()]; 501 rb->GetNativeImageNamed(IDR_ICON_PROFILES_EDIT_PRESSED).AsNSImage()];
497 [self setImagePosition:NSImageRight]; 502 [self setImagePosition:NSImageRight];
498 [self setTarget:self]; 503 [self setTarget:self];
499 [self setAction:@selector(showEditableView:)]; 504 [self setAction:@selector(showEditableView:)];
500 505
501 // We need to subtract the width of the bezel from the frame rect, so that 506 // We need to subtract the width of the bezel from the frame rect, so that
502 // the textfield can take the exact same space as the button. 507 // the textfield can take the exact same space as the button.
503 frameRect.size.height -= 2 * kBezelThickness; 508 frameRect.size.height -= 2 * kBezelThickness;
504 frameRect.origin = NSMakePoint(0, kBezelThickness); 509 frameRect.origin = NSMakePoint(0, kBezelThickness);
505 profileNameTextField_.reset( 510 profileNameTextField_.reset(
506 [[NSTextField alloc] initWithFrame:frameRect]); 511 [[NSTextField alloc] initWithFrame:frameRect]);
507 [profileNameTextField_ setStringValue:profileName]; 512 [profileNameTextField_ setStringValue:profileName];
508 [profileNameTextField_ setFont:[NSFont labelFontOfSize:kTitleFontSize]]; 513 [profileNameTextField_ setFont:[NSFont labelFontOfSize:kTitleFontSize]];
509 [profileNameTextField_ setEditable:YES]; 514 [profileNameTextField_ setEditable:YES];
510 [profileNameTextField_ setDrawsBackground:YES]; 515 [profileNameTextField_ setDrawsBackground:YES];
511 [profileNameTextField_ setBezeled:YES]; 516 [profileNameTextField_ setBezeled:YES];
517 [profileNameTextField_ setAlignment:NSCenterTextAlignment];
512 [[profileNameTextField_ cell] setWraps:NO]; 518 [[profileNameTextField_ cell] setWraps:NO];
513 [[profileNameTextField_ cell] setLineBreakMode: 519 [[profileNameTextField_ cell] setLineBreakMode:
514 NSLineBreakByTruncatingTail]; 520 NSLineBreakByTruncatingTail];
515 [profileNameTextField_ setDelegate:self]; 521 [profileNameTextField_ setDelegate:self];
516 [self addSubview:profileNameTextField_]; 522 [self addSubview:profileNameTextField_];
517 523
518 // Hide the textfield until the user clicks on the button. 524 // Hide the textfield until the user clicks on the button.
519 [profileNameTextField_ setHidden:YES]; 525 [profileNameTextField_ setHidden:YES];
520 } 526 }
521 } 527 }
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 591
586 - (NSSize)cellSize { 592 - (NSSize)cellSize {
587 NSSize buttonSize = [super cellSize]; 593 NSSize buttonSize = [super cellSize];
588 buttonSize.width += leftMarginSpacing_ + imageTitleSpacing_; 594 buttonSize.width += leftMarginSpacing_ + imageTitleSpacing_;
589 return buttonSize; 595 return buttonSize;
590 } 596 }
591 597
592 @end 598 @end
593 599
594 // A custom button that allows for setting a background color when hovered over. 600 // A custom button that allows for setting a background color when hovered over.
595 @interface BackgroundColorHoverButton : HoverImageButton 601 @interface BackgroundColorHoverButton : HoverImageButton {
602 @private
603 base::scoped_nsobject<NSColor> backgroundColor_;
604 base::scoped_nsobject<NSColor> hoverColor_;
605 }
596 @end 606 @end
597 607
598 @implementation BackgroundColorHoverButton 608 @implementation BackgroundColorHoverButton
599 - (id)initWithFrame:(NSRect)frameRect { 609
610 - (id)initWithFrame:(NSRect)frameRect
611 imageTitleSpacing:(int)imageTitleSpacing
612 backgroundColor:(NSColor*)backgroundColor {
600 if ((self = [super initWithFrame:frameRect])) { 613 if ((self = [super initWithFrame:frameRect])) {
614 backgroundColor_.reset([backgroundColor retain]);
615 hoverColor_.reset([gfx::SkColorToCalibratedNSColor(
616 ui::NativeTheme::instance()->GetSystemColor(
617 ui::NativeTheme::kColorId_ButtonHoverBackgroundColor)) retain]);
618
601 [self setBordered:NO]; 619 [self setBordered:NO];
602 [self setFont:[NSFont labelFontOfSize:kTextFontSize]]; 620 [self setFont:[NSFont labelFontOfSize:kTextFontSize]];
603 [self setButtonType:NSMomentaryChangeButton]; 621 [self setButtonType:NSMomentaryChangeButton];
604 622
605 base::scoped_nsobject<CustomPaddingImageButtonCell> cell( 623 base::scoped_nsobject<CustomPaddingImageButtonCell> cell(
606 [[CustomPaddingImageButtonCell alloc] 624 [[CustomPaddingImageButtonCell alloc]
607 initWithLeftMarginSpacing:kHorizontalSpacing 625 initWithLeftMarginSpacing:kHorizontalSpacing
608 imageTitleSpacing:kImageTitleSpacing]); 626 imageTitleSpacing:imageTitleSpacing]);
609 [cell setLineBreakMode:NSLineBreakByTruncatingTail]; 627 [cell setLineBreakMode:NSLineBreakByTruncatingTail];
610 [self setCell:cell.get()]; 628 [self setCell:cell.get()];
611 } 629 }
612 return self; 630 return self;
613 } 631 }
614 632
615 - (void)setHoverState:(HoverState)state { 633 - (void)setHoverState:(HoverState)state {
616 [super setHoverState:state]; 634 [super setHoverState:state];
617 bool isHighlighted = ([self hoverState] != kHoverStateNone); 635 bool isHighlighted = ([self hoverState] != kHoverStateNone);
618 636
619 NSColor* backgroundColor = gfx::SkColorToCalibratedNSColor( 637 NSColor* backgroundColor = isHighlighted ? hoverColor_ : backgroundColor_;
620 ui::NativeTheme::instance()->GetSystemColor(isHighlighted?
621 ui::NativeTheme::kColorId_MenuSeparatorColor :
622 ui::NativeTheme::kColorId_DialogBackground));
623
624 [[self cell] setBackgroundColor:backgroundColor]; 638 [[self cell] setBackgroundColor:backgroundColor];
625 } 639 }
626 640
627 @end 641 @end
628 642
629 // A custom view with the given background color. 643 // A custom view with the given background color.
630 @interface BackgroundColorView : NSView { 644 @interface BackgroundColorView : NSView {
631 @private 645 @private
632 base::scoped_nsobject<NSColor> backgroundColor_; 646 base::scoped_nsobject<NSColor> backgroundColor_;
633 } 647 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
666 // out the feature. Otherwise, it notifies the user that the feature has been 680 // out the feature. Otherwise, it notifies the user that the feature has been
667 // enabled if needed. 681 // enabled if needed.
668 - (NSView*)buildPreviewTutorialIfNeeded:(const AvatarMenu::Item&)item; 682 - (NSView*)buildPreviewTutorialIfNeeded:(const AvatarMenu::Item&)item;
669 683
670 // Creates the main profile card for the profile |item| at the top of 684 // Creates the main profile card for the profile |item| at the top of
671 // the bubble. 685 // the bubble.
672 - (NSView*)createCurrentProfileView:(const AvatarMenu::Item&)item; 686 - (NSView*)createCurrentProfileView:(const AvatarMenu::Item&)item;
673 687
674 // Creates the possible links for the main profile card with profile |item|. 688 // Creates the possible links for the main profile card with profile |item|.
675 - (NSView*)createCurrentProfileLinksForItem:(const AvatarMenu::Item&)item 689 - (NSView*)createCurrentProfileLinksForItem:(const AvatarMenu::Item&)item
676 withXOffset:(CGFloat)xOffset; 690 rect:(NSRect)rect;
677 691
678 // Creates a main profile card for the guest user. 692 // Creates a main profile card for the guest user.
679 - (NSView*)createGuestProfileView; 693 - (NSView*)createGuestProfileView;
680 694
681 // Creates an item for the profile |itemIndex| that is used in the fast profile 695 // Creates an item for the profile |itemIndex| that is used in the fast profile
682 // switcher in the middle of the bubble. 696 // switcher in the middle of the bubble.
683 - (NSButton*)createOtherProfileView:(int)itemIndex; 697 - (NSButton*)createOtherProfileView:(int)itemIndex;
684 698
685 // Creates the "Not you" and Lock option buttons. 699 // Creates the "Not you" and Lock option buttons.
686 - (NSView*)createOptionsViewWithRect:(NSRect)rect 700 - (NSView*)createOptionsViewWithRect:(NSRect)rect
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
733 } 747 }
734 748
735 - (IBAction)showUserManager:(id)sender { 749 - (IBAction)showUserManager:(id)sender {
736 profiles::ShowUserManagerMaybeWithTutorial(browser_->profile()); 750 profiles::ShowUserManagerMaybeWithTutorial(browser_->profile());
737 } 751 }
738 752
739 - (IBAction)showAccountManagement:(id)sender { 753 - (IBAction)showAccountManagement:(id)sender {
740 [self initMenuContentsWithView:BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT]; 754 [self initMenuContentsWithView:BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT];
741 } 755 }
742 756
757 - (IBAction)hideAccountManagement:(id)sender {
758 [self initMenuContentsWithView:BUBBLE_VIEW_MODE_PROFILE_CHOOSER];
759 }
760
743 - (IBAction)lockProfile:(id)sender { 761 - (IBAction)lockProfile:(id)sender {
744 profiles::LockProfile(browser_->profile()); 762 profiles::LockProfile(browser_->profile());
745 } 763 }
746 764
747 - (IBAction)showSigninPage:(id)sender { 765 - (IBAction)showInlineSigninPage:(id)sender {
748 [self initMenuContentsWithView:BUBBLE_VIEW_MODE_GAIA_SIGNIN]; 766 [self initMenuContentsWithView:BUBBLE_VIEW_MODE_GAIA_SIGNIN];
749 } 767 }
750 768
769 - (IBAction)showTabbedSigninPage:(id)sender {
770 chrome::ShowBrowserSignin(browser_, signin::SOURCE_MENU);
771 }
772
751 - (IBAction)addAccount:(id)sender { 773 - (IBAction)addAccount:(id)sender {
752 [self initMenuContentsWithView:BUBBLE_VIEW_MODE_GAIA_ADD_ACCOUNT]; 774 [self initMenuContentsWithView:BUBBLE_VIEW_MODE_GAIA_ADD_ACCOUNT];
753 } 775 }
754 776
755 - (IBAction)navigateBackFromSigninPage:(id)sender { 777 - (IBAction)navigateBackFromSigninPage:(id)sender {
756 std::string primaryAccount = SigninManagerFactory::GetForProfile( 778 std::string primaryAccount = SigninManagerFactory::GetForProfile(
757 browser_->profile())->GetAuthenticatedUsername(); 779 browser_->profile())->GetAuthenticatedUsername();
758 [self initMenuContentsWithView:primaryAccount.empty() ? 780 [self initMenuContentsWithView:primaryAccount.empty() ?
759 BUBBLE_VIEW_MODE_PROFILE_CHOOSER : BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT]; 781 BUBBLE_VIEW_MODE_PROFILE_CHOOSER : BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT];
760 } 782 }
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
881 enableLock = item.signed_in; 903 enableLock = item.signed_in;
882 } else { 904 } else {
883 [otherProfiles addObject:[self createOtherProfileView:i]]; 905 [otherProfiles addObject:[self createOtherProfileView:i]];
884 } 906 }
885 } 907 }
886 if (!currentProfileView) // Guest windows don't have an active profile. 908 if (!currentProfileView) // Guest windows don't have an active profile.
887 currentProfileView = [self createGuestProfileView]; 909 currentProfileView = [self createGuestProfileView];
888 910
889 // |yOffset| is the next position at which to draw in |contentView| 911 // |yOffset| is the next position at which to draw in |contentView|
890 // coordinates. 912 // coordinates.
891 CGFloat yOffset = kSmallVerticalSpacing; 913 CGFloat yOffset = 0;
892 914
893 // Option buttons. 915 // Option buttons. Only available with the new profile management flag.
894 NSView* optionsView = [self createOptionsViewWithRect: 916 if (switches::IsNewProfileManagement()) {
895 NSMakeRect(0, yOffset, kFixedMenuWidth, 0) 917 NSRect rect = NSMakeRect(0, yOffset, kFixedMenuWidth, 0);
896 enableLock:enableLock]; 918 NSView* optionsView = [self createOptionsViewWithRect:rect
897 [contentView addSubview:optionsView]; 919 enableLock:enableLock];
898 yOffset = NSMaxY([optionsView frame]) + kSmallVerticalSpacing; 920 [contentView addSubview:optionsView];
921 rect.origin.y = NSMaxY([optionsView frame]);
899 922
900 NSBox* separator = [self separatorWithFrame: 923 NSBox* separator = [self separatorWithFrame:rect];
901 NSMakeRect(0, yOffset, kFixedMenuWidth, 0)]; 924 [contentView addSubview:separator];
902 [contentView addSubview:separator]; 925 yOffset = NSMaxY([separator frame]);
903 yOffset = NSMaxY([separator frame]) + kVerticalSpacing; 926 }
904 927
905 if (viewToDisplay == BUBBLE_VIEW_MODE_PROFILE_CHOOSER && 928 if (viewToDisplay == BUBBLE_VIEW_MODE_PROFILE_CHOOSER &&
906 switches::IsFastUserSwitching()) { 929 switches::IsFastUserSwitching()) {
907 // Other profiles switcher. The profiles have already been sorted 930 // Other profiles switcher. The profiles have already been sorted
908 // by their y-coordinate, so they can be added in the existing order. 931 // by their y-coordinate, so they can be added in the existing order.
909 for (NSView *otherProfileView in otherProfiles.get()) { 932 for (NSView *otherProfileView in otherProfiles.get()) {
910 [otherProfileView setFrameOrigin:NSMakePoint(kHorizontalSpacing, 933 [otherProfileView setFrameOrigin:NSMakePoint(0, yOffset)];
911 yOffset)];
912 [contentView addSubview:otherProfileView]; 934 [contentView addSubview:otherProfileView];
913 yOffset = NSMaxY([otherProfileView frame]) + kSmallVerticalSpacing; 935 yOffset = NSMaxY([otherProfileView frame]);
936
937 NSBox* separator =
938 [self separatorWithFrame:NSMakeRect(0, yOffset, kFixedMenuWidth, 0)];
939 [contentView addSubview:separator];
940 yOffset = NSMaxY([separator frame]);
914 } 941 }
915
916 // If we displayed other profiles, ensure the spacing between the last item
917 // and the active profile card is the same as the spacing between the active
918 // profile card and the bottom of the bubble.
919 if ([otherProfiles.get() count] > 0)
920 yOffset += kSmallVerticalSpacing;
921 } else if (viewToDisplay == BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT) { 942 } else if (viewToDisplay == BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT) {
922 NSView* currentProfileAccountsView = [self createCurrentProfileAccountsView: 943 NSView* currentProfileAccountsView = [self createCurrentProfileAccountsView:
923 NSMakeRect(kHorizontalSpacing, 944 NSMakeRect(0, yOffset, kFixedMenuWidth, 0)];
924 yOffset,
925 kFixedMenuWidth - 2 * kHorizontalSpacing,
926 0)];
927 [contentView addSubview:currentProfileAccountsView]; 945 [contentView addSubview:currentProfileAccountsView];
928 yOffset = NSMaxY([currentProfileAccountsView frame]) + kVerticalSpacing; 946 yOffset = NSMaxY([currentProfileAccountsView frame]);
929 947
930 NSBox* accountsSeparator = [self separatorWithFrame: 948 NSBox* accountsSeparator = [self separatorWithFrame:
931 NSMakeRect(0, yOffset, kFixedMenuWidth, 0)]; 949 NSMakeRect(0, yOffset, kFixedMenuWidth, 0)];
932 [contentView addSubview:accountsSeparator]; 950 [contentView addSubview:accountsSeparator];
933 yOffset = NSMaxY([accountsSeparator frame]) + kVerticalSpacing; 951 yOffset = NSMaxY([accountsSeparator frame]);
934 } 952 }
935 953
936 // Active profile card. 954 // Active profile card.
937 if (currentProfileView) { 955 if (currentProfileView) {
938 [currentProfileView setFrameOrigin:NSMakePoint(kHorizontalSpacing, 956 yOffset += kVerticalSpacing;
939 yOffset)]; 957 [currentProfileView setFrameOrigin:NSMakePoint(0, yOffset)];
940 [contentView addSubview:currentProfileView]; 958 [contentView addSubview:currentProfileView];
941 yOffset = NSMaxY([currentProfileView frame]) + kVerticalSpacing; 959 yOffset = NSMaxY([currentProfileView frame]) + kVerticalSpacing;
942 } 960 }
943 961
944 if (tutorialView) { 962 if (tutorialView) {
945 [tutorialView setFrameOrigin:NSMakePoint(0, yOffset)]; 963 [tutorialView setFrameOrigin:NSMakePoint(0, yOffset)];
946 [contentView addSubview:tutorialView]; 964 [contentView addSubview:tutorialView];
947 yOffset = NSMaxY([tutorialView frame]); 965 yOffset = NSMaxY([tutorialView frame]);
948 } else { 966 } else {
949 tutorialShowing_ = false; 967 tutorialShowing_ = false;
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
1083 1101
1084 [containerWithCaret setFrameSize: 1102 [containerWithCaret setFrameSize:
1085 NSMakeSize(kFixedMenuWidth, NSMaxY([container frame]))]; 1103 NSMakeSize(kFixedMenuWidth, NSMaxY([container frame]))];
1086 return containerWithCaret.autorelease(); 1104 return containerWithCaret.autorelease();
1087 } 1105 }
1088 1106
1089 - (NSView*)createCurrentProfileView:(const AvatarMenu::Item&)item { 1107 - (NSView*)createCurrentProfileView:(const AvatarMenu::Item&)item {
1090 base::scoped_nsobject<NSView> container([[NSView alloc] 1108 base::scoped_nsobject<NSView> container([[NSView alloc]
1091 initWithFrame:NSZeroRect]); 1109 initWithFrame:NSZeroRect]);
1092 1110
1093 // Profile icon. 1111 CGFloat xOffset = kHorizontalSpacing;
1094 base::scoped_nsobject<EditableProfilePhoto> iconView( 1112 CGFloat yOffset = 0;
1095 [[EditableProfilePhoto alloc] 1113 CGFloat availableTextWidth = kFixedMenuWidth - 2 * kHorizontalSpacing;
1096 initWithFrame:NSMakeRect(0, 0, kLargeImageSide, kLargeImageSide)
1097 avatarMenu:avatarMenu_.get()
1098 profileIcon:item.icon
1099 editingAllowed:!isGuestSession_]);
1100 1114
1101 [container addSubview:iconView]; 1115 // Profile options. This can be a link to the accounts view, the profile's
1102 1116 // username for signed in users, or a "Sign in" button for local profiles.
1103 CGFloat xOffset = NSMaxX([iconView frame]) + kHorizontalSpacing; 1117 if (!isGuestSession_) {
1104 CGFloat yOffset = kVerticalSpacing;
1105 if (!isGuestSession_ && viewMode_ == BUBBLE_VIEW_MODE_PROFILE_CHOOSER) {
1106 NSView* linksContainer = 1118 NSView* linksContainer =
1107 [self createCurrentProfileLinksForItem:item withXOffset:xOffset]; 1119 [self createCurrentProfileLinksForItem:item
1120 rect:NSMakeRect(xOffset, yOffset,
1121 availableTextWidth,
1122 0)];
1108 [container addSubview:linksContainer]; 1123 [container addSubview:linksContainer];
1109 yOffset = NSMaxY([linksContainer frame]); 1124 yOffset = NSMaxY([linksContainer frame]);
1110 } 1125 }
1111 1126
1112 // Profile name. 1127 // Profile name, centered.
1113 CGFloat availableTextWidth =
1114 kFixedMenuWidth - xOffset - 2 * kHorizontalSpacing;
1115 base::scoped_nsobject<EditableProfileNameButton> profileName( 1128 base::scoped_nsobject<EditableProfileNameButton> profileName(
1116 [[EditableProfileNameButton alloc] 1129 [[EditableProfileNameButton alloc]
1117 initWithFrame:NSMakeRect(xOffset, yOffset, 1130 initWithFrame:NSMakeRect(xOffset, yOffset,
1118 availableTextWidth, 1131 availableTextWidth,
1119 kProfileButtonHeight) 1132 kProfileButtonHeight)
1120 profile:browser_->profile() 1133 profile:browser_->profile()
1121 profileName:base::SysUTF16ToNSString( 1134 profileName:base::SysUTF16ToNSString(
1122 profiles::GetAvatarNameForProfile(browser_->profile())) 1135 profiles::GetAvatarNameForProfile(browser_->profile()))
1123 editingAllowed:!isGuestSession_]); 1136 editingAllowed:!isGuestSession_]);
1124 1137
1125 [container addSubview:profileName]; 1138 [container addSubview:profileName];
1126 [container setFrameSize:NSMakeSize(kFixedMenuWidth, 1139 yOffset = NSMaxY([profileName frame]);
1127 NSHeight([iconView frame]))]; 1140
1141 // Profile icon, centered.
1142 xOffset = (kFixedMenuWidth - kLargeImageSide) / 2;
1143 base::scoped_nsobject<EditableProfilePhoto> iconView(
1144 [[EditableProfilePhoto alloc]
1145 initWithFrame:NSMakeRect(xOffset, yOffset,
1146 kLargeImageSide, kLargeImageSide)
1147 avatarMenu:avatarMenu_.get()
1148 profileIcon:item.icon
1149 editingAllowed:!isGuestSession_]);
1150
1151 [container addSubview:iconView];
1152 yOffset = NSMaxY([iconView frame]);
1153
1154 [container setFrameSize:NSMakeSize(kFixedMenuWidth, yOffset)];
1128 return container.autorelease(); 1155 return container.autorelease();
1129 } 1156 }
1130 1157
1131 - (NSView*)createCurrentProfileLinksForItem:(const AvatarMenu::Item&)item 1158 - (NSView*)createCurrentProfileLinksForItem:(const AvatarMenu::Item&)item
1132 withXOffset:(CGFloat)xOffset { 1159 rect:(NSRect)rect {
1133 base::scoped_nsobject<NSView> container([[NSView alloc] 1160 base::scoped_nsobject<NSView> container([[NSView alloc] initWithFrame:rect]);
1134 initWithFrame:NSZeroRect]);
1135 1161
1162 // Don't double-apply the left margin to the sub-views.
1163 rect.origin.x = 0;
1164
1165 // The available links depend on the type of profile that is active.
1136 NSButton* link; 1166 NSButton* link;
1137 NSPoint frameOrigin = NSMakePoint(xOffset, kSmallVerticalSpacing);
1138 // The available links depend on the type of profile that is active.
1139 if (item.signed_in) { 1167 if (item.signed_in) {
1140 link = [self linkButtonWithTitle:l10n_util::GetNSString( 1168 if (switches::IsNewProfileManagement()) {
1141 IDS_PROFILES_PROFILE_MANAGE_ACCOUNTS_BUTTON) 1169 NSString* linkTitle = l10n_util::GetNSString(
1142 frameOrigin:frameOrigin 1170 viewMode_ == BUBBLE_VIEW_MODE_PROFILE_CHOOSER ?
1143 action:@selector(showAccountManagement:)]; 1171 IDS_PROFILES_PROFILE_MANAGE_ACCOUNTS_BUTTON :
1172 IDS_PROFILES_PROFILE_HIDE_MANAGE_ACCOUNTS_BUTTON);
1173 SEL linkSelector = (viewMode_ == BUBBLE_VIEW_MODE_PROFILE_CHOOSER) ?
1174 @selector(showAccountManagement:) : @selector(hideAccountManagement:);
1175 link = [self linkButtonWithTitle:linkTitle
1176 frameOrigin:rect.origin
1177 action:linkSelector];
1178 } else {
1179 link = [self linkButtonWithTitle:base::SysUTF16ToNSString(item.sync_state)
1180 frameOrigin:rect.origin
1181 action:nil];
1182 [[link cell] setTextColor:[NSColor blackColor]];
1183 }
1184 // -linkButtonWithTitle sizeToFit's the link, so re-stretch it so that it
1185 // can be centered correctly in the view.
1186 rect.size.height = NSMaxY([link frame]);
1187 [link setFrame:rect];
1188 [link setAlignment:NSCenterTextAlignment];
1144 } else { 1189 } else {
1145 link = [self linkButtonWithTitle:l10n_util::GetNSStringFWithFixup( 1190 rect.size.height = kBlueButtonHeight;
1146 IDS_SYNC_START_SYNC_BUTTON_LABEL, 1191 link = [[BlueLabelButton alloc] initWithFrame:rect];
1147 l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME)) 1192
1148 frameOrigin:frameOrigin 1193 // Manually elide the button text so that the contents fit inside the bubble
1149 action:@selector(showSigninPage:)]; 1194 // This is needed because the BlueLabelButton cell resets the style on
1195 // every call to -cellSize, which prevents setting a custom lineBreakMode.
1196 NSString* elidedButtonText = base::SysUTF16ToNSString(gfx::ElideText(
1197 l10n_util::GetStringFUTF16(
1198 IDS_SYNC_START_SYNC_BUTTON_LABEL,
1199 l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME)),
1200 ui::ResourceBundle::GetSharedInstance().GetFontList(
1201 ui::ResourceBundle::BaseFont),
1202 rect.size.width,
1203 gfx::ELIDE_AT_END));
1204
1205 [link setTitle:elidedButtonText];
1206 [link setTarget:self];
1207 [link setAction:switches::IsNewProfileManagement() ?
1208 @selector(showInlineSigninPage:) : @selector(showTabbedSigninPage:)];
1150 } 1209 }
1151 1210
1152 [container addSubview:link]; 1211 [container addSubview:link];
1153 [container setFrameSize:NSMakeSize( 1212 [container setFrameSize:rect.size];
1154 NSMaxX([link frame]), NSMaxY([link frame]) + kSmallVerticalSpacing)];
1155 return container.autorelease(); 1213 return container.autorelease();
1156 } 1214 }
1157 1215
1158 - (NSView*)createGuestProfileView { 1216 - (NSView*)createGuestProfileView {
1159 gfx::Image guestIcon = 1217 gfx::Image guestIcon =
1160 ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed( 1218 ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed(
1161 IDR_LOGIN_GUEST); 1219 IDR_LOGIN_GUEST);
1162 AvatarMenu::Item guestItem(std::string::npos, /* menu_index, not used */ 1220 AvatarMenu::Item guestItem(std::string::npos, /* menu_index, not used */
1163 std::string::npos, /* profile_index, not used */ 1221 std::string::npos, /* profile_index, not used */
1164 guestIcon); 1222 guestIcon);
1165 guestItem.active = true; 1223 guestItem.active = true;
1166 guestItem.name = base::SysNSStringToUTF16( 1224 guestItem.name = base::SysNSStringToUTF16(
1167 l10n_util::GetNSString(IDS_PROFILES_GUEST_PROFILE_NAME)); 1225 l10n_util::GetNSString(IDS_PROFILES_GUEST_PROFILE_NAME));
1168 1226
1169 return [self createCurrentProfileView:guestItem]; 1227 return [self createCurrentProfileView:guestItem];
1170 } 1228 }
1171 1229
1172 - (NSButton*)createOtherProfileView:(int)itemIndex { 1230 - (NSButton*)createOtherProfileView:(int)itemIndex {
1173 const AvatarMenu::Item& item = avatarMenu_->GetItemAt(itemIndex); 1231 const AvatarMenu::Item& item = avatarMenu_->GetItemAt(itemIndex);
1174 base::scoped_nsobject<NSButton> profileButton([[NSButton alloc]
1175 initWithFrame:NSZeroRect]);
1176 base::scoped_nsobject<CustomPaddingImageButtonCell> cell(
1177 [[CustomPaddingImageButtonCell alloc]
1178 initWithLeftMarginSpacing:0
1179 imageTitleSpacing:kImageTitleSpacing]);
1180 [profileButton setCell:cell.get()];
1181 1232
1182 [[profileButton cell] setLineBreakMode:NSLineBreakByTruncatingTail]; 1233 NSRect rect = NSMakeRect(0, 0, kFixedMenuWidth,
1234 kBlueButtonHeight + kSmallVerticalSpacing);
1235 base::scoped_nsobject<BackgroundColorHoverButton> profileButton(
1236 [[BackgroundColorHoverButton alloc]
1237 initWithFrame:rect
1238 imageTitleSpacing:kImageTitleSpacing
1239 backgroundColor:GetDialogBackgroundColor()]);
1183 [profileButton setTitle:base::SysUTF16ToNSString(item.name)]; 1240 [profileButton setTitle:base::SysUTF16ToNSString(item.name)];
1184 [profileButton setImage:CreateProfileImage( 1241 [profileButton setDefaultImage:CreateProfileImage(
1185 item.icon, kSmallImageSide).ToNSImage()]; 1242 item.icon, kSmallImageSide).ToNSImage()];
1186 [profileButton setImagePosition:NSImageLeft]; 1243 [profileButton setImagePosition:NSImageLeft];
1187 [profileButton setAlignment:NSLeftTextAlignment]; 1244 [profileButton setAlignment:NSLeftTextAlignment];
1188 [profileButton setBordered:NO]; 1245 [profileButton setBordered:NO];
1189 [profileButton setFont:[NSFont labelFontOfSize:kTitleFontSize]];
1190 [profileButton setTag:itemIndex]; 1246 [profileButton setTag:itemIndex];
1191 [profileButton setTarget:self]; 1247 [profileButton setTarget:self];
1192 [profileButton setAction:@selector(switchToProfile:)]; 1248 [profileButton setAction:@selector(switchToProfile:)];
1193 1249
1194 // Since the bubble is fixed width, we need to calculate the width available
1195 // for the profile name, as longer names will have to be elided.
1196 CGFloat availableTextWidth = kFixedMenuWidth - 2 * kHorizontalSpacing;
1197 [profileButton sizeToFit];
1198 [profileButton setFrameSize:NSMakeSize(availableTextWidth,
1199 NSHeight([profileButton frame]))];
1200
1201 return profileButton.autorelease(); 1250 return profileButton.autorelease();
1202 } 1251 }
1203 1252
1204 - (NSView*)createOptionsViewWithRect:(NSRect)rect 1253 - (NSView*)createOptionsViewWithRect:(NSRect)rect
1205 enableLock:(BOOL)enableLock { 1254 enableLock:(BOOL)enableLock {
1206 int widthOfLockButton = enableLock? 2 * kHorizontalSpacing + 12 : 0; 1255 int widthOfLockButton = enableLock? 2 * kHorizontalSpacing + 12 : 0;
1207 NSRect viewRect = NSMakeRect(0, 0, 1256 NSRect viewRect = NSMakeRect(0, 0,
1208 rect.size.width - widthOfLockButton, 1257 rect.size.width - widthOfLockButton,
1209 kBlueButtonHeight); 1258 kBlueButtonHeight + kVerticalSpacing);
1210 NSButton* notYouButton = 1259 NSButton* notYouButton =
1211 [self hoverButtonWithRect:viewRect 1260 [self hoverButtonWithRect:viewRect
1212 text:l10n_util::GetNSStringF( 1261 text:l10n_util::GetNSStringF(
1213 IDS_PROFILES_NOT_YOU_BUTTON, 1262 IDS_PROFILES_NOT_YOU_BUTTON,
1214 profiles::GetAvatarNameForProfile(browser_->profile())) 1263 profiles::GetAvatarNameForProfile(browser_->profile()))
1215 imageResourceId:IDR_ICON_PROFILES_MENU_AVATAR 1264 imageResourceId:IDR_ICON_PROFILES_MENU_AVATAR
1216 alternateImageResourceId:IDR_ICON_PROFILES_MENU_AVATAR 1265 alternateImageResourceId:IDR_ICON_PROFILES_MENU_AVATAR
1217 action:@selector(showUserManager:)]; 1266 action:@selector(showUserManager:)];
1218 1267
1219 rect.size.height = NSMaxY([notYouButton frame]); 1268 rect.size.height = NSMaxY([notYouButton frame]);
1220 base::scoped_nsobject<NSView> container([[NSView alloc] 1269 base::scoped_nsobject<NSView> container([[NSView alloc] initWithFrame:rect]);
1221 initWithFrame:rect]);
1222 [container addSubview:notYouButton]; 1270 [container addSubview:notYouButton];
1223 1271
1224 if (enableLock) { 1272 if (enableLock) {
1225 viewRect.origin.x = NSMaxX([notYouButton frame]); 1273 viewRect.origin.x = NSMaxX([notYouButton frame]);
1226 viewRect.size.width = widthOfLockButton; 1274 viewRect.size.width = widthOfLockButton;
1227 NSButton* lockButton = 1275 NSButton* lockButton =
1228 [self hoverButtonWithRect:viewRect 1276 [self hoverButtonWithRect:viewRect
1229 text:@"" 1277 text:@""
1230 imageResourceId:IDR_ICON_PROFILES_MENU_LOCK 1278 imageResourceId:IDR_ICON_PROFILES_MENU_LOCK
1231 alternateImageResourceId:IDR_ICON_PROFILES_MENU_LOCK 1279 alternateImageResourceId:IDR_ICON_PROFILES_MENU_LOCK
1232 action:@selector(lockProfile:)]; 1280 action:@selector(lockProfile:)];
1233 [container addSubview:lockButton]; 1281 [container addSubview:lockButton];
1234 } 1282 }
1235 1283
1236 return container.autorelease(); 1284 return container.autorelease();
1237 } 1285 }
1238 1286
1239 - (NSView*)createCurrentProfileAccountsView:(NSRect)rect { 1287 - (NSView*)createCurrentProfileAccountsView:(NSRect)rect {
1240 const CGFloat kAccountButtonHeight = 15; 1288 const CGFloat kAccountButtonHeight = 34;
1241 1289
1242 const AvatarMenu::Item& item = 1290 const AvatarMenu::Item& item =
1243 avatarMenu_->GetItemAt(avatarMenu_->GetActiveProfileIndex()); 1291 avatarMenu_->GetItemAt(avatarMenu_->GetActiveProfileIndex());
1244 DCHECK(item.signed_in); 1292 DCHECK(item.signed_in);
1245 1293
1246 base::scoped_nsobject<NSView> container([[NSView alloc] initWithFrame:rect]); 1294 NSColor* backgroundColor = gfx::SkColorToCalibratedNSColor(
1247 1295 profiles::kAvatarBubbleAccountsBackgroundColor);
1248 NSRect viewRect = NSMakeRect(0, 0, rect.size.width, kBlueButtonHeight); 1296 base::scoped_nsobject<NSView> container([[BackgroundColorView alloc]
1249 base::scoped_nsobject<NSButton> addAccountsButton([[BlueLabelButton alloc] 1297 initWithFrame:rect
1250 initWithFrame:viewRect]); 1298 withColor:backgroundColor]);
1251 1299
1252 // Manually elide the button text so that the contents fit inside the bubble. 1300 // Manually elide the button text so that the contents fit inside the bubble.
1253 // This is needed because the BlueLabelButton cell resets the style on 1301 // This is needed because the BlueLabelButton cell resets the style on
1254 // every call to -cellSize, which prevents setting a custom lineBreakMode. 1302 // every call to -cellSize, which prevents setting a custom lineBreakMode.
1255 NSString* elidedButtonText = base::SysUTF16ToNSString(gfx::ElideText( 1303 NSString* elidedButtonText = base::SysUTF16ToNSString(gfx::ElideText(
1256 l10n_util::GetStringFUTF16( 1304 l10n_util::GetStringFUTF16(
1257 IDS_PROFILES_PROFILE_ADD_ACCOUNT_BUTTON, item.name), 1305 IDS_PROFILES_PROFILE_ADD_ACCOUNT_BUTTON, item.name),
1258 ui::ResourceBundle::GetSharedInstance().GetFontList( 1306 ui::ResourceBundle::GetSharedInstance().GetFontList(
1259 ui::ResourceBundle::BaseFont), 1307 ui::ResourceBundle::BaseFont),
1260 rect.size.width, 1308 rect.size.width,
1261 gfx::ELIDE_AT_END)); 1309 gfx::ELIDE_AT_END));
1262 1310
1263 [addAccountsButton setTitle:elidedButtonText]; 1311 NSButton* addAccountsButton =
1264 [addAccountsButton setTarget:self]; 1312 [self linkButtonWithTitle:elidedButtonText
1265 [addAccountsButton setAction:@selector(addAccount:)]; 1313 frameOrigin:NSMakePoint(
1314 kHorizontalSpacing, kSmallVerticalSpacing)
1315 action:@selector(addAccount:)];
1266 [container addSubview:addAccountsButton]; 1316 [container addSubview:addAccountsButton];
1267 1317
1268 // Update the height of the email account buttons. This is needed so that the 1318 NSView* accountEmails = [self createAccountsListWithRect:NSMakeRect(
1269 // all the buttons span the entire width of the bubble. 1319 0, kAccountButtonHeight, rect.size.width, kAccountButtonHeight)];
1270 viewRect.origin.y = NSMaxY([addAccountsButton frame]) + kVerticalSpacing; 1320 [container addSubview:accountEmails];
1271 viewRect.size.height = kAccountButtonHeight;
1272 1321
1273 NSView* accountEmails = [self createAccountsListWithRect:viewRect]; 1322 [container setFrameSize:NSMakeSize(rect.size.width,
1274 [container addSubview:accountEmails]; 1323 NSMaxY([accountEmails frame]))];
1275 [container setFrameSize:NSMakeSize(
1276 NSWidth([container frame]), NSMaxY([accountEmails frame]))];
1277 return container.autorelease(); 1324 return container.autorelease();
1278 } 1325 }
1279 1326
1280 - (NSView*)createAccountsListWithRect:(NSRect)rect { 1327 - (NSView*)createAccountsListWithRect:(NSRect)rect {
1281 base::scoped_nsobject<NSView> container([[NSView alloc] initWithFrame:rect]); 1328 base::scoped_nsobject<NSView> container([[NSView alloc] initWithFrame:rect]);
1282 currentProfileAccounts_.clear(); 1329 currentProfileAccounts_.clear();
1283 1330
1284 Profile* profile = browser_->profile(); 1331 Profile* profile = browser_->profile();
1285 std::string primaryAccount = 1332 std::string primaryAccount =
1286 SigninManagerFactory::GetForProfile(profile)->GetAuthenticatedUsername(); 1333 SigninManagerFactory::GetForProfile(profile)->GetAuthenticatedUsername();
1287 DCHECK(!primaryAccount.empty()); 1334 DCHECK(!primaryAccount.empty());
1288 std::vector<std::string>accounts = 1335 std::vector<std::string>accounts =
1289 profiles::GetSecondaryAccountsForProfile(profile, primaryAccount); 1336 profiles::GetSecondaryAccountsForProfile(profile, primaryAccount);
1290 1337
1291 rect.origin.y = 0; 1338 rect.origin.y = 0;
1292 for (size_t i = 0; i < accounts.size(); ++i) { 1339 for (size_t i = 0; i < accounts.size(); ++i) {
1293 // Save the original email address, as the button text could be elided. 1340 // Save the original email address, as the button text could be elided.
1294 currentProfileAccounts_[i] = accounts[i]; 1341 currentProfileAccounts_[i] = accounts[i];
1295 NSButton* accountButton = [self accountButtonWithRect:rect 1342 NSButton* accountButton = [self accountButtonWithRect:rect
1296 title:accounts[i]]; 1343 title:accounts[i]];
1297 [accountButton setTag:i]; 1344 [accountButton setTag:i];
1298 [container addSubview:accountButton]; 1345 [container addSubview:accountButton];
1299 rect.origin.y = NSMaxY([accountButton frame]) + kSmallVerticalSpacing; 1346 rect.origin.y = NSMaxY([accountButton frame]);
1300 } 1347 }
1301 1348
1302 // The primary account should always be listed first. 1349 // The primary account should always be listed first.
1303 NSButton* accountButton = [self accountButtonWithRect:rect 1350 NSButton* accountButton = [self accountButtonWithRect:rect
1304 title:primaryAccount]; 1351 title:primaryAccount];
1305 [container addSubview:accountButton]; 1352 [container addSubview:accountButton];
1306 [container setFrameSize:NSMakeSize(NSWidth([container frame]), 1353 [container setFrameSize:NSMakeSize(NSWidth([container frame]),
1307 NSMaxY([accountButton frame]))]; 1354 NSMaxY([accountButton frame]))];
1308 [accountButton setTag:kPrimaryProfileTag]; 1355 [accountButton setTag:kPrimaryProfileTag];
1309 return container.autorelease(); 1356 return container.autorelease();
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
1427 clickedOnLink:(id)link 1474 clickedOnLink:(id)link
1428 atIndex:(NSUInteger)charIndex { 1475 atIndex:(NSUInteger)charIndex {
1429 chrome::ShowSettings(browser_); 1476 chrome::ShowSettings(browser_);
1430 return YES; 1477 return YES;
1431 } 1478 }
1432 1479
1433 - (NSButton*)hoverButtonWithRect:(NSRect)rect 1480 - (NSButton*)hoverButtonWithRect:(NSRect)rect
1434 text:(NSString*)text 1481 text:(NSString*)text
1435 imageResourceId:(int)imageResourceId 1482 imageResourceId:(int)imageResourceId
1436 alternateImageResourceId:(int)alternateImageResourceId 1483 alternateImageResourceId:(int)alternateImageResourceId
1437 action:(SEL)action { 1484 action:(SEL)action {
1438 base::scoped_nsobject<BackgroundColorHoverButton> button( 1485 base::scoped_nsobject<BackgroundColorHoverButton> button(
1439 [[BackgroundColorHoverButton alloc] initWithFrame:rect]); 1486 [[BackgroundColorHoverButton alloc]
1487 initWithFrame:rect
1488 imageTitleSpacing:kImageTitleSpacing
1489 backgroundColor:GetDialogBackgroundColor()]);
1440 1490
1441 [button setTitle:text]; 1491 [button setTitle:text];
1442 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); 1492 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
1443 NSImage* alternateImage = rb->GetNativeImageNamed( 1493 NSImage* alternateImage = rb->GetNativeImageNamed(
1444 alternateImageResourceId).ToNSImage(); 1494 alternateImageResourceId).ToNSImage();
1445 [button setDefaultImage:rb->GetNativeImageNamed(imageResourceId).ToNSImage()]; 1495 [button setDefaultImage:rb->GetNativeImageNamed(imageResourceId).ToNSImage()];
1446 [button setHoverImage:alternateImage]; 1496 [button setHoverImage:alternateImage];
1447 [button setPressedImage:alternateImage]; 1497 [button setPressedImage:alternateImage];
1448 [button setImagePosition:NSImageLeft]; 1498 [button setImagePosition:NSImageLeft];
1449 [button setAlignment:NSLeftTextAlignment]; 1499 [button setAlignment:NSLeftTextAlignment];
(...skipping 19 matching lines...) Expand all
1469 [link setTarget:self]; 1519 [link setTarget:self];
1470 [link setAction:action]; 1520 [link setAction:action];
1471 [link setFrameOrigin:frameOrigin]; 1521 [link setFrameOrigin:frameOrigin];
1472 [link sizeToFit]; 1522 [link sizeToFit];
1473 1523
1474 return link.autorelease(); 1524 return link.autorelease();
1475 } 1525 }
1476 1526
1477 - (NSButton*)accountButtonWithRect:(NSRect)rect 1527 - (NSButton*)accountButtonWithRect:(NSRect)rect
1478 title:(const std::string&)title { 1528 title:(const std::string&)title {
1479 base::scoped_nsobject<NSButton> button([[NSButton alloc] initWithFrame:rect]); 1529 NSColor* backgroundColor = gfx::SkColorToCalibratedNSColor(
1530 profiles::kAvatarBubbleAccountsBackgroundColor);
1531 base::scoped_nsobject<BackgroundColorHoverButton> button(
1532 [[BackgroundColorHoverButton alloc] initWithFrame:rect
1533 imageTitleSpacing:0
1534 backgroundColor:backgroundColor]);
1535
1480 [button setTitle:ElideEmail(title, rect.size.width)]; 1536 [button setTitle:ElideEmail(title, rect.size.width)];
1481 [button setAlignment:NSLeftTextAlignment]; 1537 [button setAlignment:NSLeftTextAlignment];
1482 [button setBordered:NO]; 1538 [button setBordered:NO];
1483
1484 [button setImage:ui::ResourceBundle::GetSharedInstance().
1485 GetNativeImageNamed(IDR_CLOSE_1).ToNSImage()];
1486 [button setImagePosition:NSImageRight];
1487 [button setTarget:self]; 1539 [button setTarget:self];
1488 [button setAction:@selector(showAccountRemovalView:)]; 1540 [button setAction:@selector(showAccountRemovalView:)];
1489 1541
1490 return button.autorelease(); 1542 return button.autorelease();
1491 } 1543 }
1492 1544
1493 @end 1545 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698