blob: dbecd2324f1686f14c727f55aaea0cbd39450970 [file] [log] [blame]
// Copyright (c) 2012 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.
#include "chrome/browser/ui/cocoa/status_icons/status_icon_mac.h"
#import <AppKit/AppKit.h>
#include "base/logging.h"
#include "base/strings/sys_string_conversions.h"
#include "skia/ext/skia_utils_mac.h"
#include "third_party/skia/include/core/SkBitmap.h"
#import "ui/base/cocoa/menu_controller.h"
#include "ui/gfx/image/image_skia.h"
@interface StatusItemController : NSObject {
StatusIconMac* statusIcon_; // weak
}
- (id)initWithIcon:(StatusIconMac*)icon;
- (void)handleClick:(id)sender;
@end // @interface StatusItemController
@implementation StatusItemController
- (id)initWithIcon:(StatusIconMac*)icon {
statusIcon_ = icon;
return self;
}
- (void)handleClick:(id)sender {
// Pass along the click notification to our owner.
DCHECK(statusIcon_);
// Bring up the status icon menu if there is one, relay the click event
// otherwise.
if (!statusIcon_->HasStatusIconMenu())
statusIcon_->DispatchClickEvent();
}
@end
StatusIconMac::StatusIconMac()
: item_(NULL) {
controller_.reset([[StatusItemController alloc] initWithIcon:this]);
}
StatusIconMac::~StatusIconMac() {
// Remove the status item from the status bar.
if (item_)
[[NSStatusBar systemStatusBar] removeStatusItem:item_];
}
NSStatusItem* StatusIconMac::item() {
if (!item_.get()) {
// Create a new status item.
item_.reset([[[NSStatusBar systemStatusBar]
statusItemWithLength:NSSquareStatusItemLength] retain]);
[item_ setEnabled:YES];
[item_ setTarget:controller_];
[item_ setAction:@selector(handleClick:)];
[item_ setHighlightMode:YES];
}
return item_.get();
}
void StatusIconMac::SetImage(const gfx::ImageSkia& image) {
if (!image.isNull()) {
NSImage* ns_image = gfx::SkBitmapToNSImage(*image.bitmap());
if (ns_image)
[item() setImage:ns_image];
}
}
void StatusIconMac::SetToolTip(const base::string16& tool_tip) {
// If we have a status icon menu, make the tool tip part of the menu instead
// of a pop-up tool tip when hovering the mouse over the image.
toolTip_.reset([base::SysUTF16ToNSString(tool_tip) retain]);
if (menu_.get()) {
SetToolTip(nil);
CreateMenu([menu_ model], toolTip_.get());
} else {
SetToolTip(toolTip_.get());
}
}
void StatusIconMac::DisplayBalloon(const gfx::ImageSkia& icon,
const base::string16& title,
const base::string16& contents) {
notification_.DisplayBalloon(icon, title, contents);
}
bool StatusIconMac::HasStatusIconMenu() {
return menu_.get() != nil;
}
void StatusIconMac::UpdatePlatformContextMenu(StatusIconMenuModel* model) {
if (!model) {
menu_.reset();
} else {
SetToolTip(nil);
CreateMenu(model, toolTip_.get());
}
}
void StatusIconMac::CreateMenu(ui::MenuModel* model, NSString* toolTip) {
DCHECK(model);
if (!toolTip) {
menu_.reset([[MenuController alloc] initWithModel:model
useWithPopUpButtonCell:NO]);
} else {
// When using a popup button cell menu controller, an extra blank item is
// added at index 0. Use this item for the tooltip.
menu_.reset([[MenuController alloc] initWithModel:model
useWithPopUpButtonCell:YES]);
NSMenuItem* toolTipItem = [[menu_ menu] itemAtIndex:0];
[toolTipItem setTitle:toolTip];
}
[item() setMenu:[menu_ menu]];
}
void StatusIconMac::SetToolTip(NSString* toolTip) {
[item() setToolTip:toolTip];
}