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 b580df5ed4480d7042dc38c41b7ff2c8f0a842f4..ff26ba435368cc4ad2897e717b227132ea5760c9 100644 |
--- a/chrome/browser/ui/views/autofill/autofill_dialog_views.cc |
+++ b/chrome/browser/ui/views/autofill/autofill_dialog_views.cc |
@@ -152,8 +152,20 @@ class SectionRowView : public views::View { |
// views::View implementation: |
virtual gfx::Size GetPreferredSize() OVERRIDE { |
- // Only the height matters anyway. |
- return child_at(2)->GetPreferredSize(); |
+ int h = 0; |
+ int w = 0; |
Ilya Sherman
2013/08/06 08:00:23
nit: Please spell out "height" and "width" (throug
Evan Stade
2013/08/06 19:00:37
I'll change it here, but the views function in vie
Evan Stade
2013/08/06 19:34:53
scratch that, all updated.
|
+ for (int i = 0; i < child_count(); ++i) { |
+ if (child_at(i)->visible()) { |
+ if (w > 0) |
+ w += kAroundTextPadding; |
+ |
+ gfx::Size size = child_at(i)->GetPreferredSize(); |
+ h = std::max(h, size.height()); |
+ w += size.width(); |
+ } |
+ } |
+ |
+ return gfx::Size(w, h); |
} |
virtual void Layout() OVERRIDE { |
@@ -986,12 +998,10 @@ ui::MouseEvent AutofillDialogViews::SectionContainer::ProxyEvent( |
// AutofilDialogViews::SuggestionView ------------------------------------------ |
AutofillDialogViews::SuggestionView::SuggestionView( |
- const base::string16& edit_label, |
AutofillDialogViews* autofill_dialog) |
: label_(new views::Label()), |
label_line_2_(new views::Label()), |
icon_(new views::ImageView()), |
- label_container_(new SectionRowView()), |
decorated_( |
new DecoratedTextfield(base::string16(), |
base::string16(), |
@@ -1000,16 +1010,20 @@ AutofillDialogViews::SuggestionView::SuggestionView( |
set_border( |
views::Border::CreateSolidSidedBorder(1, 0, 0, 0, SK_ColorLTGRAY)); |
+ SectionRowView* label_container = new SectionRowView(); |
+ AddChildView(label_container); |
+ |
// Label and icon. |
+ label_container->AddChildView(icon_); |
label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
- label_container_->AddChildView(icon_); |
- label_container_->AddChildView(label_); |
- label_container_->AddChildView(decorated_); |
- decorated_->SetVisible(false); |
+ label_container->AddChildView(label_); |
+ |
// TODO(estade): get the sizing and spacing right on this textfield. |
+ decorated_->SetVisible(false); |
decorated_->set_default_width_in_chars(10); |
- AddChildView(label_container_); |
+ label_container->AddChildView(decorated_); |
+ // TODO(estade): need to get the line height right. |
label_line_2_->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
label_line_2_->SetVisible(false); |
label_line_2_->SetMultiLine(true); |
@@ -1021,12 +1035,73 @@ AutofillDialogViews::SuggestionView::SuggestionView( |
AutofillDialogViews::SuggestionView::~SuggestionView() {} |
-void AutofillDialogViews::SuggestionView::SetSuggestionText( |
- const base::string16& text, |
- gfx::Font::FontStyle text_style) { |
- label_->SetFont(ui::ResourceBundle::GetSharedInstance().GetFont( |
- ui::ResourceBundle::BaseFont).DeriveFont(0, text_style)); |
+gfx::Size AutofillDialogViews::SuggestionView::GetPreferredSize() { |
+ // There's no preferred width. The parent's layout should get the preferred |
+ // height from GetHeightForWidth(). |
+ return gfx::Size(); |
+} |
+ |
+int AutofillDialogViews::SuggestionView::GetHeightForWidth(int w) { |
+ int h = 0; |
+ CanUseVerticallyCompactText(w, &h); |
+ return h; |
+} |
+ |
+bool AutofillDialogViews::SuggestionView::CanUseVerticallyCompactText( |
+ int available_width, int* resulting_height) { |
+ // This calculation may be costly, avoid doing it more than once per width. |
+ if (!calculated_heights_.count(available_width)) { |
+ // Changing the state of |this| now will lead to extra layouts and |
+ // paints we don't want, so create another SuggestionView to calculate |
+ // which label we have room to show. |
+ SuggestionView sizing_view(NULL); |
+ sizing_view.SetLabelText(state_.vertically_compact_text); |
+ sizing_view.SetIcon(state_.icon); |
+ sizing_view.SetTextfield(state_.extra_text, state_.extra_icon); |
+ |
+ // Shortcut |sizing_view|'s GetHeightForWidth() to avoid an infinite loop. |
+ // Its BoxLayout must do these calculations for us. |
+ views::LayoutManager* layout = sizing_view.GetLayoutManager(); |
+ if (layout->GetPreferredSize(&sizing_view).width() <= available_width) { |
+ calculated_heights_[available_width] = std::make_pair( |
+ true, |
+ layout->GetPreferredHeightForWidth(&sizing_view, available_width)); |
+ } else { |
+ sizing_view.SetLabelText(state_.horizontally_compact_text); |
+ calculated_heights_[available_width] = std::make_pair( |
+ false, |
+ layout->GetPreferredHeightForWidth(&sizing_view, available_width)); |
+ } |
+ } |
+ |
+ std::pair<bool, int> values = calculated_heights_[available_width]; |
+ *resulting_height = values.second; |
+ return values.first; |
+} |
+ |
+void AutofillDialogViews::SuggestionView::OnBoundsChanged( |
+ const gfx::Rect& previous_bounds) { |
+ int unused; |
+ SetLabelText(CanUseVerticallyCompactText(width(), &unused) ? |
+ state_.vertically_compact_text : |
+ state_.horizontally_compact_text); |
+} |
+ |
+void AutofillDialogViews::SuggestionView::SetState( |
+ const SuggestionState& state) { |
+ calculated_heights_.clear(); |
+ state_ = state; |
+ SetVisible(state_.show); |
+ // Set to the more compact text for now. |this| will optionally switch to |
+ // the more vertically expanded view when the bounds are set. |
+ SetLabelText(state_.vertically_compact_text); |
+ SetIcon(state_.icon); |
+ SetTextfield(state_.extra_text, state_.extra_icon); |
+ PreferredSizeChanged(); |
+} |
+void AutofillDialogViews::SuggestionView::SetLabelText( |
+ const base::string16& text) { |
// TODO(estade): does this localize well? |
base::string16 line_return(ASCIIToUTF16("\n")); |
size_t position = text.find(line_return); |
@@ -1040,21 +1115,18 @@ void AutofillDialogViews::SuggestionView::SetSuggestionText( |
} |
} |
-void AutofillDialogViews::SuggestionView::SetSuggestionIcon( |
+void AutofillDialogViews::SuggestionView::SetIcon( |
const gfx::Image& image) { |
icon_->SetVisible(!image.IsEmpty()); |
icon_->SetImage(image.AsImageSkia()); |
} |
-void AutofillDialogViews::SuggestionView::ShowTextfield( |
+void AutofillDialogViews::SuggestionView::SetTextfield( |
const base::string16& placeholder_text, |
const gfx::Image& icon) { |
decorated_->set_placeholder_text(placeholder_text); |
decorated_->SetIcon(icon); |
- decorated_->SetVisible(true); |
- // The textfield will increase the height of the first row and cause the |
- // label to be aligned properly, so the border is not necessary. |
- label_->set_border(NULL); |
+ decorated_->SetVisible(!placeholder_text.empty()); |
} |
// AutofillDialogViews::AutocheckoutStepsArea --------------------------------- |
@@ -1796,8 +1868,7 @@ views::View* AutofillDialogViews::CreateInputsContainer(DialogSection section) { |
views::View* manual_inputs = InitInputsView(section); |
info_view->AddChildView(manual_inputs); |
- SuggestionView* suggested_info = |
- new SuggestionView(controller_->EditSuggestionText(), this); |
+ SuggestionView* suggested_info = new SuggestionView(this); |
info_view->AddChildView(suggested_info); |
// TODO(estade): It might be slightly more OO if this button were created |
@@ -1953,19 +2024,8 @@ void AutofillDialogViews::UpdateSectionImpl( |
void AutofillDialogViews::UpdateDetailsGroupState(const DetailsGroup& group) { |
const SuggestionState& suggestion_state = |
controller_->SuggestionStateForSection(group.section); |
- bool show_suggestions = !suggestion_state.text.empty(); |
- group.suggested_info->SetVisible(show_suggestions); |
- group.suggested_info->SetSuggestionText(suggestion_state.text, |
- suggestion_state.text_style); |
- group.suggested_info->SetSuggestionIcon(suggestion_state.icon); |
- |
- if (!suggestion_state.extra_text.empty()) { |
- group.suggested_info->ShowTextfield( |
- suggestion_state.extra_text, |
- suggestion_state.extra_icon); |
- } |
- |
- group.manual_input->SetVisible(!show_suggestions); |
+ group.suggested_info->SetState(suggestion_state); |
+ group.manual_input->SetVisible(!suggestion_state.show); |
// Show or hide the "Save in chrome" checkbox. If nothing is in editing mode, |
// hide. If the controller tells us not to show it, likewise hide. |
@@ -1977,7 +2037,8 @@ void AutofillDialogViews::UpdateDetailsGroupState(const DetailsGroup& group) { |
group.suggested_button->SetVisible(has_menu); |
if (group.container) { |
- group.container->SetForwardMouseEvents(has_menu && show_suggestions); |
+ group.container->SetForwardMouseEvents( |
+ has_menu && suggestion_state.show); |
group.container->SetVisible(controller_->SectionIsActive(group.section)); |
if (group.container->visible()) |
ValidateGroup(group, VALIDATE_EDIT); |