| // Copyright 2016 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/ui/views/payments/order_summary_view_controller.h" |
| |
| #include <memory> |
| #include <utility> |
| #include <vector> |
| |
| #include "base/strings/utf_string_conversions.h" |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/ui/views/payments/payment_request_dialog_view.h" |
| #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h" |
| #include "chrome/browser/ui/views/payments/payment_request_views_util.h" |
| #include "components/payments/core/currency_formatter.h" |
| #include "components/strings/grit/components_strings.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "ui/base/metadata/metadata_impl_macros.h" |
| #include "ui/color/color_id.h" |
| #include "ui/color/color_provider.h" |
| #include "ui/gfx/font.h" |
| #include "ui/gfx/geometry/insets.h" |
| #include "ui/views/border.h" |
| #include "ui/views/controls/button/md_text_button.h" |
| #include "ui/views/controls/label.h" |
| #include "ui/views/controls/styled_label.h" |
| #include "ui/views/layout/box_layout.h" |
| #include "ui/views/layout/table_layout.h" |
| #include "ui/views/view.h" |
| |
| namespace payments { |
| |
| namespace { |
| |
| class LineItemRow : public views::View { |
| public: |
| METADATA_HEADER(LineItemRow); |
| |
| // views::View: |
| void OnThemeChanged() override { |
| View::OnThemeChanged(); |
| // The vertical spacing for these rows is slightly different than the |
| // spacing spacing for clickable rows, so don't use |
| // kPaymentRequestRowVerticalInsets. |
| constexpr int kRowVerticalInset = 4; |
| const auto row_insets = gfx::Insets::TLBR( |
| kRowVerticalInset, payments::kPaymentRequestRowHorizontalInsets, |
| kRowVerticalInset, payments::kPaymentRequestRowHorizontalInsets); |
| SetBorder(payments::CreatePaymentRequestRowBorder( |
| GetColorProvider()->GetColor(ui::kColorSeparator), row_insets)); |
| } |
| }; |
| |
| BEGIN_METADATA(LineItemRow, views::View) |
| END_METADATA |
| |
| // Creates a view for a line item to be displayed in the Order Summary Sheet. |
| // |label| is the text in the left-aligned label and |amount| is the text of the |
| // right-aliged label in the row. The |amount| and |label| texts are emphasized |
| // if |emphasize| is true, which is only the case for the last row containing |
| // the total of the order. |amount_label_id| is specified to recall the view |
| // later, e.g. in tests. |
| std::unique_ptr<views::View> CreateLineItemView(const std::u16string& label, |
| const std::u16string& currency, |
| const std::u16string& amount, |
| bool emphasize, |
| DialogViewID currency_label_id, |
| DialogViewID amount_label_id) { |
| std::unique_ptr<views::View> row = std::make_unique<LineItemRow>(); |
| views::TableLayout* const layout = |
| row->SetLayoutManager(std::make_unique<views::TableLayout>()); |
| |
| // The first column has resize_percent = 1 so that it stretches all the way |
| // across the row up to the amount label. This way the first label elides as |
| // required. |
| layout->AddColumn(views::LayoutAlignment::kStart, |
| views::LayoutAlignment::kCenter, 1.0, |
| views::TableLayout::ColumnSize::kUsePreferred, 0, 0); |
| layout->AddColumn(views::LayoutAlignment::kCenter, |
| views::LayoutAlignment::kCenter, |
| views::TableLayout::kFixedSize, |
| views::TableLayout::ColumnSize::kUsePreferred, |
| kAmountSectionWidth, kAmountSectionWidth); |
| layout->AddColumn(views::LayoutAlignment::kEnd, |
| views::LayoutAlignment::kCenter, |
| views::TableLayout::kFixedSize, |
| views::TableLayout::ColumnSize::kUsePreferred, 0, 0); |
| |
| layout->AddRows(1, views::TableLayout::kFixedSize); |
| std::unique_ptr<views::Label> label_text; |
| std::unique_ptr<views::Label> currency_text; |
| std::unique_ptr<views::Label> amount_text; |
| if (emphasize) { |
| label_text = CreateMediumLabel(label); |
| currency_text = CreateMediumLabel(currency); |
| amount_text = CreateMediumLabel(amount); |
| } else { |
| label_text = std::make_unique<views::Label>(label); |
| currency_text = CreateHintLabel(currency); |
| amount_text = std::make_unique<views::Label>(amount); |
| } |
| // Strings from the website may not match the locale of the device, so align |
| // them according to the language of the text. This will result, for example, |
| // in "he" labels being right-aligned in a browser that's using "en" locale. |
| label_text->SetHorizontalAlignment(gfx::ALIGN_TO_HEAD); |
| amount_text->SetID(static_cast<int>(amount_label_id)); |
| amount_text->SetMultiLine(true); |
| // The amount is formatted by the browser (and not provided by the website) so |
| // it can be aligned to left. |
| amount_text->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| amount_text->SetAllowCharacterBreak(true); |
| |
| currency_text->SetID(static_cast<int>(currency_label_id)); |
| |
| row->AddChildView(std::move(label_text)); |
| row->AddChildView(std::move(currency_text)); |
| row->AddChildView(std::move(amount_text)); |
| |
| return row; |
| } |
| |
| } // namespace |
| |
| OrderSummaryViewController::OrderSummaryViewController( |
| base::WeakPtr<PaymentRequestSpec> spec, |
| base::WeakPtr<PaymentRequestState> state, |
| base::WeakPtr<PaymentRequestDialogView> dialog) |
| : PaymentRequestSheetController(spec, state, dialog) { |
| DCHECK(spec); |
| DCHECK(state); |
| spec->AddObserver(this); |
| state->AddObserver(this); |
| } |
| |
| OrderSummaryViewController::~OrderSummaryViewController() { |
| if (spec()) |
| spec()->RemoveObserver(this); |
| |
| state()->RemoveObserver(this); |
| } |
| |
| void OrderSummaryViewController::OnSpecUpdated() { |
| UpdateContentView(); |
| } |
| |
| void OrderSummaryViewController::OnSelectedInformationChanged() { |
| primary_button()->SetEnabled(GetPrimaryButtonEnabled()); |
| } |
| |
| bool OrderSummaryViewController::ShouldShowSecondaryButton() { |
| return false; |
| } |
| |
| std::u16string OrderSummaryViewController::GetSheetTitle() { |
| return l10n_util::GetStringUTF16(IDS_PAYMENTS_ORDER_SUMMARY_LABEL); |
| } |
| |
| void OrderSummaryViewController::FillContentView(views::View* content_view) { |
| if (!spec()) |
| return; |
| |
| auto layout = std::make_unique<views::BoxLayout>( |
| views::BoxLayout::Orientation::kVertical); |
| layout->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kStart); |
| layout->set_cross_axis_alignment( |
| views::BoxLayout::CrossAxisAlignment::kStretch); |
| content_view->SetLayoutManager(std::move(layout)); |
| |
| bool is_mixed_currency = spec()->IsMixedCurrency(); |
| // Set the ID for the first few line items labels, for testing. |
| const std::vector<DialogViewID> line_items{ |
| DialogViewID::ORDER_SUMMARY_LINE_ITEM_1, |
| DialogViewID::ORDER_SUMMARY_LINE_ITEM_2, |
| DialogViewID::ORDER_SUMMARY_LINE_ITEM_3}; |
| const auto& display_items = spec()->GetDisplayItems(state()->selected_app()); |
| for (size_t i = 0; i < display_items.size(); i++) { |
| DialogViewID view_id = |
| i < line_items.size() ? line_items[i] : DialogViewID::VIEW_ID_NONE; |
| std::u16string currency = u""; |
| if (is_mixed_currency) { |
| currency = base::UTF8ToUTF16((*display_items[i])->amount->currency); |
| } |
| |
| content_view->AddChildView( |
| CreateLineItemView( |
| base::UTF8ToUTF16((*display_items[i])->label), currency, |
| spec()->GetFormattedCurrencyAmount((*display_items[i])->amount), |
| false, DialogViewID::VIEW_ID_NONE, view_id) |
| .release()); |
| } |
| |
| std::u16string total_label_value = l10n_util::GetStringFUTF16( |
| IDS_PAYMENT_REQUEST_ORDER_SUMMARY_SHEET_TOTAL_FORMAT, |
| base::UTF8ToUTF16( |
| spec()->GetTotal(state()->selected_app())->amount->currency), |
| spec()->GetFormattedCurrencyAmount( |
| spec()->GetTotal(state()->selected_app())->amount)); |
| |
| content_view->AddChildView( |
| CreateLineItemView( |
| base::UTF8ToUTF16(spec()->GetTotal(state()->selected_app())->label), |
| base::UTF8ToUTF16( |
| spec()->GetTotal(state()->selected_app())->amount->currency), |
| spec()->GetFormattedCurrencyAmount( |
| spec()->GetTotal(state()->selected_app())->amount), |
| true, DialogViewID::ORDER_SUMMARY_TOTAL_CURRENCY_LABEL, |
| DialogViewID::ORDER_SUMMARY_TOTAL_AMOUNT_LABEL) |
| .release()); |
| } |
| |
| bool OrderSummaryViewController::GetSheetId(DialogViewID* sheet_id) { |
| *sheet_id = DialogViewID::ORDER_SUMMARY_SHEET; |
| return true; |
| } |
| |
| bool OrderSummaryViewController::ShouldAccelerateEnterKey() { |
| return true; |
| } |
| |
| base::WeakPtr<PaymentRequestSheetController> |
| OrderSummaryViewController::GetWeakPtr() { |
| return weak_ptr_factory_.GetWeakPtr(); |
| } |
| |
| } // namespace payments |