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 |