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

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

Issue 1014683007: Autofill OSX: Add "Verifying card" / "Your card is verified" status overlay. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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
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/bind.h"
6 #include "base/message_loop/message_loop.h"
5 #include "base/strings/sys_string_conversions.h" 7 #include "base/strings/sys_string_conversions.h"
6 #include "chrome/browser/ui/autofill/autofill_dialog_models.h" 8 #include "chrome/browser/ui/autofill/autofill_dialog_models.h"
7 #include "chrome/browser/ui/autofill/card_unmask_prompt_controller.h" 9 #include "chrome/browser/ui/autofill/card_unmask_prompt_controller.h"
8 #include "chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.h" 10 #include "chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.h"
9 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_button.h" 11 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_button.h"
10 #include "chrome/browser/ui/chrome_style.h" 12 #include "chrome/browser/ui/chrome_style.h"
11 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_control_u tils.h" 13 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_control_u tils.h"
12 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sh eet.h" 14 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sh eet.h"
13 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_wi ndow.h" 15 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_wi ndow.h"
14 #import "chrome/browser/ui/cocoa/key_equivalent_constants.h" 16 #import "chrome/browser/ui/cocoa/key_equivalent_constants.h"
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 54
53 CardUnmaskPromptViewBridge::~CardUnmaskPromptViewBridge() { 55 CardUnmaskPromptViewBridge::~CardUnmaskPromptViewBridge() {
54 } 56 }
55 57
56 void CardUnmaskPromptViewBridge::ControllerGone() { 58 void CardUnmaskPromptViewBridge::ControllerGone() {
57 controller_ = nullptr; 59 controller_ = nullptr;
58 PerformClose(); 60 PerformClose();
59 } 61 }
60 62
61 void CardUnmaskPromptViewBridge::DisableAndWaitForVerification() { 63 void CardUnmaskPromptViewBridge::DisableAndWaitForVerification() {
62 [view_controller_ setInputsEnabled:false]; 64 [view_controller_ setInputRowHidden:YES];
63 [view_controller_ updateVerifyButtonEnabled]; 65 [view_controller_ updateVerifyButtonEnabled];
66
67 [view_controller_ setProgressOverlayText:
68 l10n_util::GetStringUTF16(
69 IDS_AUTOFILL_CARD_UNMASK_VERIFICATION_IN_PROGRESS)];
70 [view_controller_ setProgressOverlayHidden:NO];
64 } 71 }
65 72
66 void CardUnmaskPromptViewBridge::GotVerificationResult( 73 void CardUnmaskPromptViewBridge::GotVerificationResult(
67 const base::string16& error_message, 74 const base::string16& error_message,
68 bool allow_retry) { 75 bool allow_retry) {
69 [view_controller_ setInputsEnabled:true]; 76 if (error_message.empty()) {
70 [view_controller_ updateVerifyButtonEnabled]; 77 [view_controller_ setProgressOverlayText:
78 l10n_util::GetStringUTF16(
79 IDS_AUTOFILL_CARD_UNMASK_VERIFICATION_SUCCESS)];
80
81 base::MessageLoop::current()->PostDelayedTask(
82 FROM_HERE, base::Bind(&CardUnmaskPromptViewBridge::PerformClose,
83 base::Unretained(this)),
84 base::TimeDelta::FromSeconds(1));
bondd 2015/03/18 02:48:37 This call to PostDelayedTask is copied from the Vi
85 } else {
86 [view_controller_ setInputRowHidden:NO];
87 [view_controller_ setProgressOverlayHidden:YES];
88 [view_controller_ updateVerifyButtonEnabled];
89 }
71 } 90 }
72 91
73 void CardUnmaskPromptViewBridge::OnConstrainedWindowClosed( 92 void CardUnmaskPromptViewBridge::OnConstrainedWindowClosed(
74 ConstrainedWindowMac* window) { 93 ConstrainedWindowMac* window) {
75 constrained_window_.reset(); 94 constrained_window_.reset();
76 if (controller_) 95 if (controller_)
77 controller_->OnUnmaskDialogClosed(); 96 controller_->OnUnmaskDialogClosed();
78 } 97 }
79 98
80 CardUnmaskPromptController* CardUnmaskPromptViewBridge::GetController() { 99 CardUnmaskPromptController* CardUnmaskPromptViewBridge::GetController() {
81 return controller_; 100 return controller_;
82 } 101 }
83 102
84 void CardUnmaskPromptViewBridge::PerformClose() { 103 void CardUnmaskPromptViewBridge::PerformClose() {
85 constrained_window_->CloseWebContentsModalDialog(); 104 constrained_window_->CloseWebContentsModalDialog();
86 } 105 }
87 106
88 } // autofill 107 } // autofill
89 108
90 #pragma mark CardUnmaskPromptViewCocoa 109 #pragma mark CardUnmaskPromptViewCocoa
91 110
92 @implementation CardUnmaskPromptViewCocoa { 111 @implementation CardUnmaskPromptViewCocoa {
93 base::scoped_nsobject<NSTextField> cvcInput_; 112 base::scoped_nsobject<NSTextField> cvcInput_;
94 base::scoped_nsobject<NSPopUpButton> monthPopup_; 113 base::scoped_nsobject<NSPopUpButton> monthPopup_;
95 base::scoped_nsobject<NSPopUpButton> yearPopup_; 114 base::scoped_nsobject<NSPopUpButton> yearPopup_;
96 base::scoped_nsobject<NSButton> verifyButton_; 115 base::scoped_nsobject<NSButton> verifyButton_;
116 base::scoped_nsobject<NSView> inputRow_;
117 base::scoped_nsobject<NSView> progressOverlay_;
groby-ooo-7-16 2015/03/18 07:10:05 Why a separate view and not just a text field?
bondd 2015/03/18 22:01:40 Done.
118 base::scoped_nsobject<NSTextField> progressOverlayText_;
97 119
98 int monthPopupDefaultIndex_; 120 int monthPopupDefaultIndex_;
99 int yearPopupDefaultIndex_; 121 int yearPopupDefaultIndex_;
100 122
101 // Owns |self|. 123 // Owns |self|.
102 autofill::CardUnmaskPromptViewBridge* bridge_; 124 autofill::CardUnmaskPromptViewBridge* bridge_;
103 } 125 }
104 126
105 + (NSPopUpButton*)buildDatePopupWithModel:(ui::ComboboxModel&)model { 127 + (NSPopUpButton*)buildDatePopupWithModel:(ui::ComboboxModel&)model {
106 NSPopUpButton* popup = 128 NSPopUpButton* popup =
(...skipping 27 matching lines...) Expand all
134 156
135 - (id)initWithBridge:(autofill::CardUnmaskPromptViewBridge*)bridge { 157 - (id)initWithBridge:(autofill::CardUnmaskPromptViewBridge*)bridge {
136 DCHECK(bridge); 158 DCHECK(bridge);
137 159
138 if ((self = [super initWithNibName:nil bundle:nil])) 160 if ((self = [super initWithNibName:nil bundle:nil]))
139 bridge_ = bridge; 161 bridge_ = bridge;
140 162
141 return self; 163 return self;
142 } 164 }
143 165
144 - (void)setInputsEnabled:(BOOL)enabled { 166 - (void)setInputRowHidden:(BOOL)hidden {
145 [cvcInput_ setEnabled:enabled]; 167 [inputRow_ setHidden:hidden];
146 [monthPopup_ setEnabled:enabled]; 168 }
147 [yearPopup_ setEnabled:enabled]; 169
170 - (void)setProgressOverlayHidden:(BOOL)hidden {
171 [progressOverlay_ setHidden:hidden];
172 }
173
174 - (void)setProgressOverlayText:(const base::string16&)text {
175 NSAttributedString* attributedString =
176 constrained_window::GetAttributedLabelString(
177 SysUTF16ToNSString(text), chrome_style::kTitleFontStyle,
178 NSCenterTextAlignment, NSLineBreakByWordWrapping);
179 [progressOverlayText_ setAttributedStringValue:attributedString];
180
181 [progressOverlayText_ sizeToFit];
182 [progressOverlayText_
183 setFrameSize:NSMakeSize(NSWidth([progressOverlay_ frame]),
184 NSHeight([progressOverlayText_ frame]))];
185 [CardUnmaskPromptViewCocoa verticallyCenterSubviewsInView:progressOverlay_];
148 } 186 }
149 187
150 - (void)updateVerifyButtonEnabled { 188 - (void)updateVerifyButtonEnabled {
151 autofill::CardUnmaskPromptController* controller = bridge_->GetController(); 189 autofill::CardUnmaskPromptController* controller = bridge_->GetController();
152 DCHECK(controller); 190 DCHECK(controller);
153 191
154 BOOL enable = 192 BOOL enable =
155 [cvcInput_ isEnabled] && 193 ![inputRow_ isHidden] &&
156 controller->InputCvcIsValid( 194 controller->InputCvcIsValid(
157 base::SysNSStringToUTF16([cvcInput_ stringValue])) && 195 base::SysNSStringToUTF16([cvcInput_ stringValue])) &&
158 (!monthPopup_ || 196 (!monthPopup_ ||
159 [monthPopup_ indexOfSelectedItem] != monthPopupDefaultIndex_) && 197 [monthPopup_ indexOfSelectedItem] != monthPopupDefaultIndex_) &&
160 (!yearPopup_ || 198 (!yearPopup_ ||
161 [yearPopup_ indexOfSelectedItem] != yearPopupDefaultIndex_); 199 [yearPopup_ indexOfSelectedItem] != yearPopupDefaultIndex_);
162 200
163 [verifyButton_ setEnabled:enable]; 201 [verifyButton_ setEnabled:enable];
164 } 202 }
165 203
(...skipping 13 matching lines...) Expand all
179 217
180 - (void)onExpirationDateChanged:(id)sender { 218 - (void)onExpirationDateChanged:(id)sender {
181 [self updateVerifyButtonEnabled]; 219 [self updateVerifyButtonEnabled];
182 } 220 }
183 221
184 // Called when text in CVC input field changes. 222 // Called when text in CVC input field changes.
185 - (void)controlTextDidChange:(NSNotification*)notification { 223 - (void)controlTextDidChange:(NSNotification*)notification {
186 [self updateVerifyButtonEnabled]; 224 [self updateVerifyButtonEnabled];
187 } 225 }
188 226
227 - (void)createProgressOverlay {
228 progressOverlay_.reset([[NSView alloc] initWithFrame:NSZeroRect]);
229 progressOverlayText_.reset([constrained_window::CreateLabel() retain]);
230 [progressOverlay_ addSubview:progressOverlayText_];
231 [progressOverlay_ setHidden:YES];
232 }
233
189 - (void)loadView { 234 - (void)loadView {
190 autofill::CardUnmaskPromptController* controller = bridge_->GetController(); 235 autofill::CardUnmaskPromptController* controller = bridge_->GetController();
191 DCHECK(controller); 236 DCHECK(controller);
192 237
193 base::scoped_nsobject<NSBox> mainView( 238 base::scoped_nsobject<NSBox> mainView(
194 [[NSBox alloc] initWithFrame:NSZeroRect]); 239 [[NSBox alloc] initWithFrame:NSZeroRect]);
195 [mainView setBoxType:NSBoxCustom]; 240 [mainView setBoxType:NSBoxCustom];
196 [mainView setBorderType:NSNoBorder]; 241 [mainView setBorderType:NSNoBorder];
197 [mainView setTitlePosition:NSNoTitle]; 242 [mainView setTitlePosition:NSNoTitle];
198 [mainView 243 [mainView
199 setContentViewMargins:NSMakeSize(chrome_style::kHorizontalPadding, 0)]; 244 setContentViewMargins:NSMakeSize(chrome_style::kHorizontalPadding, 0)];
200 245
201 base::scoped_nsobject<NSView> inputRowView( 246 inputRow_.reset([[NSView alloc] initWithFrame:NSZeroRect]);
202 [[NSView alloc] initWithFrame:NSZeroRect]); 247 [mainView addSubview:inputRow_];
203 [mainView addSubview:inputRowView];
204 248
205 // Title label. 249 // Title label.
206 NSTextField* title = constrained_window::CreateLabel(); 250 NSTextField* title = constrained_window::CreateLabel();
207 NSAttributedString* titleString = 251 NSAttributedString* titleString =
208 constrained_window::GetAttributedLabelString( 252 constrained_window::GetAttributedLabelString(
209 SysUTF16ToNSString(controller->GetWindowTitle()), 253 SysUTF16ToNSString(controller->GetWindowTitle()),
210 chrome_style::kTitleFontStyle, NSNaturalTextAlignment, 254 chrome_style::kTitleFontStyle, NSNaturalTextAlignment,
211 NSLineBreakByWordWrapping); 255 NSLineBreakByWordWrapping);
212 [title setAttributedStringValue:titleString]; 256 [title setAttributedStringValue:titleString];
213 [title sizeToFit]; 257 [title sizeToFit];
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 [expirationView addSubview:yearPopup_]; 291 [expirationView addSubview:yearPopup_];
248 292
249 // Layout month and year within expirationView. 293 // Layout month and year within expirationView.
250 [yearPopup_ 294 [yearPopup_
251 setFrameOrigin:NSMakePoint(NSMaxX([monthPopup_ frame]) + kButtonGap, 295 setFrameOrigin:NSMakePoint(NSMaxX([monthPopup_ frame]) + kButtonGap,
252 0)]; 296 0)];
253 NSRect expirationFrame = 297 NSRect expirationFrame =
254 NSUnionRect([monthPopup_ frame], [yearPopup_ frame]); 298 NSUnionRect([monthPopup_ frame], [yearPopup_ frame]);
255 expirationFrame.size.width += kButtonGap; 299 expirationFrame.size.width += kButtonGap;
256 [expirationView setFrame:expirationFrame]; 300 [expirationView setFrame:expirationFrame];
257 [inputRowView addSubview:expirationView]; 301 [inputRow_ addSubview:expirationView];
258 } 302 }
259 303
260 // CVC text input. 304 // CVC text input.
261 cvcInput_.reset([[NSTextField alloc] initWithFrame:NSZeroRect]); 305 cvcInput_.reset([[NSTextField alloc] initWithFrame:NSZeroRect]);
262 [[cvcInput_ cell] 306 [[cvcInput_ cell]
263 setPlaceholderString:l10n_util::GetNSString( 307 setPlaceholderString:l10n_util::GetNSString(
264 IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC)]; 308 IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC)];
265 [[cvcInput_ cell] setScrollable:YES]; 309 [[cvcInput_ cell] setScrollable:YES];
266 [cvcInput_ setDelegate:self]; 310 [cvcInput_ setDelegate:self];
267 [cvcInput_ sizeToFit]; 311 [cvcInput_ sizeToFit];
268 [cvcInput_ setFrame:NSMakeRect(NSMaxX([expirationView frame]), 0, 312 [cvcInput_ setFrame:NSMakeRect(NSMaxX([expirationView frame]), 0,
269 kCvcInputWidth, NSHeight([cvcInput_ frame]))]; 313 kCvcInputWidth, NSHeight([cvcInput_ frame]))];
270 [inputRowView addSubview:cvcInput_]; 314 [inputRow_ addSubview:cvcInput_];
271 315
272 // CVC image. 316 // CVC image.
273 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 317 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
274 NSImage* cvcImage = 318 NSImage* cvcImage =
275 rb.GetNativeImageNamed(controller->GetCvcImageRid()).ToNSImage(); 319 rb.GetNativeImageNamed(controller->GetCvcImageRid()).ToNSImage();
276 base::scoped_nsobject<NSImageView> cvcImageView( 320 base::scoped_nsobject<NSImageView> cvcImageView(
277 [[NSImageView alloc] initWithFrame:NSZeroRect]); 321 [[NSImageView alloc] initWithFrame:NSZeroRect]);
278 [cvcImageView setImage:cvcImage]; 322 [cvcImageView setImage:cvcImage];
279 [cvcImageView setFrameSize:[cvcImage size]]; 323 [cvcImageView setFrameSize:[cvcImage size]];
280 [cvcImageView 324 [cvcImageView
281 setFrameOrigin:NSMakePoint(NSMaxX([cvcInput_ frame]) + kButtonGap, 0)]; 325 setFrameOrigin:NSMakePoint(NSMaxX([cvcInput_ frame]) + kButtonGap, 0)];
282 [inputRowView addSubview:cvcImageView]; 326 [inputRow_ addSubview:cvcImageView];
283 327
284 // Cancel button. 328 // Cancel button.
285 base::scoped_nsobject<NSButton> cancelButton( 329 base::scoped_nsobject<NSButton> cancelButton(
286 [[ConstrainedWindowButton alloc] initWithFrame:NSZeroRect]); 330 [[ConstrainedWindowButton alloc] initWithFrame:NSZeroRect]);
287 [cancelButton setTitle:l10n_util::GetNSStringWithFixup(IDS_CANCEL)]; 331 [cancelButton setTitle:l10n_util::GetNSStringWithFixup(IDS_CANCEL)];
288 [cancelButton setKeyEquivalent:kKeyEquivalentEscape]; 332 [cancelButton setKeyEquivalent:kKeyEquivalentEscape];
289 [cancelButton setTarget:self]; 333 [cancelButton setTarget:self];
290 [cancelButton setAction:@selector(onCancel:)]; 334 [cancelButton setAction:@selector(onCancel:)];
291 [cancelButton sizeToFit]; 335 [cancelButton sizeToFit];
292 [mainView addSubview:cancelButton]; 336 [mainView addSubview:cancelButton];
293 337
294 // Verify button. 338 // Verify button.
295 verifyButton_.reset( 339 verifyButton_.reset(
296 [[ConstrainedWindowButton alloc] initWithFrame:NSZeroRect]); 340 [[ConstrainedWindowButton alloc] initWithFrame:NSZeroRect]);
297 // TODO(bondd): use l10n string. 341 // TODO(bondd): use l10n string.
298 [verifyButton_ setTitle:@"Verify"]; 342 [verifyButton_ setTitle:@"Verify"];
299 [verifyButton_ setKeyEquivalent:kKeyEquivalentReturn]; 343 [verifyButton_ setKeyEquivalent:kKeyEquivalentReturn];
300 [verifyButton_ setTarget:self]; 344 [verifyButton_ setTarget:self];
301 [verifyButton_ setAction:@selector(onVerify:)]; 345 [verifyButton_ setAction:@selector(onVerify:)];
302 [verifyButton_ sizeToFit]; 346 [verifyButton_ sizeToFit];
303 [self updateVerifyButtonEnabled]; 347 [self updateVerifyButtonEnabled];
304 [mainView addSubview:verifyButton_]; 348 [mainView addSubview:verifyButton_];
305 349
306 // Layout inputRowView. 350 // Layout inputRow_.
307 [CardUnmaskPromptViewCocoa sizeToFitView:inputRowView]; 351 [CardUnmaskPromptViewCocoa sizeToFitView:inputRow_];
308 [CardUnmaskPromptViewCocoa verticallyCenterSubviewsInView:inputRowView]; 352 [CardUnmaskPromptViewCocoa verticallyCenterSubviewsInView:inputRow_];
309 353
310 // Calculate dialog content width. 354 // Calculate dialog content width.
311 CGFloat contentWidth = 355 CGFloat contentWidth =
312 std::max(NSWidth([title frame]), NSWidth([inputRowView frame])); 356 std::max(NSWidth([title frame]), NSWidth([inputRow_ frame]));
313 contentWidth = std::max(contentWidth, kDialogContentMinWidth); 357 contentWidth = std::max(contentWidth, kDialogContentMinWidth);
314 358
315 // Layout mainView contents, starting at the bottom and moving up. 359 // Layout mainView contents, starting at the bottom and moving up.
316 360
317 // Verify and Cancel buttons. 361 // Verify and Cancel buttons.
318 [verifyButton_ 362 [verifyButton_
319 setFrameOrigin:NSMakePoint(contentWidth - NSWidth([verifyButton_ frame]), 363 setFrameOrigin:NSMakePoint(contentWidth - NSWidth([verifyButton_ frame]),
320 chrome_style::kClientBottomPadding)]; 364 chrome_style::kClientBottomPadding)];
321 365
322 [cancelButton 366 [cancelButton
323 setFrameOrigin:NSMakePoint(NSMinX([verifyButton_ frame]) - kButtonGap - 367 setFrameOrigin:NSMakePoint(NSMinX([verifyButton_ frame]) - kButtonGap -
324 NSWidth([cancelButton frame]), 368 NSWidth([cancelButton frame]),
325 NSMinY([verifyButton_ frame]))]; 369 NSMinY([verifyButton_ frame]))];
326 370
327 // Input row. 371 // Input row.
328 [inputRowView setFrameOrigin:NSMakePoint(0, NSMaxY([cancelButton frame]) + 372 [inputRow_ setFrameOrigin:NSMakePoint(0, NSMaxY([cancelButton frame]) +
329 chrome_style::kRowPadding)]; 373 chrome_style::kRowPadding)];
330 374
331 // Instruction label. 375 // Instruction label.
332 [instructions setFrameOrigin:NSMakePoint(0, NSMaxY([inputRowView frame]) + 376 [instructions setFrameOrigin:NSMakePoint(0, NSMaxY([inputRow_ frame]) +
333 chrome_style::kRowPadding)]; 377 chrome_style::kRowPadding)];
334 NSSize instructionsSize = [[instructions cell] 378 NSSize instructionsSize = [[instructions cell]
335 cellSizeForBounds:NSMakeRect(0, 0, contentWidth, CGFLOAT_MAX)]; 379 cellSizeForBounds:NSMakeRect(0, 0, contentWidth, CGFLOAT_MAX)];
336 [instructions setFrameSize:instructionsSize]; 380 [instructions setFrameSize:instructionsSize];
337 381
338 // Title label. 382 // Title label.
339 [title setFrameOrigin:NSMakePoint(0, NSMaxY([instructions frame]) + 383 [title setFrameOrigin:NSMakePoint(0, NSMaxY([instructions frame]) +
340 chrome_style::kRowPadding)]; 384 chrome_style::kRowPadding)];
341 385
342 // Dialog size. 386 // Dialog size.
343 [mainView 387 [mainView
344 setFrameSize:NSMakeSize( 388 setFrameSize:NSMakeSize(
345 contentWidth + [mainView contentViewMargins].width * 2.0, 389 contentWidth + [mainView contentViewMargins].width * 2.0,
346 NSMaxY([title frame]) + chrome_style::kTitleTopPadding)]; 390 NSMaxY([title frame]) + chrome_style::kTitleTopPadding)];
347 391
392 // Add progress overlay.
393 [self createProgressOverlay];
groby-ooo-7-16 2015/03/18 07:10:05 In case it becomes a single view, doing this inlin
bondd 2015/03/18 22:01:40 Done. I also did an alternate implementation where
394 [progressOverlay_
395 setFrame:NSMakeRect(0, NSMinY([inputRow_ frame]), contentWidth,
396 NSHeight([inputRow_ frame]))];
397 [mainView addSubview:progressOverlay_];
398
348 [self setView:mainView]; 399 [self setView:mainView];
349 } 400 }
350 401
351 @end 402 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698