| 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 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 @end | 189 @end |
| 190 | 190 |
| 191 //////////////////////////////////////////////////////////////////////////////// | 191 //////////////////////////////////////////////////////////////////////////////// |
| 192 | 192 |
| 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*)createImageView; | 199 - (NSView*)createIconView; |
| 200 |
| 201 // Creates a box that shows a border when the icon is not big enough to fill the |
| 202 // space. |
| 203 - (NSBox*)createImageBox; |
| 200 | 204 |
| 201 // Initializes the closeButton_ ivar with the configured button. | 205 // Initializes the closeButton_ ivar with the configured button. |
| 202 - (void)configureCloseButtonInFrame:(NSRect)rootFrame; | 206 - (void)configureCloseButtonInFrame:(NSRect)rootFrame; |
| 203 | 207 |
| 204 // Initializes title_ in the given frame. | 208 // Initializes title_ in the given frame. |
| 205 - (void)configureTitleInFrame:(NSRect)rootFrame; | 209 - (void)configureTitleInFrame:(NSRect)rootFrame; |
| 206 | 210 |
| 207 // Initializes message_ in the given frame. | 211 // Initializes message_ in the given frame. |
| 208 - (void)configureBodyInFrame:(NSRect)rootFrame; | 212 - (void)configureBodyInFrame:(NSRect)rootFrame; |
| 209 | 213 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 238 notification_ = notification; | 242 notification_ = notification; |
| 239 notificationID_ = notification_->id(); | 243 notificationID_ = notification_->id(); |
| 240 messageCenter_ = messageCenter; | 244 messageCenter_ = messageCenter; |
| 241 } | 245 } |
| 242 return self; | 246 return self; |
| 243 } | 247 } |
| 244 | 248 |
| 245 - (void)loadView { | 249 - (void)loadView { |
| 246 // Create the root view of the notification. | 250 // Create the root view of the notification. |
| 247 NSRect rootFrame = NSMakeRect(0, 0, | 251 NSRect rootFrame = NSMakeRect(0, 0, |
| 248 message_center::kNotificationPreferredImageSize, | 252 message_center::kNotificationPreferredImageWidth, |
| 249 message_center::kNotificationIconSize); | 253 message_center::kNotificationIconSize); |
| 250 base::scoped_nsobject<MCNotificationView> rootView( | 254 base::scoped_nsobject<MCNotificationView> rootView( |
| 251 [[MCNotificationView alloc] initWithController:self frame:rootFrame]); | 255 [[MCNotificationView alloc] initWithController:self frame:rootFrame]); |
| 252 [self configureCustomBox:rootView]; | 256 [self configureCustomBox:rootView]; |
| 253 [rootView setFillColor:gfx::SkColorToCalibratedNSColor( | 257 [rootView setFillColor:gfx::SkColorToCalibratedNSColor( |
| 254 message_center::kNotificationBackgroundColor)]; | 258 message_center::kNotificationBackgroundColor)]; |
| 255 [self setView:rootView]; | 259 [self setView:rootView]; |
| 256 | 260 |
| 257 [rootView addSubview:[self createImageView]]; | 261 [rootView addSubview:[self createIconView]]; |
| 258 | 262 |
| 259 // Create the close button. | 263 // Create the close button. |
| 260 [self configureCloseButtonInFrame:rootFrame]; | 264 [self configureCloseButtonInFrame:rootFrame]; |
| 261 [rootView addSubview:closeButton_]; | 265 [rootView addSubview:closeButton_]; |
| 262 | 266 |
| 263 // Create the title. | 267 // Create the title. |
| 264 [self configureTitleInFrame:rootFrame]; | 268 [self configureTitleInFrame:rootFrame]; |
| 265 [rootView addSubview:title_]; | 269 [rootView addSubview:title_]; |
| 266 | 270 |
| 267 // Create the message body. | 271 // Create the message body. |
| 268 [self configureBodyInFrame:rootFrame]; | 272 [self configureBodyInFrame:rootFrame]; |
| 269 [rootView addSubview:message_]; | 273 [rootView addSubview:message_]; |
| 270 | 274 |
| 271 // Create the context message body. | 275 // Create the context message body. |
| 272 [self configureContextMessageInFrame:rootFrame]; | 276 [self configureContextMessageInFrame:rootFrame]; |
| 273 [rootView addSubview:contextMessage_]; | 277 [rootView addSubview:contextMessage_]; |
| 274 | 278 |
| 275 // Populate the data. | 279 // Populate the data. |
| 276 [self updateNotification:notification_]; | 280 [self updateNotification:notification_]; |
| 277 } | 281 } |
| 278 | 282 |
| 279 - (NSRect)updateNotification:(const message_center::Notification*)notification { | 283 - (NSRect)updateNotification:(const message_center::Notification*)notification { |
| 280 DCHECK_EQ(notification->id(), notificationID_); | 284 DCHECK_EQ(notification->id(), notificationID_); |
| 281 notification_ = notification; | 285 notification_ = notification; |
| 282 | 286 |
| 283 NSRect rootFrame = NSMakeRect(0, 0, | 287 NSRect rootFrame = NSMakeRect(0, 0, |
| 284 message_center::kNotificationPreferredImageSize, | 288 message_center::kNotificationPreferredImageWidth, |
| 285 message_center::kNotificationIconSize); | 289 message_center::kNotificationIconSize); |
| 286 | 290 |
| 287 // Update the icon. | 291 // Update the icon. |
| 288 [icon_ setImage:notification_->icon().AsNSImage()]; | 292 [icon_ setImage:notification_->icon().AsNSImage()]; |
| 289 | 293 |
| 290 // The message_center:: constants are relative to capHeight at the top and | 294 // The message_center:: constants are relative to capHeight at the top and |
| 291 // relative to the baseline at the bottom, but NSTextField uses the full line | 295 // relative to the baseline at the bottom, but NSTextField uses the full line |
| 292 // height for its height. | 296 // height for its height. |
| 293 CGFloat titleTopGap = | 297 CGFloat titleTopGap = |
| 294 roundf([[title_ font] ascender] - [[title_ font] capHeight]); | 298 roundf([[title_ font] ascender] - [[title_ font] capHeight]); |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 498 [[AccessibilityIgnoredBox alloc] initWithFrame:separatorFrame]); | 502 [[AccessibilityIgnoredBox alloc] initWithFrame:separatorFrame]); |
| 499 [self configureCustomBox:separator]; | 503 [self configureCustomBox:separator]; |
| 500 [separator setFillColor:gfx::SkColorToCalibratedNSColor( | 504 [separator setFillColor:gfx::SkColorToCalibratedNSColor( |
| 501 message_center::kButtonSeparatorColor)]; | 505 message_center::kButtonSeparatorColor)]; |
| 502 y += NSHeight(separatorFrame); | 506 y += NSHeight(separatorFrame); |
| 503 frame.size.height += NSHeight(separatorFrame); | 507 frame.size.height += NSHeight(separatorFrame); |
| 504 [bottomView_ addSubview:separator]; | 508 [bottomView_ addSubview:separator]; |
| 505 } | 509 } |
| 506 | 510 |
| 507 // Create the image view if appropriate. | 511 // Create the image view if appropriate. |
| 508 if (!notification->image().IsEmpty()) { | 512 gfx::Image notificationImage = notification->image(); |
| 509 NSImage* image = notification->image().AsNSImage(); | 513 if (!notificationImage.IsEmpty()) { |
| 510 NSRect imageFrame = frame; | 514 NSBox* imageBox = [self createImageBox:notificationImage]; |
| 511 imageFrame.origin = NSMakePoint(0, y); | 515 NSRect outerFrame = frame; |
| 512 imageFrame.size = NSSizeFromCGSize(message_center::GetImageSizeForWidth( | 516 outerFrame.origin = NSMakePoint(0, y); |
| 513 NSWidth(frame), notification->image().Size()).ToCGSize()); | 517 outerFrame.size = [imageBox frame].size; |
| 514 base::scoped_nsobject<NSImageView> imageView( | 518 [imageBox setFrame:outerFrame]; |
| 515 [[NSImageView alloc] initWithFrame:imageFrame]); | 519 |
| 516 [imageView setImage:image]; | 520 y += NSHeight(outerFrame); |
| 517 [imageView setImageScaling:NSImageScaleProportionallyUpOrDown]; | 521 frame.size.height += NSHeight(outerFrame); |
| 518 y += NSHeight(imageFrame); | 522 |
| 519 frame.size.height += NSHeight(imageFrame); | 523 [bottomView_ addSubview:imageBox]; |
| 520 [bottomView_ addSubview:imageView]; | |
| 521 } | 524 } |
| 522 | 525 |
| 523 [bottomView_ setFrame:frame]; | 526 [bottomView_ setFrame:frame]; |
| 524 [[self view] addSubview:bottomView_]; | 527 [[self view] addSubview:bottomView_]; |
| 525 | 528 |
| 526 rootFrame.size.height += NSHeight(frame); | 529 rootFrame.size.height += NSHeight(frame); |
| 527 titleFrame.origin.y += NSHeight(frame); | 530 titleFrame.origin.y += NSHeight(frame); |
| 528 messageFrame.origin.y += NSHeight(frame); | 531 messageFrame.origin.y += NSHeight(frame); |
| 529 contextMessageFrame.origin.y += NSHeight(frame); | 532 contextMessageFrame.origin.y += NSHeight(frame); |
| 530 listFrame.origin.y += NSHeight(frame); | 533 listFrame.origin.y += NSHeight(frame); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 577 | 580 |
| 578 // Private ///////////////////////////////////////////////////////////////////// | 581 // Private ///////////////////////////////////////////////////////////////////// |
| 579 | 582 |
| 580 - (void)configureCustomBox:(NSBox*)box { | 583 - (void)configureCustomBox:(NSBox*)box { |
| 581 [box setBoxType:NSBoxCustom]; | 584 [box setBoxType:NSBoxCustom]; |
| 582 [box setBorderType:NSNoBorder]; | 585 [box setBorderType:NSNoBorder]; |
| 583 [box setTitlePosition:NSNoTitle]; | 586 [box setTitlePosition:NSNoTitle]; |
| 584 [box setContentViewMargins:NSZeroSize]; | 587 [box setContentViewMargins:NSZeroSize]; |
| 585 } | 588 } |
| 586 | 589 |
| 587 - (NSView*)createImageView { | 590 - (NSView*)createIconView { |
| 588 // Create another box that shows a background color when the icon is not | 591 // Create another box that shows a background color when the icon is not |
| 589 // big enough to fill the space. | 592 // big enough to fill the space. |
| 590 NSRect imageFrame = NSMakeRect(0, 0, | 593 NSRect imageFrame = NSMakeRect(0, 0, |
| 591 message_center::kNotificationIconSize, | 594 message_center::kNotificationIconSize, |
| 592 message_center::kNotificationIconSize); | 595 message_center::kNotificationIconSize); |
| 593 base::scoped_nsobject<NSBox> imageBox( | 596 base::scoped_nsobject<NSBox> imageBox( |
| 594 [[AccessibilityIgnoredBox alloc] initWithFrame:imageFrame]); | 597 [[AccessibilityIgnoredBox alloc] initWithFrame:imageFrame]); |
| 595 [self configureCustomBox:imageBox]; | 598 [self configureCustomBox:imageBox]; |
| 596 [imageBox setFillColor:gfx::SkColorToCalibratedNSColor( | 599 [imageBox setFillColor:gfx::SkColorToCalibratedNSColor( |
| 597 message_center::kIconBackgroundColor)]; | 600 message_center::kIconBackgroundColor)]; |
| 598 [imageBox setAutoresizingMask:NSViewMinYMargin]; | 601 [imageBox setAutoresizingMask:NSViewMinYMargin]; |
| 599 | 602 |
| 600 // Inside the image box put the actual icon view. | 603 // Inside the image box put the actual icon view. |
| 601 icon_.reset([[NSImageView alloc] initWithFrame:imageFrame]); | 604 icon_.reset([[NSImageView alloc] initWithFrame:imageFrame]); |
| 602 [imageBox setContentView:icon_]; | 605 [imageBox setContentView:icon_]; |
| 603 | 606 |
| 604 return imageBox.autorelease(); | 607 return imageBox.autorelease(); |
| 605 } | 608 } |
| 606 | 609 |
| 610 - (NSBox*)createImageBox:(gfx::Image)notificationImage { |
| 611 using message_center::kNotificationImageBorderSize; |
| 612 using message_center::kNotificationPreferredImageWidth; |
| 613 using message_center::kNotificationPreferredImageHeight; |
| 614 |
| 615 NSRect imageFrame = NSMakeRect(0, 0, |
| 616 kNotificationPreferredImageWidth, |
| 617 kNotificationPreferredImageHeight); |
| 618 base::scoped_nsobject<NSBox> imageBox( |
| 619 [[AccessibilityIgnoredBox alloc] initWithFrame:imageFrame]); |
| 620 [self configureCustomBox:imageBox]; |
| 621 [imageBox setFillColor:gfx::SkColorToCalibratedNSColor( |
| 622 message_center::kImageBackgroundColor)]; |
| 623 |
| 624 // Images with non-preferred aspect ratios get a border on all sides. |
| 625 gfx::Size idealSize = gfx::Size( |
| 626 kNotificationPreferredImageWidth, kNotificationPreferredImageHeight); |
| 627 gfx::Size scaledSize = message_center::GetImageSizeForWidth( |
| 628 kNotificationPreferredImageWidth, notificationImage.Size()); |
| 629 if (scaledSize != idealSize) { |
| 630 NSSize borderSize = |
| 631 NSMakeSize(kNotificationImageBorderSize, kNotificationImageBorderSize); |
| 632 [imageBox setContentViewMargins:borderSize]; |
| 633 } |
| 634 |
| 635 NSImage* image = notificationImage.AsNSImage(); |
| 636 base::scoped_nsobject<NSImageView> imageView( |
| 637 [[NSImageView alloc] initWithFrame:imageFrame]); |
| 638 [imageView setImage:image]; |
| 639 [imageView setImageScaling:NSImageScaleProportionallyUpOrDown]; |
| 640 [imageBox setContentView:imageView]; |
| 641 |
| 642 return imageBox.autorelease(); |
| 643 } |
| 644 |
| 607 - (void)configureCloseButtonInFrame:(NSRect)rootFrame { | 645 - (void)configureCloseButtonInFrame:(NSRect)rootFrame { |
| 608 closeButton_.reset([[HoverImageButton alloc] initWithFrame:NSMakeRect( | 646 closeButton_.reset([[HoverImageButton alloc] initWithFrame:NSMakeRect( |
| 609 NSMaxX(rootFrame) - message_center::kControlButtonSize, | 647 NSMaxX(rootFrame) - message_center::kControlButtonSize, |
| 610 NSMaxY(rootFrame) - message_center::kControlButtonSize, | 648 NSMaxY(rootFrame) - message_center::kControlButtonSize, |
| 611 message_center::kControlButtonSize, | 649 message_center::kControlButtonSize, |
| 612 message_center::kControlButtonSize)]); | 650 message_center::kControlButtonSize)]); |
| 613 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 651 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 614 [closeButton_ setDefaultImage: | 652 [closeButton_ setDefaultImage: |
| 615 rb.GetNativeImageNamed(IDR_NOTIFICATION_CLOSE).ToNSImage()]; | 653 rb.GetNativeImageNamed(IDR_NOTIFICATION_CLOSE).ToNSImage()]; |
| 616 [closeButton_ setHoverImage: | 654 [closeButton_ setHoverImage: |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 710 if (gfx::GetStringWidth(last, font_list) > width) | 748 if (gfx::GetStringWidth(last, font_list) > width) |
| 711 last = gfx::ElideText(last, font_list, width, gfx::ELIDE_AT_END); | 749 last = gfx::ElideText(last, font_list, width, gfx::ELIDE_AT_END); |
| 712 wrapped.resize(lines - 1); | 750 wrapped.resize(lines - 1); |
| 713 wrapped.push_back(last); | 751 wrapped.push_back(last); |
| 714 } | 752 } |
| 715 | 753 |
| 716 return lines == 1 ? wrapped[0] : JoinString(wrapped, '\n'); | 754 return lines == 1 ? wrapped[0] : JoinString(wrapped, '\n'); |
| 717 } | 755 } |
| 718 | 756 |
| 719 @end | 757 @end |
| OLD | NEW |