| 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" |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 @interface MCNotificationController (Private) | 193 @interface MCNotificationController (Private) |
| 194 // Configures a NSBox to be borderless, titleless, and otherwise appearance- | 194 // Configures a NSBox to be borderless, titleless, and otherwise appearance- |
| 195 // free. | 195 // free. |
| 196 - (void)configureCustomBox:(NSBox*)box; | 196 - (void)configureCustomBox:(NSBox*)box; |
| 197 | 197 |
| 198 // Initializes the icon_ ivar and returns the view to insert into the hierarchy. | 198 // Initializes the icon_ ivar and returns the view to insert into the hierarchy. |
| 199 - (NSView*)createIconView; | 199 - (NSView*)createIconView; |
| 200 | 200 |
| 201 // Creates a box that shows a border when the icon is not big enough to fill the | 201 // Creates a box that shows a border when the icon is not big enough to fill the |
| 202 // space. | 202 // space. |
| 203 - (NSBox*)createImageBox; | 203 - (NSBox*)createImageBox:(const gfx::Image&)notificationImage; |
| 204 | 204 |
| 205 // Initializes the closeButton_ ivar with the configured button. | 205 // Initializes the closeButton_ ivar with the configured button. |
| 206 - (void)configureCloseButtonInFrame:(NSRect)rootFrame; | 206 - (void)configureCloseButtonInFrame:(NSRect)rootFrame; |
| 207 | 207 |
| 208 // Initializes the smallImage_ ivar with the appropriate frame. |
| 209 - (void)configureSmallImageInFrame:(NSRect)rootFrame; |
| 210 |
| 208 // Initializes title_ in the given frame. | 211 // Initializes title_ in the given frame. |
| 209 - (void)configureTitleInFrame:(NSRect)rootFrame; | 212 - (void)configureTitleInFrame:(NSRect)rootFrame; |
| 210 | 213 |
| 211 // Initializes message_ in the given frame. | 214 // Initializes message_ in the given frame. |
| 212 - (void)configureBodyInFrame:(NSRect)rootFrame; | 215 - (void)configureBodyInFrame:(NSRect)rootFrame; |
| 213 | 216 |
| 214 // Initializes contextMessage_ in the given frame. | 217 // Initializes contextMessage_ in the given frame. |
| 215 - (void)configureContextMessageInFrame:(NSRect)rootFrame; | 218 - (void)configureContextMessageInFrame:(NSRect)rootFrame; |
| 216 | 219 |
| 217 // Creates a NSTextView that the caller owns configured as a label in a | 220 // Creates a NSTextView that the caller owns configured as a label in a |
| 218 // notification. | 221 // notification. |
| 219 - (NSTextView*)newLabelWithFrame:(NSRect)frame; | 222 - (NSTextView*)newLabelWithFrame:(NSRect)frame; |
| 220 | 223 |
| 221 // Gets the rectangle in which notification content should be placed. This | 224 // Gets the rectangle in which notification content should be placed. This |
| 222 // rectangle is to the right of the icon and left of the control buttons. | 225 // rectangle is to the right of the icon and left of the control buttons. |
| 223 // This depends on the icon_ and closeButton_ being initialized. | 226 // This depends on the icon_ and closeButton_ being initialized. |
| 224 - (NSRect)currentContentRect; | 227 - (NSRect)currentContentRect; |
| 225 | 228 |
| 226 // Returns the wrapped text that could fit within the content rect with not | 229 // Returns the wrapped text that could fit within the content rect with not |
| 227 // more than the given number of lines. The wrapped text would be painted using | 230 // more than the given number of lines. The wrapped text would be painted using |
| 228 // the given font. The Ellipsis could be added at the end of the last line if | 231 // the given font. The Ellipsis could be added at the end of the last line if |
| 229 // it is too long. | 232 // it is too long. |
| 230 - (base::string16)wrapText:(const base::string16&)text | 233 - (base::string16)wrapText:(const base::string16&)text |
| 231 forFont:(NSFont*)font | 234 forFont:(NSFont*)font |
| 232 maxNumberOfLines:(size_t)lines; | 235 maxNumberOfLines:(size_t)lines; |
| 233 @end | 236 @end |
| 234 | 237 |
| 235 //////////////////////////////////////////////////////////////////////////////// | 238 //////////////////////////////////////////////////////////////////////////////// |
| 236 | 239 |
| 237 @implementation MCNotificationController | 240 @implementation MCNotificationController |
| 238 | 241 |
| 239 - (id)initWithNotification:(const message_center::Notification*)notification | 242 - (id)initWithNotification:(const message_center::Notification*)notification |
| 240 messageCenter:(message_center::MessageCenter*)messageCenter { | 243 messageCenter:(message_center::MessageCenter*)messageCenter { |
| 241 if ((self = [super initWithNibName:nil bundle:nil])) { | 244 if ((self = [super initWithNibName:nil bundle:nil])) { |
| 242 notification_ = notification; | 245 notification_ = notification; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 257 [rootView setFillColor:gfx::SkColorToCalibratedNSColor( | 260 [rootView setFillColor:gfx::SkColorToCalibratedNSColor( |
| 258 message_center::kNotificationBackgroundColor)]; | 261 message_center::kNotificationBackgroundColor)]; |
| 259 [self setView:rootView]; | 262 [self setView:rootView]; |
| 260 | 263 |
| 261 [rootView addSubview:[self createIconView]]; | 264 [rootView addSubview:[self createIconView]]; |
| 262 | 265 |
| 263 // Create the close button. | 266 // Create the close button. |
| 264 [self configureCloseButtonInFrame:rootFrame]; | 267 [self configureCloseButtonInFrame:rootFrame]; |
| 265 [rootView addSubview:closeButton_]; | 268 [rootView addSubview:closeButton_]; |
| 266 | 269 |
| 270 [self configureSmallImageInFrame:rootFrame]; |
| 271 [[self view] addSubview:smallImage_]; |
| 272 |
| 267 // Create the title. | 273 // Create the title. |
| 268 [self configureTitleInFrame:rootFrame]; | 274 [self configureTitleInFrame:rootFrame]; |
| 269 [rootView addSubview:title_]; | 275 [rootView addSubview:title_]; |
| 270 | 276 |
| 271 // Create the message body. | 277 // Create the message body. |
| 272 [self configureBodyInFrame:rootFrame]; | 278 [self configureBodyInFrame:rootFrame]; |
| 273 [rootView addSubview:message_]; | 279 [rootView addSubview:message_]; |
| 274 | 280 |
| 275 // Create the context message body. | 281 // Create the context message body. |
| 276 [self configureContextMessageInFrame:rootFrame]; | 282 [self configureContextMessageInFrame:rootFrame]; |
| 277 [rootView addSubview:contextMessage_]; | 283 [rootView addSubview:contextMessage_]; |
| 278 | 284 |
| 279 // Populate the data. | 285 // Populate the data. |
| 280 [self updateNotification:notification_]; | 286 [self updateNotification:notification_]; |
| 281 } | 287 } |
| 282 | 288 |
| 283 - (NSRect)updateNotification:(const message_center::Notification*)notification { | 289 - (NSRect)updateNotification:(const message_center::Notification*)notification { |
| 284 DCHECK_EQ(notification->id(), notificationID_); | 290 DCHECK_EQ(notification->id(), notificationID_); |
| 285 notification_ = notification; | 291 notification_ = notification; |
| 286 | 292 |
| 287 NSRect rootFrame = NSMakeRect(0, 0, | 293 NSRect rootFrame = NSMakeRect(0, 0, |
| 288 message_center::kNotificationPreferredImageWidth, | 294 message_center::kNotificationPreferredImageWidth, |
| 289 message_center::kNotificationIconSize); | 295 message_center::kNotificationIconSize); |
| 290 | 296 |
| 297 [smallImage_ setImage:notification_->small_image().AsNSImage()]; |
| 298 |
| 291 // Update the icon. | 299 // Update the icon. |
| 292 [icon_ setImage:notification_->icon().AsNSImage()]; | 300 [icon_ setImage:notification_->icon().AsNSImage()]; |
| 293 | 301 |
| 294 // The message_center:: constants are relative to capHeight at the top and | 302 // The message_center:: constants are relative to capHeight at the top and |
| 295 // relative to the baseline at the bottom, but NSTextField uses the full line | 303 // relative to the baseline at the bottom, but NSTextField uses the full line |
| 296 // height for its height. | 304 // height for its height. |
| 297 CGFloat titleTopGap = | 305 CGFloat titleTopGap = |
| 298 roundf([[title_ font] ascender] - [[title_ font] capHeight]); | 306 roundf([[title_ font] ascender] - [[title_ font] capHeight]); |
| 299 CGFloat titleBottomGap = roundf(fabs([[title_ font] descender])); | 307 CGFloat titleBottomGap = roundf(fabs([[title_ font] descender])); |
| 300 CGFloat titlePadding = message_center::kTextTopPadding - titleTopGap; | 308 CGFloat titlePadding = message_center::kTextTopPadding - titleTopGap; |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 600 message_center::kIconBackgroundColor)]; | 608 message_center::kIconBackgroundColor)]; |
| 601 [imageBox setAutoresizingMask:NSViewMinYMargin]; | 609 [imageBox setAutoresizingMask:NSViewMinYMargin]; |
| 602 | 610 |
| 603 // Inside the image box put the actual icon view. | 611 // Inside the image box put the actual icon view. |
| 604 icon_.reset([[NSImageView alloc] initWithFrame:imageFrame]); | 612 icon_.reset([[NSImageView alloc] initWithFrame:imageFrame]); |
| 605 [imageBox setContentView:icon_]; | 613 [imageBox setContentView:icon_]; |
| 606 | 614 |
| 607 return imageBox.autorelease(); | 615 return imageBox.autorelease(); |
| 608 } | 616 } |
| 609 | 617 |
| 610 - (NSBox*)createImageBox:(gfx::Image)notificationImage { | 618 - (NSBox*)createImageBox:(const gfx::Image&)notificationImage { |
| 611 using message_center::kNotificationImageBorderSize; | 619 using message_center::kNotificationImageBorderSize; |
| 612 using message_center::kNotificationPreferredImageWidth; | 620 using message_center::kNotificationPreferredImageWidth; |
| 613 using message_center::kNotificationPreferredImageHeight; | 621 using message_center::kNotificationPreferredImageHeight; |
| 614 | 622 |
| 615 NSRect imageFrame = NSMakeRect(0, 0, | 623 NSRect imageFrame = NSMakeRect(0, 0, |
| 616 kNotificationPreferredImageWidth, | 624 kNotificationPreferredImageWidth, |
| 617 kNotificationPreferredImageHeight); | 625 kNotificationPreferredImageHeight); |
| 618 base::scoped_nsobject<NSBox> imageBox( | 626 base::scoped_nsobject<NSBox> imageBox( |
| 619 [[AccessibilityIgnoredBox alloc] initWithFrame:imageFrame]); | 627 [[AccessibilityIgnoredBox alloc] initWithFrame:imageFrame]); |
| 620 [self configureCustomBox:imageBox]; | 628 [self configureCustomBox:imageBox]; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 636 base::scoped_nsobject<NSImageView> imageView( | 644 base::scoped_nsobject<NSImageView> imageView( |
| 637 [[NSImageView alloc] initWithFrame:imageFrame]); | 645 [[NSImageView alloc] initWithFrame:imageFrame]); |
| 638 [imageView setImage:image]; | 646 [imageView setImage:image]; |
| 639 [imageView setImageScaling:NSImageScaleProportionallyUpOrDown]; | 647 [imageView setImageScaling:NSImageScaleProportionallyUpOrDown]; |
| 640 [imageBox setContentView:imageView]; | 648 [imageBox setContentView:imageView]; |
| 641 | 649 |
| 642 return imageBox.autorelease(); | 650 return imageBox.autorelease(); |
| 643 } | 651 } |
| 644 | 652 |
| 645 - (void)configureCloseButtonInFrame:(NSRect)rootFrame { | 653 - (void)configureCloseButtonInFrame:(NSRect)rootFrame { |
| 646 closeButton_.reset([[HoverImageButton alloc] initWithFrame:NSMakeRect( | 654 // The close button is configured to be the same size as the small image. |
| 647 NSMaxX(rootFrame) - message_center::kControlButtonSize, | 655 int closeButtonOriginOffset = |
| 648 NSMaxY(rootFrame) - message_center::kControlButtonSize, | 656 message_center::kSmallImageSize + message_center::kSmallImagePadding; |
| 649 message_center::kControlButtonSize, | 657 NSRect closeButtonFrame = |
| 650 message_center::kControlButtonSize)]); | 658 NSMakeRect(NSMaxX(rootFrame) - closeButtonOriginOffset, |
| 659 NSMaxY(rootFrame) - closeButtonOriginOffset, |
| 660 message_center::kSmallImageSize, |
| 661 message_center::kSmallImageSize); |
| 662 closeButton_.reset([[HoverImageButton alloc] initWithFrame:closeButtonFrame]); |
| 651 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 663 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 652 [closeButton_ setDefaultImage: | 664 [closeButton_ setDefaultImage: |
| 653 rb.GetNativeImageNamed(IDR_NOTIFICATION_CLOSE).ToNSImage()]; | 665 rb.GetNativeImageNamed(IDR_NOTIFICATION_CLOSE).ToNSImage()]; |
| 654 [closeButton_ setHoverImage: | 666 [closeButton_ setHoverImage: |
| 655 rb.GetNativeImageNamed(IDR_NOTIFICATION_CLOSE_HOVER).ToNSImage()]; | 667 rb.GetNativeImageNamed(IDR_NOTIFICATION_CLOSE_HOVER).ToNSImage()]; |
| 656 [closeButton_ setPressedImage: | 668 [closeButton_ setPressedImage: |
| 657 rb.GetNativeImageNamed(IDR_NOTIFICATION_CLOSE_PRESSED).ToNSImage()]; | 669 rb.GetNativeImageNamed(IDR_NOTIFICATION_CLOSE_PRESSED).ToNSImage()]; |
| 658 [[closeButton_ cell] setHighlightsBy:NSOnState]; | 670 [[closeButton_ cell] setHighlightsBy:NSOnState]; |
| 659 [closeButton_ setTrackingEnabled:YES]; | 671 [closeButton_ setTrackingEnabled:YES]; |
| 660 [closeButton_ setBordered:NO]; | 672 [closeButton_ setBordered:NO]; |
| 661 [closeButton_ setAutoresizingMask:NSViewMinYMargin]; | 673 [closeButton_ setAutoresizingMask:NSViewMinYMargin]; |
| 662 [closeButton_ setTarget:self]; | 674 [closeButton_ setTarget:self]; |
| 663 [closeButton_ setAction:@selector(close:)]; | 675 [closeButton_ setAction:@selector(close:)]; |
| 664 [[closeButton_ cell] | 676 [[closeButton_ cell] |
| 665 accessibilitySetOverrideValue:NSAccessibilityCloseButtonSubrole | 677 accessibilitySetOverrideValue:NSAccessibilityCloseButtonSubrole |
| 666 forAttribute:NSAccessibilitySubroleAttribute]; | 678 forAttribute:NSAccessibilitySubroleAttribute]; |
| 667 [[closeButton_ cell] | 679 [[closeButton_ cell] |
| 668 accessibilitySetOverrideValue: | 680 accessibilitySetOverrideValue: |
| 669 l10n_util::GetNSString(IDS_APP_ACCNAME_CLOSE) | 681 l10n_util::GetNSString(IDS_APP_ACCNAME_CLOSE) |
| 670 forAttribute:NSAccessibilityTitleAttribute]; | 682 forAttribute:NSAccessibilityTitleAttribute]; |
| 671 } | 683 } |
| 672 | 684 |
| 685 - (void)configureSmallImageInFrame:(NSRect)rootFrame { |
| 686 int smallImageXOffset = |
| 687 message_center::kSmallImagePadding + message_center::kSmallImageSize; |
| 688 NSRect smallImageFrame = |
| 689 NSMakeRect(NSMaxX(rootFrame) - smallImageXOffset, |
| 690 NSMinY(rootFrame) + message_center::kSmallImagePadding, |
| 691 message_center::kSmallImageSize, |
| 692 message_center::kSmallImageSize); |
| 693 smallImage_.reset([[NSImageView alloc] initWithFrame:smallImageFrame]); |
| 694 [smallImage_ setImageScaling:NSImageScaleProportionallyUpOrDown]; |
| 695 [smallImage_ setAutoresizingMask:NSViewMinYMargin]; |
| 696 } |
| 697 |
| 673 - (void)configureTitleInFrame:(NSRect)rootFrame { | 698 - (void)configureTitleInFrame:(NSRect)rootFrame { |
| 674 NSRect frame = [self currentContentRect]; | 699 NSRect frame = [self currentContentRect]; |
| 675 frame.size.height = 0; | 700 frame.size.height = 0; |
| 676 title_.reset([self newLabelWithFrame:frame]); | 701 title_.reset([self newLabelWithFrame:frame]); |
| 677 [title_ setAutoresizingMask:NSViewMinYMargin]; | 702 [title_ setAutoresizingMask:NSViewMinYMargin]; |
| 678 [title_ setTextColor:gfx::SkColorToCalibratedNSColor( | 703 [title_ setTextColor:gfx::SkColorToCalibratedNSColor( |
| 679 message_center::kRegularTextColor)]; | 704 message_center::kRegularTextColor)]; |
| 680 [title_ setFont:[NSFont messageFontOfSize:message_center::kTitleFontSize]]; | 705 [title_ setFont:[NSFont messageFontOfSize:message_center::kTitleFontSize]]; |
| 681 } | 706 } |
| 682 | 707 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 749 if (gfx::GetStringWidth(last, font_list) > width) | 774 if (gfx::GetStringWidth(last, font_list) > width) |
| 750 last = gfx::ElideText(last, font_list, width, gfx::ELIDE_AT_END); | 775 last = gfx::ElideText(last, font_list, width, gfx::ELIDE_AT_END); |
| 751 wrapped.resize(lines - 1); | 776 wrapped.resize(lines - 1); |
| 752 wrapped.push_back(last); | 777 wrapped.push_back(last); |
| 753 } | 778 } |
| 754 | 779 |
| 755 return lines == 1 ? wrapped[0] : JoinString(wrapped, '\n'); | 780 return lines == 1 ? wrapped[0] : JoinString(wrapped, '\n'); |
| 756 } | 781 } |
| 757 | 782 |
| 758 @end | 783 @end |
| OLD | NEW |