| 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/autofill/autofill_popup_controller_impl.h" | 5 #include "chrome/browser/ui/autofill/autofill_popup_controller_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 const std::vector<string16>& names, | 115 const std::vector<string16>& names, |
| 116 const std::vector<string16>& subtexts, | 116 const std::vector<string16>& subtexts, |
| 117 const std::vector<string16>& icons, | 117 const std::vector<string16>& icons, |
| 118 const std::vector<int>& identifiers) { | 118 const std::vector<int>& identifiers) { |
| 119 SetValues(names, subtexts, icons, identifiers); | 119 SetValues(names, subtexts, icons, identifiers); |
| 120 | 120 |
| 121 #if !defined(OS_ANDROID) | 121 #if !defined(OS_ANDROID) |
| 122 // Android displays the long text with ellipsis using the view attributes. | 122 // Android displays the long text with ellipsis using the view attributes. |
| 123 | 123 |
| 124 UpdatePopupBounds(); | 124 UpdatePopupBounds(); |
| 125 int popup_width = popup_bounds().width(); | 125 float popup_width = popup_bounds().width(); |
| 126 | 126 |
| 127 // Elide the name and subtext strings so that the popup fits in the available | 127 // Elide the name and subtext strings so that the popup fits in the available |
| 128 // space. | 128 // space. |
| 129 for (size_t i = 0; i < names_.size(); ++i) { | 129 for (size_t i = 0; i < names_.size(); ++i) { |
| 130 int name_width = GetNameFontForRow(i).GetStringWidth(names_[i]); | 130 float name_width = GetNameFontForRow(i).GetStringWidth(names_[i]); |
| 131 int subtext_width = subtext_font().GetStringWidth(subtexts_[i]); | 131 float subtext_width = subtext_font().GetStringWidth(subtexts_[i]); |
| 132 int total_text_length = name_width + subtext_width; | 132 float total_text_length = name_width + subtext_width; |
| 133 | 133 |
| 134 // The line can have no strings if it represents a UI element, such as | 134 // The line can have no strings if it represents a UI element, such as |
| 135 // a separator line. | 135 // a separator line. |
| 136 if (total_text_length == 0) | 136 if (total_text_length == 0) |
| 137 continue; | 137 continue; |
| 138 | 138 |
| 139 int available_width = popup_width - RowWidthWithoutText(i); | 139 float available_width = popup_width - RowWidthWithoutText(i); |
| 140 | 140 |
| 141 // Each field recieves space in proportion to its length. | 141 // Each field recieves space in proportion to its length. |
| 142 int name_size = available_width * name_width / total_text_length; | 142 float name_size = available_width * name_width / total_text_length; |
| 143 names_[i] = gfx::ElideText(names_[i], | 143 names_[i] = gfx::ElideText(names_[i], |
| 144 GetNameFontForRow(i), | 144 GetNameFontForRow(i), |
| 145 name_size, | 145 name_size, |
| 146 gfx::ELIDE_AT_END); | 146 gfx::ELIDE_AT_END); |
| 147 | 147 |
| 148 int subtext_size = available_width * subtext_width / total_text_length; | 148 float subtext_size = available_width * subtext_width / total_text_length; |
| 149 subtexts_[i] = gfx::ElideText(subtexts_[i], | 149 subtexts_[i] = gfx::ElideText(subtexts_[i], |
| 150 subtext_font(), | 150 subtext_font(), |
| 151 subtext_size, | 151 subtext_size, |
| 152 gfx::ELIDE_AT_END); | 152 gfx::ELIDE_AT_END); |
| 153 } | 153 } |
| 154 #endif | 154 #endif |
| 155 | 155 |
| 156 if (!view_) { | 156 if (!view_) { |
| 157 view_ = AutofillPopupView::Create(this); | 157 view_ = AutofillPopupView::Create(this); |
| 158 | 158 |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 int id = identifiers_[index]; | 328 int id = identifiers_[index]; |
| 329 return id > 0 || | 329 return id > 0 || |
| 330 id == WebAutofillClient::MenuItemIDAutocompleteEntry || | 330 id == WebAutofillClient::MenuItemIDAutocompleteEntry || |
| 331 id == WebAutofillClient::MenuItemIDPasswordEntry; | 331 id == WebAutofillClient::MenuItemIDPasswordEntry; |
| 332 } | 332 } |
| 333 | 333 |
| 334 bool AutofillPopupControllerImpl::IsWarning(size_t index) const { | 334 bool AutofillPopupControllerImpl::IsWarning(size_t index) const { |
| 335 return identifiers_[index] == WebAutofillClient::MenuItemIDWarningMessage; | 335 return identifiers_[index] == WebAutofillClient::MenuItemIDWarningMessage; |
| 336 } | 336 } |
| 337 | 337 |
| 338 gfx::Rect AutofillPopupControllerImpl::GetRowBounds(size_t index) { | 338 gfx::RectF AutofillPopupControllerImpl::GetRowBounds(size_t index) { |
| 339 int top = 0; | 339 int top = 0; |
| 340 for (size_t i = 0; i < index; ++i) { | 340 for (size_t i = 0; i < index; ++i) { |
| 341 top += GetRowHeightFromId(identifiers()[i]); | 341 top += GetRowHeightFromId(identifiers()[i]); |
| 342 } | 342 } |
| 343 | 343 |
| 344 return gfx::Rect( | 344 return gfx::RectF( |
| 345 0, | 345 0, |
| 346 top, | 346 top, |
| 347 popup_bounds_.width(), | 347 popup_bounds_.width(), |
| 348 GetRowHeightFromId(identifiers()[index])); | 348 GetRowHeightFromId(identifiers()[index])); |
| 349 } | 349 } |
| 350 | 350 |
| 351 void AutofillPopupControllerImpl::SetPopupBounds(const gfx::Rect& bounds) { | 351 void AutofillPopupControllerImpl::SetPopupBounds(const gfx::RectF& bounds) { |
| 352 popup_bounds_ = bounds; | 352 popup_bounds_ = bounds; |
| 353 UpdateBoundsAndRedrawPopup(); | 353 UpdateBoundsAndRedrawPopup(); |
| 354 } | 354 } |
| 355 | 355 |
| 356 const gfx::Rect& AutofillPopupControllerImpl::popup_bounds() const { | 356 const gfx::RectF& AutofillPopupControllerImpl::popup_bounds() const { |
| 357 return popup_bounds_; | 357 return popup_bounds_; |
| 358 } | 358 } |
| 359 | 359 |
| 360 gfx::NativeView AutofillPopupControllerImpl::container_view() const { | 360 gfx::NativeView AutofillPopupControllerImpl::container_view() const { |
| 361 return container_view_; | 361 return container_view_; |
| 362 } | 362 } |
| 363 | 363 |
| 364 const gfx::RectF& AutofillPopupControllerImpl::element_bounds() const { | 364 const gfx::RectF& AutofillPopupControllerImpl::element_bounds() const { |
| 365 return element_bounds_; | 365 return element_bounds_; |
| 366 } | 366 } |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 view_->Show(); | 558 view_->Show(); |
| 559 } | 559 } |
| 560 | 560 |
| 561 void AutofillPopupControllerImpl::InvalidateRow(size_t row) { | 561 void AutofillPopupControllerImpl::InvalidateRow(size_t row) { |
| 562 DCHECK(0 <= row); | 562 DCHECK(0 <= row); |
| 563 DCHECK(row < identifiers_.size()); | 563 DCHECK(row < identifiers_.size()); |
| 564 view_->InvalidateRow(row); | 564 view_->InvalidateRow(row); |
| 565 } | 565 } |
| 566 | 566 |
| 567 #if !defined(OS_ANDROID) | 567 #if !defined(OS_ANDROID) |
| 568 int AutofillPopupControllerImpl::GetDesiredPopupWidth() const { | 568 float AutofillPopupControllerImpl::GetDesiredPopupWidth() const { |
| 569 if (!name_font_.platform_font() || !subtext_font_.platform_font()) { | 569 if (!name_font_.platform_font() || !subtext_font_.platform_font()) { |
| 570 // We can't calculate the size of the popup if the fonts | 570 // We can't calculate the size of the popup if the fonts |
| 571 // aren't present. | 571 // aren't present. |
| 572 return 0; | 572 return 0; |
| 573 } | 573 } |
| 574 | 574 |
| 575 int popup_width = RoundedElementBounds().width(); | 575 float popup_width = RoundedElementBounds().width(); |
| 576 DCHECK_EQ(names().size(), subtexts().size()); | 576 DCHECK_EQ(names().size(), subtexts().size()); |
| 577 for (size_t i = 0; i < names().size(); ++i) { | 577 for (size_t i = 0; i < names().size(); ++i) { |
| 578 int row_size = name_font_.GetStringWidth(names()[i]) + | 578 float row_size = name_font_.GetStringWidth(names()[i]) + |
| 579 subtext_font_.GetStringWidth(subtexts()[i]) + | 579 subtext_font_.GetStringWidth(subtexts()[i]) + |
| 580 RowWidthWithoutText(i); | 580 RowWidthWithoutText(i); |
| 581 | 581 |
| 582 popup_width = std::max(popup_width, row_size); | 582 popup_width = std::max(popup_width, row_size); |
| 583 } | 583 } |
| 584 | 584 |
| 585 return popup_width; | 585 return popup_width; |
| 586 } | 586 } |
| 587 | 587 |
| 588 int AutofillPopupControllerImpl::GetDesiredPopupHeight() const { | 588 int AutofillPopupControllerImpl::GetDesiredPopupHeight() const { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 605 if (!icons_[row].empty()) | 605 if (!icons_[row].empty()) |
| 606 row_size += kAutofillIconWidth + kIconPadding; | 606 row_size += kAutofillIconWidth + kIconPadding; |
| 607 | 607 |
| 608 // Add the padding at the end | 608 // Add the padding at the end |
| 609 row_size += kEndPadding; | 609 row_size += kEndPadding; |
| 610 | 610 |
| 611 return row_size; | 611 return row_size; |
| 612 } | 612 } |
| 613 | 613 |
| 614 void AutofillPopupControllerImpl::UpdatePopupBounds() { | 614 void AutofillPopupControllerImpl::UpdatePopupBounds() { |
| 615 int popup_required_width = GetDesiredPopupWidth(); | 615 float popup_required_width = GetDesiredPopupWidth(); |
| 616 int popup_height = GetDesiredPopupHeight(); | 616 int popup_height = GetDesiredPopupHeight(); |
| 617 // This is the top left point of the popup if the popup is above the element | 617 // This is the top left point of the popup if the popup is above the element |
| 618 // and grows to the left (since that is the highest and furthest left the | 618 // and grows to the left (since that is the highest and furthest left the |
| 619 // popup go could). | 619 // popup go could). |
| 620 gfx::Point top_left_corner_of_popup = RoundedElementBounds().origin() + | 620 gfx::Point top_left_corner_of_popup = RoundedElementBounds().origin() + |
| 621 gfx::Vector2d(RoundedElementBounds().width() - popup_required_width, | 621 gfx::Vector2d(RoundedElementBounds().width() - popup_required_width, |
| 622 -popup_height); | 622 -popup_height); |
| 623 | 623 |
| 624 // This is the bottom right point of the popup if the popup is below the | 624 // This is the bottom right point of the popup if the popup is below the |
| 625 // element and grows to the right (since the is the lowest and furthest right | 625 // element and grows to the right (since the is the lowest and furthest right |
| 626 // the popup could go). | 626 // the popup could go). |
| 627 gfx::Point bottom_right_corner_of_popup = RoundedElementBounds().origin() + | 627 gfx::Point bottom_right_corner_of_popup = RoundedElementBounds().origin() + |
| 628 gfx::Vector2d(popup_required_width, | 628 gfx::Vector2d(popup_required_width, |
| 629 RoundedElementBounds().height() + popup_height); | 629 RoundedElementBounds().height() + popup_height); |
| 630 | 630 |
| 631 gfx::Display top_left_display = GetDisplayNearestPoint( | 631 gfx::Display top_left_display = GetDisplayNearestPoint( |
| 632 top_left_corner_of_popup); | 632 top_left_corner_of_popup); |
| 633 gfx::Display bottom_right_display = GetDisplayNearestPoint( | 633 gfx::Display bottom_right_display = GetDisplayNearestPoint( |
| 634 bottom_right_corner_of_popup); | 634 bottom_right_corner_of_popup); |
| 635 | 635 |
| 636 std::pair<int, int> popup_x_and_width = CalculatePopupXAndWidth( | 636 std::pair<float, float> popup_x_and_width = CalculatePopupXAndWidth( |
| 637 top_left_display, bottom_right_display, popup_required_width); | 637 top_left_display, bottom_right_display, popup_required_width); |
| 638 std::pair<int, int> popup_y_and_height = CalculatePopupYAndHeight( | 638 std::pair<int, int> popup_y_and_height = CalculatePopupYAndHeight( |
| 639 top_left_display, bottom_right_display, popup_height); | 639 top_left_display, bottom_right_display, popup_height); |
| 640 | 640 |
| 641 popup_bounds_ = gfx::Rect(popup_x_and_width.first, | 641 popup_bounds_ = gfx::RectF(popup_x_and_width.first, |
| 642 popup_y_and_height.first, | 642 popup_y_and_height.first, |
| 643 popup_x_and_width.second, | 643 popup_x_and_width.second, |
| 644 popup_y_and_height.second); | 644 popup_y_and_height.second); |
| 645 } | 645 } |
| 646 #endif // !defined(OS_ANDROID) | 646 #endif // !defined(OS_ANDROID) |
| 647 | 647 |
| 648 WeakPtr<AutofillPopupControllerImpl> AutofillPopupControllerImpl::GetWeakPtr() { | 648 WeakPtr<AutofillPopupControllerImpl> AutofillPopupControllerImpl::GetWeakPtr() { |
| 649 return weak_ptr_factory_.GetWeakPtr(); | 649 return weak_ptr_factory_.GetWeakPtr(); |
| 650 } | 650 } |
| 651 | 651 |
| 652 void AutofillPopupControllerImpl::ClearState() { | 652 void AutofillPopupControllerImpl::ClearState() { |
| 653 // Don't clear view_, because otherwise the popup will have to get regenerated | 653 // Don't clear view_, because otherwise the popup will have to get regenerated |
| 654 // and this will cause flickering. | 654 // and this will cause flickering. |
| 655 | 655 |
| 656 popup_bounds_ = gfx::Rect(); | 656 popup_bounds_ = gfx::RectF(); |
| 657 | 657 |
| 658 names_.clear(); | 658 names_.clear(); |
| 659 subtexts_.clear(); | 659 subtexts_.clear(); |
| 660 icons_.clear(); | 660 icons_.clear(); |
| 661 identifiers_.clear(); | 661 identifiers_.clear(); |
| 662 full_names_.clear(); | 662 full_names_.clear(); |
| 663 | 663 |
| 664 selected_line_ = kNoSelection; | 664 selected_line_ = kNoSelection; |
| 665 } | 665 } |
| 666 | 666 |
| 667 const gfx::Rect AutofillPopupControllerImpl::RoundedElementBounds() const { | 667 const gfx::Rect AutofillPopupControllerImpl::RoundedElementBounds() const { |
| 668 return gfx::ToEnclosingRect(element_bounds_); | 668 return gfx::ToEnclosingRect(element_bounds_); |
| 669 } | 669 } |
| 670 | 670 |
| 671 gfx::Display AutofillPopupControllerImpl::GetDisplayNearestPoint( | 671 gfx::Display AutofillPopupControllerImpl::GetDisplayNearestPoint( |
| 672 const gfx::Point& point) const { | 672 const gfx::Point& point) const { |
| 673 return gfx::Screen::GetScreenFor(container_view())->GetDisplayNearestPoint( | 673 return gfx::Screen::GetScreenFor(container_view())->GetDisplayNearestPoint( |
| 674 point); | 674 point); |
| 675 } | 675 } |
| 676 | 676 |
| 677 std::pair<int, int> AutofillPopupControllerImpl::CalculatePopupXAndWidth( | 677 std::pair<float, float> AutofillPopupControllerImpl::CalculatePopupXAndWidth( |
| 678 const gfx::Display& left_display, | 678 const gfx::Display& left_display, |
| 679 const gfx::Display& right_display, | 679 const gfx::Display& right_display, |
| 680 int popup_required_width) const { | 680 float popup_required_width) const { |
| 681 int leftmost_display_x = left_display.bounds().x(); | 681 int leftmost_display_x = left_display.bounds().x(); |
| 682 int rightmost_display_x = | 682 int rightmost_display_x = |
| 683 right_display.GetSizeInPixel().width() + right_display.bounds().x(); | 683 right_display.GetSizeInPixel().width() + right_display.bounds().x(); |
| 684 | 684 |
| 685 // Calculate the start coordinates for the popup if it is growing right or | 685 // Calculate the start coordinates for the popup if it is growing right or |
| 686 // the end position if it is growing to the left, capped to screen space. | 686 // the end position if it is growing to the left, capped to screen space. |
| 687 int right_growth_start = std::max(leftmost_display_x, | 687 int right_growth_start = std::max(leftmost_display_x, |
| 688 std::min(rightmost_display_x, | 688 std::min(rightmost_display_x, |
| 689 RoundedElementBounds().x())); | 689 RoundedElementBounds().x())); |
| 690 int left_growth_end = std::max(leftmost_display_x, | 690 int left_growth_end = std::max(leftmost_display_x, |
| 691 std::min(rightmost_display_x, | 691 std::min(rightmost_display_x, |
| 692 RoundedElementBounds().right())); | 692 RoundedElementBounds().right())); |
| 693 | 693 |
| 694 int right_available = rightmost_display_x - right_growth_start; | 694 int right_available = rightmost_display_x - right_growth_start; |
| 695 int left_available = left_growth_end - leftmost_display_x; | 695 int left_available = left_growth_end - leftmost_display_x; |
| 696 | 696 |
| 697 int popup_width = std::min(popup_required_width, | 697 float popup_width = std::min<float>( |
| 698 std::max(right_available, left_available)); | 698 popup_required_width, std::max(right_available, left_available)); |
| 699 | 699 |
| 700 // If there is enough space for the popup on the right, show it there, | 700 // If there is enough space for the popup on the right, show it there, |
| 701 // otherwise choose the larger size. | 701 // otherwise choose the larger size. |
| 702 if (right_available >= popup_width || right_available >= left_available) | 702 if (right_available >= popup_width || right_available >= left_available) |
| 703 return std::make_pair(right_growth_start, popup_width); | 703 return std::make_pair(right_growth_start, popup_width); |
| 704 else | 704 else |
| 705 return std::make_pair(left_growth_end - popup_width, popup_width); | 705 return std::make_pair(left_growth_end - popup_width, popup_width); |
| 706 } | 706 } |
| 707 | 707 |
| 708 std::pair<int,int> AutofillPopupControllerImpl::CalculatePopupYAndHeight( | 708 std::pair<int,int> AutofillPopupControllerImpl::CalculatePopupYAndHeight( |
| (...skipping 21 matching lines...) Expand all Loading... |
| 730 // The popup can appear below the field. | 730 // The popup can appear below the field. |
| 731 return std::make_pair(bottom_growth_start, popup_required_height); | 731 return std::make_pair(bottom_growth_start, popup_required_height); |
| 732 } else { | 732 } else { |
| 733 // The popup must appear above the field. | 733 // The popup must appear above the field. |
| 734 return std::make_pair(top_growth_end - popup_required_height, | 734 return std::make_pair(top_growth_end - popup_required_height, |
| 735 popup_required_height); | 735 popup_required_height); |
| 736 } | 736 } |
| 737 } | 737 } |
| 738 | 738 |
| 739 } // namespace autofill | 739 } // namespace autofill |
| OLD | NEW |