Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(597)

Side by Side Diff: chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.mm

Issue 929293005: Autofill: Add contents of CVC unmask prompt dialog on OSX. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@cup_01_initial_add
Patch Set: Address groby@ comments for patch set 3 - make layout code less verbose. Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. 1 // Copyright (c) 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 #include "base/strings/sys_string_conversions.h"
6 #include "chrome/browser/ui/autofill/autofill_dialog_models.h"
5 #include "chrome/browser/ui/autofill/card_unmask_prompt_controller.h" 7 #include "chrome/browser/ui/autofill/card_unmask_prompt_controller.h"
6 #include "chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.h" 8 #include "chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.h"
9 #import "chrome/browser/ui/cocoa/autofill/autofill_pop_up_button.h"
7 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_button.h" 10 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_button.h"
8 #include "chrome/browser/ui/chrome_style.h" 11 #include "chrome/browser/ui/chrome_style.h"
12 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_control_u tils.h"
9 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sh eet.h" 13 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sh eet.h"
10 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_wi ndow.h" 14 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_wi ndow.h"
11 #import "chrome/browser/ui/cocoa/key_equivalent_constants.h" 15 #import "chrome/browser/ui/cocoa/key_equivalent_constants.h"
12 #include "grit/generated_resources.h" 16 #include "grit/generated_resources.h"
13 #include "ui/base/cocoa/window_size_constants.h" 17 #include "ui/base/cocoa/window_size_constants.h"
14 #include "ui/base/l10n/l10n_util.h" 18 #include "ui/base/l10n/l10n_util.h"
15 19
16 namespace { 20 namespace {
21
17 const CGFloat kButtonGap = 6.0f; 22 const CGFloat kButtonGap = 6.0f;
23 const CGFloat kDialogContentMinWidth = 210.0f;
24 const CGFloat kCvcInputWidth = 64.0f;
25
18 } // namespace 26 } // namespace
19 27
20 namespace autofill { 28 namespace autofill {
21 29
22 // static 30 // static
23 CardUnmaskPromptView* CardUnmaskPromptView::CreateAndShow( 31 CardUnmaskPromptView* CardUnmaskPromptView::CreateAndShow(
24 CardUnmaskPromptController* controller) { 32 CardUnmaskPromptController* controller) {
25 return new CardUnmaskPromptViewBridge(controller); 33 return new CardUnmaskPromptViewBridge(controller);
26 } 34 }
27 35
28 #pragma mark CardUnmaskPromptViewBridge 36 #pragma mark CardUnmaskPromptViewBridge
29 37
30 CardUnmaskPromptViewBridge::CardUnmaskPromptViewBridge( 38 CardUnmaskPromptViewBridge::CardUnmaskPromptViewBridge(
31 CardUnmaskPromptController* controller) 39 CardUnmaskPromptController* controller)
32 : controller_(controller) { 40 : controller_(controller) {
33 sheet_controller_.reset([[CardUnmaskPromptViewCocoa alloc] 41 view_controller_.reset([[CardUnmaskPromptViewCocoa alloc]
34 initWithWebContents:controller_->GetWebContents() 42 initWithWebContents:controller_->GetWebContents()
35 bridge:this]); 43 bridge:this]);
44
45 // Setup the constrained window that will show the view.
46 base::scoped_nsobject<NSWindow> window([[ConstrainedWindowCustomWindow alloc]
47 initWithContentRect:[[view_controller_ view] bounds]]);
48 [window setContentView:[view_controller_ view]];
36 base::scoped_nsobject<CustomConstrainedWindowSheet> sheet( 49 base::scoped_nsobject<CustomConstrainedWindowSheet> sheet(
37 [[CustomConstrainedWindowSheet alloc] 50 [[CustomConstrainedWindowSheet alloc] initWithCustomWindow:window]);
38 initWithCustomWindow:[sheet_controller_ window]]);
39 constrained_window_.reset( 51 constrained_window_.reset(
40 new ConstrainedWindowMac(this, controller_->GetWebContents(), sheet)); 52 new ConstrainedWindowMac(this, controller_->GetWebContents(), sheet));
41 } 53 }
42 54
43 CardUnmaskPromptViewBridge::~CardUnmaskPromptViewBridge() { 55 CardUnmaskPromptViewBridge::~CardUnmaskPromptViewBridge() {
44 } 56 }
45 57
46 void CardUnmaskPromptViewBridge::ControllerGone() { 58 void CardUnmaskPromptViewBridge::ControllerGone() {
59 controller_ = nullptr;
60 PerformClose();
47 } 61 }
48 62
49 void CardUnmaskPromptViewBridge::DisableAndWaitForVerification() { 63 void CardUnmaskPromptViewBridge::DisableAndWaitForVerification() {
50 } 64 }
51 65
52 void CardUnmaskPromptViewBridge::GotVerificationResult(bool success) { 66 void CardUnmaskPromptViewBridge::GotVerificationResult(bool success) {
53 } 67 }
54 68
55 void CardUnmaskPromptViewBridge::OnConstrainedWindowClosed( 69 void CardUnmaskPromptViewBridge::OnConstrainedWindowClosed(
56 ConstrainedWindowMac* window) { 70 ConstrainedWindowMac* window) {
57 constrained_window_.reset(); 71 constrained_window_.reset();
58 controller_->OnUnmaskDialogClosed(); 72 if (controller_)
73 controller_->OnUnmaskDialogClosed();
74 }
75
76 CardUnmaskPromptController* CardUnmaskPromptViewBridge::GetController() {
77 return controller_;
59 } 78 }
60 79
61 void CardUnmaskPromptViewBridge::PerformClose() { 80 void CardUnmaskPromptViewBridge::PerformClose() {
62 constrained_window_->CloseWebContentsModalDialog(); 81 constrained_window_->CloseWebContentsModalDialog();
63 } 82 }
64 83
65 } // autofill 84 } // autofill
66 85
67 #pragma mark CardUnmaskPromptViewCocoa 86 #pragma mark CardUnmaskPromptViewCocoa
68 87
69 @implementation CardUnmaskPromptViewCocoa 88 @implementation CardUnmaskPromptViewCocoa
70 89
90 + (AutofillPopUpButton*)buildDatePopupWithModel:(ui::ComboboxModel&)model {
91 AutofillPopUpButton* popup =
92 [[AutofillPopUpButton alloc] initWithFrame:NSZeroRect pullsDown:NO];
93
94 for (int i = 0; i < model.GetItemCount(); ++i) {
95 [popup addItemWithTitle:base::SysUTF16ToNSString(model.GetItemAt(i))];
96 }
97 [popup setDefaultValue:base::SysUTF16ToNSString(
98 model.GetItemAt(model.GetDefaultIndex()))];
99 [popup sizeToFit];
100 return popup;
101 }
102
103 // Set |view|'s frame to the minimum dimensions required to contain all of its
104 // subviews.
105 + (void)sizeToFitView:(NSView*)view {
bondd 2015/03/04 20:45:30 Moved inputRowView layout to these helper methods
groby-ooo-7-16 2015/03/06 00:12:27 Acknowledged.
106 NSRect frame = NSZeroRect;
107 for (NSView* child in [view subviews]) {
108 frame = NSUnionRect(frame, [child frame]);
109 }
110 [view setFrame:frame];
111 }
112
113 + (void)verticallyCenterSubviewsInView:(NSView*)view {
bondd 2015/03/04 20:45:30 Is there an easier way to center elements vertical
groby-ooo-7-16 2015/03/06 00:12:27 I don't think there is.
114 CGFloat height = NSHeight([view frame]);
115 for (NSView* child in [view subviews]) {
116 [child setFrameOrigin:NSMakePoint(
117 NSMinX([child frame]),
118 ceil((height - NSHeight([child frame])) * 0.5))];
119 }
120 }
121
71 - (id)initWithWebContents:(content::WebContents*)webContents 122 - (id)initWithWebContents:(content::WebContents*)webContents
72 bridge:(autofill::CardUnmaskPromptViewBridge*)bridge { 123 bridge:(autofill::CardUnmaskPromptViewBridge*)bridge {
73 DCHECK(webContents); 124 DCHECK(webContents);
74 DCHECK(bridge); 125 DCHECK(bridge);
75 126
76 NSRect frame = NSMakeRect(0, 0, 550, 600); 127 if ((self = [super initWithNibName:nil bundle:nil])) {
77 base::scoped_nsobject<ConstrainedWindowCustomWindow> window(
78 [[ConstrainedWindowCustomWindow alloc] initWithContentRect:frame]);
79 if ((self = [super initWithWindow:window])) {
80 webContents_ = webContents; 128 webContents_ = webContents;
81 bridge_ = bridge; 129 bridge_ = bridge;
82
83 [self buildWindowButtons];
84 } 130 }
85 return self; 131 return self;
86 } 132 }
87 133
88 - (IBAction)closeSheet:(id)sender { 134 - (IBAction)closeSheet:(id)sender {
89 bridge_->PerformClose(); 135 bridge_->PerformClose();
90 } 136 }
91 137
92 - (void)buildWindowButtons { 138 - (void)loadView {
93 base::scoped_nsobject<NSView> buttonContainer( 139 autofill::CardUnmaskPromptController* controller = bridge_->GetController();
140 DCHECK(controller);
141
142 base::scoped_nsobject<NSBox> mainView(
143 [[NSBox alloc] initWithFrame:NSZeroRect]);
144 [mainView setBoxType:NSBoxCustom];
145 [mainView setBorderType:NSNoBorder];
146 [mainView setTitlePosition:NSNoTitle];
147 [mainView
148 setContentViewMargins:NSMakeSize(chrome_style::kHorizontalPadding, 0)];
149
150 base::scoped_nsobject<NSView> inputRowView(
bondd 2015/03/04 20:45:31 Gave input row its own NSView. I think it makes th
groby-ooo-7-16 2015/03/06 00:12:26 Acknowledged.
94 [[NSView alloc] initWithFrame:NSZeroRect]); 151 [[NSView alloc] initWithFrame:NSZeroRect]);
152 [mainView addSubview:inputRowView];
95 153
96 base::scoped_nsobject<NSButton> button( 154 // Title label.
155 NSTextField* title = constrained_window::CreateLabel();
156 NSAttributedString* titleString =
157 constrained_window::GetAttributedLabelString(
158 SysUTF16ToNSString(controller->GetWindowTitle()),
159 chrome_style::kTitleFontStyle, NSNaturalTextAlignment,
160 NSLineBreakByWordWrapping);
161 [title setAttributedStringValue:titleString];
162 [title sizeToFit];
163 [mainView addSubview:title];
164
165 // Instructions label.
166 NSTextField* instructions = constrained_window::CreateLabel();
167 NSAttributedString* instructionsString =
168 constrained_window::GetAttributedLabelString(
169 SysUTF16ToNSString(controller->GetInstructionsMessage()),
170 chrome_style::kTextFontStyle, NSNaturalTextAlignment,
171 NSLineBreakByWordWrapping);
172 [instructions setAttributedStringValue:instructionsString];
173 [mainView addSubview:instructions];
174
175 // Expiration date.
176 base::scoped_nsobject<NSView> expirationView;
177 if (controller->ShouldRequestExpirationDate()) {
178 expirationView.reset([[NSView alloc] initWithFrame:NSZeroRect]);
179
180 // Month.
181 autofill::MonthComboboxModel monthModel;
182 base::scoped_nsobject<AutofillPopUpButton> monthPopup(
183 [CardUnmaskPromptViewCocoa buildDatePopupWithModel:monthModel]);
184 [expirationView addSubview:monthPopup];
185
186 // Year.
187 autofill::YearComboboxModel yearModel;
188 base::scoped_nsobject<AutofillPopUpButton> yearPopup(
189 [CardUnmaskPromptViewCocoa buildDatePopupWithModel:yearModel]);
190 [expirationView addSubview:yearPopup];
191
192 // Layout month and year within expirationView.
193 [yearPopup
194 setFrameOrigin:NSMakePoint(NSMaxX([monthPopup frame]) + kButtonGap, 0)];
195 NSRect expirationFrame = NSUnionRect([monthPopup frame], [yearPopup frame]);
196 expirationFrame.size.width += kButtonGap;
197 [expirationView setFrame:expirationFrame];
198 [inputRowView addSubview:expirationView];
199 }
200
201 // CVC text input.
202 base::scoped_nsobject<NSTextField> cvcInput(
203 [[NSTextField alloc] initWithFrame:NSZeroRect]);
204 [[cvcInput cell]
205 setPlaceholderString:l10n_util::GetNSString(
206 IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC)];
207 [[cvcInput cell] setScrollable:YES];
208 [cvcInput sizeToFit];
209 [cvcInput setFrame:NSMakeRect(NSMaxX([expirationView frame]), 0,
210 kCvcInputWidth, NSHeight([cvcInput frame]))];
211 [inputRowView addSubview:cvcInput];
212
213 // CVC image.
214 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
215 NSImage* cvcImage =
216 rb.GetNativeImageNamed(controller->GetCvcImageRid()).ToNSImage();
217 base::scoped_nsobject<NSImageView> cvcImageView(
218 [[NSImageView alloc] initWithFrame:NSZeroRect]);
219 [cvcImageView setImage:cvcImage];
220 [cvcImageView setFrameSize:[cvcImage size]];
221 [cvcImageView
222 setFrameOrigin:NSMakePoint(NSMaxX([cvcInput frame]) + kButtonGap, 0)];
223 [inputRowView addSubview:cvcImageView];
224
225 // Cancel button.
226 base::scoped_nsobject<NSButton> cancelButton(
97 [[ConstrainedWindowButton alloc] initWithFrame:NSZeroRect]); 227 [[ConstrainedWindowButton alloc] initWithFrame:NSZeroRect]);
98 [button setTitle:l10n_util::GetNSStringWithFixup(IDS_CANCEL)]; 228 [cancelButton setTitle:l10n_util::GetNSStringWithFixup(IDS_CANCEL)];
99 [button setKeyEquivalent:kKeyEquivalentEscape]; 229 [cancelButton setKeyEquivalent:kKeyEquivalentEscape];
100 [button setTarget:self]; 230 [cancelButton setTarget:self];
101 [button setAction:@selector(closeSheet:)]; 231 [cancelButton setAction:@selector(closeSheet:)];
102 [button sizeToFit]; 232 [cancelButton sizeToFit];
103 [buttonContainer addSubview:button]; 233 [mainView addSubview:cancelButton];
104 234
105 CGFloat nextX = NSMaxX([button frame]) + kButtonGap; 235 // Verify button.
106 button.reset([[ConstrainedWindowButton alloc] initWithFrame:NSZeroRect]); 236 base::scoped_nsobject<NSButton> verifyButton(
107 [button setFrameOrigin:NSMakePoint(nextX, 0)]; 237 [[ConstrainedWindowButton alloc] initWithFrame:NSZeroRect]);
108 [button setTitle:l10n_util::GetNSStringWithFixup( 238 // TODO(bondd): use l10n string.
109 IDS_AUTOFILL_DIALOG_SUBMIT_BUTTON)]; 239 [verifyButton setTitle:@"Verify"];
110 [button setKeyEquivalent:kKeyEquivalentReturn]; 240 [verifyButton setKeyEquivalent:kKeyEquivalentReturn];
111 [button setTarget:self]; 241 [verifyButton setTarget:self];
112 [button setAction:@selector(closeSheet:)]; 242 [verifyButton setAction:@selector(closeSheet:)];
113 [button sizeToFit]; 243 [verifyButton sizeToFit];
114 [buttonContainer addSubview:button]; 244 [mainView addSubview:verifyButton];
115 245
116 const CGFloat dialogOffset = NSWidth([[self window] frame]) - 246 // Layout inputRowView.
117 chrome_style::kHorizontalPadding - 247 [CardUnmaskPromptViewCocoa sizeToFitView:inputRowView];
118 NSMaxX([button frame]); 248 [CardUnmaskPromptViewCocoa verticallyCenterSubviewsInView:inputRowView];
119 [buttonContainer
120 setFrame:NSMakeRect(dialogOffset, chrome_style::kClientBottomPadding,
121 NSMaxX([button frame]), NSMaxY([button frame]))];
122 249
123 [[[self window] contentView] addSubview:buttonContainer]; 250 // Calculate dialog content width.
251 CGFloat contentWidth =
252 std::max(NSWidth([title frame]), NSWidth([inputRowView frame]));
253 contentWidth = std::max(contentWidth, kDialogContentMinWidth);
254
255 // Layout mainView contents, starting at the bottom and moving up.
256
257 // Verify and Cancel buttons.
258 [verifyButton
259 setFrameOrigin:NSMakePoint(contentWidth - NSWidth([verifyButton frame]),
260 chrome_style::kClientBottomPadding)];
261
262 [cancelButton
263 setFrameOrigin:NSMakePoint(NSMinX([verifyButton frame]) - kButtonGap -
264 NSWidth([cancelButton frame]),
265 NSMinY([verifyButton frame]))];
266
267 // Input row.
268 [inputRowView setFrameOrigin:NSMakePoint(0, NSMaxY([cancelButton frame]) +
269 chrome_style::kRowPadding)];
270
271 // Instruction label.
272 [instructions setFrameOrigin:NSMakePoint(0, NSMaxY([inputRowView frame]) +
273 chrome_style::kRowPadding)];
274 NSSize instructionsSize = [[instructions cell]
275 cellSizeForBounds:NSMakeRect(0, 0, contentWidth, CGFLOAT_MAX)];
276 [instructions setFrameSize:instructionsSize];
277
278 // Title label.
279 [title setFrameOrigin:NSMakePoint(0, NSMaxY([instructions frame]) +
280 chrome_style::kRowPadding)];
281
282 // Dialog size.
283 [mainView
284 setFrameSize:NSMakeSize(
285 contentWidth + [mainView contentViewMargins].width * 2.0,
286 NSMaxY([title frame]) + chrome_style::kTitleTopPadding)];
287
288 [self setView:mainView];
124 } 289 }
125 290
126 @end 291 @end
OLDNEW
« no previous file with comments | « chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698