| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.h" | 5 #include "chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/mac/bundle_locations.h" | 8 #include "base/mac/bundle_locations.h" |
| 9 #include "base/mac/scoped_nsobject.h" | 9 #include "base/mac/scoped_nsobject.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| 11 #include "base/strings/sys_string_conversions.h" | 11 #include "base/strings/sys_string_conversions.h" |
| 12 #include "chrome/browser/ui/autofill/autofill_dialog_view_delegate.h" | 12 #include "chrome/browser/ui/autofill/autofill_dialog_view_delegate.h" |
| 13 #include "chrome/browser/ui/chrome_style.h" | 13 #include "chrome/browser/ui/chrome_style.h" |
| 14 #include "chrome/browser/ui/chrome_style.h" | 14 #include "chrome/browser/ui/chrome_style.h" |
| 15 #include "chrome/browser/ui/chrome_style.h" | 15 #include "chrome/browser/ui/chrome_style.h" |
| 16 #import "chrome/browser/ui/cocoa/autofill/autofill_account_chooser.h" | 16 #import "chrome/browser/ui/cocoa/autofill/autofill_account_chooser.h" |
| 17 #import "chrome/browser/ui/cocoa/autofill/autofill_details_container.h" | 17 #import "chrome/browser/ui/cocoa/autofill/autofill_details_container.h" |
| 18 #include "chrome/browser/ui/cocoa/autofill/autofill_dialog_constants.h" | 18 #include "chrome/browser/ui/cocoa/autofill/autofill_dialog_constants.h" |
| 19 #import "chrome/browser/ui/cocoa/autofill/autofill_main_container.h" | 19 #import "chrome/browser/ui/cocoa/autofill/autofill_main_container.h" |
| 20 #import "chrome/browser/ui/cocoa/autofill/autofill_overlay_controller.h" |
| 20 #import "chrome/browser/ui/cocoa/autofill/autofill_section_container.h" | 21 #import "chrome/browser/ui/cocoa/autofill/autofill_section_container.h" |
| 21 #import "chrome/browser/ui/cocoa/autofill/autofill_sign_in_container.h" | 22 #import "chrome/browser/ui/cocoa/autofill/autofill_sign_in_container.h" |
| 22 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sh
eet.h" | 23 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sh
eet.h" |
| 23 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_wi
ndow.h" | 24 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_wi
ndow.h" |
| 24 #include "content/public/browser/web_contents.h" | 25 #include "content/public/browser/web_contents.h" |
| 25 #include "content/public/browser/web_contents_view.h" | 26 #include "content/public/browser/web_contents_view.h" |
| 26 #include "grit/generated_resources.h" | 27 #include "grit/generated_resources.h" |
| 27 #import "ui/base/cocoa/flipped_view.h" | 28 #import "ui/base/cocoa/flipped_view.h" |
| 28 #include "ui/base/cocoa/window_size_constants.h" | 29 #include "ui/base/cocoa/window_size_constants.h" |
| 29 #include "ui/base/l10n/l10n_util.h" | 30 #include "ui/base/l10n/l10n_util.h" |
| (...skipping 26 matching lines...) Expand all Loading... |
| 56 // This should only be called once. | 57 // This should only be called once. |
| 57 DCHECK(!sheet_delegate_.get()); | 58 DCHECK(!sheet_delegate_.get()); |
| 58 sheet_delegate_.reset([[AutofillDialogWindowController alloc] | 59 sheet_delegate_.reset([[AutofillDialogWindowController alloc] |
| 59 initWithWebContents:delegate_->GetWebContents() | 60 initWithWebContents:delegate_->GetWebContents() |
| 60 autofillDialog:this]); | 61 autofillDialog:this]); |
| 61 base::scoped_nsobject<CustomConstrainedWindowSheet> sheet( | 62 base::scoped_nsobject<CustomConstrainedWindowSheet> sheet( |
| 62 [[CustomConstrainedWindowSheet alloc] | 63 [[CustomConstrainedWindowSheet alloc] |
| 63 initWithCustomWindow:[sheet_delegate_ window]]); | 64 initWithCustomWindow:[sheet_delegate_ window]]); |
| 64 constrained_window_.reset( | 65 constrained_window_.reset( |
| 65 new ConstrainedWindowMac(this, delegate_->GetWebContents(), sheet)); | 66 new ConstrainedWindowMac(this, delegate_->GetWebContents(), sheet)); |
| 67 [sheet_delegate_ show]; |
| 66 } | 68 } |
| 67 | 69 |
| 68 void AutofillDialogCocoa::Hide() { | 70 void AutofillDialogCocoa::Hide() { |
| 69 [sheet_delegate_ hide]; | 71 [sheet_delegate_ hide]; |
| 70 } | 72 } |
| 71 | 73 |
| 72 void AutofillDialogCocoa::PerformClose() { | 74 void AutofillDialogCocoa::PerformClose() { |
| 73 if (!close_weak_ptr_factory_.HasWeakPtrs()) { | 75 if (!close_weak_ptr_factory_.HasWeakPtrs()) { |
| 74 base::MessageLoop::current()->PostTask( | 76 base::MessageLoop::current()->PostTask( |
| 75 FROM_HERE, | 77 FROM_HERE, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 88 | 90 |
| 89 void AutofillDialogCocoa::UpdatesFinished() { | 91 void AutofillDialogCocoa::UpdatesFinished() { |
| 90 // TODO(estade): implement if it makes sense to. | 92 // TODO(estade): implement if it makes sense to. |
| 91 } | 93 } |
| 92 | 94 |
| 93 void AutofillDialogCocoa::UpdateAccountChooser() { | 95 void AutofillDialogCocoa::UpdateAccountChooser() { |
| 94 [sheet_delegate_ updateAccountChooser]; | 96 [sheet_delegate_ updateAccountChooser]; |
| 95 } | 97 } |
| 96 | 98 |
| 97 void AutofillDialogCocoa::UpdateButtonStrip() { | 99 void AutofillDialogCocoa::UpdateButtonStrip() { |
| 100 [sheet_delegate_ updateButtonStrip]; |
| 98 } | 101 } |
| 99 | 102 |
| 100 void AutofillDialogCocoa::UpdateDetailArea() { | 103 void AutofillDialogCocoa::UpdateDetailArea() { |
| 101 } | 104 } |
| 102 | 105 |
| 103 void AutofillDialogCocoa::UpdateForErrors() { | 106 void AutofillDialogCocoa::UpdateForErrors() { |
| 104 } | 107 } |
| 105 | 108 |
| 106 void AutofillDialogCocoa::UpdateNotificationArea() { | 109 void AutofillDialogCocoa::UpdateNotificationArea() { |
| 107 [sheet_delegate_ updateNotificationArea]; | 110 [sheet_delegate_ updateNotificationArea]; |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 [loadingShieldTextField_ setFont:loadingFont]; | 281 [loadingShieldTextField_ setFont:loadingFont]; |
| 279 [loadingShieldTextField_ setEditable:NO]; | 282 [loadingShieldTextField_ setEditable:NO]; |
| 280 [loadingShieldTextField_ setBordered:NO]; | 283 [loadingShieldTextField_ setBordered:NO]; |
| 281 [loadingShieldTextField_ setDrawsBackground:NO]; | 284 [loadingShieldTextField_ setDrawsBackground:NO]; |
| 282 | 285 |
| 283 base::scoped_nsobject<AutofillOpaqueView> loadingShieldView( | 286 base::scoped_nsobject<AutofillOpaqueView> loadingShieldView( |
| 284 [[AutofillOpaqueView alloc] initWithFrame:NSZeroRect]); | 287 [[AutofillOpaqueView alloc] initWithFrame:NSZeroRect]); |
| 285 [loadingShieldView setHidden:YES]; | 288 [loadingShieldView setHidden:YES]; |
| 286 [loadingShieldView addSubview:loadingShieldTextField_]; | 289 [loadingShieldView addSubview:loadingShieldTextField_]; |
| 287 | 290 |
| 291 overlayController_.reset([[AutofillOverlayController alloc] init]); |
| 292 [[overlayController_ view] setHidden:YES]; |
| 293 |
| 288 // This needs a flipped content view because otherwise the size | 294 // This needs a flipped content view because otherwise the size |
| 289 // animation looks odd. However, replacing the contentView for constrained | 295 // animation looks odd. However, replacing the contentView for constrained |
| 290 // windows does not work - it does custom rendering. | 296 // windows does not work - it does custom rendering. |
| 291 base::scoped_nsobject<NSView> flippedContentView( | 297 base::scoped_nsobject<NSView> flippedContentView( |
| 292 [[FlippedView alloc] initWithFrame:NSZeroRect]); | 298 [[FlippedView alloc] initWithFrame:NSZeroRect]); |
| 293 [flippedContentView setSubviews: | 299 [flippedContentView setSubviews: |
| 294 @[accountChooser_, | 300 @[accountChooser_, |
| 295 [mainContainer_ view], | 301 [mainContainer_ view], |
| 296 [signInContainer_ view], | 302 [signInContainer_ view], |
| 297 loadingShieldView]]; | 303 loadingShieldView, |
| 304 [overlayController_ view]]]; |
| 298 [flippedContentView setAutoresizingMask: | 305 [flippedContentView setAutoresizingMask: |
| 299 (NSViewWidthSizable | NSViewHeightSizable)]; | 306 (NSViewWidthSizable | NSViewHeightSizable)]; |
| 300 [[[self window] contentView] addSubview:flippedContentView]; | 307 [[[self window] contentView] addSubview:flippedContentView]; |
| 301 [mainContainer_ setAnchorView:[[accountChooser_ subviews] objectAtIndex:1]]; | 308 [mainContainer_ setAnchorView:[[accountChooser_ subviews] objectAtIndex:1]]; |
| 302 | 309 |
| 303 NSRect contentRect = clientRect; | 310 NSRect contentRect = clientRect; |
| 304 contentRect.origin = NSZeroPoint; | 311 contentRect.origin = NSZeroPoint; |
| 305 contentRect.size.width += 2 * chrome_style::kHorizontalPadding; | 312 contentRect.size.width += 2 * chrome_style::kHorizontalPadding; |
| 306 contentRect.size.height += NSHeight(headerRect) + | 313 contentRect.size.height += NSHeight(headerRect) + |
| 307 chrome_style::kClientBottomPadding + | 314 chrome_style::kClientBottomPadding + |
| 308 chrome_style::kTitleTopPadding; | 315 chrome_style::kTitleTopPadding; |
| 309 [self performLayout]; | |
| 310 | |
| 311 // Resizing the browser causes the ConstrainedWindow to move. | |
| 312 // Observe that to allow resizes based on browser size. | |
| 313 NSView* contentView = [[self window] contentView]; | |
| 314 [contentView setPostsFrameChangedNotifications:YES]; | |
| 315 [[NSNotificationCenter defaultCenter] | |
| 316 addObserver:self | |
| 317 selector:@selector(onContentViewFrameDidChange:) | |
| 318 name:NSWindowDidMoveNotification | |
| 319 object:[self window]]; | |
| 320 } | 316 } |
| 321 return self; | 317 return self; |
| 322 } | 318 } |
| 323 | 319 |
| 324 - (void)dealloc { | 320 - (void)dealloc { |
| 325 [[NSNotificationCenter defaultCenter] removeObserver:self]; | 321 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
| 326 [super dealloc]; | 322 [super dealloc]; |
| 327 } | 323 } |
| 328 | 324 |
| 329 - (void)onContentViewFrameDidChange:(NSNotification*)notification { | 325 - (void)onContentViewFrameDidChange:(NSNotification*)notification { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 351 // Show as much of the main view as is possible without going past the | 347 // Show as much of the main view as is possible without going past the |
| 352 // bottom of the browser window. | 348 // bottom of the browser window. |
| 353 NSRect dialogFrameRect = [[self window] frame]; | 349 NSRect dialogFrameRect = [[self window] frame]; |
| 354 NSRect browserFrameRect = | 350 NSRect browserFrameRect = |
| 355 [webContents_->GetView()->GetTopLevelNativeWindow() frame]; | 351 [webContents_->GetView()->GetTopLevelNativeWindow() frame]; |
| 356 dialogFrameRect.size.height = | 352 dialogFrameRect.size.height = |
| 357 NSMaxY(dialogFrameRect) - NSMinY(browserFrameRect); | 353 NSMaxY(dialogFrameRect) - NSMinY(browserFrameRect); |
| 358 dialogFrameRect = [[self window] contentRectForFrameRect:dialogFrameRect]; | 354 dialogFrameRect = [[self window] contentRectForFrameRect:dialogFrameRect]; |
| 359 size.height = std::min(NSHeight(dialogFrameRect), size.height); | 355 size.height = std::min(NSHeight(dialogFrameRect), size.height); |
| 360 | 356 |
| 357 if (![[overlayController_ view] isHidden]) { |
| 358 int height = [overlayController_ getHeightForWidth:size.width]; |
| 359 // TODO(groby): This currently reserves size on top of the overlay image |
| 360 // equivalent to the height of the header. Clarify with UX what the final |
| 361 // padding will be. |
| 362 if (height != 0) { |
| 363 size.height = height + headerSize.height + kDetailTopPadding; |
| 364 } |
| 365 } |
| 366 |
| 361 return size; | 367 return size; |
| 362 } | 368 } |
| 363 | 369 |
| 364 - (void)performLayout { | 370 - (void)performLayout { |
| 365 NSRect contentRect = NSZeroRect; | 371 NSRect contentRect = NSZeroRect; |
| 366 contentRect.size = [self preferredSize]; | 372 contentRect.size = [self preferredSize]; |
| 367 NSRect clientRect = NSInsetRect( | 373 NSRect clientRect = NSInsetRect( |
| 368 contentRect, chrome_style::kHorizontalPadding, 0); | 374 contentRect, chrome_style::kHorizontalPadding, 0); |
| 369 clientRect.origin.y = chrome_style::kClientBottomPadding; | 375 clientRect.origin.y = chrome_style::kClientBottomPadding; |
| 370 clientRect.size.height -= chrome_style::kTitleTopPadding + | 376 clientRect.size.height -= chrome_style::kTitleTopPadding + |
| (...skipping 15 matching lines...) Expand all Loading... |
| 386 | 392 |
| 387 // Loading shield has text centered in the content rect. | 393 // Loading shield has text centered in the content rect. |
| 388 NSRect textFrame = [loadingShieldTextField_ frame]; | 394 NSRect textFrame = [loadingShieldTextField_ frame]; |
| 389 textFrame.origin.x = | 395 textFrame.origin.x = |
| 390 std::ceil((NSWidth(contentRect) - NSWidth(textFrame)) / 2.0); | 396 std::ceil((NSWidth(contentRect) - NSWidth(textFrame)) / 2.0); |
| 391 textFrame.origin.y = | 397 textFrame.origin.y = |
| 392 std::ceil((NSHeight(contentRect) - NSHeight(textFrame)) / 2.0); | 398 std::ceil((NSHeight(contentRect) - NSHeight(textFrame)) / 2.0); |
| 393 [loadingShieldTextField_ setFrame:textFrame]; | 399 [loadingShieldTextField_ setFrame:textFrame]; |
| 394 [[loadingShieldTextField_ superview] setFrame:contentRect]; | 400 [[loadingShieldTextField_ superview] setFrame:contentRect]; |
| 395 | 401 |
| 402 [[overlayController_ view] setFrame:contentRect]; |
| 403 [overlayController_ performLayout]; |
| 404 |
| 396 NSRect frameRect = [[self window] frameRectForContentRect:contentRect]; | 405 NSRect frameRect = [[self window] frameRectForContentRect:contentRect]; |
| 397 [[self window] setFrame:frameRect display:YES]; | 406 [[self window] setFrame:frameRect display:YES]; |
| 398 } | 407 } |
| 399 | 408 |
| 400 - (IBAction)accept:(id)sender { | 409 - (IBAction)accept:(id)sender { |
| 401 if ([mainContainer_ validate]) | 410 if ([mainContainer_ validate]) |
| 402 autofillDialog_->delegate()->OnAccept(); | 411 autofillDialog_->delegate()->OnAccept(); |
| 403 } | 412 } |
| 404 | 413 |
| 405 - (IBAction)cancel:(id)sender { | 414 - (IBAction)cancel:(id)sender { |
| 406 autofillDialog_->delegate()->OnCancel(); | 415 autofillDialog_->delegate()->OnCancel(); |
| 407 autofillDialog_->PerformClose(); | 416 autofillDialog_->PerformClose(); |
| 408 } | 417 } |
| 409 | 418 |
| 419 - (void)show { |
| 420 gfx::Image splashImage = autofillDialog_->delegate()->SplashPageImage(); |
| 421 if (!splashImage.IsEmpty()) { |
| 422 autofill::DialogOverlayState state; |
| 423 state.image = splashImage; |
| 424 [overlayController_ setState:state]; |
| 425 [overlayController_ beginFadeOut]; |
| 426 } |
| 427 |
| 428 // Resizing the browser causes the ConstrainedWindow to move. |
| 429 // Observe that to allow resizes based on browser size. |
| 430 // NOTE: This MUST come last after all initial setup is done, because there |
| 431 // is an immediate notification post registration. |
| 432 NSView* contentView = [[self window] contentView]; |
| 433 [contentView setPostsFrameChangedNotifications:YES]; |
| 434 [[NSNotificationCenter defaultCenter] |
| 435 addObserver:self |
| 436 selector:@selector(onContentViewFrameDidChange:) |
| 437 name:NSWindowDidMoveNotification |
| 438 object:[self window]]; |
| 439 |
| 440 [self requestRelayout]; |
| 441 } |
| 442 |
| 410 - (void)hide { | 443 - (void)hide { |
| 411 autofillDialog_->delegate()->OnCancel(); | 444 autofillDialog_->delegate()->OnCancel(); |
| 412 autofillDialog_->PerformClose(); | 445 autofillDialog_->PerformClose(); |
| 413 } | 446 } |
| 414 | 447 |
| 415 - (void)updateNotificationArea { | 448 - (void)updateNotificationArea { |
| 416 [mainContainer_ updateNotificationArea]; | 449 [mainContainer_ updateNotificationArea]; |
| 417 } | 450 } |
| 418 | 451 |
| 419 - (void)updateAccountChooser { | 452 - (void)updateAccountChooser { |
| 420 [accountChooser_ update]; | 453 [accountChooser_ update]; |
| 421 [mainContainer_ updateLegalDocuments]; | 454 [mainContainer_ updateLegalDocuments]; |
| 422 // TODO(estade): replace this with a better loading image/animation. | 455 // TODO(estade): replace this with a better loading image/animation. |
| 423 // See http://crbug.com/230932 | 456 // See http://crbug.com/230932 |
| 424 NSString* newLoadingMessage = @""; | 457 NSString* newLoadingMessage = @""; |
| 425 if (autofillDialog_->delegate()->ShouldShowSpinner()) | 458 if (autofillDialog_->delegate()->ShouldShowSpinner()) |
| 426 newLoadingMessage = l10n_util::GetNSStringWithFixup(IDS_TAB_LOADING_TITLE); | 459 newLoadingMessage = l10n_util::GetNSStringWithFixup(IDS_TAB_LOADING_TITLE); |
| 427 if (![newLoadingMessage isEqualToString: | 460 if (![newLoadingMessage isEqualToString: |
| 428 [loadingShieldTextField_ stringValue]]) { | 461 [loadingShieldTextField_ stringValue]]) { |
| 429 [loadingShieldTextField_ setStringValue:newLoadingMessage]; | 462 [loadingShieldTextField_ setStringValue:newLoadingMessage]; |
| 430 [loadingShieldTextField_ sizeToFit]; | 463 [loadingShieldTextField_ sizeToFit]; |
| 431 [[loadingShieldTextField_ superview] setHidden: | 464 [[loadingShieldTextField_ superview] setHidden: |
| 432 [newLoadingMessage length] == 0]; | 465 [newLoadingMessage length] == 0]; |
| 433 [self requestRelayout]; | 466 [self requestRelayout]; |
| 434 } | 467 } |
| 435 } | 468 } |
| 436 | 469 |
| 470 - (void)updateButtonStrip { |
| 471 [overlayController_ setState: |
| 472 autofillDialog_->delegate()->GetDialogOverlay()]; |
| 473 } |
| 474 |
| 437 - (void)updateSection:(autofill::DialogSection)section { | 475 - (void)updateSection:(autofill::DialogSection)section { |
| 438 [[mainContainer_ sectionForId:section] update]; | 476 [[mainContainer_ sectionForId:section] update]; |
| 439 } | 477 } |
| 440 | 478 |
| 441 - (void)fillSection:(autofill::DialogSection)section | 479 - (void)fillSection:(autofill::DialogSection)section |
| 442 forInput:(const autofill::DetailInput&)input { | 480 forInput:(const autofill::DetailInput&)input { |
| 443 [[mainContainer_ sectionForId:section] fillForInput:input]; | 481 [[mainContainer_ sectionForId:section] fillForInput:input]; |
| 444 } | 482 } |
| 445 | 483 |
| 446 - (content::NavigationController*)showSignIn { | 484 - (content::NavigationController*)showSignIn { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 491 } | 529 } |
| 492 | 530 |
| 493 - (void)activateFieldForInput:(const autofill::DetailInput&)input { | 531 - (void)activateFieldForInput:(const autofill::DetailInput&)input { |
| 494 for (size_t i = autofill::SECTION_MIN; i <= autofill::SECTION_MAX; ++i) { | 532 for (size_t i = autofill::SECTION_MIN; i <= autofill::SECTION_MAX; ++i) { |
| 495 autofill::DialogSection section = static_cast<autofill::DialogSection>(i); | 533 autofill::DialogSection section = static_cast<autofill::DialogSection>(i); |
| 496 [[mainContainer_ sectionForId:section] activateFieldForInput:input]; | 534 [[mainContainer_ sectionForId:section] activateFieldForInput:input]; |
| 497 } | 535 } |
| 498 } | 536 } |
| 499 | 537 |
| 500 @end | 538 @end |
| OLD | NEW |