Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ui / cocoa / status_icons / status_icon_mac.mm
blobdbecd2324f1686f14c727f55aaea0cbd39450970
1 // Copyright (c) 2012 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.
5 #include "chrome/browser/ui/cocoa/status_icons/status_icon_mac.h"
7 #import <AppKit/AppKit.h>
9 #include "base/logging.h"
10 #include "base/strings/sys_string_conversions.h"
11 #include "skia/ext/skia_utils_mac.h"
12 #include "third_party/skia/include/core/SkBitmap.h"
13 #import "ui/base/cocoa/menu_controller.h"
14 #include "ui/gfx/image/image_skia.h"
16 @interface StatusItemController : NSObject {
17   StatusIconMac* statusIcon_; // weak
19 - (id)initWithIcon:(StatusIconMac*)icon;
20 - (void)handleClick:(id)sender;
22 @end // @interface StatusItemController
24 @implementation StatusItemController
26 - (id)initWithIcon:(StatusIconMac*)icon {
27   statusIcon_ = icon;
28   return self;
31 - (void)handleClick:(id)sender {
32   // Pass along the click notification to our owner.
33   DCHECK(statusIcon_);
34   // Bring up the status icon menu if there is one, relay the click event
35   // otherwise.
36   if (!statusIcon_->HasStatusIconMenu())
37     statusIcon_->DispatchClickEvent();
40 @end
42 StatusIconMac::StatusIconMac()
43     : item_(NULL) {
44   controller_.reset([[StatusItemController alloc] initWithIcon:this]);
47 StatusIconMac::~StatusIconMac() {
48   // Remove the status item from the status bar.
49   if (item_)
50     [[NSStatusBar systemStatusBar] removeStatusItem:item_];
53 NSStatusItem* StatusIconMac::item() {
54   if (!item_.get()) {
55     // Create a new status item.
56     item_.reset([[[NSStatusBar systemStatusBar]
57                   statusItemWithLength:NSSquareStatusItemLength] retain]);
58     [item_ setEnabled:YES];
59     [item_ setTarget:controller_];
60     [item_ setAction:@selector(handleClick:)];
61     [item_ setHighlightMode:YES];
62   }
63   return item_.get();
66 void StatusIconMac::SetImage(const gfx::ImageSkia& image) {
67   if (!image.isNull()) {
68     NSImage* ns_image = gfx::SkBitmapToNSImage(*image.bitmap());
69     if (ns_image)
70       [item() setImage:ns_image];
71   }
74 void StatusIconMac::SetToolTip(const base::string16& tool_tip) {
75   // If we have a status icon menu, make the tool tip part of the menu instead
76   // of a pop-up tool tip when hovering the mouse over the image.
77   toolTip_.reset([base::SysUTF16ToNSString(tool_tip) retain]);
78   if (menu_.get()) {
79     SetToolTip(nil);
80     CreateMenu([menu_ model], toolTip_.get());
81   } else {
82     SetToolTip(toolTip_.get());
83   }
86 void StatusIconMac::DisplayBalloon(const gfx::ImageSkia& icon,
87                                    const base::string16& title,
88                                    const base::string16& contents) {
89   notification_.DisplayBalloon(icon, title, contents);
92 bool StatusIconMac::HasStatusIconMenu() {
93   return menu_.get() != nil;
96 void StatusIconMac::UpdatePlatformContextMenu(StatusIconMenuModel* model) {
97   if (!model) {
98     menu_.reset();
99   } else {
100     SetToolTip(nil);
101     CreateMenu(model, toolTip_.get());
102   }
105 void StatusIconMac::CreateMenu(ui::MenuModel* model, NSString* toolTip) {
106   DCHECK(model);
108   if (!toolTip) {
109     menu_.reset([[MenuController alloc] initWithModel:model
110                                useWithPopUpButtonCell:NO]);
111   } else {
112     // When using a popup button cell menu controller, an extra blank item is
113     // added at index 0. Use this item for the tooltip.
114     menu_.reset([[MenuController alloc] initWithModel:model
115                                useWithPopUpButtonCell:YES]);
116     NSMenuItem* toolTipItem = [[menu_ menu] itemAtIndex:0];
117     [toolTipItem setTitle:toolTip];
118   }
119   [item() setMenu:[menu_ menu]];
122 void StatusIconMac::SetToolTip(NSString* toolTip) {
123   [item() setToolTip:toolTip];