Index: chrome/browser/ui/views/autofill/autofill_dialog_views.cc |
diff --git a/chrome/browser/ui/views/autofill/autofill_dialog_views.cc b/chrome/browser/ui/views/autofill/autofill_dialog_views.cc |
index aa5384cc8b2dd90ca929d4e0678af4820524d00c..21470527478ac65e9c4059399f03b55f861f5cea 100644 |
--- a/chrome/browser/ui/views/autofill/autofill_dialog_views.cc |
+++ b/chrome/browser/ui/views/autofill/autofill_dialog_views.cc |
@@ -14,7 +14,7 @@ |
#include "chrome/browser/ui/autofill/autofill_dialog_view_delegate.h" |
#include "chrome/browser/ui/autofill/loading_animation.h" |
#include "chrome/browser/ui/views/autofill/decorated_textfield.h" |
-#include "chrome/browser/ui/views/autofill/tooltip_icon.h" |
+#include "chrome/browser/ui/views/autofill/learn_more_icon.h" |
#include "chrome/browser/ui/views/constrained_window_views.h" |
#include "components/autofill/content/browser/wallet/wallet_service_url.h" |
#include "components/autofill/core/browser/autofill_type.h" |
@@ -37,6 +37,7 @@ |
#include "ui/gfx/path.h" |
#include "ui/gfx/point.h" |
#include "ui/gfx/skia_util.h" |
+#include "ui/gfx/vector2d.h" |
#include "ui/views/background.h" |
#include "ui/views/border.h" |
#include "ui/views/bubble/bubble_border.h" |
@@ -97,9 +98,9 @@ const int kDialogEdgePadding = 20; |
// The vertical padding between rows of manual inputs (in pixels). |
const int kManualInputRowPadding = 10; |
-// The margin between the content of the error bubble and its border. |
-const int kErrorBubbleHorizontalMargin = 14; |
-const int kErrorBubbleVerticalMargin = 12; |
+// The margin between the content of an info bubble and its border. |
+const int kInfoBubbleHorizontalMargin = 14; |
+const int kInfoBubbleVerticalMargin = 12; |
// The visible width of bubble borders (differs from the actual width) in px. |
const int kBubbleBorderVisibleWidth = 1; |
@@ -252,7 +253,8 @@ class NotificationView : public views::View, |
public views::StyledLabelListener { |
public: |
NotificationView(const DialogNotification& data, |
- AutofillDialogViewDelegate* delegate) |
+ AutofillDialogViewDelegate* delegate, |
+ const base::WeakPtr<LearnMoreIconDelegate>& icon_delegate) |
: data_(data), |
delegate_(delegate), |
checkbox_(NULL) { |
@@ -300,8 +302,8 @@ class NotificationView : public views::View, |
AddChildView(label_view.release()); |
- if (!data.tooltip_text().empty()) |
- AddChildView(new TooltipIcon(data.tooltip_text())); |
+ if (!data.learn_more_text().empty()) |
+ AddChildView(new LearnMoreIcon(data.learn_more_text(), icon_delegate)); |
set_background( |
views::Background::CreateSolidBackground(data.GetBackgroundColor())); |
@@ -327,8 +329,8 @@ class NotificationView : public views::View, |
virtual int GetHeightForWidth(int width) OVERRIDE { |
int label_width = width - GetInsets().width(); |
if (child_count() > 1) { |
- views::View* tooltip_icon = child_at(1); |
- label_width -= tooltip_icon->GetPreferredSize().width() + |
+ views::View* learn_more_icon = child_at(1); |
+ label_width -= learn_more_icon->GetPreferredSize().width() + |
kDialogEdgePadding; |
} |
@@ -343,12 +345,12 @@ class NotificationView : public views::View, |
if (child_count() > 1) { |
// The icon takes up the entire vertical space and an extra 20px on |
- // each side. This increases the hover target for the tooltip. |
- views::View* tooltip_icon = child_at(1); |
- gfx::Size icon_size = tooltip_icon->GetPreferredSize(); |
+ // each side. This increases the hover target for the learn more icon. |
+ views::View* learn_more_icon = child_at(1); |
+ gfx::Size icon_size = learn_more_icon->GetPreferredSize(); |
int icon_width = icon_size.width() + kDialogEdgePadding; |
right_bound -= icon_width; |
- tooltip_icon->SetBounds( |
+ learn_more_icon->SetBounds( |
right_bound, 0, |
icon_width + kDialogEdgePadding, GetLocalBounds().height()); |
} |
@@ -460,15 +462,16 @@ class LoadingAnimationView : public views::View, |
} // namespace |
-// AutofillDialogViews::ErrorBubble -------------------------------------------- |
+// AutofillDialogViews::InfoBubble -------------------------------------------- |
-AutofillDialogViews::ErrorBubble::ErrorBubble(views::View* anchor, |
- views::View* anchor_container, |
- const base::string16& message) |
+AutofillDialogViews::InfoBubble::InfoBubble(views::View* anchor, |
+ const base::string16& message, |
+ bool snap_to_grid) |
: anchor_(anchor), |
- anchor_container_(anchor_container), |
+ anchor_container_(anchor->GetWidget()->non_client_view()), |
show_above_anchor_( |
- anchor->GetClassName() == views::Combobox::kViewClassName) { |
+ anchor->GetClassName() == views::Combobox::kViewClassName), |
+ snap_to_grid_(snap_to_grid) { |
DCHECK(anchor_container_->Contains(anchor)); |
SetAnchorView(anchor_); |
@@ -485,10 +488,10 @@ AutofillDialogViews::ErrorBubble::ErrorBubble(views::View* anchor, |
views::BubbleBorder::TOP_LEFT); |
} |
- set_margins(gfx::Insets(kErrorBubbleVerticalMargin, |
- kErrorBubbleHorizontalMargin, |
- kErrorBubbleVerticalMargin, |
- kErrorBubbleHorizontalMargin)); |
+ set_margins(gfx::Insets(kInfoBubbleVerticalMargin, |
+ kInfoBubbleHorizontalMargin, |
+ kInfoBubbleVerticalMargin, |
+ kInfoBubbleHorizontalMargin)); |
set_use_focusless(true); |
SetLayoutManager(new views::FillLayout); |
@@ -501,17 +504,17 @@ AutofillDialogViews::ErrorBubble::ErrorBubble(views::View* anchor, |
UpdatePosition(); |
} |
-AutofillDialogViews::ErrorBubble::~ErrorBubble() { |
+AutofillDialogViews::InfoBubble::~InfoBubble() { |
DCHECK(!widget_); |
} |
-void AutofillDialogViews::ErrorBubble::Hide() { |
+void AutofillDialogViews::InfoBubble::Hide() { |
views::Widget* widget = GetWidget(); |
if (widget && !widget->IsClosed()) |
widget->Close(); |
} |
-void AutofillDialogViews::ErrorBubble::UpdatePosition() { |
+void AutofillDialogViews::InfoBubble::UpdatePosition() { |
if (!widget_) |
return; |
@@ -525,45 +528,52 @@ void AutofillDialogViews::ErrorBubble::UpdatePosition() { |
} |
} |
-gfx::Size AutofillDialogViews::ErrorBubble::GetPreferredSize() { |
+gfx::Size AutofillDialogViews::InfoBubble::GetPreferredSize() { |
int pref_width = GetPreferredBubbleWidth(); |
pref_width -= GetBubbleFrameView()->GetInsets().width(); |
pref_width -= 2 * kBubbleBorderVisibleWidth; |
return gfx::Size(pref_width, GetHeightForWidth(pref_width)); |
} |
-gfx::Rect AutofillDialogViews::ErrorBubble::GetBubbleBounds() { |
+gfx::Rect AutofillDialogViews::InfoBubble::GetBubbleBounds() { |
gfx::Rect bounds = views::BubbleDelegateView::GetBubbleBounds(); |
gfx::Rect anchor_bounds = anchor_->GetBoundsInScreen(); |
+ if (anchor_->GetClassName() == LearnMoreIcon::kViewClassName) { |
Evan Stade
2013/11/05 02:01:40
boooo
Dan Beam
2013/11/05 07:00:55
removed
|
+ gfx::Size pref_size = anchor_->GetPreferredSize(); |
+ gfx::Point new_origin = anchor_bounds.CenterPoint(); |
+ new_origin.Offset(-pref_size.width() / 2, -pref_size.height() / 2); |
+ anchor_bounds = gfx::Rect(new_origin, pref_size); |
+ bounds.set_y(anchor_bounds.bottom()); |
+ } |
+ |
if (show_above_anchor_) |
bounds.set_y(anchor_bounds.y() - GetBubbleFrameView()->height()); |
- anchor_bounds.Inset(-GetBubbleFrameView()->bubble_border()->GetInsets()); |
- bounds.set_x(ShouldArrowGoOnTheRight() ? |
- anchor_bounds.right() - bounds.width() - kBubbleBorderVisibleWidth : |
- anchor_bounds.x() + kBubbleBorderVisibleWidth); |
+ if (snap_to_grid_) { |
+ anchor_bounds.Inset(-GetBubbleFrameView()->bubble_border()->GetInsets()); |
+ bounds.set_x(ShouldArrowGoOnTheRight() ? |
+ anchor_bounds.right() - bounds.width() - kBubbleBorderVisibleWidth : |
+ anchor_bounds.x() + kBubbleBorderVisibleWidth); |
+ } |
+ |
return bounds; |
} |
-void AutofillDialogViews::ErrorBubble::OnWidgetClosing(views::Widget* widget) { |
+void AutofillDialogViews::InfoBubble::OnWidgetClosing(views::Widget* widget) { |
if (widget == widget_) |
widget_ = NULL; |
} |
-bool AutofillDialogViews::ErrorBubble::ShouldFlipArrowForRtl() const { |
+bool AutofillDialogViews::InfoBubble::ShouldFlipArrowForRtl() const { |
return false; |
} |
-int AutofillDialogViews::ErrorBubble::GetContainerWidth() { |
- return anchor_container_->width() - anchor_container_->GetInsets().width(); |
-} |
- |
-int AutofillDialogViews::ErrorBubble::GetPreferredBubbleWidth() { |
- return (GetContainerWidth() - views::kRelatedControlHorizontalSpacing) / 2; |
+int AutofillDialogViews::InfoBubble::GetPreferredBubbleWidth() { |
+ return (kSectionContainerWidth - views::kRelatedControlHorizontalSpacing) / 2; |
} |
-bool AutofillDialogViews::ErrorBubble::ShouldArrowGoOnTheRight() { |
+bool AutofillDialogViews::InfoBubble::ShouldArrowGoOnTheRight() { |
gfx::Point anchor_offset; |
views::View::ConvertPointToTarget(anchor_, anchor_container_, &anchor_offset); |
anchor_offset.Offset(-anchor_container_->GetInsets().left(), 0); |
@@ -573,7 +583,8 @@ bool AutofillDialogViews::ErrorBubble::ShouldArrowGoOnTheRight() { |
return anchor_right_x >= GetPreferredBubbleWidth(); |
} |
- return anchor_offset.x() + GetPreferredBubbleWidth() > GetContainerWidth(); |
+ int container_width = anchor_container_->width(); |
+ return anchor_offset.x() + GetPreferredBubbleWidth() > container_width; |
} |
// AutofillDialogViews::AccountChooser ----------------------------------------- |
@@ -807,8 +818,10 @@ gfx::Rect AutofillDialogViews::OverlayView::ContentBoundsSansBubbleBorder() { |
// AutofillDialogViews::NotificationArea --------------------------------------- |
AutofillDialogViews::NotificationArea::NotificationArea( |
- AutofillDialogViewDelegate* delegate) |
- : delegate_(delegate) { |
+ AutofillDialogViewDelegate* delegate, |
+ const base::WeakPtr<LearnMoreIconDelegate>& icon_delegate) |
+ : delegate_(delegate), |
+ icon_delegate_(icon_delegate) { |
// Reserve vertical space for the arrow (regardless of whether one exists). |
// The -1 accounts for the border. |
set_border(views::Border::CreateEmptyBorder(kArrowHeight - 1, 0, 0, 0)); |
@@ -832,7 +845,8 @@ void AutofillDialogViews::NotificationArea::SetNotifications( |
for (size_t i = 0; i < notifications_.size(); ++i) { |
const DialogNotification& notification = notifications_[i]; |
scoped_ptr<NotificationView> view(new NotificationView(notification, |
- delegate_)); |
+ delegate_, |
+ icon_delegate_)); |
AddChildView(view.release()); |
} |
@@ -1277,7 +1291,9 @@ AutofillDialogViews::AutofillDialogViews(AutofillDialogViewDelegate* delegate) |
legal_document_view_(NULL), |
focus_manager_(NULL), |
error_bubble_(NULL), |
- observer_(this) { |
+ learn_more_bubble_(NULL), |
+ observer_(this), |
+ weak_ptr_factory_(this) { |
DCHECK(delegate); |
detail_groups_.insert(std::make_pair(SECTION_CC, |
DetailsGroup(SECTION_CC))); |
@@ -1291,6 +1307,7 @@ AutofillDialogViews::AutofillDialogViews(AutofillDialogViewDelegate* delegate) |
AutofillDialogViews::~AutofillDialogViews() { |
HideErrorBubble(); |
+ HideLearnMoreBubble(); |
DCHECK(!window_); |
} |
@@ -1661,6 +1678,8 @@ void AutofillDialogViews::Layout() { |
if (error_bubble_) |
error_bubble_->UpdatePosition(); |
+ if (learn_more_bubble_) |
+ learn_more_bubble_->UpdatePosition(); |
} |
base::string16 AutofillDialogViews::GetWindowTitle() const { |
@@ -1897,6 +1916,15 @@ void AutofillDialogViews::OnMenuButtonClicked(views::View* source, |
group->suggested_button->SetState(state); |
} |
+void AutofillDialogViews::OnLearnMoreIconMouseEntered(LearnMoreIcon* icon) { |
+ ShowLearnMoreBubbleIfNecessary(icon); |
+} |
+ |
+void AutofillDialogViews::OnLearnMoreIconMouseExited(LearnMoreIcon* icon) { |
+ DCHECK_EQ(icon, learn_more_bubble_->anchor()); |
+ HideLearnMoreBubble(); |
+} |
+ |
gfx::Size AutofillDialogViews::CalculatePreferredSize(bool get_minimum_size) { |
gfx::Insets insets = GetInsets(); |
gfx::Size scroll_size = scrollable_area_->contents()->GetPreferredSize(); |
@@ -1979,13 +2007,15 @@ void AutofillDialogViews::InitChildViews() { |
save_in_chrome_checkbox_container_->AddChildView(save_in_chrome_checkbox_); |
save_in_chrome_checkbox_container_->AddChildView( |
- new TooltipIcon(delegate_->SaveLocallyTooltip())); |
+ new LearnMoreIcon(delegate_->SaveLocallyLearnMoreText(), |
+ weak_ptr_factory_.GetWeakPtr())); |
button_strip_image_ = new views::ImageView(); |
button_strip_extra_view_->AddChildView(button_strip_image_); |
account_chooser_ = new AccountChooser(delegate_); |
- notification_area_ = new NotificationArea(delegate_); |
+ notification_area_ = |
+ new NotificationArea(delegate_, weak_ptr_factory_.GetWeakPtr()); |
notification_area_->set_arrow_centering_anchor(account_chooser_->AsWeakPtr()); |
AddChildView(notification_area_); |
@@ -2253,13 +2283,21 @@ void AutofillDialogViews::ShowErrorBubbleForViewIfNecessary(views::View* view) { |
if (!error_bubble_ || error_bubble_->anchor() != view) { |
HideErrorBubble(); |
- views::View* section = |
- view->GetAncestorWithClassName(kSectionContainerClassName); |
- error_bubble_ = new ErrorBubble(view, section, error_message->second); |
+ error_bubble_ = new InfoBubble(view, error_message->second, true); |
} |
} |
} |
+void AutofillDialogViews::ShowLearnMoreBubbleIfNecessary(LearnMoreIcon* icon) { |
+ if (!icon->GetWidget()) |
+ return; |
+ |
+ if (!learn_more_bubble_ || learn_more_bubble_->anchor() != icon) { |
+ HideLearnMoreBubble(); |
+ learn_more_bubble_ = new InfoBubble(icon, icon->learn_more_text(), false); |
+ } |
+} |
+ |
void AutofillDialogViews::HideErrorBubble() { |
if (error_bubble_) { |
error_bubble_->Hide(); |
@@ -2267,6 +2305,13 @@ void AutofillDialogViews::HideErrorBubble() { |
} |
} |
+void AutofillDialogViews::HideLearnMoreBubble() { |
+ if (learn_more_bubble_) { |
+ learn_more_bubble_->Hide(); |
+ learn_more_bubble_ = NULL; |
+ } |
+} |
+ |
void AutofillDialogViews::MarkInputsInvalid( |
DialogSection section, |
const ValidityMessages& messages, |
@@ -2513,6 +2558,8 @@ views::Combobox* AutofillDialogViews::ComboboxForInput( |
void AutofillDialogViews::DetailsContainerBoundsChanged() { |
if (error_bubble_) |
error_bubble_->UpdatePosition(); |
+ if (learn_more_bubble_) |
+ learn_more_bubble_->UpdatePosition(); |
} |
void AutofillDialogViews::SetIconsForSection(DialogSection section) { |
@@ -2534,10 +2581,12 @@ void AutofillDialogViews::SetIconsForSection(DialogSection section) { |
ServerFieldType field_type = textfield_it->first->type; |
FieldIconMap::const_iterator field_icon_it = field_icons.find(field_type); |
DecoratedTextfield* textfield = textfield_it->second; |
- if (field_icon_it != field_icons.end()) |
+ if (field_icon_it != field_icons.end()) { |
textfield->SetIcon(field_icon_it->second); |
- else |
- textfield->SetTooltipIcon(delegate_->TooltipForField(field_type)); |
+ } else { |
+ textfield->SetLearnMoreIcon(delegate_->LearnMoreTextForField(field_type), |
+ weak_ptr_factory_.GetWeakPtr()); |
+ } |
} |
} |