| OLD | NEW |
| (Empty) |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #import "chrome/browser/ui/cocoa/autofill/autofill_notification_controller.h" | |
| 6 | |
| 7 #include <algorithm> | |
| 8 | |
| 9 #include "base/logging.h" | |
| 10 #include "base/mac/foundation_util.h" | |
| 11 #include "base/mac/scoped_nsobject.h" | |
| 12 #include "base/strings/sys_string_conversions.h" | |
| 13 #include "chrome/browser/ui/autofill/autofill_dialog_types.h" | |
| 14 #include "chrome/browser/ui/autofill/autofill_dialog_view_delegate.h" | |
| 15 #include "chrome/browser/ui/chrome_style.h" | |
| 16 #include "chrome/browser/ui/cocoa/autofill/autofill_dialog_constants.h" | |
| 17 #import "chrome/browser/ui/cocoa/autofill/autofill_tooltip_controller.h" | |
| 18 #include "grit/components_scaled_resources.h" | |
| 19 #include "skia/ext/skia_utils_mac.h" | |
| 20 #import "ui/base/cocoa/controls/hyperlink_text_view.h" | |
| 21 | |
| 22 @interface AutofillNotificationView : NSView { | |
| 23 @private | |
| 24 base::scoped_nsobject<NSColor> backgroundColor_; | |
| 25 base::scoped_nsobject<NSColor> borderColor_; | |
| 26 } | |
| 27 | |
| 28 @property (nonatomic, retain) NSColor* backgroundColor; | |
| 29 @property (nonatomic, retain) NSColor* borderColor; | |
| 30 | |
| 31 @end | |
| 32 | |
| 33 @implementation AutofillNotificationView | |
| 34 | |
| 35 - (void)drawRect:(NSRect)dirtyRect { | |
| 36 [super drawRect:dirtyRect]; | |
| 37 | |
| 38 NSBezierPath* path; | |
| 39 NSRect bounds = [self bounds]; | |
| 40 path = [NSBezierPath bezierPathWithRect:bounds]; | |
| 41 | |
| 42 [backgroundColor_ setFill]; | |
| 43 [path fill]; | |
| 44 [borderColor_ setStroke]; | |
| 45 [path stroke]; | |
| 46 } | |
| 47 | |
| 48 - (NSColor*)backgroundColor { | |
| 49 return backgroundColor_; | |
| 50 } | |
| 51 | |
| 52 - (void)setBackgroundColor:(NSColor*)backgroundColor { | |
| 53 backgroundColor_.reset([backgroundColor retain]); | |
| 54 } | |
| 55 | |
| 56 - (NSColor*)borderColor { | |
| 57 return borderColor_; | |
| 58 } | |
| 59 | |
| 60 - (void)setBorderColor:(NSColor*)borderColor { | |
| 61 borderColor_.reset([borderColor retain]); | |
| 62 } | |
| 63 | |
| 64 @end | |
| 65 | |
| 66 @implementation AutofillNotificationController | |
| 67 | |
| 68 - (id)initWithNotification:(const autofill::DialogNotification*)notification | |
| 69 delegate:(autofill::AutofillDialogViewDelegate*)delegate { | |
| 70 if (self = [super init]) { | |
| 71 delegate_ = delegate; | |
| 72 notificationType_ = notification->type(); | |
| 73 | |
| 74 base::scoped_nsobject<AutofillNotificationView> view( | |
| 75 [[AutofillNotificationView alloc] initWithFrame:NSZeroRect]); | |
| 76 [view setBackgroundColor: | |
| 77 skia::SkColorToCalibratedNSColor(notification->GetBackgroundColor())]; | |
| 78 [view setBorderColor: | |
| 79 skia::SkColorToCalibratedNSColor(notification->GetBorderColor())]; | |
| 80 [self setView:view]; | |
| 81 | |
| 82 textview_.reset([[HyperlinkTextView alloc] initWithFrame:NSZeroRect]); | |
| 83 NSColor* textColor = | |
| 84 skia::SkColorToCalibratedNSColor(notification->GetTextColor()); | |
| 85 [textview_ setMessage:base::SysUTF16ToNSString(notification->display_text()) | |
| 86 withFont:[NSFont labelFontOfSize:[[textview_ font] pointSize]] | |
| 87 messageColor:textColor]; | |
| 88 if (!notification->link_range().is_empty()) { | |
| 89 linkURL_ = notification->link_url(); | |
| 90 [textview_ setDelegate:self]; | |
| 91 [textview_ addLinkRange:notification->link_range().ToNSRange() | |
| 92 withURL:base::SysUTF8ToNSString(linkURL_.spec()) | |
| 93 linkColor:[NSColor blueColor]]; | |
| 94 } | |
| 95 | |
| 96 tooltipController_.reset([[AutofillTooltipController alloc] | |
| 97 initWithArrowLocation:info_bubble::kTopRight]); | |
| 98 [tooltipController_ setImage: | |
| 99 ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed( | |
| 100 IDR_AUTOFILL_TOOLTIP_ICON).ToNSImage()]; | |
| 101 [tooltipController_ setMessage: | |
| 102 base::SysUTF16ToNSString(notification->tooltip_text())]; | |
| 103 [[tooltipController_ view] setHidden: | |
| 104 [[tooltipController_ message] length] == 0]; | |
| 105 | |
| 106 [view setSubviews:@[ textview_, [tooltipController_ view] ]]; | |
| 107 } | |
| 108 return self; | |
| 109 } | |
| 110 | |
| 111 - (AutofillNotificationView*)notificationView { | |
| 112 return base::mac::ObjCCastStrict<AutofillNotificationView>([self view]); | |
| 113 } | |
| 114 | |
| 115 - (NSTextView*)textview { | |
| 116 return textview_; | |
| 117 } | |
| 118 | |
| 119 - (NSView*)tooltipView { | |
| 120 return [tooltipController_ view]; | |
| 121 } | |
| 122 | |
| 123 - (NSSize)preferredSizeForWidth:(CGFloat)width { | |
| 124 width -= 2 * chrome_style::kHorizontalPadding; | |
| 125 if (![[tooltipController_ view] isHidden]) { | |
| 126 width -= NSWidth([[tooltipController_ view] frame]) + | |
| 127 chrome_style::kHorizontalPadding; | |
| 128 } | |
| 129 // TODO(isherman): Restore the DCHECK below once I figure out why it causes | |
| 130 // unit tests to fail. | |
| 131 //DCHECK_GT(width, 0); | |
| 132 | |
| 133 NSSize preferredSize; | |
| 134 // This method is logically const. Hence, cache the original frame so that | |
| 135 // it can be restored once the preferred size has been computed. | |
| 136 NSRect frame = [textview_ frame]; | |
| 137 | |
| 138 // Compute preferred size. | |
| 139 [textview_ setFrameSize:NSMakeSize(width, frame.size.height)]; | |
| 140 [textview_ setVerticallyResizable:YES]; | |
| 141 [textview_ sizeToFit]; | |
| 142 preferredSize = [textview_ frame].size; | |
| 143 | |
| 144 // Restore original properties, since this method is logically const. | |
| 145 [textview_ setFrame:frame]; | |
| 146 [textview_ setVerticallyResizable:NO]; | |
| 147 | |
| 148 preferredSize.height += 2 * autofill::kNotificationPadding; | |
| 149 return preferredSize; | |
| 150 } | |
| 151 | |
| 152 - (NSSize)preferredSize { | |
| 153 NOTREACHED(); | |
| 154 return NSZeroSize; | |
| 155 } | |
| 156 | |
| 157 - (void)performLayout { | |
| 158 NSRect bounds = [[self view] bounds]; | |
| 159 // Calculate the frame size, leaving room for padding around the notification, | |
| 160 // as well as for the tooltip if it is visible. | |
| 161 NSRect labelFrame = NSInsetRect(bounds, | |
| 162 chrome_style::kHorizontalPadding, | |
| 163 autofill::kNotificationPadding); | |
| 164 NSView* tooltipView = [tooltipController_ view]; | |
| 165 if (![tooltipView isHidden]) { | |
| 166 labelFrame.size.width -= | |
| 167 NSWidth([tooltipView frame]) + chrome_style::kHorizontalPadding; | |
| 168 } | |
| 169 | |
| 170 NSView* label = textview_.get(); | |
| 171 [label setFrame:labelFrame]; | |
| 172 | |
| 173 if (![tooltipView isHidden]) { | |
| 174 NSPoint tooltipOrigin = | |
| 175 NSMakePoint( | |
| 176 NSMaxX(labelFrame) + chrome_style::kHorizontalPadding, | |
| 177 NSMidY(labelFrame) - (NSHeight([tooltipView frame]) / 2.0)); | |
| 178 [tooltipView setFrameOrigin:tooltipOrigin]; | |
| 179 } | |
| 180 } | |
| 181 | |
| 182 - (BOOL)textView:(NSTextView *)textView | |
| 183 clickedOnLink:(id)link | |
| 184 atIndex:(NSUInteger)charIndex { | |
| 185 delegate_->LinkClicked(linkURL_); | |
| 186 return YES; | |
| 187 } | |
| 188 | |
| 189 @end | |
| OLD | NEW |