Upstream version 7.35.144.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / cocoa / browser / avatar_base_controller.mm
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
3 // found in the LICENSE file.
4
5 #import "chrome/browser/ui/cocoa/browser/avatar_base_controller.h"
6
7 #include "chrome/app/chrome_command_ids.h"
8 #include "chrome/browser/browser_process.h"
9 #include "chrome/browser/profiles/profile_info_cache_observer.h"
10 #include "chrome/browser/profiles/profile_info_util.h"
11 #include "chrome/browser/profiles/profile_manager.h"
12 #include "chrome/browser/profiles/profile_metrics.h"
13 #include "chrome/browser/ui/browser.h"
14 #include "chrome/browser/ui/browser_commands.h"
15 #include "chrome/browser/ui/browser_window.h"
16 #import "chrome/browser/ui/cocoa/base_bubble_controller.h"
17 #import "chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller.h"
18 #import "chrome/browser/ui/cocoa/browser/profile_chooser_controller.h"
19 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
20 #include "chrome/common/profile_management_switches.h"
21 #include "ui/base/resource/resource_bundle.h"
22
23 // Space between the avatar icon and the avatar menu bubble.
24 const CGFloat kMenuYOffsetAdjust = 1.0;
25
26 @interface AvatarBaseController (Private)
27 // Shows the avatar bubble.
28 - (IBAction)buttonClicked:(id)sender;
29 - (void)bubbleWillClose:(NSNotification*)notif;
30 // Updates the profile name displayed by the avatar button. If |layoutParent| is
31 // yes, then the BrowserWindowController is notified to relayout the subviews,
32 // as the button needs to be repositioned.
33 - (void)updateAvatarButtonAndLayoutParent:(BOOL)layoutParent;
34 @end
35
36 class ProfileInfoUpdateObserver : public ProfileInfoCacheObserver {
37  public:
38   ProfileInfoUpdateObserver(AvatarBaseController* avatarButton)
39       : avatarButton_(avatarButton) {
40     g_browser_process->profile_manager()->
41         GetProfileInfoCache().AddObserver(this);
42   }
43
44   virtual ~ProfileInfoUpdateObserver() {
45     g_browser_process->profile_manager()->
46         GetProfileInfoCache().RemoveObserver(this);
47   }
48
49   // ProfileInfoCacheObserver:
50   virtual void OnProfileAdded(const base::FilePath& profile_path) OVERRIDE {
51     [avatarButton_ updateAvatarButtonAndLayoutParent:YES];
52   }
53
54   virtual void OnProfileWasRemoved(
55       const base::FilePath& profile_path,
56       const base::string16& profile_name) OVERRIDE {
57     [avatarButton_ updateAvatarButtonAndLayoutParent:YES];
58   }
59
60   virtual void OnProfileNameChanged(
61       const base::FilePath& profile_path,
62       const base::string16& old_profile_name) OVERRIDE {
63     [avatarButton_ updateAvatarButtonAndLayoutParent:YES];
64   }
65
66   virtual void OnProfileAvatarChanged(
67       const base::FilePath& profile_path) OVERRIDE {
68     [avatarButton_ updateAvatarButtonAndLayoutParent:YES];
69   }
70
71  private:
72   AvatarBaseController* avatarButton_;  // Weak; owns this.
73
74   DISALLOW_COPY_AND_ASSIGN(ProfileInfoUpdateObserver);
75 };
76
77 @implementation AvatarBaseController
78
79 - (id)initWithBrowser:(Browser*)browser {
80   if ((self = [super init])) {
81     browser_ = browser;
82     profileInfoObserver_.reset(new ProfileInfoUpdateObserver(self));
83   }
84   return self;
85 }
86
87 - (void)dealloc {
88   [[NSNotificationCenter defaultCenter]
89       removeObserver:self
90                 name:NSWindowWillCloseNotification
91               object:[menuController_ window]];
92   [super dealloc];
93 }
94
95 - (NSButton*)buttonView {
96   CHECK(button_.get());  // Subclasses must set this.
97   return button_.get();
98 }
99
100 - (void)showAvatarBubble:(NSView*)anchor
101                 withMode:(BrowserWindow::AvatarBubbleMode)mode {
102   if (menuController_)
103     return;
104
105   DCHECK(chrome::IsCommandEnabled(browser_, IDC_SHOW_AVATAR_MENU));
106
107   NSWindowController* wc =
108       [browser_->window()->GetNativeWindow() windowController];
109   if ([wc isKindOfClass:[BrowserWindowController class]]) {
110     [static_cast<BrowserWindowController*>(wc)
111         lockBarVisibilityForOwner:self withAnimation:NO delay:NO];
112   }
113
114   // The new avatar bubble does not have an arrow, and it should be anchored
115   // to the edge of the avatar button.
116   int anchorX = switches::IsNewProfileManagement() ? NSMaxX([anchor bounds]) :
117                                                      NSMidX([anchor bounds]);
118   NSPoint point = NSMakePoint(anchorX,
119                               NSMaxY([anchor bounds]) - kMenuYOffsetAdjust);
120   point = [anchor convertPoint:point toView:nil];
121   point = [[anchor window] convertBaseToScreen:point];
122
123   // |menuController_| will automatically release itself on close.
124   if (switches::IsNewProfileManagement()) {
125     BubbleViewMode viewMode =
126         mode == BrowserWindow::AVATAR_BUBBLE_MODE_DEFAULT ?
127         PROFILE_CHOOSER_VIEW :
128         ACCOUNT_MANAGEMENT_VIEW;
129     menuController_ =
130         [[ProfileChooserController alloc] initWithBrowser:browser_
131                                                anchoredAt:point
132                                                  withMode:viewMode];
133   } else {
134     menuController_ =
135       [[AvatarMenuBubbleController alloc] initWithBrowser:browser_
136                                                anchoredAt:point];
137   }
138
139   [[NSNotificationCenter defaultCenter]
140       addObserver:self
141          selector:@selector(bubbleWillClose:)
142              name:NSWindowWillCloseNotification
143            object:[menuController_ window]];
144   [menuController_ showWindow:self];
145
146   ProfileMetrics::LogProfileOpenMethod(ProfileMetrics::ICON_AVATAR_BUBBLE);
147 }
148
149 - (IBAction)buttonClicked:(id)sender {
150   DCHECK_EQ(sender, button_.get());
151   [self showAvatarBubble:button_
152                 withMode:BrowserWindow::AVATAR_BUBBLE_MODE_DEFAULT];
153 }
154
155 - (void)bubbleWillClose:(NSNotification*)notif {
156   NSWindowController* wc =
157       [browser_->window()->GetNativeWindow() windowController];
158   if ([wc isKindOfClass:[BrowserWindowController class]]) {
159     [static_cast<BrowserWindowController*>(wc)
160         releaseBarVisibilityForOwner:self withAnimation:YES delay:NO];
161   }
162   menuController_ = nil;
163 }
164
165 - (void)updateAvatarButtonAndLayoutParent:(BOOL)layoutParent {
166   NOTREACHED();
167 }
168
169 - (BaseBubbleController*)menuController {
170   return menuController_;
171 }
172
173 @end