Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / ui / message_center / cocoa / status_item_view.mm
1 // Copyright (c) 2013 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 "ui/message_center/cocoa/status_item_view.h"
6
7 #include <cmath>
8
9 #include "base/format_macros.h"
10 #include "base/mac/sdk_forward_declarations.h"
11 #include "ui/base/resource/resource_bundle.h"
12 #include "ui/resources/grit/ui_resources.h"
13
14 // The width of the status bar item when it's just the icon.
15 const CGFloat kStatusItemLength = 26;
16
17 // The amount of space between the left and right edges and the content of the
18 // status item.
19 const CGFloat kMargin = 5;
20
21
22 @interface MCStatusItemView (Private)
23 // Whether or not the status item should be drawn highlighted.
24 - (BOOL)shouldHighlight;
25
26 - (int)getTrayResourceId;
27 @end
28
29 @implementation MCStatusItemView
30
31 @synthesize highlight = highlight_;
32
33 - (id)init {
34   statusItem_.reset([[[NSStatusBar systemStatusBar] statusItemWithLength:
35       NSVariableStatusItemLength] retain]);
36   CGFloat thickness = [[statusItem_ statusBar] thickness];
37
38   NSRect frame = NSMakeRect(0, 0, kStatusItemLength, thickness);
39   if ((self = [super initWithFrame:frame])) {
40     [statusItem_ setView:self];
41   }
42   return self;
43 }
44
45 - (void)removeItem {
46   [[NSStatusBar systemStatusBar] removeStatusItem:statusItem_];
47   statusItem_.reset();
48 }
49
50 - (size_t)unreadCount {
51   return unreadCount_;
52 }
53
54 - (message_center::StatusItemClickedCallback)callback {
55   return callback_.get();
56 }
57
58 - (void)setCallback:(message_center::StatusItemClickedCallback)callback {
59   callback_.reset(callback, base::scoped_policy::RETAIN);
60 }
61
62 - (void)setUnreadCount:(size_t)unreadCount withQuietMode:(BOOL)quietMode {
63   unreadCount_ = unreadCount;
64   quietMode_ = quietMode;
65
66   NSRect frame = [self frame];
67   frame.size.width = kStatusItemLength;
68   [self setFrame:frame];
69
70   [self setNeedsDisplay:YES];
71 }
72
73 - (void)setHighlight:(BOOL)highlight {
74   highlight_ = highlight;
75   [self setNeedsDisplay:YES];
76 }
77
78 - (void)mouseDown:(NSEvent*)event {
79   inMouseEventSequence_ = YES;
80   [self setNeedsDisplay:YES];
81
82   if (callback_)
83     callback_.get()();
84 }
85
86 - (void)mouseUp:(NSEvent*)event {
87   inMouseEventSequence_ = NO;
88   [self setNeedsDisplay:YES];
89 }
90
91 - (void)rightMouseDown:(NSEvent*)event {
92   [self mouseDown:event];
93 }
94
95 - (void)rightMouseUp:(NSEvent*)event {
96   [self mouseUp:event];
97 }
98
99 - (void)otherMouseDown:(NSEvent*)event {
100   [self mouseDown:event];
101 }
102
103 - (void)otherMouseUp:(NSEvent*)event {
104   [self mouseUp:event];
105 }
106
107 - (void)drawRect:(NSRect)dirtyRect {
108   NSRect frame = [self bounds];
109
110   // Draw the background color.
111   BOOL highlight = [self shouldHighlight];
112   [statusItem_ drawStatusBarBackgroundInRect:frame
113                                withHighlight:highlight];
114
115   int resource_id = [self getTrayResourceId];
116   // Draw the icon.
117   ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
118   NSImage* image = rb.GetNativeImageNamed(resource_id).ToNSImage();
119   NSSize size = [image size];
120   NSRect drawRect = NSMakeRect(kMargin,
121                                floorf((NSHeight(frame) - size.height) / 2),
122                                size.width,
123                                size.height);
124   [image drawInRect:drawRect
125            fromRect:NSZeroRect
126           operation:NSCompositeSourceOver
127            fraction:1.0];
128 }
129
130 - (NSArray*)accessibilityActionNames {
131   return @[ NSAccessibilityPressAction ];
132 }
133
134 - (void)accessibilityPerformAction:(NSString*)action {
135   if ([action isEqualToString:NSAccessibilityPressAction]) {
136     if (callback_)
137       callback_.get()();
138     return;
139   }
140   [super accessibilityPerformAction:action];
141 }
142
143 // Private /////////////////////////////////////////////////////////////////////
144
145 - (BOOL)shouldHighlight {
146   return highlight_ || inMouseEventSequence_;
147 }
148
149 - (int)getTrayResourceId {
150   BOOL highlight = [self shouldHighlight];
151   BOOL hasUnreadItems = unreadCount_ > 0;
152   BOOL dark = NO;
153
154   Class nsAppearanceClass = NSClassFromString(@"NSAppearance");
155   if ([self respondsToSelector:@selector(effectiveAppearance)] &&
156       [nsAppearanceClass respondsToSelector:@selector(appearanceNamed:)]) {
157     id<NSObject> darkAppearance =
158         [nsAppearanceClass appearanceNamed:NSAppearanceNameVibrantDark];
159     dark = [[self effectiveAppearance] isEqual:darkAppearance];
160   }
161
162   int kResourceIds[2][2][2][2] = {
163     {
164       {
165         { IDR_TRAY_EMPTY, IDR_TRAY_EMPTY_PRESSED },
166         { IDR_TRAY_ATTENTION, IDR_TRAY_ATTENTION_PRESSED },
167       },
168       {
169         { IDR_TRAY_DO_NOT_DISTURB_EMPTY,
170           IDR_TRAY_DO_NOT_DISTURB_EMPTY_PRESSED },
171         { IDR_TRAY_DO_NOT_DISTURB_ATTENTION,
172           IDR_TRAY_DO_NOT_DISTURB_ATTENTION_PRESSED },
173       },
174     },
175     {
176       {
177         // We chose not to support the empty version of the pressed
178         // resource for the dark theme, so we use the same resource
179         // for both "pressed" options.
180         { IDR_DARK_TRAY_EMPTY, IDR_DARK_TRAY_PRESSED },
181         { IDR_DARK_TRAY_ATTENTION, IDR_DARK_TRAY_PRESSED },
182       },
183       {
184         { IDR_DARK_TRAY_DO_NOT_DISTURB_EMPTY,
185           IDR_DARK_TRAY_DO_NOT_DISTURB_PRESSED },
186         { IDR_DARK_TRAY_DO_NOT_DISTURB_ATTENTION,
187           IDR_DARK_TRAY_DO_NOT_DISTURB_PRESSED },
188       },
189     }
190   };
191   return kResourceIds[dark][quietMode_][hasUnreadItems][highlight];
192 }
193
194 @end