Chromium Code Reviews| 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 54dc65379211bcc58ecfa5db41ac77899d78c928..2ae6e7ed97fded7effb63322aabec91c8b350869 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 height = 0; |
| + int width = 0; |
| + for (int i = 0; i < child_count(); ++i) { |
| + if (child_at(i)->visible()) { |
| + if (width > 0) |
| + width += kAroundTextPadding; |
| + |
| + gfx::Size size = child_at(i)->GetPreferredSize(); |
| + height = std::max(height, size.height()); |
| + width += size.width(); |
| + } |
| + } |
| + |
| + return gfx::Size(width, height); |
| } |
| virtual void Layout() OVERRIDE { |
| @@ -588,7 +600,7 @@ AutofillDialogViews::OverlayView::OverlayView(views::ButtonListener* listener) |
| AutofillDialogViews::OverlayView::~OverlayView() {} |
| -int AutofillDialogViews::OverlayView::GetHeightForContentsForWidth(int w) { |
| +int AutofillDialogViews::OverlayView::GetHeightForContentsForWidth(int width) { |
| // In this case, 0 means "no preference". |
| if (!message_stack_->visible()) |
| return 0; |
| @@ -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 width) { |
| + int height = 0; |
| + CanUseVerticallyCompactText(width, &height); |
| + return height; |
| +} |
| + |
| +bool AutofillDialogViews::SuggestionView::CanUseVerticallyCompactText( |
| + int available_width, int* resulting_height) { |
|
sky
2013/08/06 21:28:10
nit: when you wrap one param per line.
sky
2013/08/06 21:28:10
How many times if this called with varying widths
Evan Stade
2013/08/06 23:15:34
It's mostly called with the same width over and ov
Evan Stade
2013/08/06 23:15:34
Done.
|
| + // 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]; |
|
sky
2013/08/06 21:28:10
const std::pair&
Evan Stade
2013/08/06 23:15:34
Done.
|
| + *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_.visible); |
| + // 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 --------------------------------- |
| @@ -1464,15 +1536,15 @@ void AutofillDialogViews::Layout() { |
| const int x = content_bounds.x(); |
| const int y = content_bounds.y(); |
| - const int w = content_bounds.width(); |
| + const int width = content_bounds.width(); |
| // Layout notification area at top of dialog. |
| int notification_height = notification_area_->GetHeightForWidth(w); |
| - notification_area_->SetBounds(x, y, w, notification_height); |
| + notification_area_->SetBounds(x, y, width, notification_height); |
| // Layout Autocheckout steps at bottom of dialog. |
| int steps_height = autocheckout_steps_area_->GetHeightForWidth(w); |
| autocheckout_steps_area_->SetBounds(x, content_bounds.bottom() - steps_height, |
| - w, steps_height); |
| + width, steps_height); |
| // The rest (the |scrollable_area_|) takes up whatever's left. |
| if (scrollable_area_->visible()) { |
| @@ -1485,7 +1557,7 @@ void AutofillDialogViews::Layout() { |
| scroll_bottom -= steps_height + views::kRelatedControlVerticalSpacing; |
| scrollable_area_->contents()->SizeToPreferredSize(); |
| - scrollable_area_->SetBounds(x, scroll_y, w, scroll_bottom - scroll_y); |
| + scrollable_area_->SetBounds(x, scroll_y, width, scroll_bottom - scroll_y); |
| } |
| if (loading_shield_->visible()) |
| @@ -1795,8 +1867,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 |
| @@ -1952,19 +2023,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.visible); |
| UpdateButtonStripExtraView(); |
| @@ -1974,7 +2034,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.visible); |
| group.container->SetVisible(controller_->SectionIsActive(group.section)); |
| if (group.container->visible()) |
| ValidateGroup(group, VALIDATE_EDIT); |