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

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: preemptive nits 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 357 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 @implementation EditableProfileNameButton 465 @implementation EditableProfileNameButton
466 - (id)initWithFrame:(NSRect)frameRect 466 - (id)initWithFrame:(NSRect)frameRect
467 profile:(Profile*)profile 467 profile:(Profile*)profile
468 profileName:(NSString*)profileName 468 profileName:(NSString*)profileName
469 editingAllowed:(BOOL)editingAllowed { 469 editingAllowed:(BOOL)editingAllowed {
470 if ((self = [super initWithFrame:frameRect])) { 470 if ((self = [super initWithFrame:frameRect])) {
471 profile_ = profile; 471 profile_ = profile;
472 472
473 [self setBordered:NO]; 473 [self setBordered:NO];
474 [self setFont:[NSFont labelFontOfSize:kTitleFontSize]]; 474 [self setFont:[NSFont labelFontOfSize:kTitleFontSize]];
475 [self setAlignment:NSLeftTextAlignment]; 475 [self setAlignment:NSCenterTextAlignment];
476 [[self cell] setLineBreakMode:NSLineBreakByTruncatingTail]; 476 [[self cell] setLineBreakMode:NSLineBreakByTruncatingTail];
477 [self setTitle:profileName]; 477 [self setTitle:profileName];
478 478
479 if (editingAllowed) { 479 if (editingAllowed) {
480 // Show an "edit" pencil icon when hovering over. 480 // Show an "edit" pencil icon when hovering over. In the default state,
481 // we need to create an empty placeholder of the correct size, so that
482 // the text doesn't jump around when the hovered icon appears.
481 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); 483 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
482 [self setHoverImage: 484 NSImage* hoverImage = rb->GetNativeImageNamed(
483 rb->GetNativeImageNamed(IDR_ICON_PROFILES_EDIT_HOVER).AsNSImage()]; 485 IDR_ICON_PROFILES_EDIT_HOVER).AsNSImage();
486 NSImage* placeholder = [[NSImage alloc] initWithSize:[hoverImage size]];
487 [self setDefaultImage:placeholder];
488 [self setHoverImage:hoverImage];
484 [self setAlternateImage: 489 [self setAlternateImage:
485 rb->GetNativeImageNamed(IDR_ICON_PROFILES_EDIT_PRESSED).AsNSImage()]; 490 rb->GetNativeImageNamed(IDR_ICON_PROFILES_EDIT_PRESSED).AsNSImage()];
486 [self setImagePosition:NSImageRight]; 491 [self setImagePosition:NSImageRight];
487 [self setTarget:self]; 492 [self setTarget:self];
488 [self setAction:@selector(showEditableView:)]; 493 [self setAction:@selector(showEditableView:)];
489 494
490 // We need to subtract the width of the bezel from the frame rect, so that 495 // We need to subtract the width of the bezel from the frame rect, so that
491 // the textfield can take the exact same space as the button. 496 // the textfield can take the exact same space as the button.
492 frameRect.size.height -= 2 * kBezelThickness; 497 frameRect.size.height -= 2 * kBezelThickness;
493 frameRect.origin = NSMakePoint(0, kBezelThickness); 498 frameRect.origin = NSMakePoint(0, kBezelThickness);
494 profileNameTextField_.reset( 499 profileNameTextField_.reset(
495 [[NSTextField alloc] initWithFrame:frameRect]); 500 [[NSTextField alloc] initWithFrame:frameRect]);
496 [profileNameTextField_ setStringValue:profileName]; 501 [profileNameTextField_ setStringValue:profileName];
497 [profileNameTextField_ setFont:[NSFont labelFontOfSize:kTitleFontSize]]; 502 [profileNameTextField_ setFont:[NSFont labelFontOfSize:kTitleFontSize]];
498 [profileNameTextField_ setEditable:YES]; 503 [profileNameTextField_ setEditable:YES];
499 [profileNameTextField_ setDrawsBackground:YES]; 504 [profileNameTextField_ setDrawsBackground:YES];
500 [profileNameTextField_ setBezeled:YES]; 505 [profileNameTextField_ setBezeled:YES];
506 [profileNameTextField_ setAlignment:NSCenterTextAlignment];
501 [[profileNameTextField_ cell] setWraps:NO]; 507 [[profileNameTextField_ cell] setWraps:NO];
502 [[profileNameTextField_ cell] setLineBreakMode: 508 [[profileNameTextField_ cell] setLineBreakMode:
503 NSLineBreakByTruncatingTail]; 509 NSLineBreakByTruncatingTail];
504 [profileNameTextField_ setDelegate:self]; 510 [profileNameTextField_ setDelegate:self];
505 [self addSubview:profileNameTextField_]; 511 [self addSubview:profileNameTextField_];
506 512
507 // Hide the textfield until the user clicks on the button. 513 // Hide the textfield until the user clicks on the button.
508 [profileNameTextField_ setHidden:YES]; 514 [profileNameTextField_ setHidden:YES];
509 } 515 }
510 } 516 }
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 580
575 - (NSSize)cellSize { 581 - (NSSize)cellSize {
576 NSSize buttonSize = [super cellSize]; 582 NSSize buttonSize = [super cellSize];
577 buttonSize.width += leftMarginSpacing_ + imageTitleSpacing_; 583 buttonSize.width += leftMarginSpacing_ + imageTitleSpacing_;
578 return buttonSize; 584 return buttonSize;
579 } 585 }
580 586
581 @end 587 @end
582 588
583 // A custom button that allows for setting a background color when hovered over. 589 // A custom button that allows for setting a background color when hovered over.
584 @interface BackgroundColorHoverButton : HoverImageButton 590 @interface BackgroundColorHoverButton : HoverImageButton {
591 @private
592 SkColor backgroundColor_;
groby-ooo-7-16 2014/04/16 18:50:37 You might want to use an NSColor so you don't have
noms (inactive) 2014/04/16 19:43:35 Done.
593 }
585 @end 594 @end
586 595
587 @implementation BackgroundColorHoverButton 596 @implementation BackgroundColorHoverButton
588 - (id)initWithFrame:(NSRect)frameRect { 597
598 - (id)initWithFrame:(NSRect)frameRect
599 imageTitleSpacing:(int)imageTitleSpacing
600 backgroundColor:(SkColor)backgroundColor {
589 if ((self = [super initWithFrame:frameRect])) { 601 if ((self = [super initWithFrame:frameRect])) {
602 backgroundColor_ = backgroundColor;
603
590 [self setBordered:NO]; 604 [self setBordered:NO];
591 [self setFont:[NSFont labelFontOfSize:kTextFontSize]]; 605 [self setFont:[NSFont labelFontOfSize:kTextFontSize]];
592 [self setButtonType:NSMomentaryChangeButton]; 606 [self setButtonType:NSMomentaryChangeButton];
593 607
594 base::scoped_nsobject<CustomPaddingImageButtonCell> cell( 608 base::scoped_nsobject<CustomPaddingImageButtonCell> cell(
595 [[CustomPaddingImageButtonCell alloc] 609 [[CustomPaddingImageButtonCell alloc]
596 initWithLeftMarginSpacing:kHorizontalSpacing 610 initWithLeftMarginSpacing:kHorizontalSpacing
597 imageTitleSpacing:kImageTitleSpacing]); 611 imageTitleSpacing:imageTitleSpacing]);
598 [cell setLineBreakMode:NSLineBreakByTruncatingTail]; 612 [cell setLineBreakMode:NSLineBreakByTruncatingTail];
599 [self setCell:cell.get()]; 613 [self setCell:cell.get()];
600 } 614 }
601 return self; 615 return self;
602 } 616 }
603 617
604 - (void)setHoverState:(HoverState)state { 618 - (void)setHoverState:(HoverState)state {
605 [super setHoverState:state]; 619 [super setHoverState:state];
606 bool isHighlighted = ([self hoverState] != kHoverStateNone); 620 bool isHighlighted = ([self hoverState] != kHoverStateNone);
607 621
608 NSColor* backgroundColor = gfx::SkColorToCalibratedNSColor( 622 NSColor* backgroundColor = gfx::SkColorToCalibratedNSColor(isHighlighted ?
609 ui::NativeTheme::instance()->GetSystemColor(isHighlighted? 623 profiles::kAvatarBubbleButtonHighlightColor : backgroundColor_);
610 ui::NativeTheme::kColorId_MenuSeparatorColor :
611 ui::NativeTheme::kColorId_DialogBackground));
612
613 [[self cell] setBackgroundColor:backgroundColor]; 624 [[self cell] setBackgroundColor:backgroundColor];
614 } 625 }
615 626
616 @end 627 @end
617 628
618 // A custom view with the given background color. 629 // A custom view with the given background color.
619 @interface BackgroundColorView : NSView { 630 @interface BackgroundColorView : NSView {
620 @private 631 @private
621 base::scoped_nsobject<NSColor> backgroundColor_; 632 base::scoped_nsobject<NSColor> backgroundColor_;
622 } 633 }
(...skipping 17 matching lines...) Expand all
640 @interface ProfileChooserController () 651 @interface ProfileChooserController ()
641 // Creates a tutorial card for the profile |avatar_item| if needed. 652 // Creates a tutorial card for the profile |avatar_item| if needed.
642 - (NSView*)createTutorialViewIfNeeded:(const AvatarMenu::Item&)item; 653 - (NSView*)createTutorialViewIfNeeded:(const AvatarMenu::Item&)item;
643 654
644 // Creates the main profile card for the profile |item| at the top of 655 // Creates the main profile card for the profile |item| at the top of
645 // the bubble. 656 // the bubble.
646 - (NSView*)createCurrentProfileView:(const AvatarMenu::Item&)item; 657 - (NSView*)createCurrentProfileView:(const AvatarMenu::Item&)item;
647 658
648 // Creates the possible links for the main profile card with profile |item|. 659 // Creates the possible links for the main profile card with profile |item|.
649 - (NSView*)createCurrentProfileLinksForItem:(const AvatarMenu::Item&)item 660 - (NSView*)createCurrentProfileLinksForItem:(const AvatarMenu::Item&)item
650 withXOffset:(CGFloat)xOffset; 661 rect:(NSRect)rect;
651 662
652 // Creates a main profile card for the guest user. 663 // Creates a main profile card for the guest user.
653 - (NSView*)createGuestProfileView; 664 - (NSView*)createGuestProfileView;
654 665
655 // Creates an item for the profile |itemIndex| that is used in the fast profile 666 // Creates an item for the profile |itemIndex| that is used in the fast profile
656 // switcher in the middle of the bubble. 667 // switcher in the middle of the bubble.
657 - (NSButton*)createOtherProfileView:(int)itemIndex; 668 - (NSButton*)createOtherProfileView:(int)itemIndex;
658 669
659 // Creates the "Not you" and Lock option buttons. 670 // Creates the "Not you" and Lock option buttons.
660 - (NSView*)createOptionsViewWithRect:(NSRect)rect 671 - (NSView*)createOptionsViewWithRect:(NSRect)rect
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
707 } 718 }
708 719
709 - (IBAction)showUserManager:(id)sender { 720 - (IBAction)showUserManager:(id)sender {
710 profiles::ShowUserManagerMaybeWithTutorial(browser_->profile()); 721 profiles::ShowUserManagerMaybeWithTutorial(browser_->profile());
711 } 722 }
712 723
713 - (IBAction)showAccountManagement:(id)sender { 724 - (IBAction)showAccountManagement:(id)sender {
714 [self initMenuContentsWithView:BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT]; 725 [self initMenuContentsWithView:BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT];
715 } 726 }
716 727
728 - (IBAction)hideAccountManagement:(id)sender {
729 [self initMenuContentsWithView:BUBBLE_VIEW_MODE_PROFILE_CHOOSER];
730 }
731
717 - (IBAction)lockProfile:(id)sender { 732 - (IBAction)lockProfile:(id)sender {
718 profiles::LockProfile(browser_->profile()); 733 profiles::LockProfile(browser_->profile());
719 } 734 }
720 735
721 - (IBAction)showSigninPage:(id)sender { 736 - (IBAction)showInlineSigninPage:(id)sender {
722 [self initMenuContentsWithView:BUBBLE_VIEW_MODE_GAIA_SIGNIN]; 737 [self initMenuContentsWithView:BUBBLE_VIEW_MODE_GAIA_SIGNIN];
723 } 738 }
724 739
740 - (IBAction)showTabbedSigninPage:(id)sender {
741 chrome::ShowBrowserSignin(browser_, signin::SOURCE_MENU);
742 }
743
725 - (IBAction)addAccount:(id)sender { 744 - (IBAction)addAccount:(id)sender {
726 [self initMenuContentsWithView:BUBBLE_VIEW_MODE_GAIA_ADD_ACCOUNT]; 745 [self initMenuContentsWithView:BUBBLE_VIEW_MODE_GAIA_ADD_ACCOUNT];
727 } 746 }
728 747
729 - (IBAction)navigateBackFromSigninPage:(id)sender { 748 - (IBAction)navigateBackFromSigninPage:(id)sender {
730 std::string primaryAccount = SigninManagerFactory::GetForProfile( 749 std::string primaryAccount = SigninManagerFactory::GetForProfile(
731 browser_->profile())->GetAuthenticatedUsername(); 750 browser_->profile())->GetAuthenticatedUsername();
732 [self initMenuContentsWithView:primaryAccount.empty() ? 751 [self initMenuContentsWithView:primaryAccount.empty() ?
733 BUBBLE_VIEW_MODE_PROFILE_CHOOSER : BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT]; 752 BUBBLE_VIEW_MODE_PROFILE_CHOOSER : BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT];
734 } 753 }
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
854 enableLock = item.signed_in; 873 enableLock = item.signed_in;
855 } else { 874 } else {
856 [otherProfiles addObject:[self createOtherProfileView:i]]; 875 [otherProfiles addObject:[self createOtherProfileView:i]];
857 } 876 }
858 } 877 }
859 if (!currentProfileView) // Guest windows don't have an active profile. 878 if (!currentProfileView) // Guest windows don't have an active profile.
860 currentProfileView = [self createGuestProfileView]; 879 currentProfileView = [self createGuestProfileView];
861 880
862 // |yOffset| is the next position at which to draw in |contentView| 881 // |yOffset| is the next position at which to draw in |contentView|
863 // coordinates. 882 // coordinates.
864 CGFloat yOffset = kSmallVerticalSpacing; 883 CGFloat yOffset = 0;
865 884
866 // Option buttons. 885 // Option buttons. Only available with the new profile management flag.
867 NSView* optionsView = [self createOptionsViewWithRect: 886 if (switches::IsNewProfileManagement()) {
868 NSMakeRect(0, yOffset, kFixedMenuWidth, 0) 887 NSRect rect = NSMakeRect(0, yOffset, kFixedMenuWidth, 0);
869 enableLock:enableLock]; 888 NSView* optionsView = [self createOptionsViewWithRect:rect
870 [contentView addSubview:optionsView]; 889 enableLock:enableLock];
871 yOffset = NSMaxY([optionsView frame]) + kSmallVerticalSpacing; 890 [contentView addSubview:optionsView];
891 rect.origin.y = NSMaxY([optionsView frame]);
872 892
873 NSBox* separator = [self separatorWithFrame: 893 NSBox* separator = [self separatorWithFrame:rect];
874 NSMakeRect(0, yOffset, kFixedMenuWidth, 0)]; 894 [contentView addSubview:separator];
875 [contentView addSubview:separator]; 895 yOffset = NSMaxY([separator frame]);
876 yOffset = NSMaxY([separator frame]) + kVerticalSpacing; 896 }
877 897
878 if (viewToDisplay == BUBBLE_VIEW_MODE_PROFILE_CHOOSER && 898 if (viewToDisplay == BUBBLE_VIEW_MODE_PROFILE_CHOOSER &&
879 switches::IsFastUserSwitching()) { 899 switches::IsFastUserSwitching()) {
880 // Other profiles switcher. The profiles have already been sorted 900 // Other profiles switcher. The profiles have already been sorted
881 // by their y-coordinate, so they can be added in the existing order. 901 // by their y-coordinate, so they can be added in the existing order.
882 for (NSView *otherProfileView in otherProfiles.get()) { 902 for (NSView *otherProfileView in otherProfiles.get()) {
883 [otherProfileView setFrameOrigin:NSMakePoint(kHorizontalSpacing, 903 [otherProfileView setFrameOrigin:NSMakePoint(0, yOffset)];
884 yOffset)];
885 [contentView addSubview:otherProfileView]; 904 [contentView addSubview:otherProfileView];
886 yOffset = NSMaxY([otherProfileView frame]) + kSmallVerticalSpacing; 905 yOffset = NSMaxY([otherProfileView frame]);
906
907 NSBox* separator =
908 [self separatorWithFrame:NSMakeRect(0, yOffset, kFixedMenuWidth, 0)];
909 [contentView addSubview:separator];
910 yOffset = NSMaxY([separator frame]);
887 } 911 }
888
889 // If we displayed other profiles, ensure the spacing between the last item
890 // and the active profile card is the same as the spacing between the active
891 // profile card and the bottom of the bubble.
892 if ([otherProfiles.get() count] > 0)
893 yOffset += kSmallVerticalSpacing;
894 } else if (viewToDisplay == BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT) { 912 } else if (viewToDisplay == BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT) {
895 NSView* currentProfileAccountsView = [self createCurrentProfileAccountsView: 913 NSView* currentProfileAccountsView = [self createCurrentProfileAccountsView:
896 NSMakeRect(kHorizontalSpacing, 914 NSMakeRect(0, yOffset, kFixedMenuWidth, 0)];
897 yOffset,
898 kFixedMenuWidth - 2 * kHorizontalSpacing,
899 0)];
900 [contentView addSubview:currentProfileAccountsView]; 915 [contentView addSubview:currentProfileAccountsView];
901 yOffset = NSMaxY([currentProfileAccountsView frame]) + kVerticalSpacing; 916 yOffset = NSMaxY([currentProfileAccountsView frame]);
902 917
903 NSBox* accountsSeparator = [self separatorWithFrame: 918 NSBox* accountsSeparator = [self separatorWithFrame:
904 NSMakeRect(0, yOffset, kFixedMenuWidth, 0)]; 919 NSMakeRect(0, yOffset, kFixedMenuWidth, 0)];
905 [contentView addSubview:accountsSeparator]; 920 [contentView addSubview:accountsSeparator];
906 yOffset = NSMaxY([accountsSeparator frame]) + kVerticalSpacing; 921 yOffset = NSMaxY([accountsSeparator frame]);
907 } 922 }
908 923
909 // Active profile card. 924 // Active profile card.
910 if (currentProfileView) { 925 if (currentProfileView) {
911 [currentProfileView setFrameOrigin:NSMakePoint(kHorizontalSpacing, 926 yOffset += kVerticalSpacing;
912 yOffset)]; 927 [currentProfileView setFrameOrigin:NSMakePoint(0, yOffset)];
913 [contentView addSubview:currentProfileView]; 928 [contentView addSubview:currentProfileView];
914 yOffset = NSMaxY([currentProfileView frame]) + kVerticalSpacing; 929 yOffset = NSMaxY([currentProfileView frame]) + kVerticalSpacing;
915 } 930 }
916 931
917 if (tutorialView) { 932 if (tutorialView) {
918 [tutorialView setFrameOrigin:NSMakePoint(0, yOffset)]; 933 [tutorialView setFrameOrigin:NSMakePoint(0, yOffset)];
919 [contentView addSubview:tutorialView]; 934 [contentView addSubview:tutorialView];
920 yOffset = NSMaxY([tutorialView frame]); 935 yOffset = NSMaxY([tutorialView frame]);
921 } else { 936 } else {
922 tutorialShowing_ = false; 937 tutorialShowing_ = false;
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1029 1044
1030 [containerWithCaret setFrameSize: 1045 [containerWithCaret setFrameSize:
1031 NSMakeSize(kFixedMenuWidth, NSMaxY([container frame]))]; 1046 NSMakeSize(kFixedMenuWidth, NSMaxY([container frame]))];
1032 return containerWithCaret.autorelease(); 1047 return containerWithCaret.autorelease();
1033 } 1048 }
1034 1049
1035 - (NSView*)createCurrentProfileView:(const AvatarMenu::Item&)item { 1050 - (NSView*)createCurrentProfileView:(const AvatarMenu::Item&)item {
1036 base::scoped_nsobject<NSView> container([[NSView alloc] 1051 base::scoped_nsobject<NSView> container([[NSView alloc]
1037 initWithFrame:NSZeroRect]); 1052 initWithFrame:NSZeroRect]);
1038 1053
1039 // Profile icon. 1054 CGFloat xOffset = kHorizontalSpacing;
1040 base::scoped_nsobject<EditableProfilePhoto> iconView( 1055 CGFloat yOffset = 0;
1041 [[EditableProfilePhoto alloc] 1056 CGFloat availableTextWidth = kFixedMenuWidth - 2 * kHorizontalSpacing;
1042 initWithFrame:NSMakeRect(0, 0, kLargeImageSide, kLargeImageSide)
1043 avatarMenu:avatarMenu_.get()
1044 profileIcon:item.icon
1045 editingAllowed:!isGuestSession_]);
1046 1057
1047 [container addSubview:iconView]; 1058 // Profile options. This can be a link to the accounts view, the profile's
1048 1059 // username for signed in users, or a "Sign in" button for local profiles.
1049 CGFloat xOffset = NSMaxX([iconView frame]) + kHorizontalSpacing; 1060 if (!isGuestSession_) {
1050 CGFloat yOffset = kVerticalSpacing;
1051 if (!isGuestSession_ && viewMode_ == BUBBLE_VIEW_MODE_PROFILE_CHOOSER) {
1052 NSView* linksContainer = 1061 NSView* linksContainer =
1053 [self createCurrentProfileLinksForItem:item withXOffset:xOffset]; 1062 [self createCurrentProfileLinksForItem:item
1063 rect:NSMakeRect(xOffset, yOffset,
1064 availableTextWidth,
1065 0)];
1054 [container addSubview:linksContainer]; 1066 [container addSubview:linksContainer];
1055 yOffset = NSMaxY([linksContainer frame]); 1067 yOffset = NSMaxY([linksContainer frame]);
1056 } 1068 }
1057 1069
1058 // Profile name. 1070 // Profile name, centered.
1059 CGFloat availableTextWidth =
1060 kFixedMenuWidth - xOffset - 2 * kHorizontalSpacing;
1061 base::scoped_nsobject<EditableProfileNameButton> profileName( 1071 base::scoped_nsobject<EditableProfileNameButton> profileName(
1062 [[EditableProfileNameButton alloc] 1072 [[EditableProfileNameButton alloc]
1063 initWithFrame:NSMakeRect(xOffset, yOffset, 1073 initWithFrame:NSMakeRect(xOffset, yOffset,
1064 availableTextWidth, 1074 availableTextWidth,
1065 kProfileButtonHeight) 1075 kProfileButtonHeight)
1066 profile:browser_->profile() 1076 profile:browser_->profile()
1067 profileName:base::SysUTF16ToNSString( 1077 profileName:base::SysUTF16ToNSString(
1068 profiles::GetAvatarNameForProfile(browser_->profile())) 1078 profiles::GetAvatarNameForProfile(browser_->profile()))
1069 editingAllowed:!isGuestSession_]); 1079 editingAllowed:!isGuestSession_]);
1070 1080
1071 [container addSubview:profileName]; 1081 [container addSubview:profileName];
1072 [container setFrameSize:NSMakeSize(kFixedMenuWidth, 1082 yOffset = NSMaxY([profileName frame]);
1073 NSHeight([iconView frame]))]; 1083
1084 // Profile icon, centered.
1085 xOffset = (kFixedMenuWidth - kLargeImageSide) / 2;
1086 base::scoped_nsobject<EditableProfilePhoto> iconView(
1087 [[EditableProfilePhoto alloc]
1088 initWithFrame:NSMakeRect(xOffset, yOffset,
1089 kLargeImageSide, kLargeImageSide)
1090 avatarMenu:avatarMenu_.get()
1091 profileIcon:item.icon
1092 editingAllowed:!isGuestSession_]);
1093
1094 [container addSubview:iconView];
1095 yOffset = NSMaxY([iconView frame]);
1096
1097 [container setFrameSize:NSMakeSize(kFixedMenuWidth, yOffset)];
1074 return container.autorelease(); 1098 return container.autorelease();
1075 } 1099 }
1076 1100
1077 - (NSView*)createCurrentProfileLinksForItem:(const AvatarMenu::Item&)item 1101 - (NSView*)createCurrentProfileLinksForItem:(const AvatarMenu::Item&)item
1078 withXOffset:(CGFloat)xOffset { 1102 rect:(NSRect)rect {
1079 base::scoped_nsobject<NSView> container([[NSView alloc] 1103 base::scoped_nsobject<NSView> container([[NSView alloc] initWithFrame:rect]);
1080 initWithFrame:NSZeroRect]);
1081 1104
1105 // Don't double-apply the left margin to the sub-views.
1106 rect.origin.x = 0;
1107
1108 // The available links depend on the type of profile that is active.
1082 NSButton* link; 1109 NSButton* link;
1083 NSPoint frameOrigin = NSMakePoint(xOffset, kSmallVerticalSpacing);
1084 // The available links depend on the type of profile that is active.
1085 if (item.signed_in) { 1110 if (item.signed_in) {
1086 link = [self linkButtonWithTitle:l10n_util::GetNSString( 1111 if (switches::IsNewProfileManagement()) {
1087 IDS_PROFILES_PROFILE_MANAGE_ACCOUNTS_BUTTON) 1112 NSString* linkTitle = l10n_util::GetNSString(
1088 frameOrigin:frameOrigin 1113 viewMode_ == BUBBLE_VIEW_MODE_PROFILE_CHOOSER ?
1089 action:@selector(showAccountManagement:)]; 1114 IDS_PROFILES_PROFILE_MANAGE_ACCOUNTS_BUTTON :
1115 IDS_PROFILES_PROFILE_HIDE_MANAGE_ACCOUNTS_BUTTON);
1116 SEL linkSelector = viewMode_ == BUBBLE_VIEW_MODE_PROFILE_CHOOSER ?
groby-ooo-7-16 2014/04/16 18:50:37 Would you mind parenthesizing the condition at lea
noms (inactive) 2014/04/16 19:43:35 Absolutely! I prefer that, but have got comments a
1117 @selector(showAccountManagement:) : @selector(hideAccountManagement:);
1118 link = [self linkButtonWithTitle:linkTitle
1119 frameOrigin:rect.origin
1120 action:linkSelector];
1121 } else {
1122 link = [self linkButtonWithTitle:base::SysUTF16ToNSString(item.sync_state)
1123 frameOrigin:rect.origin
1124 action:nil];
1125 [[link cell] setTextColor:[NSColor blackColor]];
1126 }
1127 // -linkButtonWithTitle sizeToFit's the link, so re-stretch it so that it
1128 // can be centered correctly in the view.
1129 rect.size.height = NSMaxY([link frame]);
1130 [link setFrame:rect];
1131 [link setAlignment:NSCenterTextAlignment];
1090 } else { 1132 } else {
1091 link = [self linkButtonWithTitle:l10n_util::GetNSStringFWithFixup( 1133 rect.size.height = kBlueButtonHeight;
1092 IDS_SYNC_START_SYNC_BUTTON_LABEL, 1134 link = [[BlueLabelButton alloc] initWithFrame:rect];
1093 l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME)) 1135
1094 frameOrigin:frameOrigin 1136 // Manually elide the button text so that the contents fit inside the bubble
1095 action:@selector(showSigninPage:)]; 1137 // This is needed because the BlueLabelButton cell resets the style on
groby-ooo-7-16 2014/04/16 18:50:37 Maybe file a bug on BlueLabelButton for this - it
1138 // every call to -cellSize, which prevents setting a custom lineBreakMode.
1139 NSString* elidedButtonText = base::SysUTF16ToNSString(gfx::ElideText(
1140 l10n_util::GetStringFUTF16(
1141 IDS_SYNC_START_SYNC_BUTTON_LABEL,
1142 l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME)),
1143 ui::ResourceBundle::GetSharedInstance().GetFontList(
1144 ui::ResourceBundle::BaseFont),
1145 rect.size.width,
1146 gfx::ELIDE_AT_END));
1147
1148 [link setTitle:elidedButtonText];
1149 [link setTarget:self];
1150 [link setAction:switches::IsNewProfileManagement() ?
1151 @selector(showInlineSigninPage:) : @selector(showTabbedSigninPage:)];
1096 } 1152 }
1097 1153
1098 [container addSubview:link]; 1154 [container addSubview:link];
1099 [container setFrameSize:NSMakeSize( 1155 [container setFrameSize:rect.size];
1100 NSMaxX([link frame]), NSMaxY([link frame]) + kSmallVerticalSpacing)];
1101 return container.autorelease(); 1156 return container.autorelease();
1102 } 1157 }
1103 1158
1104 - (NSView*)createGuestProfileView { 1159 - (NSView*)createGuestProfileView {
1105 gfx::Image guestIcon = 1160 gfx::Image guestIcon =
1106 ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed( 1161 ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed(
1107 IDR_LOGIN_GUEST); 1162 IDR_LOGIN_GUEST);
1108 AvatarMenu::Item guestItem(std::string::npos, /* menu_index, not used */ 1163 AvatarMenu::Item guestItem(std::string::npos, /* menu_index, not used */
1109 std::string::npos, /* profile_index, not used */ 1164 std::string::npos, /* profile_index, not used */
1110 guestIcon); 1165 guestIcon);
1111 guestItem.active = true; 1166 guestItem.active = true;
1112 guestItem.name = base::SysNSStringToUTF16( 1167 guestItem.name = base::SysNSStringToUTF16(
1113 l10n_util::GetNSString(IDS_PROFILES_GUEST_PROFILE_NAME)); 1168 l10n_util::GetNSString(IDS_PROFILES_GUEST_PROFILE_NAME));
1114 1169
1115 return [self createCurrentProfileView:guestItem]; 1170 return [self createCurrentProfileView:guestItem];
1116 } 1171 }
1117 1172
1118 - (NSButton*)createOtherProfileView:(int)itemIndex { 1173 - (NSButton*)createOtherProfileView:(int)itemIndex {
1119 const AvatarMenu::Item& item = avatarMenu_->GetItemAt(itemIndex); 1174 const AvatarMenu::Item& item = avatarMenu_->GetItemAt(itemIndex);
1120 base::scoped_nsobject<NSButton> profileButton([[NSButton alloc]
1121 initWithFrame:NSZeroRect]);
1122 base::scoped_nsobject<CustomPaddingImageButtonCell> cell(
1123 [[CustomPaddingImageButtonCell alloc]
1124 initWithLeftMarginSpacing:0
1125 imageTitleSpacing:kImageTitleSpacing]);
1126 [profileButton setCell:cell.get()];
1127 1175
1128 [[profileButton cell] setLineBreakMode:NSLineBreakByTruncatingTail]; 1176 NSRect rect = NSMakeRect(0, 0, kFixedMenuWidth,
1177 kBlueButtonHeight + kSmallVerticalSpacing);
1178 SkColor backgroundColor = ui::NativeTheme::instance()->GetSystemColor(
1179 ui::NativeTheme::kColorId_DialogBackground);
1180
1181 base::scoped_nsobject<BackgroundColorHoverButton> profileButton(
1182 [[BackgroundColorHoverButton alloc] initWithFrame:rect
1183 imageTitleSpacing:kImageTitleSpacing
1184 backgroundColor:backgroundColor]);
1129 [profileButton setTitle:base::SysUTF16ToNSString(item.name)]; 1185 [profileButton setTitle:base::SysUTF16ToNSString(item.name)];
1130 [profileButton setImage:CreateProfileImage( 1186 [profileButton setDefaultImage:CreateProfileImage(
1131 item.icon, kSmallImageSide).ToNSImage()]; 1187 item.icon, kSmallImageSide).ToNSImage()];
1132 [profileButton setImagePosition:NSImageLeft]; 1188 [profileButton setImagePosition:NSImageLeft];
1133 [profileButton setAlignment:NSLeftTextAlignment]; 1189 [profileButton setAlignment:NSLeftTextAlignment];
1134 [profileButton setBordered:NO]; 1190 [profileButton setBordered:NO];
1135 [profileButton setFont:[NSFont labelFontOfSize:kTitleFontSize]];
1136 [profileButton setTag:itemIndex]; 1191 [profileButton setTag:itemIndex];
1137 [profileButton setTarget:self]; 1192 [profileButton setTarget:self];
1138 [profileButton setAction:@selector(switchToProfile:)]; 1193 [profileButton setAction:@selector(switchToProfile:)];
1139 1194
1140 // Since the bubble is fixed width, we need to calculate the width available
1141 // for the profile name, as longer names will have to be elided.
1142 CGFloat availableTextWidth = kFixedMenuWidth - 2 * kHorizontalSpacing;
1143 [profileButton sizeToFit];
1144 [profileButton setFrameSize:NSMakeSize(availableTextWidth,
1145 NSHeight([profileButton frame]))];
1146
1147 return profileButton.autorelease(); 1195 return profileButton.autorelease();
1148 } 1196 }
1149 1197
1150 - (NSView*)createOptionsViewWithRect:(NSRect)rect 1198 - (NSView*)createOptionsViewWithRect:(NSRect)rect
1151 enableLock:(BOOL)enableLock { 1199 enableLock:(BOOL)enableLock {
1152 int widthOfLockButton = enableLock? 2 * kHorizontalSpacing + 12 : 0; 1200 int widthOfLockButton = enableLock? 2 * kHorizontalSpacing + 12 : 0;
1153 NSRect viewRect = NSMakeRect(0, 0, 1201 NSRect viewRect = NSMakeRect(0, 0,
1154 rect.size.width - widthOfLockButton, 1202 rect.size.width - widthOfLockButton,
1155 kBlueButtonHeight); 1203 kBlueButtonHeight + kVerticalSpacing);
1156 NSButton* notYouButton = 1204 NSButton* notYouButton =
1157 [self hoverButtonWithRect:viewRect 1205 [self hoverButtonWithRect:viewRect
1158 text:l10n_util::GetNSStringF( 1206 text:l10n_util::GetNSStringF(
1159 IDS_PROFILES_NOT_YOU_BUTTON, 1207 IDS_PROFILES_NOT_YOU_BUTTON,
1160 profiles::GetAvatarNameForProfile(browser_->profile())) 1208 profiles::GetAvatarNameForProfile(browser_->profile()))
1161 imageResourceId:IDR_ICON_PROFILES_MENU_AVATAR 1209 imageResourceId:IDR_ICON_PROFILES_MENU_AVATAR
1162 alternateImageResourceId:IDR_ICON_PROFILES_MENU_AVATAR 1210 alternateImageResourceId:IDR_ICON_PROFILES_MENU_AVATAR
1163 action:@selector(showUserManager:)]; 1211 action:@selector(showUserManager:)];
1164 1212
1165 rect.size.height = NSMaxY([notYouButton frame]); 1213 rect.size.height = NSMaxY([notYouButton frame]);
1166 base::scoped_nsobject<NSView> container([[NSView alloc] 1214 base::scoped_nsobject<NSView> container([[NSView alloc] initWithFrame:rect]);
1167 initWithFrame:rect]);
1168 [container addSubview:notYouButton]; 1215 [container addSubview:notYouButton];
1169 1216
1170 if (enableLock) { 1217 if (enableLock) {
1171 viewRect.origin.x = NSMaxX([notYouButton frame]); 1218 viewRect.origin.x = NSMaxX([notYouButton frame]);
1172 viewRect.size.width = widthOfLockButton; 1219 viewRect.size.width = widthOfLockButton;
1173 NSButton* lockButton = 1220 NSButton* lockButton =
1174 [self hoverButtonWithRect:viewRect 1221 [self hoverButtonWithRect:viewRect
1175 text:@"" 1222 text:@""
1176 imageResourceId:IDR_ICON_PROFILES_MENU_LOCK 1223 imageResourceId:IDR_ICON_PROFILES_MENU_LOCK
1177 alternateImageResourceId:IDR_ICON_PROFILES_MENU_LOCK 1224 alternateImageResourceId:IDR_ICON_PROFILES_MENU_LOCK
1178 action:@selector(lockProfile:)]; 1225 action:@selector(lockProfile:)];
1179 [container addSubview:lockButton]; 1226 [container addSubview:lockButton];
1180 } 1227 }
1181 1228
1182 return container.autorelease(); 1229 return container.autorelease();
1183 } 1230 }
1184 1231
1185 - (NSView*)createCurrentProfileAccountsView:(NSRect)rect { 1232 - (NSView*)createCurrentProfileAccountsView:(NSRect)rect {
1186 const CGFloat kAccountButtonHeight = 15; 1233 const CGFloat kAccountButtonHeight = 34;
1187 1234
1188 const AvatarMenu::Item& item = 1235 const AvatarMenu::Item& item =
1189 avatarMenu_->GetItemAt(avatarMenu_->GetActiveProfileIndex()); 1236 avatarMenu_->GetItemAt(avatarMenu_->GetActiveProfileIndex());
1190 DCHECK(item.signed_in); 1237 DCHECK(item.signed_in);
1191 1238
1192 base::scoped_nsobject<NSView> container([[NSView alloc] initWithFrame:rect]); 1239 NSColor* backgroundColor =
1193 1240 gfx::SkColorToSRGBNSColor(profiles::kAvatarBubbleAccountsBackgroundColor);
groby-ooo-7-16 2014/04/16 18:50:37 Is there a reason this is an SRGBNSColor instead o
noms (inactive) 2014/04/16 19:43:35 Done.
1194 NSRect viewRect = NSMakeRect(0, 0, rect.size.width, kBlueButtonHeight); 1241 base::scoped_nsobject<NSView> container([[BackgroundColorView alloc]
1195 base::scoped_nsobject<NSButton> addAccountsButton([[BlueLabelButton alloc] 1242 initWithFrame:rect
1196 initWithFrame:viewRect]); 1243 withColor:backgroundColor]);
1197 1244
1198 // Manually elide the button text so that the contents fit inside the bubble. 1245 // Manually elide the button text so that the contents fit inside the bubble.
1199 // This is needed because the BlueLabelButton cell resets the style on 1246 // This is needed because the BlueLabelButton cell resets the style on
1200 // every call to -cellSize, which prevents setting a custom lineBreakMode. 1247 // every call to -cellSize, which prevents setting a custom lineBreakMode.
1201 NSString* elidedButtonText = base::SysUTF16ToNSString(gfx::ElideText( 1248 NSString* elidedButtonText = base::SysUTF16ToNSString(gfx::ElideText(
1202 l10n_util::GetStringFUTF16( 1249 l10n_util::GetStringFUTF16(
1203 IDS_PROFILES_PROFILE_ADD_ACCOUNT_BUTTON, item.name), 1250 IDS_PROFILES_PROFILE_ADD_ACCOUNT_BUTTON, item.name),
1204 ui::ResourceBundle::GetSharedInstance().GetFontList( 1251 ui::ResourceBundle::GetSharedInstance().GetFontList(
1205 ui::ResourceBundle::BaseFont), 1252 ui::ResourceBundle::BaseFont),
1206 rect.size.width, 1253 rect.size.width,
1207 gfx::ELIDE_AT_END)); 1254 gfx::ELIDE_AT_END));
1208 1255
1209 [addAccountsButton setTitle:elidedButtonText]; 1256 NSButton* addAccountsButton =
1210 [addAccountsButton setTarget:self]; 1257 [self linkButtonWithTitle:elidedButtonText
1211 [addAccountsButton setAction:@selector(addAccount:)]; 1258 frameOrigin:NSMakePoint(
1259 kHorizontalSpacing, kSmallVerticalSpacing)
1260 action:@selector(addAccount:)];
1212 [container addSubview:addAccountsButton]; 1261 [container addSubview:addAccountsButton];
1213 1262
1214 // Update the height of the email account buttons. This is needed so that the 1263 NSView* accountEmails = [self createAccountsListWithRect:NSMakeRect(
1215 // all the buttons span the entire width of the bubble. 1264 0, kAccountButtonHeight, rect.size.width, kAccountButtonHeight)];
1216 viewRect.origin.y = NSMaxY([addAccountsButton frame]) + kVerticalSpacing; 1265 [container addSubview:accountEmails];
1217 viewRect.size.height = kAccountButtonHeight;
1218 1266
1219 NSView* accountEmails = [self createAccountsListWithRect:viewRect]; 1267 [container setFrameSize:NSMakeSize(rect.size.width,
1220 [container addSubview:accountEmails]; 1268 NSMaxY([accountEmails frame]))];
1221 [container setFrameSize:NSMakeSize(
1222 NSWidth([container frame]), NSMaxY([accountEmails frame]))];
1223 return container.autorelease(); 1269 return container.autorelease();
1224 } 1270 }
1225 1271
1226 - (NSView*)createAccountsListWithRect:(NSRect)rect { 1272 - (NSView*)createAccountsListWithRect:(NSRect)rect {
1227 base::scoped_nsobject<NSView> container([[NSView alloc] initWithFrame:rect]); 1273 base::scoped_nsobject<NSView> container([[NSView alloc] initWithFrame:rect]);
1228 currentProfileAccounts_.clear(); 1274 currentProfileAccounts_.clear();
1229 1275
1230 Profile* profile = browser_->profile(); 1276 Profile* profile = browser_->profile();
1231 std::string primaryAccount = 1277 std::string primaryAccount =
1232 SigninManagerFactory::GetForProfile(profile)->GetAuthenticatedUsername(); 1278 SigninManagerFactory::GetForProfile(profile)->GetAuthenticatedUsername();
1233 DCHECK(!primaryAccount.empty()); 1279 DCHECK(!primaryAccount.empty());
1234 std::vector<std::string>accounts = 1280 std::vector<std::string>accounts =
1235 profiles::GetSecondaryAccountsForProfile(profile, primaryAccount); 1281 profiles::GetSecondaryAccountsForProfile(profile, primaryAccount);
1236 1282
1237 rect.origin.y = 0; 1283 rect.origin.y = 0;
1238 for (size_t i = 0; i < accounts.size(); ++i) { 1284 for (size_t i = 0; i < accounts.size(); ++i) {
1239 // Save the original email address, as the button text could be elided. 1285 // Save the original email address, as the button text could be elided.
1240 currentProfileAccounts_[i] = accounts[i]; 1286 currentProfileAccounts_[i] = accounts[i];
1241 NSButton* accountButton = [self accountButtonWithRect:rect 1287 NSButton* accountButton = [self accountButtonWithRect:rect
1242 title:accounts[i]]; 1288 title:accounts[i]];
1243 [accountButton setTag:i]; 1289 [accountButton setTag:i];
1244 [container addSubview:accountButton]; 1290 [container addSubview:accountButton];
1245 rect.origin.y = NSMaxY([accountButton frame]) + kSmallVerticalSpacing; 1291 rect.origin.y = NSMaxY([accountButton frame]);
1246 } 1292 }
1247 1293
1248 // The primary account should always be listed first. 1294 // The primary account should always be listed first.
1249 NSButton* accountButton = [self accountButtonWithRect:rect 1295 NSButton* accountButton = [self accountButtonWithRect:rect
1250 title:primaryAccount]; 1296 title:primaryAccount];
1251 [container addSubview:accountButton]; 1297 [container addSubview:accountButton];
1252 [container setFrameSize:NSMakeSize(NSWidth([container frame]), 1298 [container setFrameSize:NSMakeSize(NSWidth([container frame]),
1253 NSMaxY([accountButton frame]))]; 1299 NSMaxY([accountButton frame]))];
1254 [accountButton setTag:kPrimaryProfileTag]; 1300 [accountButton setTag:kPrimaryProfileTag];
1255 return container.autorelease(); 1301 return container.autorelease();
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1375 clickedOnLink:(id)link 1421 clickedOnLink:(id)link
1376 atIndex:(NSUInteger)charIndex { 1422 atIndex:(NSUInteger)charIndex {
1377 chrome::ShowSettings(browser_); 1423 chrome::ShowSettings(browser_);
1378 return YES; 1424 return YES;
1379 } 1425 }
1380 1426
1381 - (NSButton*)hoverButtonWithRect:(NSRect)rect 1427 - (NSButton*)hoverButtonWithRect:(NSRect)rect
1382 text:(NSString*)text 1428 text:(NSString*)text
1383 imageResourceId:(int)imageResourceId 1429 imageResourceId:(int)imageResourceId
1384 alternateImageResourceId:(int)alternateImageResourceId 1430 alternateImageResourceId:(int)alternateImageResourceId
1385 action:(SEL)action { 1431 action:(SEL)action {
1432 SkColor backgroundColor = ui::NativeTheme::instance()->GetSystemColor(
1433 ui::NativeTheme::kColorId_DialogBackground);
1386 base::scoped_nsobject<BackgroundColorHoverButton> button( 1434 base::scoped_nsobject<BackgroundColorHoverButton> button(
1387 [[BackgroundColorHoverButton alloc] initWithFrame:rect]); 1435 [[BackgroundColorHoverButton alloc] initWithFrame:rect
1436 imageTitleSpacing:kImageTitleSpacing
1437 backgroundColor:backgroundColor]);
1388 1438
1389 [button setTitle:text]; 1439 [button setTitle:text];
1390 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); 1440 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
1391 NSImage* alternateImage = rb->GetNativeImageNamed( 1441 NSImage* alternateImage = rb->GetNativeImageNamed(
1392 alternateImageResourceId).ToNSImage(); 1442 alternateImageResourceId).ToNSImage();
1393 [button setDefaultImage:rb->GetNativeImageNamed(imageResourceId).ToNSImage()]; 1443 [button setDefaultImage:rb->GetNativeImageNamed(imageResourceId).ToNSImage()];
1394 [button setHoverImage:alternateImage]; 1444 [button setHoverImage:alternateImage];
1395 [button setPressedImage:alternateImage]; 1445 [button setPressedImage:alternateImage];
1396 [button setImagePosition:NSImageLeft]; 1446 [button setImagePosition:NSImageLeft];
1397 [button setAlignment:NSLeftTextAlignment]; 1447 [button setAlignment:NSLeftTextAlignment];
(...skipping 19 matching lines...) Expand all
1417 [link setTarget:self]; 1467 [link setTarget:self];
1418 [link setAction:action]; 1468 [link setAction:action];
1419 [link setFrameOrigin:frameOrigin]; 1469 [link setFrameOrigin:frameOrigin];
1420 [link sizeToFit]; 1470 [link sizeToFit];
1421 1471
1422 return link.autorelease(); 1472 return link.autorelease();
1423 } 1473 }
1424 1474
1425 - (NSButton*)accountButtonWithRect:(NSRect)rect 1475 - (NSButton*)accountButtonWithRect:(NSRect)rect
1426 title:(const std::string&)title { 1476 title:(const std::string&)title {
1427 base::scoped_nsobject<NSButton> button([[NSButton alloc] initWithFrame:rect]); 1477 SkColor backgroundColor = profiles::kAvatarBubbleAccountsBackgroundColor;
1478 base::scoped_nsobject<BackgroundColorHoverButton> button(
1479 [[BackgroundColorHoverButton alloc] initWithFrame:rect
1480 imageTitleSpacing:0
1481 backgroundColor:backgroundColor]);
1482
1428 [button setTitle:ElideEmail(title, rect.size.width)]; 1483 [button setTitle:ElideEmail(title, rect.size.width)];
1429 [button setAlignment:NSLeftTextAlignment]; 1484 [button setAlignment:NSLeftTextAlignment];
1430 [button setBordered:NO]; 1485 [button setBordered:NO];
1431
1432 [button setImage:ui::ResourceBundle::GetSharedInstance().
1433 GetNativeImageNamed(IDR_CLOSE_1).ToNSImage()];
1434 [button setImagePosition:NSImageRight];
1435 [button setTarget:self]; 1486 [button setTarget:self];
1436 [button setAction:@selector(showAccountRemovalView:)]; 1487 [button setAction:@selector(showAccountRemovalView:)];
1437 1488
1438 return button.autorelease(); 1489 return button.autorelease();
1439 } 1490 }
1440 1491
1441 @end 1492 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698