summaryrefslogtreecommitdiffstats
path: root/chrome/browser/ui/cocoa/status_icons/status_icon_mac.mm
blob: f0566febac48f4a81e4c6a97f0b0043e9333d80b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// 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"
#include "ui/message_center/notifier_settings.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 = skia::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,
    const message_center::NotifierId& notifier_id) {
  notification_.DisplayBalloon(icon, title, contents, notifier_id);
}

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];
}