Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import "ui/message_center/cocoa/status_item_view.h" | 5 #import "ui/message_center/cocoa/status_item_view.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 | 8 |
| 9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
| 10 #include "grit/ui_resources.h" | 10 #include "grit/ui_resources.h" |
| 11 #include "ui/base/resource/resource_bundle.h" | 11 #include "ui/base/resource/resource_bundle.h" |
| 12 | 12 |
| 13 namespace { | 13 namespace { |
| 14 | 14 |
| 15 // The width of the status bar. | 15 // The width of the status bar item when it's just the icon. |
| 16 const CGFloat kStatusItemLength = 45; | 16 const CGFloat kStatusItemLength = 26; |
| 17 | 17 |
| 18 // The amount of space between the edge of the status item and where the icon | 18 // The amount of space between the left and right edges and the content of the |
| 19 // should start drawing. | 19 // status item. |
| 20 const CGFloat kInset = 6; | 20 const CGFloat kMargin = 5; |
| 21 | |
| 22 // The amount of space between the icon and the unread count number. | |
| 23 const CGFloat kUnreadCountPadding = 3; | |
| 24 | |
| 25 // The lower-left Y coordinate of the unread count number. | |
| 26 const CGFloat kUnreadCountMinY = 4; | |
| 21 | 27 |
| 22 } // namespace | 28 } // namespace |
| 23 | 29 |
| 30 @interface MCStatusItemView (Private) | |
| 31 // Whether or not the status item should be drawn highlighted. | |
| 32 - (BOOL)shouldHighlight; | |
| 33 | |
| 34 // Returns an autoreleased, styled string for the unread count. | |
| 35 - (NSAttributedString*)unreadCountString; | |
| 36 @end | |
| 37 | |
| 24 @implementation MCStatusItemView | 38 @implementation MCStatusItemView |
| 25 | 39 |
| 26 @synthesize unreadCount = unreadCount_; | 40 @synthesize unreadCount = unreadCount_; |
| 27 @synthesize highlight = highlight_; | 41 @synthesize highlight = highlight_; |
| 28 | 42 |
| 29 - (id)initWithStatusItem:(NSStatusItem*)item { | 43 - (id)initWithStatusItem:(NSStatusItem*)item { |
| 30 CGFloat thickness = [[item statusBar] thickness]; | 44 CGFloat thickness = [[item statusBar] thickness]; |
| 31 NSRect frame = NSMakeRect(0, 0, kStatusItemLength, thickness); | 45 NSRect frame = NSMakeRect(0, 0, kStatusItemLength, thickness); |
| 32 if ((self = [super initWithFrame:frame])) { | 46 if ((self = [super initWithFrame:frame])) { |
| 33 statusItem_.reset([item retain]); | 47 statusItem_.reset([item retain]); |
| 34 [statusItem_ setView:self]; | 48 [statusItem_ setView:self]; |
| 35 } | 49 } |
| 36 return self; | 50 return self; |
| 37 } | 51 } |
| 38 | 52 |
| 39 - (message_center::StatusItemClickedCallack)callback { | 53 - (message_center::StatusItemClickedCallack)callback { |
| 40 return callback_.get(); | 54 return callback_.get(); |
| 41 } | 55 } |
| 42 | 56 |
| 43 - (void)setCallback:(message_center::StatusItemClickedCallack)callback { | 57 - (void)setCallback:(message_center::StatusItemClickedCallack)callback { |
| 44 callback_.reset(Block_copy(callback)); | 58 callback_.reset(Block_copy(callback)); |
| 45 } | 59 } |
| 46 | 60 |
| 47 - (void)setUnreadCount:(size_t)unreadCount { | 61 - (void)setUnreadCount:(size_t)unreadCount { |
| 48 unreadCount_ = unreadCount; | 62 unreadCount_ = unreadCount; |
| 63 | |
| 64 NSRect frame = [self frame]; | |
| 65 if (unreadCount_ == 0) { | |
|
sail
2013/05/29 16:58:43
Small nit. It might be better to do:
frame.size.wi
Robert Sesek
2013/05/29 17:52:31
Done.
| |
| 66 frame.size.width = kStatusItemLength; | |
| 67 } else { | |
| 68 // Get the subpixel bounding rectangle for the string. -size doesn't yield | |
|
sail
2013/05/29 16:58:43
I didn't know that. Should I stop using -[NSAttrib
Robert Sesek
2013/05/29 17:52:31
No, it's fine for most cases. -size basically retu
| |
| 69 // correct results for pixel-precise drawing, since it doesn't use the | |
| 70 // device metrics. | |
| 71 NSAttributedString* countString = [self unreadCountString]; | |
| 72 NSRect boundingRect = | |
| 73 [countString boundingRectWithSize:NSZeroSize | |
| 74 options:NSStringDrawingUsesDeviceMetrics]; | |
| 75 frame.size.width = | |
| 76 kStatusItemLength + roundf(NSWidth(boundingRect)) + kMargin; | |
| 77 } | |
| 78 [self setFrame:frame]; | |
| 79 | |
| 49 [self setNeedsDisplay:YES]; | 80 [self setNeedsDisplay:YES]; |
| 50 } | 81 } |
| 51 | 82 |
| 52 - (void)setHighlight:(BOOL)highlight { | 83 - (void)setHighlight:(BOOL)highlight { |
| 53 highlight_ = highlight; | 84 highlight_ = highlight; |
| 54 [self setNeedsDisplay:YES]; | 85 [self setNeedsDisplay:YES]; |
| 55 } | 86 } |
| 56 | 87 |
| 57 - (void)mouseDown:(NSEvent*)event { | 88 - (void)mouseDown:(NSEvent*)event { |
| 58 inMouseEventSequence_ = YES; | 89 inMouseEventSequence_ = YES; |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 80 } | 111 } |
| 81 | 112 |
| 82 - (void)otherMouseUp:(NSEvent*)event { | 113 - (void)otherMouseUp:(NSEvent*)event { |
| 83 [self mouseUp:event]; | 114 [self mouseUp:event]; |
| 84 } | 115 } |
| 85 | 116 |
| 86 - (void)drawRect:(NSRect)dirtyRect { | 117 - (void)drawRect:(NSRect)dirtyRect { |
| 87 NSRect frame = [self bounds]; | 118 NSRect frame = [self bounds]; |
| 88 | 119 |
| 89 // Draw the background color. | 120 // Draw the background color. |
| 90 BOOL highlight = highlight_ || inMouseEventSequence_; | 121 BOOL highlight = [self shouldHighlight]; |
| 91 [statusItem_ drawStatusBarBackgroundInRect:frame | 122 [statusItem_ drawStatusBarBackgroundInRect:frame |
| 92 withHighlight:highlight]; | 123 withHighlight:highlight]; |
| 93 | 124 |
| 94 // Draw the icon. | 125 // Draw the icon. |
| 95 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 126 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 96 NSImage* image = rb.GetNativeImageNamed( | 127 NSImage* image = rb.GetNativeImageNamed( |
| 97 highlight ? IDR_TRAY_ICON_PRESSED : IDR_TRAY_ICON_REGULAR).ToNSImage(); | 128 highlight ? IDR_TRAY_ICON_PRESSED : IDR_TRAY_ICON_REGULAR).ToNSImage(); |
| 98 NSSize size = [image size]; | 129 NSSize size = [image size]; |
| 99 NSRect drawRect = NSMakeRect(kInset, | 130 NSRect drawRect = NSMakeRect(kMargin, |
| 100 floorf((NSHeight(frame) - size.height) / 2), | 131 floorf((NSHeight(frame) - size.height) / 2), |
| 101 size.width, | 132 size.width, |
| 102 size.height); | 133 size.height); |
| 103 [image drawInRect:drawRect | 134 [image drawInRect:drawRect |
| 104 fromRect:NSZeroRect | 135 fromRect:NSZeroRect |
| 105 operation:NSCompositeSourceOver | 136 operation:NSCompositeSourceOver |
| 106 fraction:1.0]; | 137 fraction:1.0]; |
| 107 | 138 |
| 108 // Draw the unread count. | 139 // Draw the unread count. |
| 109 if (unreadCount_ > 0) { | 140 NSAttributedString* countString = [self unreadCountString]; |
| 110 NSString* count = nil; | 141 if (countString) { |
| 111 if (unreadCount_ > 9) | |
| 112 count = @"9+"; | |
| 113 else | |
| 114 count = [NSString stringWithFormat:@"%"PRIuS, unreadCount_]; | |
| 115 | |
| 116 NSColor* fontColor = highlight ? [NSColor whiteColor] | |
| 117 : [NSColor blackColor]; | |
| 118 NSDictionary* attributes = @{ | |
| 119 NSFontAttributeName: [NSFont fontWithName:@"Helvetica-Bold" size:12], | |
| 120 NSForegroundColorAttributeName: fontColor, | |
| 121 }; | |
| 122 | |
| 123 // Center the string inside the remaining space of the status item. | |
| 124 NSSize stringSize = [count sizeWithAttributes:attributes]; | |
| 125 NSRect iconSlice, textSlice; | |
| 126 NSDivideRect(frame, &iconSlice, &textSlice, NSMaxX(drawRect), NSMinXEdge); | |
| 127 NSPoint countPoint = NSMakePoint( | 142 NSPoint countPoint = NSMakePoint( |
| 128 floorf(NSMinX(textSlice) + (NSWidth(textSlice) - stringSize.width) / 2), | 143 NSMaxX(drawRect) + kUnreadCountPadding, kUnreadCountMinY); |
| 129 floorf(NSMinY(textSlice) + | 144 [countString drawAtPoint:countPoint]; |
| 130 (NSHeight(textSlice) - stringSize.height) / 2)); | |
| 131 | |
| 132 [count drawAtPoint:countPoint withAttributes:attributes]; | |
| 133 } | 145 } |
| 134 } | 146 } |
| 135 | 147 |
| 148 // Private ///////////////////////////////////////////////////////////////////// | |
| 149 | |
| 150 - (BOOL)shouldHighlight { | |
| 151 return highlight_ || inMouseEventSequence_; | |
| 152 } | |
| 153 | |
| 154 - (NSAttributedString*)unreadCountString { | |
| 155 if (unreadCount_ == 0) | |
| 156 return nil; | |
| 157 | |
| 158 NSString* count = nil; | |
| 159 if (unreadCount_ > 9) | |
| 160 count = @"9+"; | |
| 161 else | |
| 162 count = [NSString stringWithFormat:@"%"PRIuS, unreadCount_]; | |
| 163 | |
| 164 NSColor* fontColor = [self shouldHighlight] ? [NSColor whiteColor] | |
| 165 : [NSColor blackColor]; | |
| 166 NSDictionary* attributes = @{ | |
| 167 NSFontAttributeName: [NSFont fontWithName:@"Helvetica-Bold" size:12], | |
| 168 NSForegroundColorAttributeName: fontColor, | |
| 169 }; | |
| 170 return [[[NSAttributedString alloc] initWithString:count | |
| 171 attributes:attributes] autorelease]; | |
| 172 } | |
| 173 | |
| 136 @end | 174 @end |
| OLD | NEW |