| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/views/autofill/autofill_dialog_views.h" | 5 #include "chrome/browser/ui/views/autofill/autofill_dialog_views.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/location.h" | 10 #include "base/location.h" |
| 11 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
| 12 #include "chrome/browser/profiles/profile.h" | 12 #include "chrome/browser/profiles/profile.h" |
| 13 #include "chrome/browser/ui/autofill/autofill_dialog_sign_in_delegate.h" | 13 #include "chrome/browser/ui/autofill/autofill_dialog_sign_in_delegate.h" |
| 14 #include "chrome/browser/ui/autofill/autofill_dialog_view_delegate.h" | 14 #include "chrome/browser/ui/autofill/autofill_dialog_view_delegate.h" |
| 15 #include "chrome/browser/ui/autofill/loading_animation.h" | 15 #include "chrome/browser/ui/autofill/loading_animation.h" |
| 16 #include "chrome/browser/ui/views/autofill/decorated_textfield.h" | 16 #include "chrome/browser/ui/views/autofill/decorated_textfield.h" |
| 17 #include "chrome/browser/ui/views/autofill/info_bubble.h" |
| 17 #include "chrome/browser/ui/views/autofill/tooltip_icon.h" | 18 #include "chrome/browser/ui/views/autofill/tooltip_icon.h" |
| 18 #include "chrome/browser/ui/views/constrained_window_views.h" | 19 #include "chrome/browser/ui/views/constrained_window_views.h" |
| 19 #include "components/autofill/content/browser/wallet/wallet_service_url.h" | 20 #include "components/autofill/content/browser/wallet/wallet_service_url.h" |
| 20 #include "components/autofill/core/browser/autofill_type.h" | 21 #include "components/autofill/core/browser/autofill_type.h" |
| 21 #include "components/web_modal/web_contents_modal_dialog_host.h" | 22 #include "components/web_modal/web_contents_modal_dialog_host.h" |
| 22 #include "components/web_modal/web_contents_modal_dialog_manager.h" | 23 #include "components/web_modal/web_contents_modal_dialog_manager.h" |
| 23 #include "components/web_modal/web_contents_modal_dialog_manager_delegate.h" | 24 #include "components/web_modal/web_contents_modal_dialog_manager_delegate.h" |
| 24 #include "content/public/browser/native_web_keyboard_event.h" | 25 #include "content/public/browser/native_web_keyboard_event.h" |
| 25 #include "content/public/browser/navigation_controller.h" | 26 #include "content/public/browser/navigation_controller.h" |
| 26 #include "content/public/browser/web_contents.h" | 27 #include "content/public/browser/web_contents.h" |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 | 91 |
| 91 const int kArrowHeight = 7; | 92 const int kArrowHeight = 7; |
| 92 const int kArrowWidth = 2 * kArrowHeight; | 93 const int kArrowWidth = 2 * kArrowHeight; |
| 93 | 94 |
| 94 // The padding inside the edges of the dialog, in pixels. | 95 // The padding inside the edges of the dialog, in pixels. |
| 95 const int kDialogEdgePadding = 20; | 96 const int kDialogEdgePadding = 20; |
| 96 | 97 |
| 97 // The vertical padding between rows of manual inputs (in pixels). | 98 // The vertical padding between rows of manual inputs (in pixels). |
| 98 const int kManualInputRowPadding = 10; | 99 const int kManualInputRowPadding = 10; |
| 99 | 100 |
| 100 // The margin between the content of the error bubble and its border. | |
| 101 const int kErrorBubbleHorizontalMargin = 14; | |
| 102 const int kErrorBubbleVerticalMargin = 12; | |
| 103 | |
| 104 // The visible width of bubble borders (differs from the actual width) in px. | |
| 105 const int kBubbleBorderVisibleWidth = 1; | |
| 106 | |
| 107 // Slight shading for mouse hover and legal document background. | 101 // Slight shading for mouse hover and legal document background. |
| 108 SkColor kShadingColor = SkColorSetARGB(7, 0, 0, 0); | 102 SkColor kShadingColor = SkColorSetARGB(7, 0, 0, 0); |
| 109 | 103 |
| 110 // A border color for the legal document view. | 104 // A border color for the legal document view. |
| 111 SkColor kSubtleBorderColor = SkColorSetARGB(10, 0, 0, 0); | 105 SkColor kSubtleBorderColor = SkColorSetARGB(10, 0, 0, 0); |
| 112 | 106 |
| 113 // The top and bottom padding, in pixels, for the suggestions menu dropdown | 107 // The top and bottom padding, in pixels, for the suggestions menu dropdown |
| 114 // arrows. | 108 // arrows. |
| 115 const int kMenuButtonTopInset = 3; | 109 const int kMenuButtonTopInset = 3; |
| 116 const int kMenuButtonBottomInset = 6; | 110 const int kMenuButtonBottomInset = 6; |
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 453 // Contains the "Loading" label and the dots. | 447 // Contains the "Loading" label and the dots. |
| 454 views::View* container_; | 448 views::View* container_; |
| 455 | 449 |
| 456 LoadingAnimation animation_; | 450 LoadingAnimation animation_; |
| 457 | 451 |
| 458 DISALLOW_COPY_AND_ASSIGN(LoadingAnimationView); | 452 DISALLOW_COPY_AND_ASSIGN(LoadingAnimationView); |
| 459 }; | 453 }; |
| 460 | 454 |
| 461 } // namespace | 455 } // namespace |
| 462 | 456 |
| 463 // AutofillDialogViews::ErrorBubble -------------------------------------------- | |
| 464 | |
| 465 AutofillDialogViews::ErrorBubble::ErrorBubble(views::View* anchor, | |
| 466 views::View* anchor_container, | |
| 467 const base::string16& message) | |
| 468 : anchor_(anchor), | |
| 469 anchor_container_(anchor_container), | |
| 470 show_above_anchor_( | |
| 471 anchor->GetClassName() == views::Combobox::kViewClassName) { | |
| 472 DCHECK(anchor_container_->Contains(anchor)); | |
| 473 SetAnchorView(anchor_); | |
| 474 | |
| 475 // TODO(dbeam): currently we assume that combobox menus always show downward | |
| 476 // (which isn't true). If the invalid combobox is low enough on the screen, | |
| 477 // its menu will actually show upward and obscure the bubble. Figure out when | |
| 478 // this might happen and adjust |show_above_anchor_| accordingly. This is not | |
| 479 // that big of deal because it rarely happens in practice. | |
| 480 if (show_above_anchor_) { | |
| 481 set_arrow(ShouldArrowGoOnTheRight() ? views::BubbleBorder::BOTTOM_RIGHT : | |
| 482 views::BubbleBorder::BOTTOM_LEFT); | |
| 483 } else { | |
| 484 set_arrow(ShouldArrowGoOnTheRight() ? views::BubbleBorder::TOP_RIGHT : | |
| 485 views::BubbleBorder::TOP_LEFT); | |
| 486 } | |
| 487 | |
| 488 set_margins(gfx::Insets(kErrorBubbleVerticalMargin, | |
| 489 kErrorBubbleHorizontalMargin, | |
| 490 kErrorBubbleVerticalMargin, | |
| 491 kErrorBubbleHorizontalMargin)); | |
| 492 set_use_focusless(true); | |
| 493 | |
| 494 SetLayoutManager(new views::FillLayout); | |
| 495 views::Label* label = new views::Label(message); | |
| 496 label->SetHorizontalAlignment(gfx::ALIGN_LEFT); | |
| 497 label->SetMultiLine(true); | |
| 498 AddChildView(label); | |
| 499 | |
| 500 widget_ = views::BubbleDelegateView::CreateBubble(this); | |
| 501 UpdatePosition(); | |
| 502 } | |
| 503 | |
| 504 AutofillDialogViews::ErrorBubble::~ErrorBubble() { | |
| 505 DCHECK(!widget_); | |
| 506 } | |
| 507 | |
| 508 void AutofillDialogViews::ErrorBubble::Hide() { | |
| 509 views::Widget* widget = GetWidget(); | |
| 510 if (widget && !widget->IsClosed()) | |
| 511 widget->Close(); | |
| 512 } | |
| 513 | |
| 514 void AutofillDialogViews::ErrorBubble::UpdatePosition() { | |
| 515 if (!widget_) | |
| 516 return; | |
| 517 | |
| 518 if (!anchor_->GetVisibleBounds().IsEmpty()) { | |
| 519 SizeToContents(); | |
| 520 widget_->SetVisibilityChangedAnimationsEnabled(true); | |
| 521 widget_->ShowInactive(); | |
| 522 } else { | |
| 523 widget_->SetVisibilityChangedAnimationsEnabled(false); | |
| 524 widget_->Hide(); | |
| 525 } | |
| 526 } | |
| 527 | |
| 528 gfx::Size AutofillDialogViews::ErrorBubble::GetPreferredSize() { | |
| 529 int pref_width = GetPreferredBubbleWidth(); | |
| 530 pref_width -= GetBubbleFrameView()->GetInsets().width(); | |
| 531 pref_width -= 2 * kBubbleBorderVisibleWidth; | |
| 532 return gfx::Size(pref_width, GetHeightForWidth(pref_width)); | |
| 533 } | |
| 534 | |
| 535 gfx::Rect AutofillDialogViews::ErrorBubble::GetBubbleBounds() { | |
| 536 gfx::Rect bounds = views::BubbleDelegateView::GetBubbleBounds(); | |
| 537 gfx::Rect anchor_bounds = anchor_->GetBoundsInScreen(); | |
| 538 | |
| 539 if (show_above_anchor_) | |
| 540 bounds.set_y(anchor_bounds.y() - GetBubbleFrameView()->height()); | |
| 541 | |
| 542 anchor_bounds.Inset(-GetBubbleFrameView()->bubble_border()->GetInsets()); | |
| 543 bounds.set_x(ShouldArrowGoOnTheRight() ? | |
| 544 anchor_bounds.right() - bounds.width() - kBubbleBorderVisibleWidth : | |
| 545 anchor_bounds.x() + kBubbleBorderVisibleWidth); | |
| 546 return bounds; | |
| 547 } | |
| 548 | |
| 549 void AutofillDialogViews::ErrorBubble::OnWidgetClosing(views::Widget* widget) { | |
| 550 if (widget == widget_) | |
| 551 widget_ = NULL; | |
| 552 } | |
| 553 | |
| 554 bool AutofillDialogViews::ErrorBubble::ShouldFlipArrowForRtl() const { | |
| 555 return false; | |
| 556 } | |
| 557 | |
| 558 int AutofillDialogViews::ErrorBubble::GetContainerWidth() { | |
| 559 return anchor_container_->width() - anchor_container_->GetInsets().width(); | |
| 560 } | |
| 561 | |
| 562 int AutofillDialogViews::ErrorBubble::GetPreferredBubbleWidth() { | |
| 563 return (GetContainerWidth() - views::kRelatedControlHorizontalSpacing) / 2; | |
| 564 } | |
| 565 | |
| 566 bool AutofillDialogViews::ErrorBubble::ShouldArrowGoOnTheRight() { | |
| 567 gfx::Point anchor_offset; | |
| 568 views::View::ConvertPointToTarget(anchor_, anchor_container_, &anchor_offset); | |
| 569 anchor_offset.Offset(-anchor_container_->GetInsets().left(), 0); | |
| 570 | |
| 571 if (base::i18n::IsRTL()) { | |
| 572 int anchor_right_x = anchor_offset.x() + anchor_->width(); | |
| 573 return anchor_right_x >= GetPreferredBubbleWidth(); | |
| 574 } | |
| 575 | |
| 576 return anchor_offset.x() + GetPreferredBubbleWidth() > GetContainerWidth(); | |
| 577 } | |
| 578 | |
| 579 // AutofillDialogViews::AccountChooser ----------------------------------------- | 457 // AutofillDialogViews::AccountChooser ----------------------------------------- |
| 580 | 458 |
| 581 AutofillDialogViews::AccountChooser::AccountChooser( | 459 AutofillDialogViews::AccountChooser::AccountChooser( |
| 582 AutofillDialogViewDelegate* delegate) | 460 AutofillDialogViewDelegate* delegate) |
| 583 : image_(new views::ImageView()), | 461 : image_(new views::ImageView()), |
| 584 menu_button_(new views::MenuButton(NULL, base::string16(), this, true)), | 462 menu_button_(new views::MenuButton(NULL, base::string16(), this, true)), |
| 585 link_(new views::Link()), | 463 link_(new views::Link()), |
| 586 delegate_(delegate) { | 464 delegate_(delegate) { |
| 587 set_border(views::Border::CreateEmptyBorder(0, 0, 0, 10)); | 465 set_border(views::Border::CreateEmptyBorder(0, 0, 0, 10)); |
| 588 SetLayoutManager( | 466 SetLayoutManager( |
| (...skipping 1657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2246 return; | 2124 return; |
| 2247 } | 2125 } |
| 2248 | 2126 |
| 2249 std::map<views::View*, base::string16>::iterator error_message = | 2127 std::map<views::View*, base::string16>::iterator error_message = |
| 2250 validity_map_.find(view); | 2128 validity_map_.find(view); |
| 2251 if (error_message != validity_map_.end()) { | 2129 if (error_message != validity_map_.end()) { |
| 2252 view->ScrollRectToVisible(view->GetLocalBounds()); | 2130 view->ScrollRectToVisible(view->GetLocalBounds()); |
| 2253 | 2131 |
| 2254 if (!error_bubble_ || error_bubble_->anchor() != view) { | 2132 if (!error_bubble_ || error_bubble_->anchor() != view) { |
| 2255 HideErrorBubble(); | 2133 HideErrorBubble(); |
| 2256 views::View* section = | 2134 error_bubble_ = new InfoBubble(view, error_message->second); |
| 2257 view->GetAncestorWithClassName(kSectionContainerClassName); | 2135 error_bubble_->set_align_to_anchor_edge(true); |
| 2258 error_bubble_ = new ErrorBubble(view, section, error_message->second); | 2136 error_bubble_->set_container_insets(gfx::Insets(kDialogEdgePadding, |
| 2137 kDialogEdgePadding, |
| 2138 kDialogEdgePadding, |
| 2139 kDialogEdgePadding)); |
| 2140 error_bubble_->set_preferred_width( |
| 2141 (kSectionContainerWidth - views::kRelatedControlVerticalSpacing) / 2); |
| 2142 error_bubble_->Show(); |
| 2259 } | 2143 } |
| 2260 } | 2144 } |
| 2261 } | 2145 } |
| 2262 | 2146 |
| 2263 void AutofillDialogViews::HideErrorBubble() { | 2147 void AutofillDialogViews::HideErrorBubble() { |
| 2264 if (error_bubble_) { | 2148 if (error_bubble_) { |
| 2265 error_bubble_->Hide(); | 2149 error_bubble_->Hide(); |
| 2266 error_bubble_ = NULL; | 2150 error_bubble_ = NULL; |
| 2267 } | 2151 } |
| 2268 } | 2152 } |
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2569 AutofillDialogViews::DetailsGroup::DetailsGroup(DialogSection section) | 2453 AutofillDialogViews::DetailsGroup::DetailsGroup(DialogSection section) |
| 2570 : section(section), | 2454 : section(section), |
| 2571 container(NULL), | 2455 container(NULL), |
| 2572 manual_input(NULL), | 2456 manual_input(NULL), |
| 2573 suggested_info(NULL), | 2457 suggested_info(NULL), |
| 2574 suggested_button(NULL) {} | 2458 suggested_button(NULL) {} |
| 2575 | 2459 |
| 2576 AutofillDialogViews::DetailsGroup::~DetailsGroup() {} | 2460 AutofillDialogViews::DetailsGroup::~DetailsGroup() {} |
| 2577 | 2461 |
| 2578 } // namespace autofill | 2462 } // namespace autofill |
| OLD | NEW |