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/notification_controller.h" | 5 #import "ui/message_center/cocoa/notification_controller.h" |
| 6 | 6 |
| 7 #include "base/mac/foundation_util.h" | 7 #include "base/mac/foundation_util.h" |
| 8 #include "base/strings/string_util.h" | 8 #include "base/strings/string_util.h" |
| 9 #include "base/strings/sys_string_conversions.h" | 9 #include "base/strings/sys_string_conversions.h" |
| 10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
| 11 #include "grit/ui_resources.h" | 11 #include "grit/ui_resources.h" |
| 12 #include "grit/ui_strings.h" | |
| 12 #include "skia/ext/skia_utils_mac.h" | 13 #include "skia/ext/skia_utils_mac.h" |
| 13 #import "ui/base/cocoa/hover_image_button.h" | 14 #import "ui/base/cocoa/hover_image_button.h" |
| 15 #include "ui/base/l10n/l10n_util_mac.h" | |
| 14 #include "ui/base/resource/resource_bundle.h" | 16 #include "ui/base/resource/resource_bundle.h" |
| 15 #include "ui/base/text/text_elider.h" | 17 #include "ui/base/text/text_elider.h" |
| 16 #include "ui/message_center/message_center.h" | 18 #include "ui/message_center/message_center.h" |
| 17 #include "ui/message_center/message_center_style.h" | 19 #include "ui/message_center/message_center_style.h" |
| 18 #include "ui/message_center/notification.h" | 20 #include "ui/message_center/notification.h" |
| 19 | 21 |
| 20 @interface MCNotificationButtonCell : NSButtonCell { | 22 @interface MCNotificationButtonCell : NSButtonCell { |
| 21 BOOL hovered_; | 23 BOOL hovered_; |
| 22 } | 24 } |
| 23 @end | 25 @end |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 82 // Else the cell won't be repainted on hover. | 84 // Else the cell won't be repainted on hover. |
| 83 [super mouseEntered:event]; | 85 [super mouseEntered:event]; |
| 84 } | 86 } |
| 85 | 87 |
| 86 - (void)mouseExited:(NSEvent*)event { | 88 - (void)mouseExited:(NSEvent*)event { |
| 87 hovered_ = NO; | 89 hovered_ = NO; |
| 88 [super mouseExited:event]; | 90 [super mouseExited:event]; |
| 89 } | 91 } |
| 90 @end | 92 @end |
| 91 | 93 |
| 94 //////////////////////////////////////////////////////////////////////////////// | |
| 95 | |
| 92 @interface MCNotificationView : NSBox { | 96 @interface MCNotificationView : NSBox { |
| 93 @private | 97 @private |
| 94 MCNotificationController* controller_; | 98 MCNotificationController* controller_; |
| 95 } | 99 } |
| 96 | 100 |
| 97 - (id)initWithController:(MCNotificationController*)controller | 101 - (id)initWithController:(MCNotificationController*)controller |
| 98 frame:(NSRect)frame; | 102 frame:(NSRect)frame; |
| 99 @end | 103 @end |
| 100 | 104 |
| 101 @implementation MCNotificationView | 105 @implementation MCNotificationView |
| 102 - (id)initWithController:(MCNotificationController*)controller | 106 - (id)initWithController:(MCNotificationController*)controller |
| 103 frame:(NSRect)frame { | 107 frame:(NSRect)frame { |
| 104 if ((self = [super initWithFrame:frame])) | 108 if ((self = [super initWithFrame:frame])) |
| 105 controller_ = controller; | 109 controller_ = controller; |
| 106 return self; | 110 return self; |
| 107 } | 111 } |
| 108 | 112 |
| 109 - (void)mouseDown:(NSEvent*)event { | 113 - (void)mouseDown:(NSEvent*)event { |
| 110 if ([event type] != NSLeftMouseDown) { | 114 if ([event type] != NSLeftMouseDown) { |
| 111 [super mouseDown:event]; | 115 [super mouseDown:event]; |
| 112 return; | 116 return; |
| 113 } | 117 } |
| 114 [controller_ notificationClicked]; | 118 [controller_ notificationClicked]; |
| 115 } | 119 } |
| 120 | |
| 121 - (BOOL)accessibilityIsIgnored { | |
| 122 return NO; | |
| 123 } | |
| 124 | |
| 125 - (NSArray*)accessibilityActionNames { | |
| 126 return @[ NSAccessibilityPressAction ]; | |
| 127 } | |
| 128 | |
| 129 - (void)accessibilityPerformAction:(NSString*)action { | |
| 130 if ([action isEqualToString:NSAccessibilityPressAction]) { | |
| 131 [controller_ notificationClicked]; | |
| 132 return; | |
| 133 } | |
| 134 [super accessibilityPerformAction:action]; | |
| 135 } | |
| 116 @end | 136 @end |
| 117 | 137 |
| 138 //////////////////////////////////////////////////////////////////////////////// | |
| 139 | |
| 140 @interface AccessibilityIgnoredBox : NSBox | |
| 141 @end | |
| 142 | |
| 143 @implementation AccessibilityIgnoredBox | |
| 144 - (BOOL)accessibilityIsIgnored { | |
| 145 return YES; | |
| 146 } | |
| 147 @end | |
|
Nico
2013/06/20 21:03:23
Huh, this looks like something that should already
Robert Sesek
2013/06/22 01:56:00
I couldn't find it. There's some other Accessibili
| |
| 148 | |
| 149 //////////////////////////////////////////////////////////////////////////////// | |
| 150 | |
| 118 @interface MCNotificationController (Private) | 151 @interface MCNotificationController (Private) |
| 119 // Returns a string with item's title in title color and item's message in | 152 // Returns a string with item's title in title color and item's message in |
| 120 // message color. | 153 // message color. |
| 121 + (NSAttributedString*) | 154 + (NSAttributedString*) |
| 122 attributedStringForItem:(const message_center::NotificationItem&)item | 155 attributedStringForItem:(const message_center::NotificationItem&)item |
| 123 font:(NSFont*)font; | 156 font:(NSFont*)font; |
| 124 | 157 |
| 125 // Configures a NSBox to be borderless, titleless, and otherwise appearance- | 158 // Configures a NSBox to be borderless, titleless, and otherwise appearance- |
| 126 // free. | 159 // free. |
| 127 - (void)configureCustomBox:(NSBox*)box; | 160 - (void)configureCustomBox:(NSBox*)box; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 148 - (NSRect)currentContentRect; | 181 - (NSRect)currentContentRect; |
| 149 | 182 |
| 150 // Returns the wrapped text that could fit within the given text field with not | 183 // Returns the wrapped text that could fit within the given text field with not |
| 151 // more than the given number of lines. The Ellipsis could be added at the end | 184 // more than the given number of lines. The Ellipsis could be added at the end |
| 152 // of the last line if it is too long. | 185 // of the last line if it is too long. |
| 153 - (string16)wrapText:(const string16&)text | 186 - (string16)wrapText:(const string16&)text |
| 154 forField:(NSTextField*)field | 187 forField:(NSTextField*)field |
| 155 maxNumberOfLines:(size_t)lines; | 188 maxNumberOfLines:(size_t)lines; |
| 156 @end | 189 @end |
| 157 | 190 |
| 191 //////////////////////////////////////////////////////////////////////////////// | |
| 192 | |
| 158 @implementation MCNotificationController | 193 @implementation MCNotificationController |
| 159 | 194 |
| 160 - (id)initWithNotification:(const message_center::Notification*)notification | 195 - (id)initWithNotification:(const message_center::Notification*)notification |
| 161 messageCenter:(message_center::MessageCenter*)messageCenter { | 196 messageCenter:(message_center::MessageCenter*)messageCenter { |
| 162 if ((self = [super initWithNibName:nil bundle:nil])) { | 197 if ((self = [super initWithNibName:nil bundle:nil])) { |
| 163 notification_ = notification; | 198 notification_ = notification; |
| 164 notificationID_ = notification_->id(); | 199 notificationID_ = notification_->id(); |
| 165 messageCenter_ = messageCenter; | 200 messageCenter_ = messageCenter; |
| 166 } | 201 } |
| 167 return self; | 202 return self; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 245 // Create the list item views (up to a maximum). | 280 // Create the list item views (up to a maximum). |
| 246 [listItemView_ removeFromSuperview]; | 281 [listItemView_ removeFromSuperview]; |
| 247 const std::vector<message_center::NotificationItem>& items = | 282 const std::vector<message_center::NotificationItem>& items = |
| 248 notification->items(); | 283 notification->items(); |
| 249 NSRect listFrame = NSZeroRect; | 284 NSRect listFrame = NSZeroRect; |
| 250 if (items.size() > 0) { | 285 if (items.size() > 0) { |
| 251 listFrame = [self currentContentRect]; | 286 listFrame = [self currentContentRect]; |
| 252 listFrame.origin.y = 0; | 287 listFrame.origin.y = 0; |
| 253 listFrame.size.height = 0; | 288 listFrame.size.height = 0; |
| 254 listItemView_.reset([[NSView alloc] initWithFrame:listFrame]); | 289 listItemView_.reset([[NSView alloc] initWithFrame:listFrame]); |
| 290 [listItemView_ accessibilitySetOverrideValue:NSAccessibilityListRole | |
|
dmazzoni
2013/06/20 23:05:10
This is a little confusing to me - is listItemView
Robert Sesek
2013/06/22 01:56:00
listItemView is a container for list items.
| |
| 291 forAttribute:NSAccessibilityRoleAttribute]; | |
| 292 [listItemView_ | |
| 293 accessibilitySetOverrideValue:NSAccessibilityContentListSubrole | |
| 294 forAttribute:NSAccessibilitySubroleAttribute]; | |
| 255 CGFloat y = 0; | 295 CGFloat y = 0; |
| 256 | 296 |
| 257 NSFont* font = [NSFont systemFontOfSize:message_center::kMessageFontSize]; | 297 NSFont* font = [NSFont systemFontOfSize:message_center::kMessageFontSize]; |
| 258 CGFloat lineHeight = roundf(NSHeight([font boundingRectForFont])); | 298 CGFloat lineHeight = roundf(NSHeight([font boundingRectForFont])); |
| 259 | 299 |
| 260 const int kNumNotifications = | 300 const int kNumNotifications = |
| 261 std::min(items.size(), message_center::kNotificationMaximumItems); | 301 std::min(items.size(), message_center::kNotificationMaximumItems); |
| 262 for (int i = kNumNotifications - 1; i >= 0; --i) { | 302 for (int i = kNumNotifications - 1; i >= 0; --i) { |
| 263 NSTextField* field = [self newLabelWithFrame: | 303 NSTextField* field = [self newLabelWithFrame: |
| 264 NSMakeRect(0, y, NSWidth(listFrame), lineHeight)]; | 304 NSMakeRect(0, y, NSWidth(listFrame), lineHeight)]; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 320 [button setTarget:self]; | 360 [button setTarget:self]; |
| 321 [button setAction:@selector(buttonClicked:)]; | 361 [button setAction:@selector(buttonClicked:)]; |
| 322 y += NSHeight(buttonFrame); | 362 y += NSHeight(buttonFrame); |
| 323 frame.size.height += NSHeight(buttonFrame); | 363 frame.size.height += NSHeight(buttonFrame); |
| 324 [bottomView_ addSubview:button]; | 364 [bottomView_ addSubview:button]; |
| 325 | 365 |
| 326 NSRect separatorFrame = frame; | 366 NSRect separatorFrame = frame; |
| 327 separatorFrame.origin = NSMakePoint(0, y); | 367 separatorFrame.origin = NSMakePoint(0, y); |
| 328 separatorFrame.size.height = 1; | 368 separatorFrame.size.height = 1; |
| 329 scoped_nsobject<NSBox> separator( | 369 scoped_nsobject<NSBox> separator( |
| 330 [[NSBox alloc] initWithFrame:separatorFrame]); | 370 [[AccessibilityIgnoredBox alloc] initWithFrame:separatorFrame]); |
| 331 [self configureCustomBox:separator]; | 371 [self configureCustomBox:separator]; |
| 332 [separator setFillColor:gfx::SkColorToCalibratedNSColor( | 372 [separator setFillColor:gfx::SkColorToCalibratedNSColor( |
| 333 message_center::kButtonSeparatorColor)]; | 373 message_center::kButtonSeparatorColor)]; |
| 334 y += NSHeight(separatorFrame); | 374 y += NSHeight(separatorFrame); |
| 335 frame.size.height += NSHeight(separatorFrame); | 375 frame.size.height += NSHeight(separatorFrame); |
| 336 [bottomView_ addSubview:separator]; | 376 [bottomView_ addSubview:separator]; |
| 337 } | 377 } |
| 338 | 378 |
| 339 // Create the image view if appropriate. | 379 // Create the image view if appropriate. |
| 340 if (!notification->image().IsEmpty()) { | 380 if (!notification->image().IsEmpty()) { |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 434 [box setTitlePosition:NSNoTitle]; | 474 [box setTitlePosition:NSNoTitle]; |
| 435 [box setContentViewMargins:NSZeroSize]; | 475 [box setContentViewMargins:NSZeroSize]; |
| 436 } | 476 } |
| 437 | 477 |
| 438 - (NSView*)createImageView { | 478 - (NSView*)createImageView { |
| 439 // Create another box that shows a background color when the icon is not | 479 // Create another box that shows a background color when the icon is not |
| 440 // big enough to fill the space. | 480 // big enough to fill the space. |
| 441 NSRect imageFrame = NSMakeRect(0, 0, | 481 NSRect imageFrame = NSMakeRect(0, 0, |
| 442 message_center::kNotificationIconSize, | 482 message_center::kNotificationIconSize, |
| 443 message_center::kNotificationIconSize); | 483 message_center::kNotificationIconSize); |
| 444 scoped_nsobject<NSBox> imageBox([[NSBox alloc] initWithFrame:imageFrame]); | 484 scoped_nsobject<NSBox> imageBox( |
| 485 [[AccessibilityIgnoredBox alloc] initWithFrame:imageFrame]); | |
| 445 [self configureCustomBox:imageBox]; | 486 [self configureCustomBox:imageBox]; |
| 446 [imageBox setFillColor:gfx::SkColorToCalibratedNSColor( | 487 [imageBox setFillColor:gfx::SkColorToCalibratedNSColor( |
| 447 message_center::kLegacyIconBackgroundColor)]; | 488 message_center::kLegacyIconBackgroundColor)]; |
| 448 [imageBox setAutoresizingMask:NSViewMinYMargin]; | 489 [imageBox setAutoresizingMask:NSViewMinYMargin]; |
| 449 | 490 |
| 450 // Inside the image box put the actual icon view. | 491 // Inside the image box put the actual icon view. |
| 451 icon_.reset([[NSImageView alloc] initWithFrame:imageFrame]); | 492 icon_.reset([[NSImageView alloc] initWithFrame:imageFrame]); |
| 452 [imageBox setContentView:icon_]; | 493 [imageBox setContentView:icon_]; |
| 453 | 494 |
| 454 return imageBox.autorelease(); | 495 return imageBox.autorelease(); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 466 [closeButton_ setHoverImage: | 507 [closeButton_ setHoverImage: |
| 467 rb.GetNativeImageNamed(IDR_NOTIFICATION_CLOSE_HOVER).ToNSImage()]; | 508 rb.GetNativeImageNamed(IDR_NOTIFICATION_CLOSE_HOVER).ToNSImage()]; |
| 468 [closeButton_ setPressedImage: | 509 [closeButton_ setPressedImage: |
| 469 rb.GetNativeImageNamed(IDR_NOTIFICATION_CLOSE_PRESSED).ToNSImage()]; | 510 rb.GetNativeImageNamed(IDR_NOTIFICATION_CLOSE_PRESSED).ToNSImage()]; |
| 470 [[closeButton_ cell] setHighlightsBy:NSOnState]; | 511 [[closeButton_ cell] setHighlightsBy:NSOnState]; |
| 471 [closeButton_ setTrackingEnabled:YES]; | 512 [closeButton_ setTrackingEnabled:YES]; |
| 472 [closeButton_ setBordered:NO]; | 513 [closeButton_ setBordered:NO]; |
| 473 [closeButton_ setAutoresizingMask:NSViewMinYMargin]; | 514 [closeButton_ setAutoresizingMask:NSViewMinYMargin]; |
| 474 [closeButton_ setTarget:self]; | 515 [closeButton_ setTarget:self]; |
| 475 [closeButton_ setAction:@selector(close:)]; | 516 [closeButton_ setAction:@selector(close:)]; |
| 517 [[closeButton_ cell] | |
| 518 accessibilitySetOverrideValue:NSAccessibilityCloseButtonSubrole | |
| 519 forAttribute:NSAccessibilitySubroleAttribute]; | |
| 520 [[closeButton_ cell] | |
| 521 accessibilitySetOverrideValue: | |
| 522 l10n_util::GetNSString(IDS_APP_ACCNAME_CLOSE) | |
| 523 forAttribute:NSAccessibilityTitleAttribute]; | |
| 476 } | 524 } |
| 477 | 525 |
| 478 - (void)configureTitleInFrame:(NSRect)rootFrame { | 526 - (void)configureTitleInFrame:(NSRect)rootFrame { |
| 479 NSRect frame = [self currentContentRect]; | 527 NSRect frame = [self currentContentRect]; |
| 480 frame.size.height = 0; | 528 frame.size.height = 0; |
| 481 title_.reset([self newLabelWithFrame:frame]); | 529 title_.reset([self newLabelWithFrame:frame]); |
| 482 [title_ setAutoresizingMask:NSViewMinYMargin]; | 530 [title_ setAutoresizingMask:NSViewMinYMargin]; |
| 483 [title_ setTextColor:gfx::SkColorToCalibratedNSColor( | 531 [title_ setTextColor:gfx::SkColorToCalibratedNSColor( |
| 484 message_center::kRegularTextColor)]; | 532 message_center::kRegularTextColor)]; |
| 485 [title_ setFont:[NSFont messageFontOfSize:message_center::kTitleFontSize]]; | 533 [title_ setFont:[NSFont messageFontOfSize:message_center::kTitleFontSize]]; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 535 if (font.GetStringWidth(last) > width) | 583 if (font.GetStringWidth(last) > width) |
| 536 last = ui::ElideText(last, font, width, ui::ELIDE_AT_END); | 584 last = ui::ElideText(last, font, width, ui::ELIDE_AT_END); |
| 537 wrapped.resize(lines - 1); | 585 wrapped.resize(lines - 1); |
| 538 wrapped.push_back(last); | 586 wrapped.push_back(last); |
| 539 } | 587 } |
| 540 | 588 |
| 541 return JoinString(wrapped, '\n'); | 589 return JoinString(wrapped, '\n'); |
| 542 } | 590 } |
| 543 | 591 |
| 544 @end | 592 @end |
| OLD | NEW |