| 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..85fa8b4faf5569fe713ffb3e3d1a8254d0c6890b
|
| --- /dev/null
|
| +++ b/chrome/browser/ui/cocoa/browser/avatar_base_controller.mm
|
| @@ -0,0 +1,163 @@
|
| +// 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 {
|
| + CHECK(button_.get()); // Subclasses must set this.
|
| + 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_EQ(sender, button_.get());
|
| + [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
|
| +
|
|
|