Chromium Code Reviews| Index: chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.mm |
| diff --git a/chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.mm b/chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.mm |
| index ba5e6c62a33702b24044768134eb1c30e4e64c39..e7fae75f885c4ccd1acf9f10cee8f5860de0311b 100644 |
| --- a/chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.mm |
| +++ b/chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.mm |
| @@ -6,6 +6,7 @@ |
| #include "base/message_loop/message_loop.h" |
| #include "base/strings/sys_string_conversions.h" |
| #include "chrome/browser/ui/autofill/autofill_dialog_models.h" |
| +#include "chrome/browser/ui/autofill/autofill_dialog_types.h" |
| #include "chrome/browser/ui/autofill/card_unmask_prompt_controller.h" |
| #import "chrome/browser/ui/cocoa/autofill/autofill_tooltip_controller.h" |
| #include "chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.h" |
| @@ -17,6 +18,7 @@ |
| #import "chrome/browser/ui/cocoa/key_equivalent_constants.h" |
| #include "grit/generated_resources.h" |
| #include "grit/theme_resources.h" |
| +#include "skia/ext/skia_utils_mac.h" |
| #include "ui/base/cocoa/window_size_constants.h" |
| #include "ui/base/l10n/l10n_util.h" |
| @@ -27,6 +29,8 @@ const CGFloat kDialogContentMinWidth = 210.0f; |
| const CGFloat kCvcInputWidth = 64.0f; |
| const ui::ResourceBundle::FontStyle kProgressFontStyle = |
| chrome_style::kTitleFontStyle; |
| +const ui::ResourceBundle::FontStyle kErrorFontStyle = |
| + chrome_style::kTextFontStyle; |
| } // namespace |
| @@ -84,6 +88,9 @@ void CardUnmaskPromptViewBridge::GotVerificationResult( |
| base::TimeDelta::FromSeconds(1)); |
| } else { |
| [view_controller_ setProgressOverlayText:base::string16()]; |
| + // TODO(bondd): Views version never hides |errorLabel_|. When Views decides |
| + // when to hide it then do the same thing here. |
| + [view_controller_ setRetriableErrorMessage:error_message]; |
|
bondd
2015/03/23 21:27:55
setRetriableErrorMessage is same method name as in
groby-ooo-7-16
2015/03/24 01:26:49
Can we fix the views version too, then?
bondd
2015/03/24 23:46:47
Leaving shed this color per discussion elsewhere i
|
| } |
| } |
| @@ -107,14 +114,21 @@ void CardUnmaskPromptViewBridge::PerformClose() { |
| #pragma mark CardUnmaskPromptViewCocoa |
| @implementation CardUnmaskPromptViewCocoa { |
| + base::scoped_nsobject<NSView> expirationView_; |
|
groby-ooo-7-16
2015/03/24 01:26:49
This is never used outside -loadView, so no need t
bondd
2015/03/24 23:46:47
Done.
|
| + base::scoped_nsobject<NSView> inputRowView_; |
| + base::scoped_nsobject<NSView> storageView_; |
| + |
| + base::scoped_nsobject<NSTextField> titleLabel_; |
| + base::scoped_nsobject<NSTextField> instructionsLabel_; |
| base::scoped_nsobject<NSTextField> cvcInput_; |
| base::scoped_nsobject<NSPopUpButton> monthPopup_; |
| base::scoped_nsobject<NSPopUpButton> yearPopup_; |
| + base::scoped_nsobject<NSButton> cancelButton_; |
| base::scoped_nsobject<NSButton> verifyButton_; |
| base::scoped_nsobject<NSButton> storageCheckbox_; |
| base::scoped_nsobject<AutofillTooltipController> storageTooltip_; |
| - base::scoped_nsobject<NSView> inputRow_; |
| - base::scoped_nsobject<NSTextField> progressOverlayText_; |
| + base::scoped_nsobject<NSTextField> errorLabel_; |
| + base::scoped_nsobject<NSTextField> progressOverlayLabel_; |
| int monthPopupDefaultIndex_; |
| int yearPopupDefaultIndex_; |
| @@ -168,20 +182,29 @@ void CardUnmaskPromptViewBridge::PerformClose() { |
| constrained_window::GetAttributedLabelString( |
| SysUTF16ToNSString(text), kProgressFontStyle, NSCenterTextAlignment, |
| NSLineBreakByWordWrapping); |
| - [progressOverlayText_ setAttributedStringValue:attributedString]; |
| + [progressOverlayLabel_ setAttributedStringValue:attributedString]; |
| } |
| - [progressOverlayText_ setHidden:text.empty()]; |
| - [inputRow_ setHidden:!text.empty()]; |
| + [progressOverlayLabel_ setHidden:text.empty()]; |
| + [inputRowView_ setHidden:!text.empty()]; |
| [self updateVerifyButtonEnabled]; |
| } |
| +- (void)setRetriableErrorMessage:(const base::string16&)text { |
| + NSAttributedString* attributedString = |
| + constrained_window::GetAttributedLabelString( |
| + SysUTF16ToNSString(text), kErrorFontStyle, NSNaturalTextAlignment, |
| + NSLineBreakByWordWrapping); |
| + [errorLabel_ setAttributedStringValue:attributedString]; |
| + [self performLayout]; |
| +} |
| + |
| - (void)updateVerifyButtonEnabled { |
| autofill::CardUnmaskPromptController* controller = bridge_->GetController(); |
| DCHECK(controller); |
| BOOL enable = |
| - ![inputRow_ isHidden] && |
| + ![inputRowView_ isHidden] && |
| controller->InputCvcIsValid( |
| base::SysNSStringToUTF16([cvcInput_ stringValue])) && |
| (!monthPopup_ || |
| @@ -242,15 +265,78 @@ void CardUnmaskPromptViewBridge::PerformClose() { |
| setMessage:base::SysUTF16ToNSString(l10n_util::GetStringUTF16( |
| IDS_AUTOFILL_CARD_UNMASK_PROMPT_STORAGE_TOOLTIP))]; |
| [view addSubview:[storageTooltip_ view]]; |
| - [[storageTooltip_ view] |
| - setFrameOrigin:NSMakePoint(NSMaxX([storageCheckbox_ frame]) + kButtonGap, |
| - 0)]; |
| + [[storageTooltip_ view] setFrameOrigin: |
| + NSMakePoint(NSMaxX([storageCheckbox_ frame]) + kButtonGap, 0)]; |
| [CardUnmaskPromptViewCocoa sizeToFitView:view]; |
| [CardUnmaskPromptViewCocoa verticallyCenterSubviewsInView:view]; |
| return view; |
| } |
| +- (void)performLayout { |
| + // Calculate dialog content width. |
| + CGFloat contentWidth = |
| + std::max(NSWidth([titleLabel_ frame]), NSWidth([inputRowView_ frame])); |
| + contentWidth = std::max(contentWidth, NSWidth([storageView_ frame])); |
| + contentWidth = std::max(contentWidth, kDialogContentMinWidth); |
|
groby-ooo-7-16
2015/03/24 01:26:49
This is weird to me - we only invoke this after in
bondd
2015/03/24 23:46:47
Dialog width stays the same, but dialog height cha
|
| + |
| + [storageView_ |
|
groby-ooo-7-16
2015/03/24 01:26:49
At this point, the layout is sufficiently complex
bondd
2015/03/24 23:46:47
Done.
|
| + setFrameOrigin:NSMakePoint(0, chrome_style::kClientBottomPadding)]; |
| + |
| + [verifyButton_ setFrameOrigin: |
| + NSMakePoint(contentWidth - NSWidth([verifyButton_ frame]), |
| + NSMaxY([storageView_ frame]) + chrome_style::kRowPadding)]; |
| + |
| + [cancelButton_ |
| + setFrameOrigin:NSMakePoint(NSMinX([verifyButton_ frame]) - kButtonGap - |
| + NSWidth([cancelButton_ frame]), |
| + NSMinY([verifyButton_ frame]))]; |
| + |
| + // Error message label. |
|
groby-ooo-7-16
2015/03/24 01:26:49
Please do use a complete sentence, here and elsewh
bondd
2015/03/24 23:46:47
Done. Removed some of these comments because code
|
| + [errorLabel_ setFrameOrigin:NSMakePoint(0, NSMaxY([cancelButton_ frame]) + |
| + chrome_style::kRowPadding)]; |
| + NSSize errorSize = [[errorLabel_ cell] |
| + cellSizeForBounds:NSMakeRect(0, 0, contentWidth, CGFLOAT_MAX)]; |
|
groby-ooo-7-16
2015/03/24 01:26:50
We do this in several places - probably worth hois
bondd
2015/03/24 23:46:47
I hoisted it to the top of this class, with a TODO
|
| + [errorLabel_ setFrameSize:errorSize]; |
| + |
| + // Input row. |
| + [inputRowView_ setFrameOrigin:NSMakePoint(0, NSMaxY([errorLabel_ frame]) + |
| + chrome_style::kRowPadding)]; |
| + |
| + // Instruction label. |
| + [instructionsLabel_ |
| + setFrameOrigin:NSMakePoint(0, NSMaxY([inputRowView_ frame]) + |
| + chrome_style::kRowPadding)]; |
| + NSSize instructionsSize = [[instructionsLabel_ cell] |
| + cellSizeForBounds:NSMakeRect(0, 0, contentWidth, CGFLOAT_MAX)]; |
| + [instructionsLabel_ setFrameSize:instructionsSize]; |
| + |
| + // Title label. |
| + [titleLabel_ |
| + setFrameOrigin:NSMakePoint(0, NSMaxY([instructionsLabel_ frame]) + |
| + chrome_style::kRowPadding)]; |
| + |
| + // Center progressOverlayLabel_ vertically within inputRowView_ frame. |
| + CGFloat progressHeight = ui::ResourceBundle::GetSharedInstance() |
| + .GetFont(kProgressFontStyle) |
| + .GetHeight(); |
| + [progressOverlayLabel_ |
| + setFrame:NSMakeRect(0, ceil(NSMidY([inputRowView_ frame]) - |
| + progressHeight / 2.0), |
| + contentWidth, progressHeight)]; |
| + |
| + // Dialog size. |
| + [[self view] |
| + setFrameSize:NSMakeSize( |
| + contentWidth + chrome_style::kHorizontalPadding * 2.0, |
| + NSMaxY([titleLabel_ frame]) + |
| + chrome_style::kTitleTopPadding)]; |
| + |
| + NSRect frameRect = |
| + [[[self view] window] frameRectForContentRect:[[self view] frame]]; |
| + [[[self view] window] setFrame:frameRect display:YES]; |
| +} |
| + |
| - (void)loadView { |
| autofill::CardUnmaskPromptController* controller = bridge_->GetController(); |
| DCHECK(controller); |
| @@ -263,38 +349,40 @@ void CardUnmaskPromptViewBridge::PerformClose() { |
| [mainView |
| setContentViewMargins:NSMakeSize(chrome_style::kHorizontalPadding, 0)]; |
| - inputRow_.reset([[NSView alloc] initWithFrame:NSZeroRect]); |
| - [mainView addSubview:inputRow_]; |
| + inputRowView_.reset([[NSView alloc] initWithFrame:NSZeroRect]); |
| + [mainView addSubview:inputRowView_]; |
| - base::scoped_nsobject<NSView> storageView( |
| - [self createStorageViewWithController:controller]); |
| - [mainView addSubview:storageView]; |
| + storageView_ = [self createStorageViewWithController:controller]; |
| + [mainView addSubview:storageView_]; |
| + |
| + progressOverlayLabel_.reset([constrained_window::CreateLabel() retain]); |
| + [progressOverlayLabel_ setHidden:YES]; |
| + [mainView addSubview:progressOverlayLabel_]; |
| // Title label. |
| - NSTextField* title = constrained_window::CreateLabel(); |
| + titleLabel_.reset([constrained_window::CreateLabel() retain]); |
| NSAttributedString* titleString = |
| constrained_window::GetAttributedLabelString( |
| SysUTF16ToNSString(controller->GetWindowTitle()), |
| chrome_style::kTitleFontStyle, NSNaturalTextAlignment, |
| NSLineBreakByWordWrapping); |
| - [title setAttributedStringValue:titleString]; |
| - [title sizeToFit]; |
| - [mainView addSubview:title]; |
| + [titleLabel_ setAttributedStringValue:titleString]; |
| + [titleLabel_ sizeToFit]; |
| + [mainView addSubview:titleLabel_]; |
| // Instructions label. |
| - NSTextField* instructions = constrained_window::CreateLabel(); |
| + instructionsLabel_.reset([constrained_window::CreateLabel() retain]); |
| NSAttributedString* instructionsString = |
| constrained_window::GetAttributedLabelString( |
| SysUTF16ToNSString(controller->GetInstructionsMessage()), |
| chrome_style::kTextFontStyle, NSNaturalTextAlignment, |
| NSLineBreakByWordWrapping); |
| - [instructions setAttributedStringValue:instructionsString]; |
| - [mainView addSubview:instructions]; |
| + [instructionsLabel_ setAttributedStringValue:instructionsString]; |
| + [mainView addSubview:instructionsLabel_]; |
| // Expiration date. |
| - base::scoped_nsobject<NSView> expirationView; |
| if (controller->ShouldRequestExpirationDate()) { |
| - expirationView.reset([[NSView alloc] initWithFrame:NSZeroRect]); |
| + expirationView_.reset([[NSView alloc] initWithFrame:NSZeroRect]); |
| // Month. |
| autofill::MonthComboboxModel monthModel; |
| @@ -303,7 +391,7 @@ void CardUnmaskPromptViewBridge::PerformClose() { |
| [CardUnmaskPromptViewCocoa buildDatePopupWithModel:monthModel]); |
| [monthPopup_ setTarget:self]; |
| [monthPopup_ setAction:@selector(onExpirationDateChanged:)]; |
| - [expirationView addSubview:monthPopup_]; |
| + [expirationView_ addSubview:monthPopup_]; |
| // Year. |
| autofill::YearComboboxModel yearModel; |
| @@ -312,17 +400,17 @@ void CardUnmaskPromptViewBridge::PerformClose() { |
| [CardUnmaskPromptViewCocoa buildDatePopupWithModel:yearModel]); |
| [yearPopup_ setTarget:self]; |
| [yearPopup_ setAction:@selector(onExpirationDateChanged:)]; |
| - [expirationView addSubview:yearPopup_]; |
| + [expirationView_ addSubview:yearPopup_]; |
| - // Layout month and year within expirationView. |
| + // Layout month and year within expirationView_. |
| [yearPopup_ |
| setFrameOrigin:NSMakePoint(NSMaxX([monthPopup_ frame]) + kButtonGap, |
| 0)]; |
| NSRect expirationFrame = |
| NSUnionRect([monthPopup_ frame], [yearPopup_ frame]); |
| expirationFrame.size.width += kButtonGap; |
| - [expirationView setFrame:expirationFrame]; |
| - [inputRow_ addSubview:expirationView]; |
| + [expirationView_ setFrame:expirationFrame]; |
| + [inputRowView_ addSubview:expirationView_]; |
| } |
| // CVC text input. |
| @@ -333,9 +421,9 @@ void CardUnmaskPromptViewBridge::PerformClose() { |
| [[cvcInput_ cell] setScrollable:YES]; |
| [cvcInput_ setDelegate:self]; |
| [cvcInput_ sizeToFit]; |
| - [cvcInput_ setFrame:NSMakeRect(NSMaxX([expirationView frame]), 0, |
| + [cvcInput_ setFrame:NSMakeRect(NSMaxX([expirationView_ frame]), 0, |
| kCvcInputWidth, NSHeight([cvcInput_ frame]))]; |
| - [inputRow_ addSubview:cvcInput_]; |
| + [inputRowView_ addSubview:cvcInput_]; |
| // CVC image. |
| ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| @@ -347,17 +435,23 @@ void CardUnmaskPromptViewBridge::PerformClose() { |
| [cvcImageView setFrameSize:[cvcImage size]]; |
| [cvcImageView |
| setFrameOrigin:NSMakePoint(NSMaxX([cvcInput_ frame]) + kButtonGap, 0)]; |
| - [inputRow_ addSubview:cvcImageView]; |
| + [inputRowView_ addSubview:cvcImageView]; |
| + |
| + // Error message label. |
| + errorLabel_.reset([constrained_window::CreateLabel() retain]); |
| + [errorLabel_ |
| + setTextColor:gfx::SkColorToCalibratedNSColor(autofill::kWarningColor)]; |
| + [mainView addSubview:errorLabel_]; |
| // Cancel button. |
| - base::scoped_nsobject<NSButton> cancelButton( |
| + cancelButton_.reset( |
| [[ConstrainedWindowButton alloc] initWithFrame:NSZeroRect]); |
| - [cancelButton setTitle:l10n_util::GetNSStringWithFixup(IDS_CANCEL)]; |
| - [cancelButton setKeyEquivalent:kKeyEquivalentEscape]; |
| - [cancelButton setTarget:self]; |
| - [cancelButton setAction:@selector(onCancel:)]; |
| - [cancelButton sizeToFit]; |
| - [mainView addSubview:cancelButton]; |
| + [cancelButton_ setTitle:l10n_util::GetNSStringWithFixup(IDS_CANCEL)]; |
| + [cancelButton_ setKeyEquivalent:kKeyEquivalentEscape]; |
| + [cancelButton_ setTarget:self]; |
| + [cancelButton_ setAction:@selector(onCancel:)]; |
| + [cancelButton_ sizeToFit]; |
| + [mainView addSubview:cancelButton_]; |
| // Verify button. |
| verifyButton_.reset( |
| @@ -371,66 +465,12 @@ void CardUnmaskPromptViewBridge::PerformClose() { |
| [self updateVerifyButtonEnabled]; |
| [mainView addSubview:verifyButton_]; |
| - // Layout inputRow_. |
| - [CardUnmaskPromptViewCocoa sizeToFitView:inputRow_]; |
| - [CardUnmaskPromptViewCocoa verticallyCenterSubviewsInView:inputRow_]; |
| - |
| - // Calculate dialog content width. |
| - CGFloat contentWidth = |
| - std::max(NSWidth([title frame]), NSWidth([inputRow_ frame])); |
| - contentWidth = std::max(contentWidth, NSWidth([storageView frame])); |
| - contentWidth = std::max(contentWidth, kDialogContentMinWidth); |
| - |
| - // Layout mainView contents, starting at the bottom and moving up. |
| - |
| - [storageView |
| - setFrameOrigin:NSMakePoint(0, chrome_style::kClientBottomPadding)]; |
| - |
| - // Verify and Cancel buttons. |
| - [verifyButton_ |
| - setFrameOrigin:NSMakePoint(contentWidth - NSWidth([verifyButton_ frame]), |
| - NSMaxY([storageView frame]) + |
| - chrome_style::kRowPadding)]; |
| - |
| - [cancelButton |
| - setFrameOrigin:NSMakePoint(NSMinX([verifyButton_ frame]) - kButtonGap - |
| - NSWidth([cancelButton frame]), |
| - NSMinY([verifyButton_ frame]))]; |
| - |
| - // Input row. |
| - [inputRow_ setFrameOrigin:NSMakePoint(0, NSMaxY([cancelButton frame]) + |
| - chrome_style::kRowPadding)]; |
| - |
| - // Instruction label. |
| - [instructions setFrameOrigin:NSMakePoint(0, NSMaxY([inputRow_ frame]) + |
| - chrome_style::kRowPadding)]; |
| - NSSize instructionsSize = [[instructions cell] |
| - cellSizeForBounds:NSMakeRect(0, 0, contentWidth, CGFLOAT_MAX)]; |
| - [instructions setFrameSize:instructionsSize]; |
| - |
| - // Title label. |
| - [title setFrameOrigin:NSMakePoint(0, NSMaxY([instructions frame]) + |
| - chrome_style::kRowPadding)]; |
| - |
| - // Dialog size. |
| - [mainView |
| - setFrameSize:NSMakeSize( |
| - contentWidth + [mainView contentViewMargins].width * 2.0, |
| - NSMaxY([title frame]) + chrome_style::kTitleTopPadding)]; |
| - |
| - // Add progress overlay. |
| - progressOverlayText_.reset([constrained_window::CreateLabel() retain]); |
| - CGFloat progressHeight = ui::ResourceBundle::GetSharedInstance() |
| - .GetFont(kProgressFontStyle) |
| - .GetHeight(); |
| - // Center the text vertically within inputRow_ frame. |
| - [progressOverlayText_ setFrame:NSMakeRect(0, ceil(NSMidY([inputRow_ frame]) - |
| - progressHeight / 2.0), |
| - contentWidth, progressHeight)]; |
| - [progressOverlayText_ setHidden:YES]; |
| - [mainView addSubview:progressOverlayText_]; |
| + // Layout inputRowView_. |
| + [CardUnmaskPromptViewCocoa sizeToFitView:inputRowView_]; |
| + [CardUnmaskPromptViewCocoa verticallyCenterSubviewsInView:inputRowView_]; |
| [self setView:mainView]; |
| + [self performLayout]; |
|
groby-ooo-7-16
2015/03/24 01:26:49
At this point -loadView will automatically display
bondd
2015/03/24 23:46:46
Done.
|
| } |
| @end |