Chromium Code Reviews| Index: chrome/browser/ui/cocoa/browser/avatar_base_controller.mm |
| diff --git a/chrome/browser/ui/cocoa/browser/avatar_base_controller.mm b/chrome/browser/ui/cocoa/browser/avatar_base_controller.mm |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..0082a2a454a47c4ac9c9dcd3462ad196790caae9 |
| --- /dev/null |
| +++ b/chrome/browser/ui/cocoa/browser/avatar_base_controller.mm |
| @@ -0,0 +1,162 @@ |
| +// Copyright 2014 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#import "chrome/browser/ui/cocoa/browser/avatar_base_controller.h" |
| + |
| +#include "chrome/app/chrome_command_ids.h" |
| +#include "chrome/browser/browser_process.h" |
| +#include "chrome/browser/profiles/profile_info_cache_observer.h" |
| +#include "chrome/browser/profiles/profile_info_util.h" |
| +#include "chrome/browser/profiles/profile_manager.h" |
| +#include "chrome/browser/profiles/profile_metrics.h" |
| +#include "chrome/browser/ui/browser.h" |
| +#include "chrome/browser/ui/browser_commands.h" |
| +#include "chrome/browser/ui/browser_window.h" |
| +#import "chrome/browser/ui/cocoa/base_bubble_controller.h" |
| +#import "chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller.h" |
| +#import "chrome/browser/ui/cocoa/browser/profile_chooser_controller.h" |
| +#import "chrome/browser/ui/cocoa/browser_window_controller.h" |
| +#include "chrome/common/profile_management_switches.h" |
| +#include "ui/base/resource/resource_bundle.h" |
| + |
| +// Space between the avatar icon and the avatar menu bubble. |
| +const CGFloat kMenuYOffsetAdjust = 1.0; |
| + |
| +@interface AvatarBaseController (Private) |
| +// Shows the avatar bubble. |
| +- (IBAction)buttonClicked:(id)sender; |
| +- (void)bubbleWillClose:(NSNotification*)notif; |
| +// Updates the profile name displayed by the avatar button. If |layoutParent| is |
| +// yes, then the BrowserWindowController is notified to relayout the subviews, |
| +// as the button needs to be repositioned. |
| +- (void)updateAvatarButtonAndLayoutParent:(BOOL)layoutParent; |
| +@end |
| + |
| +class ProfileInfoUpdateObserver : public ProfileInfoCacheObserver { |
| + public: |
| + ProfileInfoUpdateObserver(AvatarBaseController* avatarButton) |
| + : avatarButton_(avatarButton) { |
| + g_browser_process->profile_manager()-> |
| + GetProfileInfoCache().AddObserver(this); |
| + } |
| + |
| + virtual ~ProfileInfoUpdateObserver() { |
| + g_browser_process->profile_manager()-> |
| + GetProfileInfoCache().RemoveObserver(this); |
| + } |
| + |
| + // ProfileInfoCacheObserver: |
| + virtual void OnProfileAdded(const base::FilePath& profile_path) OVERRIDE { |
| + [avatarButton_ updateAvatarButtonAndLayoutParent:YES]; |
| + } |
| + |
| + virtual void OnProfileWasRemoved( |
| + const base::FilePath& profile_path, |
| + const base::string16& profile_name) OVERRIDE { |
| + [avatarButton_ updateAvatarButtonAndLayoutParent:YES]; |
| + } |
| + |
| + virtual void OnProfileNameChanged( |
| + const base::FilePath& profile_path, |
| + const base::string16& old_profile_name) OVERRIDE { |
| + [avatarButton_ updateAvatarButtonAndLayoutParent:YES]; |
| + } |
| + |
| + virtual void OnProfileAvatarChanged( |
| + const base::FilePath& profile_path) OVERRIDE { |
| + [avatarButton_ updateAvatarButtonAndLayoutParent:YES]; |
| + } |
| + |
| + private: |
| + AvatarBaseController* avatarButton_; // Weak; owns this. |
| + |
| + DISALLOW_COPY_AND_ASSIGN(ProfileInfoUpdateObserver); |
| +}; |
| + |
| +@implementation AvatarBaseController |
| + |
| +- (id)initWithBrowser:(Browser*)browser { |
| + if ((self = [super init])) { |
| + browser_ = browser; |
| + profileInfoObserver_.reset(new ProfileInfoUpdateObserver(self)); |
| + } |
| + return self; |
| +} |
| + |
| +- (void)dealloc { |
| + [[NSNotificationCenter defaultCenter] |
| + removeObserver:self |
| + name:NSWindowWillCloseNotification |
| + object:[menuController_ window]]; |
| + [super dealloc]; |
| +} |
| + |
| +- (NSButton*)buttonView { |
|
Nico
2014/01/23 00:51:33
Maybe
CHECK(button_get()); // Subclasses must s
noms (inactive)
2014/01/23 18:24:27
Done.
|
| + return button_.get(); |
| +} |
| + |
| +- (void)showAvatarBubble:(NSView*)anchor { |
| + if (menuController_) |
| + return; |
| + |
| + DCHECK(chrome::IsCommandEnabled(browser_, IDC_SHOW_AVATAR_MENU)); |
| + |
| + NSWindowController* wc = |
| + [browser_->window()->GetNativeWindow() windowController]; |
| + if ([wc isKindOfClass:[BrowserWindowController class]]) { |
| + [static_cast<BrowserWindowController*>(wc) |
| + lockBarVisibilityForOwner:self withAnimation:NO delay:NO]; |
| + } |
| + |
| + NSPoint point = NSMakePoint(NSMidX([anchor bounds]), |
| + NSMaxY([anchor bounds]) - kMenuYOffsetAdjust); |
| + point = [anchor convertPoint:point toView:nil]; |
| + point = [[anchor window] convertBaseToScreen:point]; |
| + |
| + // |menuController_| will automatically release itself on close. |
| + if (switches::IsNewProfileManagement()) { |
| + menuController_ = |
| + [[ProfileChooserController alloc] initWithBrowser:browser_ |
| + anchoredAt:point]; |
| + } else { |
| + menuController_ = |
| + [[AvatarMenuBubbleController alloc] initWithBrowser:browser_ |
| + anchoredAt:point]; |
| + } |
| + |
| + [[NSNotificationCenter defaultCenter] |
| + addObserver:self |
| + selector:@selector(bubbleWillClose:) |
| + name:NSWindowWillCloseNotification |
| + object:[menuController_ window]]; |
| + [menuController_ showWindow:self]; |
| + |
| + ProfileMetrics::LogProfileOpenMethod(ProfileMetrics::ICON_AVATAR_BUBBLE); |
| +} |
| + |
| +- (IBAction)buttonClicked:(id)sender { |
| + DCHECK(sender == button_.get()); |
|
Nico
2014/01/23 00:51:33
DCHECK_EQ if it compiles
noms (inactive)
2014/01/23 18:24:27
Done.
|
| + [self showAvatarBubble:button_]; |
| +} |
| + |
| +- (void)bubbleWillClose:(NSNotification*)notif { |
| + NSWindowController* wc = |
| + [browser_->window()->GetNativeWindow() windowController]; |
| + if ([wc isKindOfClass:[BrowserWindowController class]]) { |
| + [static_cast<BrowserWindowController*>(wc) |
| + releaseBarVisibilityForOwner:self withAnimation:YES delay:NO]; |
| + } |
| + menuController_ = nil; |
| +} |
| + |
| +- (void)updateAvatarButtonAndLayoutParent:(BOOL)layoutParent { |
| + NOTREACHED(); |
| +} |
| + |
| +- (BaseBubbleController*)menuController { |
| + return menuController_; |
| +} |
| + |
| +@end |
| + |