Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(76)

Side by Side Diff: ui/message_center/cocoa/notification_controller.mm

Issue 17408004: [Mac][MC] Initial accessibility pass. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698