| Index: chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
|
| diff --git a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
|
| index 3b0dc1188412a27e5f25707567413bec7de1217e..e2126b7a039bacb104a5a98258dc5133ec034304 100644
|
| --- a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
|
| +++ b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
|
| @@ -10,6 +10,7 @@
|
| #include <utility>
|
| #include <vector>
|
|
|
| +#include "base/i18n/message_formatter.h"
|
| #include "base/macros.h"
|
| #include "base/memory/ptr_util.h"
|
| #include "base/strings/string_number_conversions.h"
|
| @@ -36,6 +37,8 @@
|
| #include "ui/gfx/font.h"
|
| #include "ui/gfx/paint_vector_icon.h"
|
| #include "ui/gfx/range/range.h"
|
| +#include "ui/gfx/text_elider.h"
|
| +#include "ui/gfx/text_utils.h"
|
| #include "ui/views/controls/button/md_text_button.h"
|
| #include "ui/views/controls/image_view.h"
|
| #include "ui/views/controls/label.h"
|
| @@ -62,6 +65,56 @@ enum class PaymentSheetViewControllerTags {
|
| PAY_BUTTON
|
| };
|
|
|
| +// A class that ensures proper elision of labels in the form
|
| +// "[preview] and N more" where preview might be elided to allow "and N more" to
|
| +// be always visible.
|
| +class PreviewEliderLabel : public views::Label {
|
| + public:
|
| + // Creates a PreviewEliderLabel where |preview_text| might be elided,
|
| + // |format_string| is the string with format argument numbers in ICU syntax
|
| + // and |n| is the "N more" item count.
|
| + PreviewEliderLabel(const base::string16& preview_text,
|
| + const base::string16& format_string,
|
| + int n)
|
| + : views::Label(base::ASCIIToUTF16("")),
|
| + preview_text_(preview_text),
|
| + format_string_(format_string),
|
| + n_(n) {}
|
| +
|
| + private:
|
| + // Formats |preview_text_|, |format_string_|, and |n_| into a string that fits
|
| + // inside of |pixel_width|, eliding |preview_text_| as required.
|
| + base::string16 CreateElidedString(int pixel_width) {
|
| + for (int preview_length = preview_text_.size(); preview_length > 0;
|
| + --preview_length) {
|
| + base::string16 elided_preview;
|
| + gfx::ElideRectangleString(preview_text_, 1, preview_length,
|
| + /*strict=*/false, &elided_preview);
|
| + base::string16 elided_string =
|
| + base::i18n::MessageFormatter::FormatWithNumberedArgs(
|
| + format_string_, "", elided_preview, n_);
|
| + if (gfx::GetStringWidth(elided_string, font_list()) <= width())
|
| + return elided_string;
|
| + }
|
| +
|
| + // TODO(crbug.com/714776): Display something meaningful if the preview can't
|
| + // be elided enough for the string to fit.
|
| + return base::ASCIIToUTF16("");
|
| + }
|
| +
|
| + // views::View:
|
| + void OnBoundsChanged(const gfx::Rect& previous_bounds) override {
|
| + SetText(CreateElidedString(width()));
|
| + views::Label::OnBoundsChanged(previous_bounds);
|
| + }
|
| +
|
| + base::string16 preview_text_;
|
| + base::string16 format_string_;
|
| + int n_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(PreviewEliderLabel);
|
| +};
|
| +
|
| int ComputeWidestNameColumnViewWidth() {
|
| // The name colums in each row should all have the same width, large enough to
|
| // accomodate the longest piece of text they contain. Because of this, each
|
| @@ -156,12 +209,12 @@ std::unique_ptr<views::Button> CreatePaymentSheetRow(
|
|
|
| // Creates a row with a button in place of the chevron.
|
| // +------------------------------------------+
|
| -// | Name | truncated_content | button_string |
|
| +// | Name | content_view | button_string |
|
| // +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
|
| std::unique_ptr<views::Button> CreatePaymentSheetRowWithButton(
|
| views::ButtonListener* listener,
|
| const base::string16& section_name,
|
| - const base::string16& truncated_content,
|
| + std::unique_ptr<views::View> content_view,
|
| const base::string16& button_string,
|
| int button_tag,
|
| int button_id,
|
| @@ -171,13 +224,57 @@ std::unique_ptr<views::Button> CreatePaymentSheetRowWithButton(
|
| button_string));
|
| button->set_tag(button_tag);
|
| button->set_id(button_id);
|
| - std::unique_ptr<views::Label> content_view =
|
| - base::MakeUnique<views::Label>(truncated_content);
|
| return CreatePaymentSheetRow(listener, section_name, std::move(content_view),
|
| nullptr, std::move(button),
|
| /*clickable=*/false, name_column_width);
|
| }
|
|
|
| +// Creates a row with a button in place of the chevron and |truncated_content|
|
| +// between |section_name| and the button.
|
| +// +------------------------------------------+
|
| +// | Name | truncated_content | button_string |
|
| +// +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
|
| +std::unique_ptr<views::Button> CreatePaymentSheetRowWithButton(
|
| + views::ButtonListener* listener,
|
| + const base::string16& section_name,
|
| + const base::string16& truncated_content,
|
| + const base::string16& button_string,
|
| + int button_tag,
|
| + int button_id,
|
| + int name_column_width) {
|
| + std::unique_ptr<views::Label> content_view =
|
| + base::MakeUnique<views::Label>(truncated_content);
|
| + content_view->SetHorizontalAlignment(gfx::ALIGN_LEFT);
|
| + return CreatePaymentSheetRowWithButton(
|
| + listener, section_name, std::move(content_view), button_string,
|
| + button_tag, button_id, name_column_width);
|
| +}
|
| +
|
| +// Creates a row with a button in place of the chevron with the string between
|
| +// |section_name| and the button built as "|preview|... and |n| more".
|
| +// |format_string| is used to assemble the truncated preview and the rest of the
|
| +// content string.
|
| +// +----------------------------------------------+
|
| +// | Name | preview... and N more | button_string |
|
| +// +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
|
| +std::unique_ptr<views::Button> CreatePaymentSheetRowWithButton(
|
| + views::ButtonListener* listener,
|
| + const base::string16& section_name,
|
| + const base::string16& preview_text,
|
| + const base::string16& format_string,
|
| + int n,
|
| + const base::string16& button_string,
|
| + int button_tag,
|
| + int button_id,
|
| + int name_column_width) {
|
| + std::unique_ptr<PreviewEliderLabel> content_view =
|
| + base::MakeUnique<PreviewEliderLabel>(preview_text, format_string, n);
|
| + content_view->SetHorizontalAlignment(gfx::ALIGN_LEFT);
|
| + return CreatePaymentSheetRowWithButton(
|
| + listener, section_name, std::move(content_view), button_string,
|
| + button_tag, button_id, name_column_width);
|
| +}
|
| +
|
| // Creates a clickable row to be displayed in the Payment Sheet. It contains
|
| // a section name and some content, followed by a chevron as a clickability
|
| // affordance. Both, either, or none of |content_view| and |extra_content_view|
|
| @@ -515,13 +612,53 @@ std::unique_ptr<views::Button> PaymentSheetViewController::CreateShippingRow() {
|
| ? l10n_util::GetStringUTF16(IDS_CHOOSE)
|
| : l10n_util::GetStringUTF16(IDS_ADD);
|
|
|
| - section = CreatePaymentSheetRowWithButton(
|
| - this, GetShippingAddressSectionString(spec()->shipping_type()),
|
| - base::ASCIIToUTF16(""), button_string,
|
| - static_cast<int>(PaymentSheetViewControllerTags::SHOW_SHIPPING_BUTTON),
|
| - static_cast<int>(
|
| - DialogViewID::PAYMENT_SHEET_SHIPPING_ADDRESS_SECTION_BUTTON),
|
| - widest_name_column_view_width_);
|
| + if (state()->shipping_profiles().empty()) {
|
| + section = CreatePaymentSheetRowWithButton(
|
| + this, GetShippingAddressSectionString(spec()->shipping_type()),
|
| + base::ASCIIToUTF16(""), button_string,
|
| + static_cast<int>(
|
| + PaymentSheetViewControllerTags::SHOW_SHIPPING_BUTTON),
|
| + static_cast<int>(
|
| + DialogViewID::PAYMENT_SHEET_SHIPPING_ADDRESS_SECTION_BUTTON),
|
| + widest_name_column_view_width_);
|
| + } else if (state()->shipping_profiles().size() == 1) {
|
| + base::string16 truncated_content =
|
| + state()->shipping_profiles()[0]->ConstructInferredLabel(
|
| + {
|
| + autofill::ADDRESS_HOME_LINE1, autofill::ADDRESS_HOME_LINE2,
|
| + autofill::ADDRESS_HOME_CITY, autofill::ADDRESS_HOME_STATE,
|
| + autofill::ADDRESS_HOME_COUNTRY,
|
| + },
|
| + 6, state()->GetApplicationLocale());
|
| + section = CreatePaymentSheetRowWithButton(
|
| + this, GetShippingAddressSectionString(spec()->shipping_type()),
|
| + truncated_content, button_string,
|
| + static_cast<int>(
|
| + PaymentSheetViewControllerTags::SHOW_SHIPPING_BUTTON),
|
| + static_cast<int>(
|
| + DialogViewID::PAYMENT_SHEET_SHIPPING_ADDRESS_SECTION_BUTTON),
|
| + widest_name_column_view_width_);
|
| + } else {
|
| + base::string16 format = l10n_util::GetPluralStringFUTF16(
|
| + IDS_PAYMENT_REQUEST_SHIPPING_ADDRESSES_PREVIEW,
|
| + state()->shipping_profiles().size() - 1);
|
| + base::string16 label =
|
| + state()->shipping_profiles()[0]->ConstructInferredLabel(
|
| + {
|
| + autofill::ADDRESS_HOME_LINE1, autofill::ADDRESS_HOME_LINE2,
|
| + autofill::ADDRESS_HOME_CITY, autofill::ADDRESS_HOME_STATE,
|
| + autofill::ADDRESS_HOME_COUNTRY,
|
| + },
|
| + 6, state()->GetApplicationLocale());
|
| + section = CreatePaymentSheetRowWithButton(
|
| + this, GetShippingAddressSectionString(spec()->shipping_type()), label,
|
| + format, state()->shipping_profiles().size() - 1, button_string,
|
| + static_cast<int>(
|
| + PaymentSheetViewControllerTags::SHOW_SHIPPING_BUTTON),
|
| + static_cast<int>(
|
| + DialogViewID::PAYMENT_SHEET_SHIPPING_ADDRESS_SECTION_BUTTON),
|
| + widest_name_column_view_width_);
|
| + }
|
| }
|
|
|
| return section;
|
| @@ -575,16 +712,44 @@ PaymentSheetViewController::CreatePaymentMethodRow() {
|
| ? l10n_util::GetStringUTF16(IDS_CHOOSE)
|
| : l10n_util::GetStringUTF16(IDS_ADD);
|
|
|
| - section = CreatePaymentSheetRowWithButton(
|
| - this,
|
| - l10n_util::GetStringUTF16(
|
| - IDS_PAYMENT_REQUEST_PAYMENT_METHOD_SECTION_NAME),
|
| - base::ASCIIToUTF16(""), button_string,
|
| - static_cast<int>(
|
| - PaymentSheetViewControllerTags::SHOW_PAYMENT_METHOD_BUTTON),
|
| - static_cast<int>(
|
| - DialogViewID::PAYMENT_SHEET_PAYMENT_METHOD_SECTION_BUTTON),
|
| - widest_name_column_view_width_);
|
| + if (state()->available_instruments().empty()) {
|
| + section = CreatePaymentSheetRowWithButton(
|
| + this,
|
| + l10n_util::GetStringUTF16(
|
| + IDS_PAYMENT_REQUEST_PAYMENT_METHOD_SECTION_NAME),
|
| + base::ASCIIToUTF16(""), button_string,
|
| + static_cast<int>(
|
| + PaymentSheetViewControllerTags::SHOW_PAYMENT_METHOD_BUTTON),
|
| + static_cast<int>(
|
| + DialogViewID::PAYMENT_SHEET_PAYMENT_METHOD_SECTION_BUTTON),
|
| + widest_name_column_view_width_);
|
| + } else if (state()->available_instruments().size() == 1) {
|
| + section = CreatePaymentSheetRowWithButton(
|
| + this,
|
| + l10n_util::GetStringUTF16(
|
| + IDS_PAYMENT_REQUEST_PAYMENT_METHOD_SECTION_NAME),
|
| + state()->available_instruments()[0]->label(), button_string,
|
| + static_cast<int>(
|
| + PaymentSheetViewControllerTags::SHOW_PAYMENT_METHOD_BUTTON),
|
| + static_cast<int>(
|
| + DialogViewID::PAYMENT_SHEET_PAYMENT_METHOD_SECTION_BUTTON),
|
| + widest_name_column_view_width_);
|
| + } else {
|
| + base::string16 format = l10n_util::GetPluralStringFUTF16(
|
| + IDS_PAYMENT_REQUEST_PAYMENT_METHODS_PREVIEW,
|
| + state()->available_instruments().size() - 1);
|
| + section = CreatePaymentSheetRowWithButton(
|
| + this,
|
| + l10n_util::GetStringUTF16(
|
| + IDS_PAYMENT_REQUEST_PAYMENT_METHOD_SECTION_NAME),
|
| + state()->available_instruments()[0]->label(), format,
|
| + state()->available_instruments().size() - 1, button_string,
|
| + static_cast<int>(
|
| + PaymentSheetViewControllerTags::SHOW_PAYMENT_METHOD_BUTTON),
|
| + static_cast<int>(
|
| + DialogViewID::PAYMENT_SHEET_PAYMENT_METHOD_SECTION_BUTTON),
|
| + widest_name_column_view_width_);
|
| + }
|
| }
|
|
|
| return section;
|
| @@ -624,16 +789,60 @@ PaymentSheetViewController::CreateContactInfoRow() {
|
| ? l10n_util::GetStringUTF16(IDS_CHOOSE)
|
| : l10n_util::GetStringUTF16(IDS_ADD);
|
|
|
| - section = CreatePaymentSheetRowWithButton(
|
| - this,
|
| - l10n_util::GetStringUTF16(
|
| - IDS_PAYMENT_REQUEST_CONTACT_INFO_SECTION_NAME),
|
| - base::ASCIIToUTF16(""), button_string,
|
| - static_cast<int>(
|
| - PaymentSheetViewControllerTags::SHOW_CONTACT_INFO_BUTTON),
|
| - static_cast<int>(
|
| - DialogViewID::PAYMENT_SHEET_CONTACT_INFO_SECTION_BUTTON),
|
| - widest_name_column_view_width_);
|
| + if (state()->contact_profiles().empty()) {
|
| + section = CreatePaymentSheetRowWithButton(
|
| + this,
|
| + l10n_util::GetStringUTF16(
|
| + IDS_PAYMENT_REQUEST_CONTACT_INFO_SECTION_NAME),
|
| + base::ASCIIToUTF16(""), button_string,
|
| + static_cast<int>(
|
| + PaymentSheetViewControllerTags::SHOW_CONTACT_INFO_BUTTON),
|
| + static_cast<int>(
|
| + DialogViewID::PAYMENT_SHEET_CONTACT_INFO_SECTION_BUTTON),
|
| + widest_name_column_view_width_);
|
| + } else if (state()->contact_profiles().size() == 1) {
|
| + base::string16 truncated_content =
|
| + state()->contact_profiles()[0]->ConstructInferredLabel(
|
| + {
|
| + autofill::ADDRESS_HOME_LINE1, autofill::ADDRESS_HOME_LINE2,
|
| + autofill::ADDRESS_HOME_CITY, autofill::ADDRESS_HOME_STATE,
|
| + autofill::ADDRESS_HOME_COUNTRY,
|
| + },
|
| + 6, state()->GetApplicationLocale());
|
| + section = CreatePaymentSheetRowWithButton(
|
| + this,
|
| + l10n_util::GetStringUTF16(
|
| + IDS_PAYMENT_REQUEST_CONTACT_INFO_SECTION_NAME),
|
| + truncated_content, button_string,
|
| + static_cast<int>(
|
| + PaymentSheetViewControllerTags::SHOW_CONTACT_INFO_BUTTON),
|
| + static_cast<int>(
|
| + DialogViewID::PAYMENT_SHEET_CONTACT_INFO_SECTION_BUTTON),
|
| + widest_name_column_view_width_);
|
| + } else {
|
| + base::string16 preview =
|
| + state()->contact_profiles()[0]->ConstructInferredLabel(
|
| + {
|
| + autofill::ADDRESS_HOME_LINE1, autofill::ADDRESS_HOME_LINE2,
|
| + autofill::ADDRESS_HOME_CITY, autofill::ADDRESS_HOME_STATE,
|
| + autofill::ADDRESS_HOME_COUNTRY,
|
| + },
|
| + 6, state()->GetApplicationLocale());
|
| + base::string16 format = l10n_util::GetPluralStringFUTF16(
|
| + IDS_PAYMENT_REQUEST_CONTACTS_PREVIEW,
|
| + state()->contact_profiles().size() - 1);
|
| + section = CreatePaymentSheetRowWithButton(
|
| + this,
|
| + l10n_util::GetStringUTF16(
|
| + IDS_PAYMENT_REQUEST_CONTACT_INFO_SECTION_NAME),
|
| + preview, format, state()->contact_profiles().size() - 1,
|
| + button_string,
|
| + static_cast<int>(
|
| + PaymentSheetViewControllerTags::SHOW_CONTACT_INFO_BUTTON),
|
| + static_cast<int>(
|
| + DialogViewID::PAYMENT_SHEET_CONTACT_INFO_SECTION_BUTTON),
|
| + widest_name_column_view_width_);
|
| + }
|
| }
|
|
|
| return section;
|
|
|