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 {
31 - (void)handleClick:(id)sender {
32 // Pass along the click notification to our owner.
34 // Bring up the status icon menu if there is one, relay the click event
36 if (!statusIcon_->HasStatusIconMenu())
37 statusIcon_->DispatchClickEvent();
42 StatusIconMac::StatusIconMac()
44 controller_.reset([[StatusItemController alloc] initWithIcon:this]);
47 StatusIconMac::~StatusIconMac() {
48 // Remove the status item from the status bar.
50 [[NSStatusBar systemStatusBar] removeStatusItem:item_];
53 NSStatusItem* StatusIconMac::item() {
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];
66 void StatusIconMac::SetImage(const gfx::ImageSkia& image) {
67 if (!image.isNull()) {
68 NSImage* ns_image = gfx::SkBitmapToNSImage(*image.bitmap());
70 [item() setImage:ns_image];
74 void StatusIconMac::SetPressedImage(const gfx::ImageSkia& image) {
75 if (!image.isNull()) {
76 NSImage* ns_image = gfx::SkBitmapToNSImage(*image.bitmap());
78 [item() setAlternateImage:ns_image];
82 void StatusIconMac::SetToolTip(const base::string16& tool_tip) {
83 // If we have a status icon menu, make the tool tip part of the menu instead
84 // of a pop-up tool tip when hovering the mouse over the image.
85 toolTip_.reset([base::SysUTF16ToNSString(tool_tip) retain]);
88 CreateMenu([menu_ model], toolTip_.get());
90 SetToolTip(toolTip_.get());
94 void StatusIconMac::DisplayBalloon(const gfx::ImageSkia& icon,
95 const base::string16& title,
96 const base::string16& contents) {
97 notification_.DisplayBalloon(icon, title, contents);
100 bool StatusIconMac::HasStatusIconMenu() {
101 return menu_.get() != nil;
104 void StatusIconMac::UpdatePlatformContextMenu(StatusIconMenuModel* model) {
109 CreateMenu(model, toolTip_.get());
113 void StatusIconMac::CreateMenu(ui::MenuModel* model, NSString* toolTip) {
117 menu_.reset([[MenuController alloc] initWithModel:model
118 useWithPopUpButtonCell:NO]);
120 // When using a popup button cell menu controller, an extra blank item is
121 // added at index 0. Use this item for the tooltip.
122 menu_.reset([[MenuController alloc] initWithModel:model
123 useWithPopUpButtonCell:YES]);
124 NSMenuItem* toolTipItem = [[menu_ menu] itemAtIndex:0];
125 [toolTipItem setTitle:toolTip];
127 [item() setMenu:[menu_ menu]];
130 void StatusIconMac::SetToolTip(NSString* toolTip) {
131 [item() setToolTip:toolTip];