OLD | NEW |
---|---|
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 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
223 | 223 |
224 [container addSubview:button]; | 224 [container addSubview:button]; |
225 [container addSubview:title_label]; | 225 [container addSubview:title_label]; |
226 CGFloat height = std::max(NSMaxY([title_label frame]), | 226 CGFloat height = std::max(NSMaxY([title_label frame]), |
227 NSMaxY([button frame])) + kSmallVerticalSpacing; | 227 NSMaxY([button frame])) + kSmallVerticalSpacing; |
228 [container setFrameSize:NSMakeSize(NSWidth([container frame]), height)]; | 228 [container setFrameSize:NSMakeSize(NSWidth([container frame]), height)]; |
229 | 229 |
230 return container.autorelease(); | 230 return container.autorelease(); |
231 } | 231 } |
232 | 232 |
233 bool HasAuthError(Profile* profile) { | |
msw
2014/06/03 04:15:31
nit: this is used twice, is a helper necessary?
noms (inactive)
2014/06/06 20:33:44
I thought it looked a little nicer, because the th
| |
234 const SigninErrorController* error = | |
235 profiles::GetSigninErrorController(profile); | |
236 return error && error->HasError(); | |
237 } | |
238 | |
239 std::string GetAuthErrorAccountId(Profile* profile) { | |
msw
2014/06/03 04:15:31
nit: this is used once, please inline it.
noms (inactive)
2014/06/06 20:33:44
Done.
| |
240 SigninErrorController* error = | |
241 ProfileOAuth2TokenServiceFactory::GetForProfile(profile)-> | |
242 signin_error_controller(); | |
243 if (!error) | |
msw
2014/06/03 04:15:31
nit: return error ? error->error_account_id() : st
noms (inactive)
2014/06/06 20:33:44
Done.
| |
244 return std::string(); | |
245 | |
246 return error->error_account_id(); | |
247 } | |
248 | |
249 std::string GetAuthErrorUsername(Profile* profile) { | |
msw
2014/06/03 04:15:31
nit: this is used once, please inline it.
noms (inactive)
2014/06/06 20:33:43
Done.
| |
250 const SigninErrorController* error = | |
251 profiles::GetSigninErrorController(profile); | |
252 if (!error) | |
msw
2014/06/03 04:15:31
nit: return error ? error->error_username() : std:
noms (inactive)
2014/06/06 20:33:44
Done.
| |
253 return std::string(); | |
254 | |
255 return error->error_username(); | |
256 } | |
257 | |
233 } // namespace | 258 } // namespace |
234 | 259 |
235 // Class that listens to changes to the OAuth2Tokens for the active profile, | 260 // Class that listens to changes to the OAuth2Tokens for the active profile, |
236 // changes to the avatar menu model or browser close notifications. | 261 // changes to the avatar menu model or browser close notifications. |
237 class ActiveProfileObserverBridge : public AvatarMenuObserver, | 262 class ActiveProfileObserverBridge : public AvatarMenuObserver, |
238 public content::NotificationObserver, | 263 public content::NotificationObserver, |
239 public OAuth2TokenService::Observer { | 264 public OAuth2TokenService::Observer { |
240 public: | 265 public: |
241 ActiveProfileObserverBridge(ProfileChooserController* controller, | 266 ActiveProfileObserverBridge(ProfileChooserController* controller, |
242 Browser* browser) | 267 Browser* browser) |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
274 } | 299 } |
275 | 300 |
276 // OAuth2TokenService::Observer: | 301 // OAuth2TokenService::Observer: |
277 virtual void OnRefreshTokenAvailable(const std::string& account_id) OVERRIDE { | 302 virtual void OnRefreshTokenAvailable(const std::string& account_id) OVERRIDE { |
278 // Tokens can only be added by adding an account through the inline flow, | 303 // Tokens can only be added by adding an account through the inline flow, |
279 // which is started from the account management view. Refresh it to show the | 304 // which is started from the account management view. Refresh it to show the |
280 // update. | 305 // update. |
281 profiles::BubbleViewMode viewMode = [controller_ viewMode]; | 306 profiles::BubbleViewMode viewMode = [controller_ viewMode]; |
282 if (viewMode == profiles::BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT || | 307 if (viewMode == profiles::BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT || |
283 viewMode == profiles::BUBBLE_VIEW_MODE_GAIA_SIGNIN || | 308 viewMode == profiles::BUBBLE_VIEW_MODE_GAIA_SIGNIN || |
284 viewMode == profiles::BUBBLE_VIEW_MODE_GAIA_ADD_ACCOUNT) { | 309 viewMode == profiles::BUBBLE_VIEW_MODE_GAIA_ADD_ACCOUNT || |
310 viewMode == profiles::BUBBLE_VIEW_MODE_GAIA_REAUTH) { | |
285 [controller_ initMenuContentsWithView: | 311 [controller_ initMenuContentsWithView: |
286 profiles::BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT]; | 312 profiles::BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT]; |
287 } | 313 } |
288 } | 314 } |
289 | 315 |
290 virtual void OnRefreshTokenRevoked(const std::string& account_id) OVERRIDE { | 316 virtual void OnRefreshTokenRevoked(const std::string& account_id) OVERRIDE { |
291 // Tokens can only be removed from the account management view. Refresh it | 317 // Tokens can only be removed from the account management view. Refresh it |
292 // to show the update. | 318 // to show the update. |
293 if ([controller_ viewMode] == profiles::BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT) | 319 if ([controller_ viewMode] == profiles::BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT) |
294 [controller_ initMenuContentsWithView: | 320 [controller_ initMenuContentsWithView: |
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
729 imageResourceId:(int)imageResourceId | 755 imageResourceId:(int)imageResourceId |
730 alternateImageResourceId:(int)alternateImageResourceId | 756 alternateImageResourceId:(int)alternateImageResourceId |
731 action:(SEL)action; | 757 action:(SEL)action; |
732 | 758 |
733 // Creates a generic link button with |title| and an |action| positioned at | 759 // Creates a generic link button with |title| and an |action| positioned at |
734 // |frameOrigin|. | 760 // |frameOrigin|. |
735 - (NSButton*)linkButtonWithTitle:(NSString*)title | 761 - (NSButton*)linkButtonWithTitle:(NSString*)title |
736 frameOrigin:(NSPoint)frameOrigin | 762 frameOrigin:(NSPoint)frameOrigin |
737 action:(SEL)action; | 763 action:(SEL)action; |
738 | 764 |
739 // Creates an email account button with |title| and a remove icon. |tag| | 765 // Creates an email account button with |title| and a remove icon. If |
766 // |reauthRequired| is true, the button also displays a warning icon. |tag| | |
740 // indicates which account the button refers to. | 767 // indicates which account the button refers to. |
741 - (NSButton*)accountButtonWithRect:(NSRect)rect | 768 - (NSButton*)accountButtonWithRect:(NSRect)rect |
742 title:(const std::string&)title | 769 title:(const std::string&)title |
743 tag:(int)tag; | 770 tag:(int)tag |
771 reauthRequired:(BOOL)reauthRequired; | |
744 | 772 |
745 @end | 773 @end |
746 | 774 |
747 @implementation ProfileChooserController | 775 @implementation ProfileChooserController |
748 - (profiles::BubbleViewMode) viewMode { | 776 - (profiles::BubbleViewMode) viewMode { |
749 return viewMode_; | 777 return viewMode_; |
750 } | 778 } |
751 | 779 |
752 - (IBAction)switchToProfile:(id)sender { | 780 - (IBAction)switchToProfile:(id)sender { |
753 // Check the event flags to see if a new window should be created. | 781 // Check the event flags to see if a new window should be created. |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
809 accountIdToRemove_ = SigninManagerFactory::GetForProfile( | 837 accountIdToRemove_ = SigninManagerFactory::GetForProfile( |
810 browser_->profile())->GetAuthenticatedUsername(); | 838 browser_->profile())->GetAuthenticatedUsername(); |
811 } else { | 839 } else { |
812 DCHECK(ContainsKey(currentProfileAccounts_, tag)); | 840 DCHECK(ContainsKey(currentProfileAccounts_, tag)); |
813 accountIdToRemove_ = currentProfileAccounts_[tag]; | 841 accountIdToRemove_ = currentProfileAccounts_[tag]; |
814 } | 842 } |
815 | 843 |
816 [self initMenuContentsWithView:profiles::BUBBLE_VIEW_MODE_ACCOUNT_REMOVAL]; | 844 [self initMenuContentsWithView:profiles::BUBBLE_VIEW_MODE_ACCOUNT_REMOVAL]; |
817 } | 845 } |
818 | 846 |
847 - (IBAction)showAccountReauthView:(id)sender { | |
848 DCHECK(!isGuestSession_); | |
849 [self initMenuContentsWithView:profiles::BUBBLE_VIEW_MODE_GAIA_REAUTH]; | |
850 } | |
851 | |
819 - (IBAction)removeAccount:(id)sender { | 852 - (IBAction)removeAccount:(id)sender { |
820 DCHECK(!accountIdToRemove_.empty()); | 853 DCHECK(!accountIdToRemove_.empty()); |
821 ProfileOAuth2TokenServiceFactory::GetPlatformSpecificForProfile( | 854 ProfileOAuth2TokenServiceFactory::GetPlatformSpecificForProfile( |
822 browser_->profile())->RevokeCredentials(accountIdToRemove_); | 855 browser_->profile())->RevokeCredentials(accountIdToRemove_); |
823 accountIdToRemove_.clear(); | 856 accountIdToRemove_.clear(); |
824 | 857 |
825 [self initMenuContentsWithView:profiles::BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT]; | 858 [self initMenuContentsWithView:profiles::BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT]; |
826 } | 859 } |
827 | 860 |
828 - (IBAction)openTutorialLearnMoreURL:(id)sender { | 861 - (IBAction)openTutorialLearnMoreURL:(id)sender { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
896 | 929 |
897 avatarMenu_.reset(new AvatarMenu( | 930 avatarMenu_.reset(new AvatarMenu( |
898 &g_browser_process->profile_manager()->GetProfileInfoCache(), | 931 &g_browser_process->profile_manager()->GetProfileInfoCache(), |
899 observer_.get(), | 932 observer_.get(), |
900 browser_)); | 933 browser_)); |
901 avatarMenu_->RebuildMenu(); | 934 avatarMenu_->RebuildMenu(); |
902 | 935 |
903 // Guest profiles do not have a token service. | 936 // Guest profiles do not have a token service. |
904 isGuestSession_ = browser_->profile()->IsGuestSession(); | 937 isGuestSession_ = browser_->profile()->IsGuestSession(); |
905 | 938 |
939 // If view mode is PROFILE_CHOOSER but there is an auth error, force | |
940 // ACCOUNT_MANAGEMENT mode. | |
941 if (viewMode_ == profiles::BUBBLE_VIEW_MODE_PROFILE_CHOOSER && | |
942 HasAuthError(browser_->profile())) { | |
943 viewMode_ = profiles::BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT; | |
944 } | |
945 | |
906 [[self bubble] setAlignment:info_bubble::kAlignRightEdgeToAnchorEdge]; | 946 [[self bubble] setAlignment:info_bubble::kAlignRightEdgeToAnchorEdge]; |
907 [[self bubble] setArrowLocation:info_bubble::kNoArrow]; | 947 [[self bubble] setArrowLocation:info_bubble::kNoArrow]; |
908 [[self bubble] setBackgroundColor:GetDialogBackgroundColor()]; | 948 [[self bubble] setBackgroundColor:GetDialogBackgroundColor()]; |
909 [self initMenuContentsWithView:viewMode_]; | 949 [self initMenuContentsWithView:viewMode_]; |
910 } | 950 } |
911 | 951 |
912 return self; | 952 return self; |
913 } | 953 } |
914 | 954 |
915 - (void)initMenuContentsWithView:(profiles::BubbleViewMode)viewToDisplay { | 955 - (void)initMenuContentsWithView:(profiles::BubbleViewMode)viewToDisplay { |
(...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1474 base::scoped_nsobject<NSView> container([[NSView alloc] initWithFrame:rect]); | 1514 base::scoped_nsobject<NSView> container([[NSView alloc] initWithFrame:rect]); |
1475 currentProfileAccounts_.clear(); | 1515 currentProfileAccounts_.clear(); |
1476 | 1516 |
1477 Profile* profile = browser_->profile(); | 1517 Profile* profile = browser_->profile(); |
1478 std::string primaryAccount = | 1518 std::string primaryAccount = |
1479 SigninManagerFactory::GetForProfile(profile)->GetAuthenticatedUsername(); | 1519 SigninManagerFactory::GetForProfile(profile)->GetAuthenticatedUsername(); |
1480 DCHECK(!primaryAccount.empty()); | 1520 DCHECK(!primaryAccount.empty()); |
1481 std::vector<std::string>accounts = | 1521 std::vector<std::string>accounts = |
1482 profiles::GetSecondaryAccountsForProfile(profile, primaryAccount); | 1522 profiles::GetSecondaryAccountsForProfile(profile, primaryAccount); |
1483 | 1523 |
1524 // Get state of authentication error, if any. | |
msw
2014/06/03 04:15:31
nit: this comment should be made more helpful or r
noms (inactive)
2014/06/06 20:33:43
Done.
| |
1525 std::string errorAccountId = GetAuthErrorAccountId(profile); | |
1526 | |
1484 rect.origin.y = 0; | 1527 rect.origin.y = 0; |
1485 for (size_t i = 0; i < accounts.size(); ++i) { | 1528 for (size_t i = 0; i < accounts.size(); ++i) { |
1486 // Save the original email address, as the button text could be elided. | 1529 // Save the original email address, as the button text could be elided. |
1487 currentProfileAccounts_[i] = accounts[i]; | 1530 currentProfileAccounts_[i] = accounts[i]; |
1488 NSButton* accountButton = [self accountButtonWithRect:rect | 1531 NSButton* accountButton = |
1489 title:accounts[i] | 1532 [self accountButtonWithRect:rect |
1490 tag:i]; | 1533 title:accounts[i] |
1534 tag:i | |
1535 reauthRequired:errorAccountId == accounts[i]]; | |
msw
2014/06/03 04:15:31
Couldn't multiple accounts have auth errors at the
noms (inactive)
2014/06/06 20:33:44
They could, but the way it works right now is that
msw
2014/06/09 19:02:38
It's also unclear to me how this retains the autho
noms (inactive)
2014/06/10 15:02:47
A little background: this error controller used to
| |
1491 [container addSubview:accountButton]; | 1536 [container addSubview:accountButton]; |
1492 rect.origin.y = NSMaxY([accountButton frame]); | 1537 rect.origin.y = NSMaxY([accountButton frame]); |
1493 } | 1538 } |
1494 | 1539 |
1495 // The primary account should always be listed first. | 1540 // The primary account should always be listed first. |
1496 NSButton* accountButton = [self accountButtonWithRect:rect | 1541 NSButton* accountButton = |
1497 title:primaryAccount | 1542 [self accountButtonWithRect:rect |
1498 tag:kPrimaryProfileTag]; | 1543 title:primaryAccount |
1544 tag:kPrimaryProfileTag | |
1545 reauthRequired:errorAccountId == primaryAccount]; | |
1499 [container addSubview:accountButton]; | 1546 [container addSubview:accountButton]; |
1500 [container setFrameSize:NSMakeSize(NSWidth([container frame]), | 1547 [container setFrameSize:NSMakeSize(NSWidth([container frame]), |
1501 NSMaxY([accountButton frame]))]; | 1548 NSMaxY([accountButton frame]))]; |
1502 return container.autorelease(); | 1549 return container.autorelease(); |
1503 } | 1550 } |
1504 | 1551 |
1505 - (NSView*)buildGaiaEmbeddedView { | 1552 - (NSView*)buildGaiaEmbeddedView { |
1506 base::scoped_nsobject<NSView> container( | 1553 base::scoped_nsobject<NSView> container( |
1507 [[NSView alloc] initWithFrame:NSZeroRect]); | 1554 [[NSView alloc] initWithFrame:NSZeroRect]); |
1508 CGFloat yOffset = 0; | 1555 CGFloat yOffset = 0; |
1509 | 1556 |
1510 bool addSecondaryAccount = | 1557 GURL url; |
1511 viewMode_ == profiles::BUBBLE_VIEW_MODE_GAIA_ADD_ACCOUNT; | 1558 int messageId; |
msw
2014/06/03 04:15:31
nit: initialize this value
noms (inactive)
2014/06/06 20:33:44
Done.
| |
1512 signin::Source source = addSecondaryAccount ? | 1559 switch (viewMode_) { |
1513 signin::SOURCE_AVATAR_BUBBLE_ADD_ACCOUNT : | 1560 case profiles::BUBBLE_VIEW_MODE_GAIA_SIGNIN: |
1514 signin::SOURCE_AVATAR_BUBBLE_SIGN_IN; | 1561 url = signin::GetPromoURL(signin::SOURCE_AVATAR_BUBBLE_SIGN_IN, |
1562 false /* auto_close */, | |
1563 true /* is_constrained */); | |
1564 messageId = IDS_PROFILES_GAIA_SIGNIN_TITLE; | |
1565 break; | |
1566 case profiles::BUBBLE_VIEW_MODE_GAIA_ADD_ACCOUNT: | |
1567 url = signin::GetPromoURL(signin::SOURCE_AVATAR_BUBBLE_ADD_ACCOUNT, | |
1568 false /* auto_close */, | |
1569 true /* is_constrained */); | |
1570 messageId = IDS_PROFILES_GAIA_ADD_ACCOUNT_TITLE; | |
1571 break; | |
1572 case profiles::BUBBLE_VIEW_MODE_GAIA_REAUTH: { | |
msw
2014/06/03 04:15:31
nit: you shouldn't need these curly braces.
noms (inactive)
2014/06/06 20:33:44
Without the curly braces, the compiler is unhappy
| |
1573 DCHECK(HasAuthError(browser_->profile())); | |
1574 url = signin::GetReauthURL(browser_->profile(), | |
1575 GetAuthErrorUsername(browser_->profile())); | |
1576 messageId = IDS_PROFILES_GAIA_REAUTH_TITLE; | |
1577 break; | |
1578 } | |
1579 default: | |
1580 NOTREACHED() << "Called with invalid mode=" << viewMode_; | |
1581 return NULL; | |
1582 } | |
1515 | 1583 |
1516 webContents_.reset(content::WebContents::Create( | 1584 webContents_.reset(content::WebContents::Create( |
1517 content::WebContents::CreateParams(browser_->profile()))); | 1585 content::WebContents::CreateParams(browser_->profile()))); |
1518 webContents_->GetController().LoadURL( | 1586 webContents_->GetController().LoadURL(url, |
1519 signin::GetPromoURL( | 1587 content::Referrer(), |
1520 source, false /* auto_close */, true /* is_constrained */), | 1588 content::PAGE_TRANSITION_AUTO_TOPLEVEL, |
1521 content::Referrer(), | 1589 std::string()); |
1522 content::PAGE_TRANSITION_AUTO_TOPLEVEL, | |
1523 std::string()); | |
1524 NSView* webview = webContents_->GetNativeView(); | 1590 NSView* webview = webContents_->GetNativeView(); |
1525 [webview setFrameSize:NSMakeSize(kFixedGaiaViewWidth, kFixedGaiaViewHeight)]; | 1591 [webview setFrameSize:NSMakeSize(kFixedGaiaViewWidth, kFixedGaiaViewHeight)]; |
1526 [container addSubview:webview]; | 1592 [container addSubview:webview]; |
1527 yOffset = NSMaxY([webview frame]); | 1593 yOffset = NSMaxY([webview frame]); |
1528 | 1594 |
1529 // Adds the title card. | 1595 // Adds the title card. |
1530 NSBox* separator = [self separatorWithFrame: | 1596 NSBox* separator = [self separatorWithFrame: |
1531 NSMakeRect(0, yOffset, kFixedGaiaViewWidth, 0)]; | 1597 NSMakeRect(0, yOffset, kFixedGaiaViewWidth, 0)]; |
1532 [container addSubview:separator]; | 1598 [container addSubview:separator]; |
1533 yOffset = NSMaxY([separator frame]) + kSmallVerticalSpacing; | 1599 yOffset = NSMaxY([separator frame]) + kSmallVerticalSpacing; |
1534 | 1600 |
1535 NSView* titleView = BuildTitleCard( | 1601 NSView* titleView = BuildTitleCard( |
1536 NSMakeRect(0, yOffset, kFixedGaiaViewWidth,0), | 1602 NSMakeRect(0, yOffset, kFixedGaiaViewWidth, 0), |
1537 addSecondaryAccount ? IDS_PROFILES_GAIA_ADD_ACCOUNT_TITLE : | 1603 messageId, |
1538 IDS_PROFILES_GAIA_SIGNIN_TITLE, | |
1539 self /* backButtonTarget*/, | 1604 self /* backButtonTarget*/, |
1540 @selector(navigateBackFromSigninPage:) /* backButtonAction */); | 1605 @selector(navigateBackFromSigninPage:) /* backButtonAction */); |
1541 [container addSubview:titleView]; | 1606 [container addSubview:titleView]; |
1542 yOffset = NSMaxY([titleView frame]); | 1607 yOffset = NSMaxY([titleView frame]); |
1543 | 1608 |
1544 [container setFrameSize:NSMakeSize(kFixedGaiaViewWidth, yOffset)]; | 1609 [container setFrameSize:NSMakeSize(kFixedGaiaViewWidth, yOffset)]; |
1545 return container.autorelease(); | 1610 return container.autorelease(); |
1546 } | 1611 } |
1547 | 1612 |
1548 - (NSView*)buildAccountRemovalView { | 1613 - (NSView*)buildAccountRemovalView { |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1717 [link setTarget:self]; | 1782 [link setTarget:self]; |
1718 [link setAction:action]; | 1783 [link setAction:action]; |
1719 [link setFrameOrigin:frameOrigin]; | 1784 [link setFrameOrigin:frameOrigin]; |
1720 [link sizeToFit]; | 1785 [link sizeToFit]; |
1721 | 1786 |
1722 return link.autorelease(); | 1787 return link.autorelease(); |
1723 } | 1788 } |
1724 | 1789 |
1725 - (NSButton*)accountButtonWithRect:(NSRect)rect | 1790 - (NSButton*)accountButtonWithRect:(NSRect)rect |
1726 title:(const std::string&)title | 1791 title:(const std::string&)title |
1727 tag:(int)tag { | 1792 tag:(int)tag |
1793 reauthRequired:(BOOL)reauthRequired { | |
1794 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); | |
1795 NSImage* deleteImage = rb->GetNativeImageNamed(IDR_CLOSE_1).AsNSImage(); | |
1796 CGFloat deleteImageWidth = [deleteImage size].width; | |
1797 | |
1798 NSImage* reauthImage = nil; | |
1799 CGFloat reauthImageWidth = 0; | |
1800 if (reauthRequired) { | |
1801 reauthImage = rb->GetNativeImageNamed( | |
1802 IDR_ICON_PROFILES_ACCOUNT_BUTTON_ERROR).AsNSImage(); | |
1803 reauthImageWidth = [reauthImage size].width; | |
msw
2014/06/03 04:15:31
Do you need to add some padding, like kHorizontalS
noms (inactive)
2014/06/06 20:33:44
Done.
| |
1804 } | |
1805 | |
1806 CGFloat availableTextWidth = rect.size.width - kHorizontalSpacing - | |
1807 deleteImageWidth - reauthImageWidth; | |
1808 | |
1728 NSColor* backgroundColor = gfx::SkColorToCalibratedNSColor( | 1809 NSColor* backgroundColor = gfx::SkColorToCalibratedNSColor( |
1729 profiles::kAvatarBubbleAccountsBackgroundColor); | 1810 profiles::kAvatarBubbleAccountsBackgroundColor); |
1730 base::scoped_nsobject<BackgroundColorHoverButton> button( | 1811 base::scoped_nsobject<BackgroundColorHoverButton> button( |
1731 [[BackgroundColorHoverButton alloc] initWithFrame:rect | 1812 [[BackgroundColorHoverButton alloc] initWithFrame:rect |
1732 imageTitleSpacing:0 | 1813 imageTitleSpacing:0 |
1733 backgroundColor:backgroundColor]); | 1814 backgroundColor:backgroundColor]); |
1734 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); | 1815 [button setTitle:ElideEmail(title, availableTextWidth)]; |
1735 NSImage* defaultImage = rb->GetNativeImageNamed(IDR_CLOSE_1).AsNSImage(); | |
1736 CGFloat kDeleteButtonWidth = [defaultImage size].width; | |
1737 CGFloat availableWidth = rect.size.width - | |
1738 kDeleteButtonWidth - kHorizontalSpacing; | |
1739 [button setTitle:ElideEmail(title, availableWidth)]; | |
1740 [button setAlignment:NSLeftTextAlignment]; | 1816 [button setAlignment:NSLeftTextAlignment]; |
1741 [button setBordered:NO]; | 1817 [button setBordered:NO]; |
1818 if (reauthRequired) { | |
1819 [button setTarget:self]; | |
1820 [button setAction:@selector(showAccountReauthView:)]; | |
1821 [button setTag:tag]; | |
1822 } | |
1742 | 1823 |
1743 // Delete button. | 1824 // Delete button. |
1744 rect.origin = NSMakePoint(availableWidth, 0); | 1825 rect.origin = NSMakePoint(availableTextWidth + reauthImageWidth, 0); |
1745 rect.size.width = kDeleteButtonWidth; | 1826 rect.size.width = deleteImageWidth; |
1746 base::scoped_nsobject<HoverImageButton> deleteButton( | 1827 base::scoped_nsobject<HoverImageButton> deleteButton( |
1747 [[HoverImageButton alloc] initWithFrame:rect]); | 1828 [[HoverImageButton alloc] initWithFrame:rect]); |
1748 [deleteButton setBordered:NO]; | 1829 [deleteButton setBordered:NO]; |
1749 [deleteButton setDefaultImage:defaultImage]; | 1830 [deleteButton setDefaultImage:deleteImage]; |
1750 [deleteButton setHoverImage:rb->GetNativeImageNamed( | 1831 [deleteButton setHoverImage:rb->GetNativeImageNamed( |
1751 IDR_CLOSE_1_H).ToNSImage()]; | 1832 IDR_CLOSE_1_H).ToNSImage()]; |
1752 [deleteButton setPressedImage:rb->GetNativeImageNamed( | 1833 [deleteButton setPressedImage:rb->GetNativeImageNamed( |
1753 IDR_CLOSE_1_P).ToNSImage()]; | 1834 IDR_CLOSE_1_P).ToNSImage()]; |
1754 [deleteButton setTarget:self]; | 1835 [deleteButton setTarget:self]; |
1755 [deleteButton setAction:@selector(showAccountRemovalView:)]; | 1836 [deleteButton setAction:@selector(showAccountRemovalView:)]; |
1756 [deleteButton setTag:tag]; | 1837 [deleteButton setTag:tag]; |
1757 | 1838 |
1758 [button addSubview:deleteButton]; | 1839 [button addSubview:deleteButton]; |
1840 | |
1841 // Warning icon. | |
1842 if (reauthRequired) { | |
1843 base::scoped_nsobject<NSImageView> reauthIcon( | |
1844 [[NSImageView alloc] initWithFrame:NSMakeRect( | |
1845 availableTextWidth, 0, reauthImageWidth, rect.size.height)]); | |
1846 [reauthIcon setImage:reauthImage]; | |
1847 [button addSubview:reauthIcon]; | |
1848 } | |
1849 | |
1759 return button.autorelease(); | 1850 return button.autorelease(); |
1760 } | 1851 } |
1761 | 1852 |
1762 @end | 1853 @end |
OLD | NEW |