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 "grit/ui_resources.h" 11 #include "ui/base/resource/resource_bundle.h" 12 13 // The width of the status bar item when it's just the icon. 14 const CGFloat kStatusItemLength = 26; 15 16 // The amount of space between the left and right edges and the content of the 17 // status item. 18 const CGFloat kMargin = 5; 19 20 21 @interface MCStatusItemView (Private) 22 // Whether or not the status item should be drawn highlighted. 23 - (BOOL)shouldHighlight; 24 25 - (int)getTrayResourceId; 26 @end 27 28 @implementation MCStatusItemView 29 30 @synthesize highlight = highlight_; 31 32 - (id)init { 33 statusItem_.reset([[[NSStatusBar systemStatusBar] statusItemWithLength: 34 NSVariableStatusItemLength] retain]); 35 CGFloat thickness = [[statusItem_ statusBar] thickness]; 36 37 NSRect frame = NSMakeRect(0, 0, kStatusItemLength, thickness); 38 if ((self = [super initWithFrame:frame])) { 39 [statusItem_ setView:self]; 40 } 41 return self; 42 } 43 44 - (void)removeItem { 45 [[NSStatusBar systemStatusBar] removeStatusItem:statusItem_]; 46 statusItem_.reset(); 47 } 48 49 - (size_t)unreadCount { 50 return unreadCount_; 51 } 52 53 - (message_center::StatusItemClickedCallack)callback { 54 return callback_.get(); 55 } 56 57 - (void)setCallback:(message_center::StatusItemClickedCallack)callback { 58 callback_.reset(Block_copy(callback)); 59 } 60 61 - (void)setUnreadCount:(size_t)unreadCount withQuietMode:(BOOL)quietMode { 62 unreadCount_ = unreadCount; 63 quietMode_ = quietMode; 64 65 NSRect frame = [self frame]; 66 frame.size.width = kStatusItemLength; 67 [self setFrame:frame]; 68 69 [self setNeedsDisplay:YES]; 70 } 71 72 - (void)setHighlight:(BOOL)highlight { 73 highlight_ = highlight; 74 [self setNeedsDisplay:YES]; 75 } 76 77 - (void)mouseDown:(NSEvent*)event { 78 inMouseEventSequence_ = YES; 79 [self setNeedsDisplay:YES]; 80 81 if (callback_) 82 callback_.get()(); 83 } 84 85 - (void)mouseUp:(NSEvent*)event { 86 inMouseEventSequence_ = NO; 87 [self setNeedsDisplay:YES]; 88 } 89 90 - (void)rightMouseDown:(NSEvent*)event { 91 [self mouseDown:event]; 92 } 93 94 - (void)rightMouseUp:(NSEvent*)event { 95 [self mouseUp:event]; 96 } 97 98 - (void)otherMouseDown:(NSEvent*)event { 99 [self mouseDown:event]; 100 } 101 102 - (void)otherMouseUp:(NSEvent*)event { 103 [self mouseUp:event]; 104 } 105 106 - (void)drawRect:(NSRect)dirtyRect { 107 NSRect frame = [self bounds]; 108 109 // Draw the background color. 110 BOOL highlight = [self shouldHighlight]; 111 [statusItem_ drawStatusBarBackgroundInRect:frame 112 withHighlight:highlight]; 113 114 int resource_id = [self getTrayResourceId]; 115 // Draw the icon. 116 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 117 NSImage* image = rb.GetNativeImageNamed(resource_id).ToNSImage(); 118 NSSize size = [image size]; 119 NSRect drawRect = NSMakeRect(kMargin, 120 floorf((NSHeight(frame) - size.height) / 2), 121 size.width, 122 size.height); 123 [image drawInRect:drawRect 124 fromRect:NSZeroRect 125 operation:NSCompositeSourceOver 126 fraction:1.0]; 127 } 128 129 - (NSArray*)accessibilityActionNames { 130 return @[ NSAccessibilityPressAction ]; 131 } 132 133 - (void)accessibilityPerformAction:(NSString*)action { 134 if ([action isEqualToString:NSAccessibilityPressAction]) { 135 if (callback_) 136 callback_.get()(); 137 return; 138 } 139 [super accessibilityPerformAction:action]; 140 } 141 142 // Private ///////////////////////////////////////////////////////////////////// 143 144 - (BOOL)shouldHighlight { 145 return highlight_ || inMouseEventSequence_; 146 } 147 148 - (int)getTrayResourceId { 149 BOOL highlight = [self shouldHighlight]; 150 BOOL hasUnreadItems = unreadCount_ > 0; 151 int kResourceIds[2][2][2] = { 152 { 153 { IDR_TRAY_EMPTY, IDR_TRAY_EMPTY_PRESSED }, 154 { IDR_TRAY_ATTENTION, IDR_TRAY_ATTENTION_PRESSED }, 155 }, 156 { 157 { IDR_TRAY_DO_NOT_DISTURB_EMPTY, 158 IDR_TRAY_DO_NOT_DISTURB_EMPTY_PRESSED }, 159 { IDR_TRAY_DO_NOT_DISTURB_ATTENTION, 160 IDR_TRAY_DO_NOT_DISTURB_ATTENTION_PRESSED }, 161 }, 162 }; 163 return kResourceIds[quietMode_][hasUnreadItems][highlight]; 164 } 165 166 @end 167