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

Side by Side Diff: chrome/browser/ui/views/autofill/autofill_dialog_views.cc

Issue 55243005: Implement learn more bubble on views. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merge Created 7 years, 1 month 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 | Annotate | Revision Log
OLDNEW
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/tooltip_icon.h" 17 #include "chrome/browser/ui/views/autofill/learn_more_icon.h"
18 #include "chrome/browser/ui/views/constrained_window_views.h" 18 #include "chrome/browser/ui/views/constrained_window_views.h"
19 #include "components/autofill/content/browser/wallet/wallet_service_url.h" 19 #include "components/autofill/content/browser/wallet/wallet_service_url.h"
20 #include "components/autofill/core/browser/autofill_type.h" 20 #include "components/autofill/core/browser/autofill_type.h"
21 #include "components/web_modal/web_contents_modal_dialog_host.h" 21 #include "components/web_modal/web_contents_modal_dialog_host.h"
22 #include "components/web_modal/web_contents_modal_dialog_manager.h" 22 #include "components/web_modal/web_contents_modal_dialog_manager.h"
23 #include "components/web_modal/web_contents_modal_dialog_manager_delegate.h" 23 #include "components/web_modal/web_contents_modal_dialog_manager_delegate.h"
24 #include "content/public/browser/native_web_keyboard_event.h" 24 #include "content/public/browser/native_web_keyboard_event.h"
25 #include "content/public/browser/navigation_controller.h" 25 #include "content/public/browser/navigation_controller.h"
26 #include "content/public/browser/web_contents.h" 26 #include "content/public/browser/web_contents.h"
27 #include "content/public/browser/web_contents_view.h" 27 #include "content/public/browser/web_contents_view.h"
28 #include "grit/theme_resources.h" 28 #include "grit/theme_resources.h"
29 #include "grit/ui_resources.h" 29 #include "grit/ui_resources.h"
30 #include "third_party/skia/include/core/SkColor.h" 30 #include "third_party/skia/include/core/SkColor.h"
31 #include "ui/base/l10n/l10n_util.h" 31 #include "ui/base/l10n/l10n_util.h"
32 #include "ui/base/models/combobox_model.h" 32 #include "ui/base/models/combobox_model.h"
33 #include "ui/base/models/menu_model.h" 33 #include "ui/base/models/menu_model.h"
34 #include "ui/base/resource/resource_bundle.h" 34 #include "ui/base/resource/resource_bundle.h"
35 #include "ui/gfx/animation/animation_delegate.h" 35 #include "ui/gfx/animation/animation_delegate.h"
36 #include "ui/gfx/canvas.h" 36 #include "ui/gfx/canvas.h"
37 #include "ui/gfx/path.h" 37 #include "ui/gfx/path.h"
38 #include "ui/gfx/point.h" 38 #include "ui/gfx/point.h"
39 #include "ui/gfx/skia_util.h" 39 #include "ui/gfx/skia_util.h"
40 #include "ui/gfx/vector2d.h"
40 #include "ui/views/background.h" 41 #include "ui/views/background.h"
41 #include "ui/views/border.h" 42 #include "ui/views/border.h"
42 #include "ui/views/bubble/bubble_border.h" 43 #include "ui/views/bubble/bubble_border.h"
43 #include "ui/views/bubble/bubble_frame_view.h" 44 #include "ui/views/bubble/bubble_frame_view.h"
44 #include "ui/views/controls/button/blue_button.h" 45 #include "ui/views/controls/button/blue_button.h"
45 #include "ui/views/controls/button/checkbox.h" 46 #include "ui/views/controls/button/checkbox.h"
46 #include "ui/views/controls/button/label_button.h" 47 #include "ui/views/controls/button/label_button.h"
47 #include "ui/views/controls/button/label_button_border.h" 48 #include "ui/views/controls/button/label_button_border.h"
48 #include "ui/views/controls/button/menu_button.h" 49 #include "ui/views/controls/button/menu_button.h"
49 #include "ui/views/controls/combobox/combobox.h" 50 #include "ui/views/controls/combobox/combobox.h"
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 // The margin between the content of an info bubble and its border.
101 const int kErrorBubbleHorizontalMargin = 14; 102 const int kInfoBubbleHorizontalMargin = 14;
102 const int kErrorBubbleVerticalMargin = 12; 103 const int kInfoBubbleVerticalMargin = 12;
103 104
104 // The visible width of bubble borders (differs from the actual width) in px. 105 // The visible width of bubble borders (differs from the actual width) in px.
105 const int kBubbleBorderVisibleWidth = 1; 106 const int kBubbleBorderVisibleWidth = 1;
106 107
107 // Slight shading for mouse hover and legal document background. 108 // Slight shading for mouse hover and legal document background.
108 SkColor kShadingColor = SkColorSetARGB(7, 0, 0, 0); 109 SkColor kShadingColor = SkColorSetARGB(7, 0, 0, 0);
109 110
110 // A border color for the legal document view. 111 // A border color for the legal document view.
111 SkColor kSubtleBorderColor = SkColorSetARGB(10, 0, 0, 0); 112 SkColor kSubtleBorderColor = SkColorSetARGB(10, 0, 0, 0);
112 113
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 private: 246 private:
246 DISALLOW_COPY_AND_ASSIGN(LayoutPropagationView); 247 DISALLOW_COPY_AND_ASSIGN(LayoutPropagationView);
247 }; 248 };
248 249
249 // A View for a single notification banner. 250 // A View for a single notification banner.
250 class NotificationView : public views::View, 251 class NotificationView : public views::View,
251 public views::ButtonListener, 252 public views::ButtonListener,
252 public views::StyledLabelListener { 253 public views::StyledLabelListener {
253 public: 254 public:
254 NotificationView(const DialogNotification& data, 255 NotificationView(const DialogNotification& data,
255 AutofillDialogViewDelegate* delegate) 256 AutofillDialogViewDelegate* delegate,
257 const base::WeakPtr<LearnMoreIconDelegate>& icon_delegate)
256 : data_(data), 258 : data_(data),
257 delegate_(delegate), 259 delegate_(delegate),
258 checkbox_(NULL) { 260 checkbox_(NULL) {
259 scoped_ptr<views::View> label_view; 261 scoped_ptr<views::View> label_view;
260 if (data.HasCheckbox()) { 262 if (data.HasCheckbox()) {
261 scoped_ptr<views::Checkbox> checkbox( 263 scoped_ptr<views::Checkbox> checkbox(
262 new views::Checkbox(base::string16())); 264 new views::Checkbox(base::string16()));
263 checkbox->SetText(data.display_text()); 265 checkbox->SetText(data.display_text());
264 checkbox->SetTextMultiLine(true); 266 checkbox->SetTextMultiLine(true);
265 checkbox->SetHorizontalAlignment(gfx::ALIGN_LEFT); 267 checkbox->SetHorizontalAlignment(gfx::ALIGN_LEFT);
(...skipping 27 matching lines...) Expand all
293 } else { 295 } else {
294 label->AddStyleRange(gfx::Range(0, data.display_text().size()), 296 label->AddStyleRange(gfx::Range(0, data.display_text().size()),
295 text_style); 297 text_style);
296 } 298 }
297 299
298 label_view.reset(label.release()); 300 label_view.reset(label.release());
299 } 301 }
300 302
301 AddChildView(label_view.release()); 303 AddChildView(label_view.release());
302 304
303 if (!data.tooltip_text().empty()) 305 if (!data.learn_more_text().empty())
304 AddChildView(new TooltipIcon(data.tooltip_text())); 306 AddChildView(new LearnMoreIcon(data.learn_more_text(), icon_delegate));
305 307
306 set_background( 308 set_background(
307 views::Background::CreateSolidBackground(data.GetBackgroundColor())); 309 views::Background::CreateSolidBackground(data.GetBackgroundColor()));
308 set_border(views::Border::CreateSolidSidedBorder(1, 0, 1, 0, 310 set_border(views::Border::CreateSolidSidedBorder(1, 0, 1, 0,
309 data.GetBorderColor())); 311 data.GetBorderColor()));
310 } 312 }
311 313
312 virtual ~NotificationView() {} 314 virtual ~NotificationView() {}
313 315
314 views::Checkbox* checkbox() { 316 views::Checkbox* checkbox() {
315 return checkbox_; 317 return checkbox_;
316 } 318 }
317 319
318 // views::View implementation. 320 // views::View implementation.
319 virtual gfx::Insets GetInsets() const OVERRIDE { 321 virtual gfx::Insets GetInsets() const OVERRIDE {
320 int vertical_padding = kNotificationPadding; 322 int vertical_padding = kNotificationPadding;
321 if (checkbox_) 323 if (checkbox_)
322 vertical_padding -= 3; 324 vertical_padding -= 3;
323 return gfx::Insets(vertical_padding, kDialogEdgePadding, 325 return gfx::Insets(vertical_padding, kDialogEdgePadding,
324 vertical_padding, kDialogEdgePadding); 326 vertical_padding, kDialogEdgePadding);
325 } 327 }
326 328
327 virtual int GetHeightForWidth(int width) OVERRIDE { 329 virtual int GetHeightForWidth(int width) OVERRIDE {
328 int label_width = width - GetInsets().width(); 330 int label_width = width - GetInsets().width();
329 if (child_count() > 1) { 331 if (child_count() > 1) {
330 views::View* tooltip_icon = child_at(1); 332 views::View* learn_more_icon = child_at(1);
331 label_width -= tooltip_icon->GetPreferredSize().width() + 333 label_width -= learn_more_icon->GetPreferredSize().width() +
332 kDialogEdgePadding; 334 kDialogEdgePadding;
333 } 335 }
334 336
335 return child_at(0)->GetHeightForWidth(label_width) + GetInsets().height(); 337 return child_at(0)->GetHeightForWidth(label_width) + GetInsets().height();
336 } 338 }
337 339
338 virtual void Layout() OVERRIDE { 340 virtual void Layout() OVERRIDE {
339 // Surprisingly, GetContentsBounds() doesn't consult GetInsets(). 341 // Surprisingly, GetContentsBounds() doesn't consult GetInsets().
340 gfx::Rect bounds = GetLocalBounds(); 342 gfx::Rect bounds = GetLocalBounds();
341 bounds.Inset(GetInsets()); 343 bounds.Inset(GetInsets());
342 int right_bound = bounds.right(); 344 int right_bound = bounds.right();
343 345
344 if (child_count() > 1) { 346 if (child_count() > 1) {
345 // The icon takes up the entire vertical space and an extra 20px on 347 // The icon takes up the entire vertical space and an extra 20px on
346 // each side. This increases the hover target for the tooltip. 348 // each side. This increases the hover target for the learn more icon.
347 views::View* tooltip_icon = child_at(1); 349 views::View* learn_more_icon = child_at(1);
348 gfx::Size icon_size = tooltip_icon->GetPreferredSize(); 350 gfx::Size icon_size = learn_more_icon->GetPreferredSize();
349 int icon_width = icon_size.width() + kDialogEdgePadding; 351 int icon_width = icon_size.width() + kDialogEdgePadding;
350 right_bound -= icon_width; 352 right_bound -= icon_width;
351 tooltip_icon->SetBounds( 353 learn_more_icon->SetBounds(
352 right_bound, 0, 354 right_bound, 0,
353 icon_width + kDialogEdgePadding, GetLocalBounds().height()); 355 icon_width + kDialogEdgePadding, GetLocalBounds().height());
354 } 356 }
355 357
356 child_at(0)->SetBounds(bounds.x(), bounds.y(), 358 child_at(0)->SetBounds(bounds.x(), bounds.y(),
357 right_bound - bounds.x(), bounds.height()); 359 right_bound - bounds.x(), bounds.height());
358 } 360 }
359 361
360 // views::ButtonListener implementation. 362 // views::ButtonListener implementation.
361 virtual void ButtonPressed(views::Button* sender, 363 virtual void ButtonPressed(views::Button* sender,
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 // Contains the "Loading" label and the dots. 455 // Contains the "Loading" label and the dots.
454 views::View* container_; 456 views::View* container_;
455 457
456 LoadingAnimation animation_; 458 LoadingAnimation animation_;
457 459
458 DISALLOW_COPY_AND_ASSIGN(LoadingAnimationView); 460 DISALLOW_COPY_AND_ASSIGN(LoadingAnimationView);
459 }; 461 };
460 462
461 } // namespace 463 } // namespace
462 464
463 // AutofillDialogViews::ErrorBubble -------------------------------------------- 465 // AutofillDialogViews::InfoBubble --------------------------------------------
464 466
465 AutofillDialogViews::ErrorBubble::ErrorBubble(views::View* anchor, 467 AutofillDialogViews::InfoBubble::InfoBubble(views::View* anchor,
466 views::View* anchor_container, 468 const base::string16& message,
467 const base::string16& message) 469 bool snap_to_grid)
468 : anchor_(anchor), 470 : anchor_(anchor),
469 anchor_container_(anchor_container), 471 anchor_container_(anchor->GetWidget()->non_client_view()),
470 show_above_anchor_( 472 show_above_anchor_(
471 anchor->GetClassName() == views::Combobox::kViewClassName) { 473 anchor->GetClassName() == views::Combobox::kViewClassName),
474 snap_to_grid_(snap_to_grid) {
472 DCHECK(anchor_container_->Contains(anchor)); 475 DCHECK(anchor_container_->Contains(anchor));
473 SetAnchorView(anchor_); 476 SetAnchorView(anchor_);
474 477
475 // TODO(dbeam): currently we assume that combobox menus always show downward 478 // 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, 479 // (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 480 // 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 481 // this might happen and adjust |show_above_anchor_| accordingly. This is not
479 // that big of deal because it rarely happens in practice. 482 // that big of deal because it rarely happens in practice.
480 if (show_above_anchor_) { 483 if (show_above_anchor_) {
481 set_arrow(ShouldArrowGoOnTheRight() ? views::BubbleBorder::BOTTOM_RIGHT : 484 set_arrow(ShouldArrowGoOnTheRight() ? views::BubbleBorder::BOTTOM_RIGHT :
482 views::BubbleBorder::BOTTOM_LEFT); 485 views::BubbleBorder::BOTTOM_LEFT);
483 } else { 486 } else {
484 set_arrow(ShouldArrowGoOnTheRight() ? views::BubbleBorder::TOP_RIGHT : 487 set_arrow(ShouldArrowGoOnTheRight() ? views::BubbleBorder::TOP_RIGHT :
485 views::BubbleBorder::TOP_LEFT); 488 views::BubbleBorder::TOP_LEFT);
486 } 489 }
487 490
488 set_margins(gfx::Insets(kErrorBubbleVerticalMargin, 491 set_margins(gfx::Insets(kInfoBubbleVerticalMargin,
489 kErrorBubbleHorizontalMargin, 492 kInfoBubbleHorizontalMargin,
490 kErrorBubbleVerticalMargin, 493 kInfoBubbleVerticalMargin,
491 kErrorBubbleHorizontalMargin)); 494 kInfoBubbleHorizontalMargin));
492 set_use_focusless(true); 495 set_use_focusless(true);
493 496
494 SetLayoutManager(new views::FillLayout); 497 SetLayoutManager(new views::FillLayout);
495 views::Label* label = new views::Label(message); 498 views::Label* label = new views::Label(message);
496 label->SetHorizontalAlignment(gfx::ALIGN_LEFT); 499 label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
497 label->SetMultiLine(true); 500 label->SetMultiLine(true);
498 AddChildView(label); 501 AddChildView(label);
499 502
500 widget_ = views::BubbleDelegateView::CreateBubble(this); 503 widget_ = views::BubbleDelegateView::CreateBubble(this);
501 UpdatePosition(); 504 UpdatePosition();
502 } 505 }
503 506
504 AutofillDialogViews::ErrorBubble::~ErrorBubble() { 507 AutofillDialogViews::InfoBubble::~InfoBubble() {
505 DCHECK(!widget_); 508 DCHECK(!widget_);
506 } 509 }
507 510
508 void AutofillDialogViews::ErrorBubble::Hide() { 511 void AutofillDialogViews::InfoBubble::Hide() {
509 views::Widget* widget = GetWidget(); 512 views::Widget* widget = GetWidget();
510 if (widget && !widget->IsClosed()) 513 if (widget && !widget->IsClosed())
511 widget->Close(); 514 widget->Close();
512 } 515 }
513 516
514 void AutofillDialogViews::ErrorBubble::UpdatePosition() { 517 void AutofillDialogViews::InfoBubble::UpdatePosition() {
515 if (!widget_) 518 if (!widget_)
516 return; 519 return;
517 520
518 if (!anchor_->GetVisibleBounds().IsEmpty()) { 521 if (!anchor_->GetVisibleBounds().IsEmpty()) {
519 SizeToContents(); 522 SizeToContents();
520 widget_->SetVisibilityChangedAnimationsEnabled(true); 523 widget_->SetVisibilityChangedAnimationsEnabled(true);
521 widget_->ShowInactive(); 524 widget_->ShowInactive();
522 } else { 525 } else {
523 widget_->SetVisibilityChangedAnimationsEnabled(false); 526 widget_->SetVisibilityChangedAnimationsEnabled(false);
524 widget_->Hide(); 527 widget_->Hide();
525 } 528 }
526 } 529 }
527 530
528 gfx::Size AutofillDialogViews::ErrorBubble::GetPreferredSize() { 531 gfx::Size AutofillDialogViews::InfoBubble::GetPreferredSize() {
529 int pref_width = GetPreferredBubbleWidth(); 532 int pref_width = GetPreferredBubbleWidth();
530 pref_width -= GetBubbleFrameView()->GetInsets().width(); 533 pref_width -= GetBubbleFrameView()->GetInsets().width();
531 pref_width -= 2 * kBubbleBorderVisibleWidth; 534 pref_width -= 2 * kBubbleBorderVisibleWidth;
532 return gfx::Size(pref_width, GetHeightForWidth(pref_width)); 535 return gfx::Size(pref_width, GetHeightForWidth(pref_width));
533 } 536 }
534 537
535 gfx::Rect AutofillDialogViews::ErrorBubble::GetBubbleBounds() { 538 gfx::Rect AutofillDialogViews::InfoBubble::GetBubbleBounds() {
536 gfx::Rect bounds = views::BubbleDelegateView::GetBubbleBounds(); 539 gfx::Rect bounds = views::BubbleDelegateView::GetBubbleBounds();
537 gfx::Rect anchor_bounds = anchor_->GetBoundsInScreen(); 540 gfx::Rect anchor_bounds = anchor_->GetBoundsInScreen();
538 541
542 if (anchor_->GetClassName() == LearnMoreIcon::kViewClassName) {
Evan Stade 2013/11/05 02:01:40 boooo
Dan Beam 2013/11/05 07:00:55 removed
543 gfx::Size pref_size = anchor_->GetPreferredSize();
544 gfx::Point new_origin = anchor_bounds.CenterPoint();
545 new_origin.Offset(-pref_size.width() / 2, -pref_size.height() / 2);
546 anchor_bounds = gfx::Rect(new_origin, pref_size);
547 bounds.set_y(anchor_bounds.bottom());
548 }
549
539 if (show_above_anchor_) 550 if (show_above_anchor_)
540 bounds.set_y(anchor_bounds.y() - GetBubbleFrameView()->height()); 551 bounds.set_y(anchor_bounds.y() - GetBubbleFrameView()->height());
541 552
542 anchor_bounds.Inset(-GetBubbleFrameView()->bubble_border()->GetInsets()); 553 if (snap_to_grid_) {
543 bounds.set_x(ShouldArrowGoOnTheRight() ? 554 anchor_bounds.Inset(-GetBubbleFrameView()->bubble_border()->GetInsets());
544 anchor_bounds.right() - bounds.width() - kBubbleBorderVisibleWidth : 555 bounds.set_x(ShouldArrowGoOnTheRight() ?
545 anchor_bounds.x() + kBubbleBorderVisibleWidth); 556 anchor_bounds.right() - bounds.width() - kBubbleBorderVisibleWidth :
557 anchor_bounds.x() + kBubbleBorderVisibleWidth);
558 }
559
546 return bounds; 560 return bounds;
547 } 561 }
548 562
549 void AutofillDialogViews::ErrorBubble::OnWidgetClosing(views::Widget* widget) { 563 void AutofillDialogViews::InfoBubble::OnWidgetClosing(views::Widget* widget) {
550 if (widget == widget_) 564 if (widget == widget_)
551 widget_ = NULL; 565 widget_ = NULL;
552 } 566 }
553 567
554 bool AutofillDialogViews::ErrorBubble::ShouldFlipArrowForRtl() const { 568 bool AutofillDialogViews::InfoBubble::ShouldFlipArrowForRtl() const {
555 return false; 569 return false;
556 } 570 }
557 571
558 int AutofillDialogViews::ErrorBubble::GetContainerWidth() { 572 int AutofillDialogViews::InfoBubble::GetPreferredBubbleWidth() {
559 return anchor_container_->width() - anchor_container_->GetInsets().width(); 573 return (kSectionContainerWidth - views::kRelatedControlHorizontalSpacing) / 2;
560 } 574 }
561 575
562 int AutofillDialogViews::ErrorBubble::GetPreferredBubbleWidth() { 576 bool AutofillDialogViews::InfoBubble::ShouldArrowGoOnTheRight() {
563 return (GetContainerWidth() - views::kRelatedControlHorizontalSpacing) / 2;
564 }
565
566 bool AutofillDialogViews::ErrorBubble::ShouldArrowGoOnTheRight() {
567 gfx::Point anchor_offset; 577 gfx::Point anchor_offset;
568 views::View::ConvertPointToTarget(anchor_, anchor_container_, &anchor_offset); 578 views::View::ConvertPointToTarget(anchor_, anchor_container_, &anchor_offset);
569 anchor_offset.Offset(-anchor_container_->GetInsets().left(), 0); 579 anchor_offset.Offset(-anchor_container_->GetInsets().left(), 0);
570 580
571 if (base::i18n::IsRTL()) { 581 if (base::i18n::IsRTL()) {
572 int anchor_right_x = anchor_offset.x() + anchor_->width(); 582 int anchor_right_x = anchor_offset.x() + anchor_->width();
573 return anchor_right_x >= GetPreferredBubbleWidth(); 583 return anchor_right_x >= GetPreferredBubbleWidth();
574 } 584 }
575 585
576 return anchor_offset.x() + GetPreferredBubbleWidth() > GetContainerWidth(); 586 int container_width = anchor_container_->width();
587 return anchor_offset.x() + GetPreferredBubbleWidth() > container_width;
577 } 588 }
578 589
579 // AutofillDialogViews::AccountChooser ----------------------------------------- 590 // AutofillDialogViews::AccountChooser -----------------------------------------
580 591
581 AutofillDialogViews::AccountChooser::AccountChooser( 592 AutofillDialogViews::AccountChooser::AccountChooser(
582 AutofillDialogViewDelegate* delegate) 593 AutofillDialogViewDelegate* delegate)
583 : image_(new views::ImageView()), 594 : image_(new views::ImageView()),
584 menu_button_(new views::MenuButton(NULL, base::string16(), this, true)), 595 menu_button_(new views::MenuButton(NULL, base::string16(), this, true)),
585 link_(new views::Link()), 596 link_(new views::Link()),
586 delegate_(delegate) { 597 delegate_(delegate) {
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
800 int bubble_width = 5; 811 int bubble_width = 5;
801 if (GetBubbleBorder()) 812 if (GetBubbleBorder())
802 bubble_width = GetBubbleBorder()->GetBorderThickness(); 813 bubble_width = GetBubbleBorder()->GetBorderThickness();
803 bounds.Inset(bubble_width, bubble_width, bubble_width, bubble_width); 814 bounds.Inset(bubble_width, bubble_width, bubble_width, bubble_width);
804 return bounds; 815 return bounds;
805 } 816 }
806 817
807 // AutofillDialogViews::NotificationArea --------------------------------------- 818 // AutofillDialogViews::NotificationArea ---------------------------------------
808 819
809 AutofillDialogViews::NotificationArea::NotificationArea( 820 AutofillDialogViews::NotificationArea::NotificationArea(
810 AutofillDialogViewDelegate* delegate) 821 AutofillDialogViewDelegate* delegate,
811 : delegate_(delegate) { 822 const base::WeakPtr<LearnMoreIconDelegate>& icon_delegate)
823 : delegate_(delegate),
824 icon_delegate_(icon_delegate) {
812 // Reserve vertical space for the arrow (regardless of whether one exists). 825 // Reserve vertical space for the arrow (regardless of whether one exists).
813 // The -1 accounts for the border. 826 // The -1 accounts for the border.
814 set_border(views::Border::CreateEmptyBorder(kArrowHeight - 1, 0, 0, 0)); 827 set_border(views::Border::CreateEmptyBorder(kArrowHeight - 1, 0, 0, 0));
815 828
816 views::BoxLayout* box_layout = 829 views::BoxLayout* box_layout =
817 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0); 830 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0);
818 SetLayoutManager(box_layout); 831 SetLayoutManager(box_layout);
819 } 832 }
820 833
821 AutofillDialogViews::NotificationArea::~NotificationArea() {} 834 AutofillDialogViews::NotificationArea::~NotificationArea() {}
822 835
823 void AutofillDialogViews::NotificationArea::SetNotifications( 836 void AutofillDialogViews::NotificationArea::SetNotifications(
824 const std::vector<DialogNotification>& notifications) { 837 const std::vector<DialogNotification>& notifications) {
825 notifications_ = notifications; 838 notifications_ = notifications;
826 839
827 RemoveAllChildViews(true); 840 RemoveAllChildViews(true);
828 841
829 if (notifications_.empty()) 842 if (notifications_.empty())
830 return; 843 return;
831 844
832 for (size_t i = 0; i < notifications_.size(); ++i) { 845 for (size_t i = 0; i < notifications_.size(); ++i) {
833 const DialogNotification& notification = notifications_[i]; 846 const DialogNotification& notification = notifications_[i];
834 scoped_ptr<NotificationView> view(new NotificationView(notification, 847 scoped_ptr<NotificationView> view(new NotificationView(notification,
835 delegate_)); 848 delegate_,
849 icon_delegate_));
836 850
837 AddChildView(view.release()); 851 AddChildView(view.release());
838 } 852 }
839 853
840 PreferredSizeChanged(); 854 PreferredSizeChanged();
841 } 855 }
842 856
843 gfx::Size AutofillDialogViews::NotificationArea::GetPreferredSize() { 857 gfx::Size AutofillDialogViews::NotificationArea::GetPreferredSize() {
844 gfx::Size size = views::View::GetPreferredSize(); 858 gfx::Size size = views::View::GetPreferredSize();
845 // Ensure that long notifications wrap and don't enlarge the dialog. 859 // Ensure that long notifications wrap and don't enlarge the dialog.
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after
1270 loading_shield_height_(0), 1284 loading_shield_height_(0),
1271 overlay_view_(NULL), 1285 overlay_view_(NULL),
1272 button_strip_extra_view_(NULL), 1286 button_strip_extra_view_(NULL),
1273 save_in_chrome_checkbox_(NULL), 1287 save_in_chrome_checkbox_(NULL),
1274 save_in_chrome_checkbox_container_(NULL), 1288 save_in_chrome_checkbox_container_(NULL),
1275 button_strip_image_(NULL), 1289 button_strip_image_(NULL),
1276 footnote_view_(NULL), 1290 footnote_view_(NULL),
1277 legal_document_view_(NULL), 1291 legal_document_view_(NULL),
1278 focus_manager_(NULL), 1292 focus_manager_(NULL),
1279 error_bubble_(NULL), 1293 error_bubble_(NULL),
1280 observer_(this) { 1294 learn_more_bubble_(NULL),
1295 observer_(this),
1296 weak_ptr_factory_(this) {
1281 DCHECK(delegate); 1297 DCHECK(delegate);
1282 detail_groups_.insert(std::make_pair(SECTION_CC, 1298 detail_groups_.insert(std::make_pair(SECTION_CC,
1283 DetailsGroup(SECTION_CC))); 1299 DetailsGroup(SECTION_CC)));
1284 detail_groups_.insert(std::make_pair(SECTION_BILLING, 1300 detail_groups_.insert(std::make_pair(SECTION_BILLING,
1285 DetailsGroup(SECTION_BILLING))); 1301 DetailsGroup(SECTION_BILLING)));
1286 detail_groups_.insert(std::make_pair(SECTION_CC_BILLING, 1302 detail_groups_.insert(std::make_pair(SECTION_CC_BILLING,
1287 DetailsGroup(SECTION_CC_BILLING))); 1303 DetailsGroup(SECTION_CC_BILLING)));
1288 detail_groups_.insert(std::make_pair(SECTION_SHIPPING, 1304 detail_groups_.insert(std::make_pair(SECTION_SHIPPING,
1289 DetailsGroup(SECTION_SHIPPING))); 1305 DetailsGroup(SECTION_SHIPPING)));
1290 } 1306 }
1291 1307
1292 AutofillDialogViews::~AutofillDialogViews() { 1308 AutofillDialogViews::~AutofillDialogViews() {
1293 HideErrorBubble(); 1309 HideErrorBubble();
1310 HideLearnMoreBubble();
1294 DCHECK(!window_); 1311 DCHECK(!window_);
1295 } 1312 }
1296 1313
1297 void AutofillDialogViews::Show() { 1314 void AutofillDialogViews::Show() {
1298 InitChildViews(); 1315 InitChildViews();
1299 UpdateAccountChooser(); 1316 UpdateAccountChooser();
1300 UpdateNotificationArea(); 1317 UpdateNotificationArea();
1301 UpdateButtonStripExtraView(); 1318 UpdateButtonStripExtraView();
1302 1319
1303 // Ownership of |contents_| is handed off by this call. The widget will take 1320 // Ownership of |contents_| is handed off by this call. The widget will take
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
1654 DCHECK_EQ(scrollable_area_->contents(), details_container_); 1671 DCHECK_EQ(scrollable_area_->contents(), details_container_);
1655 details_container_->SizeToPreferredSize(); 1672 details_container_->SizeToPreferredSize();
1656 // TODO(estade): remove this hack. See crbug.com/285996 1673 // TODO(estade): remove this hack. See crbug.com/285996
1657 details_container_->set_ignore_layouts(true); 1674 details_container_->set_ignore_layouts(true);
1658 scrollable_area_->SetBounds(x, scroll_y, width, scroll_bottom - scroll_y); 1675 scrollable_area_->SetBounds(x, scroll_y, width, scroll_bottom - scroll_y);
1659 details_container_->set_ignore_layouts(false); 1676 details_container_->set_ignore_layouts(false);
1660 } 1677 }
1661 1678
1662 if (error_bubble_) 1679 if (error_bubble_)
1663 error_bubble_->UpdatePosition(); 1680 error_bubble_->UpdatePosition();
1681 if (learn_more_bubble_)
1682 learn_more_bubble_->UpdatePosition();
1664 } 1683 }
1665 1684
1666 base::string16 AutofillDialogViews::GetWindowTitle() const { 1685 base::string16 AutofillDialogViews::GetWindowTitle() const {
1667 base::string16 title = delegate_->DialogTitle(); 1686 base::string16 title = delegate_->DialogTitle();
1668 // Hack alert: we don't want the dialog to jiggle when a title is added or 1687 // Hack alert: we don't want the dialog to jiggle when a title is added or
1669 // removed. Setting a non-empty string here keeps the dialog's title bar the 1688 // removed. Setting a non-empty string here keeps the dialog's title bar the
1670 // same size. 1689 // same size.
1671 return title.empty() ? ASCIIToUTF16(" ") : title; 1690 return title.empty() ? ASCIIToUTF16(" ") : title;
1672 } 1691 }
1673 1692
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
1890 views::MenuItemView::TOPRIGHT, 1909 views::MenuItemView::TOPRIGHT,
1891 ui::MENU_SOURCE_NONE, 1910 ui::MENU_SOURCE_NONE,
1892 0) == views::MenuRunner::MENU_DELETED) { 1911 0) == views::MenuRunner::MENU_DELETED) {
1893 return; 1912 return;
1894 } 1913 }
1895 1914
1896 group->container->SetActive(false); 1915 group->container->SetActive(false);
1897 group->suggested_button->SetState(state); 1916 group->suggested_button->SetState(state);
1898 } 1917 }
1899 1918
1919 void AutofillDialogViews::OnLearnMoreIconMouseEntered(LearnMoreIcon* icon) {
1920 ShowLearnMoreBubbleIfNecessary(icon);
1921 }
1922
1923 void AutofillDialogViews::OnLearnMoreIconMouseExited(LearnMoreIcon* icon) {
1924 DCHECK_EQ(icon, learn_more_bubble_->anchor());
1925 HideLearnMoreBubble();
1926 }
1927
1900 gfx::Size AutofillDialogViews::CalculatePreferredSize(bool get_minimum_size) { 1928 gfx::Size AutofillDialogViews::CalculatePreferredSize(bool get_minimum_size) {
1901 gfx::Insets insets = GetInsets(); 1929 gfx::Insets insets = GetInsets();
1902 gfx::Size scroll_size = scrollable_area_->contents()->GetPreferredSize(); 1930 gfx::Size scroll_size = scrollable_area_->contents()->GetPreferredSize();
1903 // The width is always set by the scroll area. 1931 // The width is always set by the scroll area.
1904 const int width = scroll_size.width(); 1932 const int width = scroll_size.width();
1905 1933
1906 if (sign_in_web_view_->visible()) { 1934 if (sign_in_web_view_->visible()) {
1907 const gfx::Size size = static_cast<views::View*>(sign_in_web_view_)-> 1935 const gfx::Size size = static_cast<views::View*>(sign_in_web_view_)->
1908 GetPreferredSize(); 1936 GetPreferredSize();
1909 return gfx::Size(width + insets.width(), size.height() + insets.height()); 1937 return gfx::Size(width + insets.width(), size.height() + insets.height());
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1972 save_in_chrome_checkbox_container_->SetLayoutManager( 2000 save_in_chrome_checkbox_container_->SetLayoutManager(
1973 new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 7)); 2001 new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 7));
1974 button_strip_extra_view_->AddChildView(save_in_chrome_checkbox_container_); 2002 button_strip_extra_view_->AddChildView(save_in_chrome_checkbox_container_);
1975 2003
1976 save_in_chrome_checkbox_ = 2004 save_in_chrome_checkbox_ =
1977 new views::Checkbox(delegate_->SaveLocallyText()); 2005 new views::Checkbox(delegate_->SaveLocallyText());
1978 save_in_chrome_checkbox_->SetChecked(delegate_->ShouldSaveInChrome()); 2006 save_in_chrome_checkbox_->SetChecked(delegate_->ShouldSaveInChrome());
1979 save_in_chrome_checkbox_container_->AddChildView(save_in_chrome_checkbox_); 2007 save_in_chrome_checkbox_container_->AddChildView(save_in_chrome_checkbox_);
1980 2008
1981 save_in_chrome_checkbox_container_->AddChildView( 2009 save_in_chrome_checkbox_container_->AddChildView(
1982 new TooltipIcon(delegate_->SaveLocallyTooltip())); 2010 new LearnMoreIcon(delegate_->SaveLocallyLearnMoreText(),
2011 weak_ptr_factory_.GetWeakPtr()));
1983 2012
1984 button_strip_image_ = new views::ImageView(); 2013 button_strip_image_ = new views::ImageView();
1985 button_strip_extra_view_->AddChildView(button_strip_image_); 2014 button_strip_extra_view_->AddChildView(button_strip_image_);
1986 2015
1987 account_chooser_ = new AccountChooser(delegate_); 2016 account_chooser_ = new AccountChooser(delegate_);
1988 notification_area_ = new NotificationArea(delegate_); 2017 notification_area_ =
2018 new NotificationArea(delegate_, weak_ptr_factory_.GetWeakPtr());
1989 notification_area_->set_arrow_centering_anchor(account_chooser_->AsWeakPtr()); 2019 notification_area_->set_arrow_centering_anchor(account_chooser_->AsWeakPtr());
1990 AddChildView(notification_area_); 2020 AddChildView(notification_area_);
1991 2021
1992 scrollable_area_ = new views::ScrollView(); 2022 scrollable_area_ = new views::ScrollView();
1993 scrollable_area_->set_hide_horizontal_scrollbar(true); 2023 scrollable_area_->set_hide_horizontal_scrollbar(true);
1994 scrollable_area_->SetContents(CreateDetailsContainer()); 2024 scrollable_area_->SetContents(CreateDetailsContainer());
1995 AddChildView(scrollable_area_); 2025 AddChildView(scrollable_area_);
1996 2026
1997 loading_shield_ = new LoadingAnimationView(delegate_->SpinnerText()); 2027 loading_shield_ = new LoadingAnimationView(delegate_->SpinnerText());
1998 AddChildView(loading_shield_); 2028 AddChildView(loading_shield_);
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
2246 return; 2276 return;
2247 } 2277 }
2248 2278
2249 std::map<views::View*, base::string16>::iterator error_message = 2279 std::map<views::View*, base::string16>::iterator error_message =
2250 validity_map_.find(view); 2280 validity_map_.find(view);
2251 if (error_message != validity_map_.end()) { 2281 if (error_message != validity_map_.end()) {
2252 view->ScrollRectToVisible(view->GetLocalBounds()); 2282 view->ScrollRectToVisible(view->GetLocalBounds());
2253 2283
2254 if (!error_bubble_ || error_bubble_->anchor() != view) { 2284 if (!error_bubble_ || error_bubble_->anchor() != view) {
2255 HideErrorBubble(); 2285 HideErrorBubble();
2256 views::View* section = 2286 error_bubble_ = new InfoBubble(view, error_message->second, true);
2257 view->GetAncestorWithClassName(kSectionContainerClassName);
2258 error_bubble_ = new ErrorBubble(view, section, error_message->second);
2259 } 2287 }
2260 } 2288 }
2261 } 2289 }
2262 2290
2291 void AutofillDialogViews::ShowLearnMoreBubbleIfNecessary(LearnMoreIcon* icon) {
2292 if (!icon->GetWidget())
2293 return;
2294
2295 if (!learn_more_bubble_ || learn_more_bubble_->anchor() != icon) {
2296 HideLearnMoreBubble();
2297 learn_more_bubble_ = new InfoBubble(icon, icon->learn_more_text(), false);
2298 }
2299 }
2300
2263 void AutofillDialogViews::HideErrorBubble() { 2301 void AutofillDialogViews::HideErrorBubble() {
2264 if (error_bubble_) { 2302 if (error_bubble_) {
2265 error_bubble_->Hide(); 2303 error_bubble_->Hide();
2266 error_bubble_ = NULL; 2304 error_bubble_ = NULL;
2267 } 2305 }
2268 } 2306 }
2269 2307
2308 void AutofillDialogViews::HideLearnMoreBubble() {
2309 if (learn_more_bubble_) {
2310 learn_more_bubble_->Hide();
2311 learn_more_bubble_ = NULL;
2312 }
2313 }
2314
2270 void AutofillDialogViews::MarkInputsInvalid( 2315 void AutofillDialogViews::MarkInputsInvalid(
2271 DialogSection section, 2316 DialogSection section,
2272 const ValidityMessages& messages, 2317 const ValidityMessages& messages,
2273 bool overwrite_unsure) { 2318 bool overwrite_unsure) {
2274 DetailsGroup* group = GroupForSection(section); 2319 DetailsGroup* group = GroupForSection(section);
2275 DCHECK(group->container->visible()); 2320 DCHECK(group->container->visible());
2276 2321
2277 if (group->manual_input->visible()) { 2322 if (group->manual_input->visible()) {
2278 for (TextfieldMap::const_iterator iter = group->textfields.begin(); 2323 for (TextfieldMap::const_iterator iter = group->textfields.begin();
2279 iter != group->textfields.end(); ++iter) { 2324 iter != group->textfields.end(); ++iter) {
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
2506 if (combo_mapping != group.comboboxes.end()) 2551 if (combo_mapping != group.comboboxes.end())
2507 return combo_mapping->second; 2552 return combo_mapping->second;
2508 } 2553 }
2509 2554
2510 return NULL; 2555 return NULL;
2511 } 2556 }
2512 2557
2513 void AutofillDialogViews::DetailsContainerBoundsChanged() { 2558 void AutofillDialogViews::DetailsContainerBoundsChanged() {
2514 if (error_bubble_) 2559 if (error_bubble_)
2515 error_bubble_->UpdatePosition(); 2560 error_bubble_->UpdatePosition();
2561 if (learn_more_bubble_)
2562 learn_more_bubble_->UpdatePosition();
2516 } 2563 }
2517 2564
2518 void AutofillDialogViews::SetIconsForSection(DialogSection section) { 2565 void AutofillDialogViews::SetIconsForSection(DialogSection section) {
2519 DetailOutputMap user_input; 2566 DetailOutputMap user_input;
2520 GetUserInput(section, &user_input); 2567 GetUserInput(section, &user_input);
2521 FieldValueMap field_values; 2568 FieldValueMap field_values;
2522 for (DetailOutputMap::const_iterator user_input_it = user_input.begin(); 2569 for (DetailOutputMap::const_iterator user_input_it = user_input.begin();
2523 user_input_it != user_input.end(); 2570 user_input_it != user_input.end();
2524 ++user_input_it) { 2571 ++user_input_it) {
2525 const DetailInput* field_detail = user_input_it->first; 2572 const DetailInput* field_detail = user_input_it->first;
2526 const string16& field_value = user_input_it->second; 2573 const string16& field_value = user_input_it->second;
2527 field_values[field_detail->type] = field_value; 2574 field_values[field_detail->type] = field_value;
2528 } 2575 }
2529 FieldIconMap field_icons = delegate_->IconsForFields(field_values); 2576 FieldIconMap field_icons = delegate_->IconsForFields(field_values);
2530 TextfieldMap* textfields = &GroupForSection(section)->textfields; 2577 TextfieldMap* textfields = &GroupForSection(section)->textfields;
2531 for (TextfieldMap::const_iterator textfield_it = textfields->begin(); 2578 for (TextfieldMap::const_iterator textfield_it = textfields->begin();
2532 textfield_it != textfields->end(); 2579 textfield_it != textfields->end();
2533 ++textfield_it) { 2580 ++textfield_it) {
2534 ServerFieldType field_type = textfield_it->first->type; 2581 ServerFieldType field_type = textfield_it->first->type;
2535 FieldIconMap::const_iterator field_icon_it = field_icons.find(field_type); 2582 FieldIconMap::const_iterator field_icon_it = field_icons.find(field_type);
2536 DecoratedTextfield* textfield = textfield_it->second; 2583 DecoratedTextfield* textfield = textfield_it->second;
2537 if (field_icon_it != field_icons.end()) 2584 if (field_icon_it != field_icons.end()) {
2538 textfield->SetIcon(field_icon_it->second); 2585 textfield->SetIcon(field_icon_it->second);
2539 else 2586 } else {
2540 textfield->SetTooltipIcon(delegate_->TooltipForField(field_type)); 2587 textfield->SetLearnMoreIcon(delegate_->LearnMoreTextForField(field_type),
2588 weak_ptr_factory_.GetWeakPtr());
2589 }
2541 } 2590 }
2542 } 2591 }
2543 2592
2544 void AutofillDialogViews::SetEditabilityForSection(DialogSection section) { 2593 void AutofillDialogViews::SetEditabilityForSection(DialogSection section) {
2545 const DetailInputs& inputs = 2594 const DetailInputs& inputs =
2546 delegate_->RequestedFieldsForSection(section); 2595 delegate_->RequestedFieldsForSection(section);
2547 DetailsGroup* group = GroupForSection(section); 2596 DetailsGroup* group = GroupForSection(section);
2548 2597
2549 for (DetailInputs::const_iterator iter = inputs.begin(); 2598 for (DetailInputs::const_iterator iter = inputs.begin();
2550 iter != inputs.end(); ++iter) { 2599 iter != inputs.end(); ++iter) {
(...skipping 18 matching lines...) Expand all
2569 AutofillDialogViews::DetailsGroup::DetailsGroup(DialogSection section) 2618 AutofillDialogViews::DetailsGroup::DetailsGroup(DialogSection section)
2570 : section(section), 2619 : section(section),
2571 container(NULL), 2620 container(NULL),
2572 manual_input(NULL), 2621 manual_input(NULL),
2573 suggested_info(NULL), 2622 suggested_info(NULL),
2574 suggested_button(NULL) {} 2623 suggested_button(NULL) {}
2575 2624
2576 AutofillDialogViews::DetailsGroup::~DetailsGroup() {} 2625 AutofillDialogViews::DetailsGroup::~DetailsGroup() {}
2577 2626
2578 } // namespace autofill 2627 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698