Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.h" | 5 #import "chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.h" |
| 6 | 6 |
| 7 #include "base/strings/sys_string_conversions.h" | 7 #include "base/strings/sys_string_conversions.h" |
| 8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
| 9 #include "chrome/browser/ui/autofill/save_card_bubble_controller.h" | 9 #include "chrome/browser/ui/autofill/save_card_bubble_controller.h" |
| 10 #include "chrome/browser/ui/chrome_style.h" | 10 #include "chrome/browser/ui/chrome_style.h" |
| 11 #import "chrome/browser/ui/cocoa/browser_window_controller.h" | 11 #import "chrome/browser/ui/cocoa/browser_window_controller.h" |
| 12 #import "chrome/browser/ui/cocoa/info_bubble_window.h" | 12 #import "chrome/browser/ui/cocoa/info_bubble_window.h" |
| 13 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h" | 13 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h" |
| 14 #include "grit/components_strings.h" | 14 #include "grit/components_strings.h" |
| 15 #include "skia/ext/skia_utils_mac.h" | 15 #include "skia/ext/skia_utils_mac.h" |
| 16 #import "ui/base/cocoa/controls/hyperlink_text_view.h" | 16 #import "ui/base/cocoa/controls/hyperlink_text_view.h" |
| 17 #import "ui/base/cocoa/window_size_constants.h" | 17 #import "ui/base/cocoa/window_size_constants.h" |
| 18 #include "ui/base/l10n/l10n_util.h" | 18 #include "ui/base/l10n/l10n_util.h" |
| 19 #include "ui/base/resource/resource_bundle.h" | 19 #include "ui/base/resource/resource_bundle.h" |
| 20 | 20 |
| 21 namespace { | 21 namespace { |
| 22 | 22 |
| 23 const CGFloat kDesiredBubbleWidth = 370; | 23 const CGFloat kDesiredBubbleWidth = 370; |
| 24 const CGFloat kDividerHeight = 1; | |
| 24 const CGFloat kFramePadding = 16; | 25 const CGFloat kFramePadding = 16; |
| 25 const CGFloat kRelatedControlHorizontalPadding = 2; | 26 const CGFloat kRelatedControlHorizontalPadding = 2; |
| 27 const CGFloat kRelatedControlVerticalPadding = 5; | |
| 26 const CGFloat kUnrelatedControlVerticalPadding = 15; | 28 const CGFloat kUnrelatedControlVerticalPadding = 15; |
| 27 | 29 |
| 28 const SkColor kIconBorderColor = 0x10000000; // SkColorSetARGB(10, 0, 0, 0); | 30 const SkColor kDividerColor = 0xFFE9E9E9; // SkColorSetRGB(0xE9, 0xE9, 0xE9); |
| 31 const SkColor kFooterColor = 0xFFF5F5F5; // SkColorSetRGB(0xF5, 0xF5, 0xF5); | |
| 32 const SkColor kIconBorderColor = 0x10000000; // SkColorSetARGB(0x10, 0, 0, 0); | |
| 33 | |
| 29 } | 34 } |
| 30 | 35 |
| 31 namespace autofill { | 36 namespace autofill { |
| 32 | 37 |
| 33 #pragma mark SaveCardBubbleViewBridge | 38 #pragma mark SaveCardBubbleViewBridge |
| 34 | 39 |
| 35 SaveCardBubbleViewBridge::SaveCardBubbleViewBridge( | 40 SaveCardBubbleViewBridge::SaveCardBubbleViewBridge( |
| 36 SaveCardBubbleController* controller, | 41 SaveCardBubbleController* controller, |
| 37 BrowserWindowController* browser_window_controller) | 42 BrowserWindowController* browser_window_controller) |
| 38 : controller_(controller) { | 43 : controller_(controller) { |
| 39 view_controller_ = [[SaveCardBubbleViewCocoa alloc] | 44 view_controller_ = [[SaveCardBubbleViewCocoa alloc] |
| 40 initWithBrowserWindowController:browser_window_controller | 45 initWithBrowserWindowController:browser_window_controller |
| 41 bridge:this]; | 46 bridge:this]; |
| 42 DCHECK(view_controller_); | 47 DCHECK(view_controller_); |
| 43 [view_controller_ showWindow:nil]; | 48 [view_controller_ showWindow:nil]; |
| 44 } | 49 } |
| 45 | 50 |
| 46 SaveCardBubbleViewBridge::~SaveCardBubbleViewBridge() {} | 51 SaveCardBubbleViewBridge::~SaveCardBubbleViewBridge() {} |
| 47 | 52 |
| 48 base::string16 SaveCardBubbleViewBridge::GetWindowTitle() const { | 53 base::string16 SaveCardBubbleViewBridge::GetWindowTitle() const { |
| 49 return controller_ ? controller_->GetWindowTitle() : base::string16(); | 54 return controller_ ? controller_->GetWindowTitle() : base::string16(); |
| 50 } | 55 } |
| 51 | 56 |
| 57 base::string16 SaveCardBubbleViewBridge::GetExplanatoryMessage() const { | |
| 58 return controller_ ? controller_->GetExplanatoryMessage() : base::string16(); | |
| 59 } | |
| 60 | |
| 52 CreditCard SaveCardBubbleViewBridge::GetCard() const { | 61 CreditCard SaveCardBubbleViewBridge::GetCard() const { |
| 53 return controller_ ? controller_->GetCard() : CreditCard(); | 62 return controller_ ? controller_->GetCard() : CreditCard(); |
| 54 } | 63 } |
| 55 | 64 |
| 65 const LegalMessageLines SaveCardBubbleViewBridge::GetLegalMessageLines() const { | |
| 66 return controller_ ? controller_->GetLegalMessageLines() | |
| 67 : LegalMessageLines(); | |
| 68 } | |
| 69 | |
| 56 void SaveCardBubbleViewBridge::OnSaveButton() { | 70 void SaveCardBubbleViewBridge::OnSaveButton() { |
| 57 if (controller_) | 71 if (controller_) |
| 58 controller_->OnSaveButton(); | 72 controller_->OnSaveButton(); |
| 59 Hide(); | 73 Hide(); |
| 60 } | 74 } |
| 61 | 75 |
| 62 void SaveCardBubbleViewBridge::OnCancelButton() { | 76 void SaveCardBubbleViewBridge::OnCancelButton() { |
| 63 if (controller_) | 77 if (controller_) |
| 64 controller_->OnCancelButton(); | 78 controller_->OnCancelButton(); |
| 65 Hide(); | 79 Hide(); |
| 66 } | 80 } |
| 67 | 81 |
| 68 void SaveCardBubbleViewBridge::OnLearnMoreClicked() { | 82 void SaveCardBubbleViewBridge::OnLearnMoreClicked() { |
| 69 if (controller_) | 83 if (controller_) |
| 70 controller_->OnLearnMoreClicked(); | 84 controller_->OnLearnMoreClicked(); |
| 71 } | 85 } |
| 72 | 86 |
| 87 void SaveCardBubbleViewBridge::OnLegalMessageLinkClicked(const GURL& url) { | |
| 88 if (controller_) | |
| 89 controller_->OnLegalMessageLinkClicked(url); | |
| 90 } | |
| 91 | |
| 73 void SaveCardBubbleViewBridge::OnBubbleClosed() { | 92 void SaveCardBubbleViewBridge::OnBubbleClosed() { |
| 74 if (controller_) | 93 if (controller_) |
| 75 controller_->OnBubbleClosed(); | 94 controller_->OnBubbleClosed(); |
| 76 | 95 |
| 77 delete this; | 96 delete this; |
| 78 } | 97 } |
| 79 | 98 |
| 80 void SaveCardBubbleViewBridge::Hide() { | 99 void SaveCardBubbleViewBridge::Hide() { |
| 81 // SaveCardBubbleViewBridge::OnBubbleClosed won't be able to call | 100 // SaveCardBubbleViewBridge::OnBubbleClosed won't be able to call |
| 82 // OnBubbleClosed on the bubble controller since we null the reference to it | 101 // OnBubbleClosed on the bubble controller since we null the reference to it |
| 83 // below. So we need to call it here. | 102 // below. So we need to call it here. |
| 84 controller_->OnBubbleClosed(); | 103 controller_->OnBubbleClosed(); |
| 85 controller_ = nullptr; | 104 controller_ = nullptr; |
| 86 [view_controller_ close]; | 105 [view_controller_ close]; |
| 87 } | 106 } |
| 88 | 107 |
| 89 } // autofill | 108 } // autofill |
| 90 | 109 |
| 91 #pragma mark SaveCardBubbleViewCocoa | 110 #pragma mark SaveCardBubbleViewCocoa |
| 92 | 111 |
| 93 @interface SaveCardBubbleViewCocoa () | 112 @interface SaveCardBubbleViewCocoa () |
| 94 + (base::scoped_nsobject<NSTextField>)makeTextField; | 113 + (base::scoped_nsobject<NSTextField>)makeLabel:(NSString*)text; |
| 95 + (base::scoped_nsobject<NSButton>)makeButton; | 114 + (base::scoped_nsobject<NSTextView>)makeWrappingLabel:(NSString*)text |
| 115 withFontSize:(CGFloat)fontSize; | |
| 116 + (base::scoped_nsobject<HyperlinkTextView>)makeHyperlinkText:(NSString*)text; | |
| 117 + (base::scoped_nsobject<NSButton>)makeButton:(NSString*)text; | |
| 96 @end | 118 @end |
| 97 | 119 |
| 98 @implementation SaveCardBubbleViewCocoa { | 120 @implementation SaveCardBubbleViewCocoa { |
| 99 autofill::SaveCardBubbleViewBridge* bridge_; // Weak. | 121 autofill::SaveCardBubbleViewBridge* bridge_; // Weak. |
| 100 } | 122 } |
| 101 | 123 |
| 102 + (base::scoped_nsobject<NSTextField>)makeTextField { | 124 + (base::scoped_nsobject<NSTextField>)makeLabel:(NSString*)text { |
| 103 base::scoped_nsobject<NSTextField> textField( | 125 base::scoped_nsobject<NSTextField> textField( |
| 104 [[NSTextField alloc] initWithFrame:NSZeroRect]); | 126 [[NSTextField alloc] initWithFrame:NSZeroRect]); |
| 105 [textField setEditable:NO]; | 127 [textField setEditable:NO]; |
| 106 [textField setSelectable:NO]; | 128 [textField setSelectable:NO]; |
| 107 [textField setDrawsBackground:NO]; | 129 [textField setDrawsBackground:NO]; |
| 108 [textField setBezeled:NO]; | 130 [textField setBezeled:NO]; |
| 131 [textField setStringValue:text]; | |
| 132 [textField sizeToFit]; | |
| 109 | 133 |
| 110 return textField; | 134 return textField; |
| 111 } | 135 } |
| 112 | 136 |
| 113 + (base::scoped_nsobject<NSButton>)makeButton { | 137 + (base::scoped_nsobject<NSTextView>)makeWrappingLabel:(NSString*)text |
| 138 withFontSize:(CGFloat)fontSize { | |
| 139 base::scoped_nsobject<NSTextView> textView( | |
| 140 [[NSTextView alloc] initWithFrame:NSZeroRect]); | |
| 141 NSDictionary* attributes = | |
| 142 @{NSFontAttributeName : [NSFont systemFontOfSize:fontSize]}; | |
| 143 base::scoped_nsobject<NSAttributedString> attributedMessage( | |
| 144 [[NSAttributedString alloc] initWithString:text attributes:attributes]); | |
| 145 [[textView textStorage] setAttributedString:attributedMessage]; | |
| 146 [[textView textContainer] setLineFragmentPadding:0.0f]; | |
| 147 [textView setEditable:NO]; | |
| 148 [textView setSelectable:NO]; | |
| 149 [textView setDrawsBackground:NO]; | |
| 150 [textView setVerticallyResizable:YES]; | |
| 151 [textView setFrameSize:NSMakeSize(kDesiredBubbleWidth - (2 * kFramePadding), | |
| 152 MAXFLOAT)]; | |
| 153 [textView sizeToFit]; | |
| 154 | |
| 155 return textView; | |
| 156 } | |
| 157 | |
| 158 + (base::scoped_nsobject<HyperlinkTextView>)makeHyperlinkText:(NSString*)text { | |
| 159 base::scoped_nsobject<HyperlinkTextView> lineView( | |
| 160 [[HyperlinkTextView alloc] initWithFrame:NSZeroRect]); | |
| 161 [lineView setMessage:text | |
| 162 withFont:[NSFont systemFontOfSize:[NSFont systemFontSize]] | |
| 163 messageColor:[NSColor blackColor]]; | |
| 164 | |
| 165 [[lineView textContainer] setLineFragmentPadding:0.0f]; | |
| 166 [lineView setVerticallyResizable:YES]; | |
| 167 [lineView setFrameSize:NSMakeSize(kDesiredBubbleWidth - 2 * kFramePadding, | |
| 168 MAXFLOAT)]; | |
| 169 [lineView sizeToFit]; | |
| 170 | |
| 171 return lineView; | |
| 172 } | |
| 173 | |
| 174 + (base::scoped_nsobject<NSButton>)makeButton:(NSString*)text { | |
| 114 base::scoped_nsobject<NSButton> button( | 175 base::scoped_nsobject<NSButton> button( |
| 115 [[NSButton alloc] initWithFrame:NSZeroRect]); | 176 [[NSButton alloc] initWithFrame:NSZeroRect]); |
| 116 [button setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; | 177 [button setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; |
| 117 [button setBezelStyle:NSRoundedBezelStyle]; | 178 [button setBezelStyle:NSRoundedBezelStyle]; |
| 118 [[button cell] setControlSize:NSSmallControlSize]; | 179 [[button cell] setControlSize:NSSmallControlSize]; |
| 180 [button setTitle:text]; | |
| 181 [button sizeToFit]; | |
| 119 | 182 |
| 120 return button; | 183 return button; |
| 121 } | 184 } |
| 122 | 185 |
| 123 - (id)initWithBrowserWindowController: | 186 - (id)initWithBrowserWindowController: |
| 124 (BrowserWindowController*)browserWindowController | 187 (BrowserWindowController*)browserWindowController |
| 125 bridge: | 188 bridge: |
| 126 (autofill::SaveCardBubbleViewBridge*)bridge { | 189 (autofill::SaveCardBubbleViewBridge*)bridge { |
| 127 DCHECK(bridge); | 190 DCHECK(bridge); |
| 128 | 191 |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 153 | 216 |
| 154 - (void)close { | 217 - (void)close { |
| 155 if (bridge_) { | 218 if (bridge_) { |
| 156 bridge_->OnBubbleClosed(); | 219 bridge_->OnBubbleClosed(); |
| 157 bridge_ = nullptr; | 220 bridge_ = nullptr; |
| 158 } | 221 } |
| 159 [super close]; | 222 [super close]; |
| 160 } | 223 } |
| 161 | 224 |
| 162 - (void)loadView { | 225 - (void)loadView { |
| 163 // Title is an NSTextView instead of an NSTextField to allow it to wrap. | 226 // Title. |
| 227 NSString* title = SysUTF16ToNSString(bridge_->GetWindowTitle()); | |
| 164 base::scoped_nsobject<NSTextView> titleLabel( | 228 base::scoped_nsobject<NSTextView> titleLabel( |
| 165 [[NSTextView alloc] initWithFrame:NSZeroRect]); | 229 [SaveCardBubbleViewCocoa makeWrappingLabel:title withFontSize:15.0]); |
| 166 NSDictionary* attributes = | |
| 167 @{NSFontAttributeName : [NSFont systemFontOfSize:15.0]}; | |
| 168 base::scoped_nsobject<NSAttributedString> attributedMessage( | |
| 169 [[NSAttributedString alloc] | |
| 170 initWithString:base::SysUTF16ToNSString(bridge_->GetWindowTitle()) | |
| 171 attributes:attributes]); | |
| 172 [[titleLabel textStorage] setAttributedString:attributedMessage]; | |
| 173 [[titleLabel textContainer] setLineFragmentPadding:0.0f]; | |
| 174 [titleLabel setEditable:NO]; | |
| 175 [titleLabel setSelectable:NO]; | |
| 176 [titleLabel setDrawsBackground:NO]; | |
| 177 [titleLabel setVerticallyResizable:YES]; | |
| 178 [titleLabel setFrameSize:NSMakeSize(kDesiredBubbleWidth - (2 * kFramePadding), | |
| 179 MAXFLOAT)]; | |
| 180 [titleLabel sizeToFit]; | |
| 181 | 230 |
| 182 // Credit card info. | 231 // Credit card info. |
| 183 autofill::CreditCard card = bridge_->GetCard(); | 232 autofill::CreditCard card = bridge_->GetCard(); |
| 184 base::scoped_nsobject<NSImageView> cardIcon( | 233 base::scoped_nsobject<NSImageView> cardIcon( |
| 185 [[NSImageView alloc] initWithFrame:NSZeroRect]); | 234 [[NSImageView alloc] initWithFrame:NSZeroRect]); |
| 186 [cardIcon setToolTip:base::SysUTF16ToNSString(card.TypeForDisplay())]; | 235 [cardIcon setToolTip:base::SysUTF16ToNSString(card.TypeForDisplay())]; |
| 187 [cardIcon setWantsLayer:YES]; | 236 [cardIcon setWantsLayer:YES]; |
| 188 [[cardIcon layer] setBorderWidth:1.0]; | 237 [[cardIcon layer] setBorderWidth:1.0]; |
| 189 [[cardIcon layer] setCornerRadius:2.0]; | 238 [[cardIcon layer] setCornerRadius:2.0]; |
| 190 [[cardIcon layer] setMasksToBounds:YES]; | 239 [[cardIcon layer] setMasksToBounds:YES]; |
| 191 [[cardIcon layer] | 240 [[cardIcon layer] |
| 192 setBorderColor:skia::CGColorCreateFromSkColor(kIconBorderColor)]; | 241 setBorderColor:skia::CGColorCreateFromSkColor(kIconBorderColor)]; |
| 193 [cardIcon setImage:ResourceBundle::GetSharedInstance() | 242 [cardIcon setImage:ResourceBundle::GetSharedInstance() |
| 194 .GetNativeImageNamed( | 243 .GetNativeImageNamed( |
| 195 autofill::CreditCard::IconResourceId(card.type())) | 244 autofill::CreditCard::IconResourceId(card.type())) |
| 196 .AsNSImage()]; | 245 .AsNSImage()]; |
| 197 [cardIcon setFrameSize:[[cardIcon image] size]]; | 246 [cardIcon setFrameSize:[[cardIcon image] size]]; |
| 198 | 247 |
| 199 base::scoped_nsobject<NSTextField> lastFourLabel( | |
| 200 [SaveCardBubbleViewCocoa makeTextField]); | |
| 201 // Midline horizontal ellipsis follwed by last four digits. | 248 // Midline horizontal ellipsis follwed by last four digits. |
| 202 [lastFourLabel setStringValue:base::SysUTF16ToNSString( | 249 base::scoped_nsobject<NSTextField> lastFourLabel([SaveCardBubbleViewCocoa |
| 203 base::UTF8ToUTF16("\xE2\x8B\xAF") + | 250 makeLabel:SysUTF16ToNSString(base::UTF8ToUTF16("\xE2\x8B\xAF") + |
|
groby-ooo-7-16
2016/03/03 00:40:22
I know, it's not your code, but can this be kEllip
Justin Donnelly
2016/03/03 18:45:10
Do you mean kEllipsis from src/ui/gfx/text_elider.
groby-ooo-7-16
2016/03/07 19:54:57
SG - (I didn't mean the elider one)
| |
| 204 card.LastFourDigits())]; | 251 card.LastFourDigits())]); |
| 205 [lastFourLabel sizeToFit]; | |
| 206 | 252 |
| 207 base::scoped_nsobject<NSTextField> expirationDateLabel( | 253 base::scoped_nsobject<NSTextField> expirationDateLabel( |
| 208 [SaveCardBubbleViewCocoa makeTextField]); | 254 [SaveCardBubbleViewCocoa |
| 209 [expirationDateLabel | 255 makeLabel:base::SysUTF16ToNSString( |
| 210 setStringValue:base::SysUTF16ToNSString( | 256 card.AbbreviatedExpirationDateForDisplay())]); |
| 211 card.AbbreviatedExpirationDateForDisplay())]; | 257 |
| 212 [expirationDateLabel sizeToFit]; | 258 // Explanatory text (only shown for upload). |
| 259 base::scoped_nsobject<NSTextView> explanationLabel( | |
|
groby-ooo-7-16
2016/03/03 00:40:22
Why are you still alloc/initing here?
Justin Donnelly
2016/03/03 18:45:09
Having a zero-size label in the case where there's
groby-ooo-7-16
2016/03/07 19:54:57
You know you can send messages to nil, right? Retu
Justin Donnelly
2016/03/07 21:21:02
I had forgotten that until you asked me why I was
| |
| 260 [[NSTextView alloc] initWithFrame:NSZeroRect]); | |
| 261 base::string16 explanation = bridge_->GetExplanatoryMessage(); | |
| 262 if (!explanation.empty()) { | |
| 263 explanationLabel.reset([SaveCardBubbleViewCocoa | |
| 264 makeWrappingLabel:SysUTF16ToNSString(explanation) | |
| 265 withFontSize:[NSFont systemFontSize]] | |
| 266 .release()); | |
|
groby-ooo-7-16
2016/03/03 00:40:22
Please don't use dot notation for message invocati
Justin Donnelly
2016/03/03 18:45:09
I couldn't figure out any other way to make this w
groby-ooo-7-16
2016/03/07 19:54:58
Sigh. Misread the release as being a Cocoa message
Justin Donnelly
2016/03/07 21:21:02
As discussed out-of-band, leaving this as is.
| |
| 267 } | |
| 213 | 268 |
| 214 // "Learn more" link. | 269 // "Learn more" link. |
| 270 NSString* learnMoreString = l10n_util::GetNSString(IDS_LEARN_MORE); | |
| 215 base::scoped_nsobject<HyperlinkTextView> learnMoreLink( | 271 base::scoped_nsobject<HyperlinkTextView> learnMoreLink( |
| 216 [[HyperlinkTextView alloc] initWithFrame:NSZeroRect]); | 272 [SaveCardBubbleViewCocoa makeHyperlinkText:learnMoreString]); |
| 217 NSString* learnMoreString = l10n_util::GetNSString(IDS_LEARN_MORE); | |
| 218 [learnMoreLink | |
| 219 setMessage:learnMoreString | |
| 220 withFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]] | |
| 221 messageColor:[NSColor blackColor]]; | |
| 222 [learnMoreLink setDelegate:self]; | 273 [learnMoreLink setDelegate:self]; |
| 274 | |
| 223 NSColor* linkColor = | 275 NSColor* linkColor = |
| 224 skia::SkColorToCalibratedNSColor(chrome_style::GetLinkColor()); | 276 skia::SkColorToCalibratedNSColor(chrome_style::GetLinkColor()); |
| 225 [learnMoreLink addLinkRange:NSMakeRange(0, [learnMoreString length]) | 277 CGFloat length = [learnMoreString length]; |
|
groby-ooo-7-16
2016/03/03 00:40:22
Might want to create the range here.
Justin Donnelly
2016/03/03 18:45:09
Done.
| |
| 278 [learnMoreLink addLinkRange:NSMakeRange(0, length) | |
| 226 withURL:nil | 279 withURL:nil |
| 227 linkColor:linkColor]; | 280 linkColor:linkColor]; |
| 228 NSTextStorage* text = [learnMoreLink textStorage]; | 281 [[learnMoreLink textStorage] addAttribute:NSUnderlineStyleAttributeName |
| 229 [text addAttribute:NSUnderlineStyleAttributeName | 282 value:@(NSUnderlineStyleNone) |
| 230 value:[NSNumber numberWithInt:NSUnderlineStyleNone] | 283 range:NSMakeRange(0, length)]; |
| 231 range:NSMakeRange(0, [learnMoreString length])]; | |
| 232 [[learnMoreLink textContainer] setLineFragmentPadding:0.0f]; | |
| 233 [learnMoreLink setVerticallyResizable:YES]; | |
| 234 [learnMoreLink | |
| 235 setFrameSize:NSMakeSize(kDesiredBubbleWidth - 2 * kFramePadding, | |
| 236 MAXFLOAT)]; | |
| 237 [learnMoreLink sizeToFit]; | |
| 238 | 284 |
| 239 // Cancel button. | 285 // Cancel button. |
| 240 base::scoped_nsobject<NSButton> cancelButton( | 286 base::scoped_nsobject<NSButton> cancelButton([SaveCardBubbleViewCocoa |
| 241 [SaveCardBubbleViewCocoa makeButton]); | 287 makeButton:l10n_util::GetNSString(IDS_AUTOFILL_SAVE_CARD_PROMPT_DENY)]); |
| 242 [cancelButton | |
| 243 setTitle:l10n_util::GetNSString(IDS_AUTOFILL_SAVE_CARD_PROMPT_DENY)]; | |
| 244 [cancelButton sizeToFit]; | |
| 245 [cancelButton setTarget:self]; | 288 [cancelButton setTarget:self]; |
| 246 [cancelButton setAction:@selector(onCancelButton:)]; | 289 [cancelButton setAction:@selector(onCancelButton:)]; |
| 247 [cancelButton setKeyEquivalent:@"\e"]; | 290 [cancelButton setKeyEquivalent:@"\e"]; |
| 248 | 291 |
| 249 // Save button. | 292 // Save button. |
| 250 base::scoped_nsobject<NSButton> saveButton( | 293 base::scoped_nsobject<NSButton> saveButton([SaveCardBubbleViewCocoa |
| 251 [SaveCardBubbleViewCocoa makeButton]); | 294 makeButton:l10n_util::GetNSString(IDS_AUTOFILL_SAVE_CARD_PROMPT_ACCEPT)]); |
| 252 [saveButton | |
| 253 setTitle:l10n_util::GetNSString(IDS_AUTOFILL_SAVE_CARD_PROMPT_ACCEPT)]; | |
| 254 [saveButton sizeToFit]; | |
| 255 [saveButton setTarget:self]; | 295 [saveButton setTarget:self]; |
| 256 [saveButton setAction:@selector(onSaveButton:)]; | 296 [saveButton setAction:@selector(onSaveButton:)]; |
| 257 [saveButton setKeyEquivalent:@"\r"]; | 297 [saveButton setKeyEquivalent:@"\r"]; |
| 258 | 298 |
| 299 // Footer with legal text (only shown for upload). | |
| 300 base::scoped_nsobject<NSBox> divider( | |
| 301 [[NSBox alloc] initWithFrame:NSZeroRect]); | |
| 302 base::scoped_nsobject<NSView> footerView( | |
| 303 [[NSView alloc] initWithFrame:NSZeroRect]); | |
| 304 const autofill::LegalMessageLines& lines = bridge_->GetLegalMessageLines(); | |
| 305 if (!lines.empty()) { | |
| 306 [divider setBoxType:NSBoxCustom]; | |
| 307 [divider setBorderType:NSLineBorder]; | |
| 308 [divider setBorderColor:skia::SkColorToCalibratedNSColor(kDividerColor)]; | |
| 309 [divider setFrameSize:NSMakeSize(kDesiredBubbleWidth, kDividerHeight)]; | |
| 310 | |
| 311 [footerView setWantsLayer:YES]; | |
| 312 [[footerView layer] | |
| 313 setBackgroundColor:skia::CGColorCreateFromSkColor(kFooterColor)]; | |
| 314 | |
| 315 CGFloat linesHeight = kFramePadding; | |
| 316 for (auto lineIter = lines.end() - 1; lineIter != lines.begin() - 1; | |
|
groby-ooo-7-16
2016/03/03 00:40:22
Why not build in the reverse direction and use (fo
Justin Donnelly
2016/03/03 18:45:09
The lines are built in cross-platform code also us
groby-ooo-7-16
2016/03/07 19:54:57
No, I mean building the UI layout in the reverse d
| |
| 317 --lineIter) { | |
| 318 // Create the legal message line view. | |
| 319 base::scoped_nsobject<HyperlinkTextView> lineView([SaveCardBubbleViewCocoa | |
| 320 makeHyperlinkText:SysUTF16ToNSString(lineIter->text())]); | |
| 321 [lineView setDelegate:self]; | |
| 322 | |
| 323 // Add the links. | |
| 324 for (auto linkIter = lineIter->links().begin(); | |
|
groby-ooo-7-16
2016/03/03 00:40:22
C++11 loop?
Justin Donnelly
2016/03/03 18:45:09
Done. So much nicer. (I couldn't find any examples
| |
| 325 linkIter != lineIter->links().end(); ++linkIter) { | |
| 326 CGFloat start = linkIter->range.start(); | |
| 327 CGFloat length = linkIter->range.length(); | |
| 328 [lineView addLinkRange:NSMakeRange(start, length) | |
| 329 withURL:nil | |
| 330 linkColor:linkColor]; | |
| 331 [[lineView textStorage] addAttribute:NSUnderlineStyleAttributeName | |
| 332 value:@(NSUnderlineStyleNone) | |
| 333 range:NSMakeRange(start, length)]; | |
| 334 } | |
| 335 | |
| 336 // Add the line to the footer view. | |
| 337 [footerView addSubview:lineView]; | |
| 338 [lineView setFrameOrigin:NSMakePoint(kFramePadding, linesHeight)]; | |
| 339 linesHeight += | |
| 340 [lineView frame].size.height + kRelatedControlVerticalPadding; | |
| 341 } | |
| 342 [footerView setFrameSize:NSMakeSize(kDesiredBubbleWidth, | |
| 343 linesHeight + kFramePadding)]; | |
| 344 } | |
| 345 | |
| 259 // Layout. | 346 // Layout. |
| 347 [footerView setFrameOrigin:NSMakePoint(0, 0)]; | |
|
groby-ooo-7-16
2016/03/03 00:40:23
NSZeroPoint
Justin Donnelly
2016/03/03 18:45:10
Done.
| |
| 348 | |
| 349 [divider setFrameOrigin:NSMakePoint(0, NSMaxY([footerView frame]))]; | |
| 350 | |
| 260 [saveButton setFrameOrigin: | 351 [saveButton setFrameOrigin: |
| 261 NSMakePoint(kDesiredBubbleWidth - kFramePadding - | 352 NSMakePoint(kDesiredBubbleWidth - kFramePadding - |
| 262 NSWidth([saveButton frame]), | 353 NSWidth([saveButton frame]), |
| 263 kFramePadding)]; | 354 NSMaxY([divider frame]) + kFramePadding)]; |
| 264 [cancelButton setFrameOrigin: | 355 [cancelButton setFrameOrigin: |
| 265 NSMakePoint(NSMinX([saveButton frame]) - | 356 NSMakePoint(NSMinX([saveButton frame]) - |
| 266 kRelatedControlHorizontalPadding - | 357 kRelatedControlHorizontalPadding - |
| 267 NSWidth([cancelButton frame]), | 358 NSWidth([cancelButton frame]), |
| 268 kFramePadding)]; | 359 NSMaxY([divider frame]) + kFramePadding)]; |
| 269 [learnMoreLink setFrameOrigin: | 360 [learnMoreLink setFrameOrigin: |
| 270 NSMakePoint(kFramePadding, | 361 NSMakePoint(kFramePadding, |
| 271 NSMidY([saveButton frame]) - | 362 NSMidY([saveButton frame]) - |
| 272 (NSHeight([learnMoreLink frame]) / 2.0))]; | 363 (NSHeight([learnMoreLink frame]) / 2.0))]; |
| 273 | 364 |
| 365 [explanationLabel setFrameOrigin: | |
| 366 NSMakePoint(kFramePadding, | |
| 367 NSMaxY([saveButton frame]) + | |
| 368 kUnrelatedControlVerticalPadding)]; | |
| 369 | |
| 370 NSView* viewBelowIcon = | |
| 371 ([explanationLabel frame].size.height > 0) ? explanationLabel.get() | |
| 372 : saveButton.get(); | |
| 274 [cardIcon setFrameOrigin: | 373 [cardIcon setFrameOrigin: |
| 275 NSMakePoint(kFramePadding, | 374 NSMakePoint(kFramePadding, |
| 276 NSMaxY([saveButton frame]) + | 375 NSMaxY([viewBelowIcon frame]) + |
| 277 kUnrelatedControlVerticalPadding)]; | 376 kUnrelatedControlVerticalPadding)]; |
| 278 [lastFourLabel setFrameOrigin: | 377 [lastFourLabel setFrameOrigin: |
| 279 NSMakePoint(NSMaxX([cardIcon frame]) + kRelatedControlHorizontalPadding, | 378 NSMakePoint(NSMaxX([cardIcon frame]) + kRelatedControlHorizontalPadding, |
| 280 NSMidY([cardIcon frame]) - | 379 NSMidY([cardIcon frame]) - |
| 281 (NSHeight([lastFourLabel frame]) / 2.0))]; | 380 (NSHeight([lastFourLabel frame]) / 2.0))]; |
| 282 [expirationDateLabel setFrameOrigin: | 381 [expirationDateLabel setFrameOrigin: |
| 283 NSMakePoint(NSMaxX([lastFourLabel frame]) + | 382 NSMakePoint(NSMaxX([lastFourLabel frame]) + |
| 284 kRelatedControlHorizontalPadding, | 383 kRelatedControlHorizontalPadding, |
| 285 NSMidY([cardIcon frame]) - | 384 NSMidY([cardIcon frame]) - |
| 286 (NSHeight([expirationDateLabel frame]) / 2.0))]; | 385 (NSHeight([expirationDateLabel frame]) / 2.0))]; |
| 287 | 386 |
| 288 [titleLabel setFrameOrigin: | 387 [titleLabel setFrameOrigin: |
| 289 NSMakePoint(kFramePadding, | 388 NSMakePoint(kFramePadding, |
| 290 NSMaxY([cardIcon frame]) + kUnrelatedControlVerticalPadding)]; | 389 NSMaxY([cardIcon frame]) + kUnrelatedControlVerticalPadding)]; |
| 291 | 390 |
| 292 [[[self window] contentView] setSubviews:@[ | 391 [[[self window] contentView] setSubviews:@[ |
| 293 titleLabel, cardIcon, lastFourLabel, expirationDateLabel, learnMoreLink, | 392 titleLabel, cardIcon, lastFourLabel, expirationDateLabel, explanationLabel, |
| 294 cancelButton, saveButton | 393 learnMoreLink, cancelButton, saveButton, divider, footerView |
| 295 ]]; | 394 ]]; |
| 296 | 395 |
| 297 // Update window frame. | 396 // Update window frame. |
| 298 NSRect windowFrame = [[self window] frame]; | 397 NSRect windowFrame = [[self window] frame]; |
| 299 windowFrame.size.height = NSMaxY([titleLabel frame]) + kFramePadding; | 398 windowFrame.size.height = NSMaxY([titleLabel frame]) + kFramePadding; |
| 300 windowFrame.size.width = kDesiredBubbleWidth; | 399 windowFrame.size.width = kDesiredBubbleWidth; |
| 301 [[self window] setFrame:windowFrame display:NO]; | 400 [[self window] setFrame:windowFrame display:NO]; |
| 302 } | 401 } |
| 303 | 402 |
| 304 - (void)onSaveButton:(id)sender { | 403 - (void)onSaveButton:(id)sender { |
| 305 DCHECK(bridge_); | 404 DCHECK(bridge_); |
| 306 bridge_->OnSaveButton(); | 405 bridge_->OnSaveButton(); |
| 307 } | 406 } |
| 308 | 407 |
| 309 - (void)onCancelButton:(id)sender { | 408 - (void)onCancelButton:(id)sender { |
| 310 DCHECK(bridge_); | 409 DCHECK(bridge_); |
| 311 bridge_->OnCancelButton(); | 410 bridge_->OnCancelButton(); |
| 312 } | 411 } |
| 313 | 412 |
| 314 - (BOOL)textView:(NSTextView*)textView | 413 - (BOOL)textView:(NSTextView*)textView |
| 315 clickedOnLink:(id)link | 414 clickedOnLink:(id)link |
|
groby-ooo-7-16
2016/03/03 00:40:23
Instead of doing the whole iteration thing - you c
Justin Donnelly
2016/03/03 18:45:10
I'm not quite sure what you mean. UIView's tag pro
groby-ooo-7-16
2016/03/07 19:54:57
I like draggable links - it's a more OSXy thing. B
| |
| 316 atIndex:(NSUInteger)charIndex { | 415 atIndex:(NSUInteger)charIndex { |
| 317 DCHECK(bridge_); | 416 DCHECK(bridge_); |
| 417 | |
| 418 // Check each of the links in each of the legal message lines ot see if they | |
| 419 // are the source of the click. | |
| 420 const autofill::LegalMessageLines& lines = bridge_->GetLegalMessageLines(); | |
| 421 for (auto lineIter = lines.begin(); lineIter != lines.end(); ++lineIter) { | |
|
groby-ooo-7-16
2016/03/03 00:40:23
C++11 loop?
Justin Donnelly
2016/03/03 18:45:10
Done.
| |
| 422 if (lineIter->text() == | |
| 423 base::SysNSStringToUTF16([[textView textStorage] string])) { | |
|
groby-ooo-7-16
2016/03/07 19:54:57
The text comparison thing just bugs me - but since
Justin Donnelly
2016/03/07 21:21:02
Payments wanted it that way for reasons I can no l
| |
| 424 for (auto linkIter = lineIter->links().begin(); | |
|
groby-ooo-7-16
2016/03/03 00:40:23
You know what I'm going to say... :)
Justin Donnelly
2016/03/03 18:45:10
Done. :)
| |
| 425 linkIter != lineIter->links().end(); ++linkIter) { | |
| 426 if (linkIter->range.start() <= charIndex && | |
|
groby-ooo-7-16
2016/03/07 19:54:58
FWIW: You could do NSLocationInRange(charIndex, NS
| |
| 427 charIndex < linkIter->range.end()) { | |
| 428 bridge_->OnLegalMessageLinkClicked(linkIter->url); | |
| 429 return YES; | |
| 430 } | |
| 431 } | |
| 432 } | |
| 433 } | |
| 434 | |
| 435 // If none of the legal message links are the source of the click, the source | |
| 436 // must be the learn more link. | |
| 318 bridge_->OnLearnMoreClicked(); | 437 bridge_->OnLearnMoreClicked(); |
| 319 return YES; | 438 return YES; |
| 320 } | 439 } |
| 321 | 440 |
| 322 @end | 441 @end |
| OLD | NEW |