| 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 | 
|---|