| 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/strings/sys_string_conversions.h" | 7 #include "base/strings/sys_string_conversions.h" |
| 8 #include "grit/ui_resources.h" | 8 #include "grit/ui_resources.h" |
| 9 #include "skia/ext/skia_utils_mac.h" | 9 #include "skia/ext/skia_utils_mac.h" |
| 10 #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" | 10 #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" |
| 11 #import "ui/base/cocoa/hover_image_button.h" | 11 #import "ui/base/cocoa/hover_image_button.h" |
| 12 #include "ui/base/resource/resource_bundle.h" | 12 #include "ui/base/resource/resource_bundle.h" |
| 13 #include "ui/message_center/message_center.h" | 13 #include "ui/message_center/message_center.h" |
| 14 #include "ui/message_center/message_center_constants.h" | 14 #include "ui/message_center/message_center_constants.h" |
| 15 #include "ui/message_center/notification.h" | 15 #include "ui/message_center/notification.h" |
| 16 | 16 |
| 17 namespace { | 17 namespace { |
| 18 | 18 |
| 19 // Compensates for padding already provided by UI elements involved. | 19 // Compensates for padding already provided by UI elements involved. |
| 20 const int kTextTopPaddingAdjustment = -6; | 20 const int kTextTopPaddingAdjustment = -6; |
| 21 | 21 |
| 22 } // namespace | 22 } // namespace |
| 23 |
| 23 @interface MCNotificationController (Private) | 24 @interface MCNotificationController (Private) |
| 24 // Configures a NSBox to be borderless, titleless, and otherwise appearance- | 25 // Configures a NSBox to be borderless, titleless, and otherwise appearance- |
| 25 // free. | 26 // free. |
| 26 - (void)configureCustomBox:(NSBox*)box; | 27 - (void)configureCustomBox:(NSBox*)box; |
| 27 | 28 |
| 28 // Initializes the icon_ ivar and returns the view to insert into the hierarchy. | 29 // Initializes the icon_ ivar and returns the view to insert into the hierarchy. |
| 29 - (NSView*)createImageView; | 30 - (NSView*)createImageView; |
| 30 | 31 |
| 31 // Initializes the closeButton_ ivar with the configured button. | 32 // Initializes the closeButton_ ivar with the configured button. |
| 32 - (void)configureCloseButtonInFrame:(NSRect)rootFrame; | 33 - (void)configureCloseButtonInFrame:(NSRect)rootFrame; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 74 | 75 |
| 75 // Create the close button. | 76 // Create the close button. |
| 76 [self configureCloseButtonInFrame:rootFrame]; | 77 [self configureCloseButtonInFrame:rootFrame]; |
| 77 [rootView addSubview:closeButton_]; | 78 [rootView addSubview:closeButton_]; |
| 78 | 79 |
| 79 // Create the title. | 80 // Create the title. |
| 80 [self configureTitleInFrame:rootFrame]; | 81 [self configureTitleInFrame:rootFrame]; |
| 81 [rootView addSubview:title_]; | 82 [rootView addSubview:title_]; |
| 82 | 83 |
| 83 // Create the message body. | 84 // Create the message body. |
| 84 [self configureBodyInFrame:rootFrame maxY:NSMinY([title_ frame])]; | 85 [self configureBodyInFrame:rootFrame]; |
| 85 [rootView addSubview:message_]; | 86 [rootView addSubview:message_]; |
| 86 | 87 |
| 88 // Populate the data. |
| 89 [self updateNotification:notification_]; |
| 90 } |
| 91 |
| 92 - (NSRect)updateNotification:(const message_center::Notification*)notification { |
| 93 DCHECK_EQ(notification->id(), notificationID_); |
| 94 notification_ = notification; |
| 95 |
| 96 NSRect rootFrame = NSMakeRect(0, 0, |
| 97 message_center::kNotificationPreferredImageSize, |
| 98 message_center::kNotificationIconSize); |
| 99 |
| 100 // Update the icon. |
| 101 [icon_ setImage:notification_->icon().AsNSImage()]; |
| 102 |
| 103 // Set the title and recalculate the frame. |
| 104 [title_ setStringValue:base::SysUTF16ToNSString(notification_->title())]; |
| 105 [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:title_]; |
| 106 NSRect titleFrame = [title_ frame]; |
| 107 titleFrame.origin.y = NSMaxY(rootFrame) - message_center::kTextTopPadding - |
| 108 NSHeight(titleFrame); |
| 109 |
| 110 // Set the message and recalculate the frame. |
| 111 [message_ setStringValue:base::SysUTF16ToNSString(notification_->message())]; |
| 112 [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:message_]; |
| 113 NSRect messageFrame = [message_ frame]; |
| 114 messageFrame.origin.y = NSMinY(titleFrame) - message_center::kTextTopPadding - |
| 115 NSHeight(messageFrame); |
| 116 messageFrame.size.height = NSHeight([message_ frame]); |
| 117 |
| 87 // In this basic notification UI, the message body is the bottom-most | 118 // In this basic notification UI, the message body is the bottom-most |
| 88 // vertical element. If it is out of the rootView's bounds, resize the view. | 119 // vertical element. If it is out of the rootView's bounds, resize the view. |
| 89 if (NSMinY([message_ frame]) < | 120 if (NSMinY(messageFrame) < |
| 90 message_center::kTextTopPadding + kTextTopPaddingAdjustment) { | 121 message_center::kTextTopPadding + kTextTopPaddingAdjustment) { |
| 91 rootFrame.size.height += message_center::kTextTopPadding + | 122 CGFloat delta = message_center::kTextTopPadding + |
| 92 kTextTopPaddingAdjustment - | 123 kTextTopPaddingAdjustment - NSMinY(messageFrame); |
| 93 NSMinY([message_ frame]); | 124 rootFrame.size.height += delta; |
| 125 titleFrame.origin.y += delta; |
| 126 messageFrame.origin.y += delta; |
| 94 } | 127 } |
| 95 | 128 |
| 96 [rootView setFrame:rootFrame]; | 129 [[self view] setFrame:rootFrame]; |
| 130 [title_ setFrame:titleFrame]; |
| 131 [message_ setFrame:messageFrame]; |
| 132 |
| 133 return rootFrame; |
| 97 } | 134 } |
| 98 | 135 |
| 99 - (void)close:(id)sender { | 136 - (void)close:(id)sender { |
| 100 messageCenter_->RemoveNotification(notification_->id(), /*by_user=*/true); | 137 messageCenter_->RemoveNotification(notification_->id(), /*by_user=*/true); |
| 101 } | 138 } |
| 102 | 139 |
| 103 - (const message_center::Notification*)notification { | 140 - (const message_center::Notification*)notification { |
| 104 return notification_; | 141 return notification_; |
| 105 } | 142 } |
| 106 | 143 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 124 message_center::kNotificationIconSize, | 161 message_center::kNotificationIconSize, |
| 125 message_center::kNotificationIconSize); | 162 message_center::kNotificationIconSize); |
| 126 scoped_nsobject<NSBox> imageBox([[NSBox alloc] initWithFrame:imageFrame]); | 163 scoped_nsobject<NSBox> imageBox([[NSBox alloc] initWithFrame:imageFrame]); |
| 127 [self configureCustomBox:imageBox]; | 164 [self configureCustomBox:imageBox]; |
| 128 [imageBox setFillColor:gfx::SkColorToCalibratedNSColor( | 165 [imageBox setFillColor:gfx::SkColorToCalibratedNSColor( |
| 129 message_center::kLegacyIconBackgroundColor)]; | 166 message_center::kLegacyIconBackgroundColor)]; |
| 130 [imageBox setAutoresizingMask:NSViewMinYMargin]; | 167 [imageBox setAutoresizingMask:NSViewMinYMargin]; |
| 131 | 168 |
| 132 // Inside the image box put the actual icon view. | 169 // Inside the image box put the actual icon view. |
| 133 icon_.reset([[NSImageView alloc] initWithFrame:imageFrame]); | 170 icon_.reset([[NSImageView alloc] initWithFrame:imageFrame]); |
| 134 [icon_ setImage:notification_->icon().AsNSImage()]; | |
| 135 [imageBox setContentView:icon_]; | 171 [imageBox setContentView:icon_]; |
| 136 | 172 |
| 137 return imageBox.autorelease(); | 173 return imageBox.autorelease(); |
| 138 } | 174 } |
| 139 | 175 |
| 140 - (void)configureCloseButtonInFrame:(NSRect)rootFrame { | 176 - (void)configureCloseButtonInFrame:(NSRect)rootFrame { |
| 141 closeButton_.reset([[HoverImageButton alloc] initWithFrame:NSMakeRect( | 177 closeButton_.reset([[HoverImageButton alloc] initWithFrame:NSMakeRect( |
| 142 NSMaxX(rootFrame) - message_center::kControlButtonSize, | 178 NSMaxX(rootFrame) - message_center::kControlButtonSize, |
| 143 NSMaxY(rootFrame) - message_center::kControlButtonSize, | 179 NSMaxY(rootFrame) - message_center::kControlButtonSize, |
| 144 message_center::kControlButtonSize, | 180 message_center::kControlButtonSize, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 156 [[closeButton_ cell] setHighlightsBy:NSOnState]; | 192 [[closeButton_ cell] setHighlightsBy:NSOnState]; |
| 157 [closeButton_ setTrackingEnabled:YES]; | 193 [closeButton_ setTrackingEnabled:YES]; |
| 158 [closeButton_ setBordered:NO]; | 194 [closeButton_ setBordered:NO]; |
| 159 [closeButton_ setAutoresizingMask:NSViewMinYMargin]; | 195 [closeButton_ setAutoresizingMask:NSViewMinYMargin]; |
| 160 [closeButton_ setTarget:self]; | 196 [closeButton_ setTarget:self]; |
| 161 [closeButton_ setAction:@selector(close:)]; | 197 [closeButton_ setAction:@selector(close:)]; |
| 162 } | 198 } |
| 163 | 199 |
| 164 - (void)configureTitleInFrame:(NSRect)rootFrame { | 200 - (void)configureTitleInFrame:(NSRect)rootFrame { |
| 165 NSRect frame = [self currentContentRect]; | 201 NSRect frame = [self currentContentRect]; |
| 166 | 202 frame.size.height = 0; |
| 167 title_.reset([self newLabelWithFrame:NSMakeRect(0, 0, NSWidth(frame), 0)]); | 203 title_.reset([self newLabelWithFrame:frame]); |
| 168 [title_ setAutoresizingMask:NSViewMinYMargin]; | 204 [title_ setAutoresizingMask:NSViewMinYMargin]; |
| 169 [title_ setStringValue:base::SysUTF16ToNSString(notification_->title())]; | |
| 170 [title_ setFont:[NSFont messageFontOfSize:message_center::kTitleFontSize]]; | 205 [title_ setFont:[NSFont messageFontOfSize:message_center::kTitleFontSize]]; |
| 171 | |
| 172 CGFloat delta = | |
| 173 [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:title_]; | |
| 174 frame.size.height = delta; | |
| 175 frame.origin.y = NSMaxY(rootFrame) - message_center::kTextTopPadding + | |
| 176 kTextTopPaddingAdjustment - delta; | |
| 177 [title_ setFrame:frame]; | |
| 178 } | 206 } |
| 179 | 207 |
| 180 - (void)configureBodyInFrame:(NSRect)rootFrame maxY:(CGFloat)maxY { | 208 - (void)configureBodyInFrame:(NSRect)rootFrame { |
| 181 NSRect frame = [self currentContentRect]; | 209 NSRect frame = [self currentContentRect]; |
| 182 | 210 frame.size.height = 0; |
| 183 message_.reset([self newLabelWithFrame:NSMakeRect(0, 0, NSWidth(frame), 0)]); | 211 message_.reset([self newLabelWithFrame:frame]); |
| 184 [message_ setAutoresizingMask:NSViewMinYMargin]; | 212 [message_ setAutoresizingMask:NSViewMinYMargin]; |
| 185 [message_ setStringValue:base::SysUTF16ToNSString(notification_->message())]; | |
| 186 [message_ setFont: | 213 [message_ setFont: |
| 187 [NSFont messageFontOfSize:message_center::kMessageFontSize]]; | 214 [NSFont messageFontOfSize:message_center::kMessageFontSize]]; |
| 188 | |
| 189 CGFloat delta = | |
| 190 [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:message_]; | |
| 191 frame.size.height = delta; | |
| 192 frame.origin.y = maxY - message_center::kTextTopPadding + | |
| 193 kTextTopPaddingAdjustment - delta; | |
| 194 [message_ setFrame:frame]; | |
| 195 } | 215 } |
| 196 | 216 |
| 197 - (NSTextField*)newLabelWithFrame:(NSRect)frame { | 217 - (NSTextField*)newLabelWithFrame:(NSRect)frame { |
| 198 NSTextField* label = [[NSTextField alloc] initWithFrame:frame]; | 218 NSTextField* label = [[NSTextField alloc] initWithFrame:frame]; |
| 199 [label setDrawsBackground:NO]; | 219 [label setDrawsBackground:NO]; |
| 200 [label setBezeled:NO]; | 220 [label setBezeled:NO]; |
| 201 [label setEditable:NO]; | 221 [label setEditable:NO]; |
| 202 [label setSelectable:NO]; | 222 [label setSelectable:NO]; |
| 203 [label setTextColor:gfx::SkColorToCalibratedNSColor( | 223 [label setTextColor:gfx::SkColorToCalibratedNSColor( |
| 204 message_center::kRegularTextColor)]; | 224 message_center::kRegularTextColor)]; |
| 205 return label; | 225 return label; |
| 206 } | 226 } |
| 207 | 227 |
| 208 - (NSRect)currentContentRect { | 228 - (NSRect)currentContentRect { |
| 209 DCHECK(icon_); | 229 DCHECK(icon_); |
| 210 DCHECK(closeButton_); | 230 DCHECK(closeButton_); |
| 211 | 231 |
| 212 NSRect iconFrame, contentFrame; | 232 NSRect iconFrame, contentFrame; |
| 213 NSDivideRect([[self view] bounds], &iconFrame, &contentFrame, | 233 NSDivideRect([[self view] bounds], &iconFrame, &contentFrame, |
| 214 NSWidth([icon_ frame]) + message_center::kIconToTextPadding, | 234 NSWidth([icon_ frame]) + message_center::kIconToTextPadding, |
| 215 NSMinXEdge); | 235 NSMinXEdge); |
| 216 contentFrame.size.width -= NSWidth([closeButton_ frame]); | 236 contentFrame.size.width -= NSWidth([closeButton_ frame]); |
| 217 return contentFrame; | 237 return contentFrame; |
| 218 } | 238 } |
| 219 | 239 |
| 220 @end | 240 @end |
| OLD | NEW |