Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Side by Side Diff: chrome/browser/ui/views/payments/payment_sheet_view_controller.cc

Issue 2621153002: [WebPayments] Add the Payment Method section in the Payment Sheet (Closed)
Patch Set: Initial patch Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/views/payments/payment_sheet_view_controller.h" 5 #include "chrome/browser/ui/views/payments/payment_sheet_view_controller.h"
6 6
7 #include <algorithm>
7 #include <memory> 8 #include <memory>
8 #include <utility> 9 #include <utility>
9 10
10 #include "base/memory/ptr_util.h" 11 #include "base/memory/ptr_util.h"
11 #include "base/strings/utf_string_conversions.h" 12 #include "base/strings/utf_string_conversions.h"
13 #include "chrome/browser/browser_process.h"
12 #include "chrome/browser/ui/views/payments/payment_request_dialog.h" 14 #include "chrome/browser/ui/views/payments/payment_request_dialog.h"
13 #include "chrome/browser/ui/views/payments/payment_request_views_util.h" 15 #include "chrome/browser/ui/views/payments/payment_request_views_util.h"
14 #include "chrome/grit/generated_resources.h" 16 #include "chrome/grit/generated_resources.h"
17 #include "components/autofill/core/browser/autofill_type.h"
18 #include "components/autofill/core/browser/credit_card.h"
19 #include "components/autofill/core/browser/field_types.h"
15 #include "components/payments/payment_request.h" 20 #include "components/payments/payment_request.h"
16 #include "components/strings/grit/components_strings.h" 21 #include "components/strings/grit/components_strings.h"
22 #include "content/public/browser/web_contents.h"
17 #include "third_party/skia/include/core/SkColor.h" 23 #include "third_party/skia/include/core/SkColor.h"
18 #include "ui/base/l10n/l10n_util.h" 24 #include "ui/base/l10n/l10n_util.h"
25 #include "ui/base/resource/resource_bundle.h"
19 #include "ui/gfx/color_utils.h" 26 #include "ui/gfx/color_utils.h"
20 #include "ui/gfx/font.h" 27 #include "ui/gfx/font.h"
21 #include "ui/gfx/geometry/insets.h" 28 #include "ui/gfx/geometry/insets.h"
22 #include "ui/gfx/paint_vector_icon.h" 29 #include "ui/gfx/paint_vector_icon.h"
23 #include "ui/gfx/range/range.h" 30 #include "ui/gfx/range/range.h"
24 #include "ui/gfx/vector_icons_public.h" 31 #include "ui/gfx/vector_icons_public.h"
25 #include "ui/views/border.h" 32 #include "ui/views/border.h"
26 #include "ui/views/controls/button/custom_button.h" 33 #include "ui/views/controls/button/custom_button.h"
27 #include "ui/views/controls/button/label_button.h" 34 #include "ui/views/controls/button/label_button.h"
28 #include "ui/views/controls/button/md_text_button.h" 35 #include "ui/views/controls/button/md_text_button.h"
29 #include "ui/views/controls/image_view.h" 36 #include "ui/views/controls/image_view.h"
30 #include "ui/views/controls/label.h" 37 #include "ui/views/controls/label.h"
31 #include "ui/views/controls/styled_label.h" 38 #include "ui/views/controls/styled_label.h"
39 #include "ui/views/layout/fill_layout.h"
32 #include "ui/views/layout/grid_layout.h" 40 #include "ui/views/layout/grid_layout.h"
33 #include "ui/views/view.h" 41 #include "ui/views/view.h"
34 42
35 namespace payments { 43 namespace payments {
36 namespace { 44 namespace {
37 45
38 enum class PaymentSheetViewControllerTags { 46 enum class PaymentSheetViewControllerTags {
39 // The tag for the button that navigates to the Order Summary sheet. 47 // The tag for the button that navigates to the Order Summary sheet.
40 SHOW_ORDER_SUMMARY_BUTTON = static_cast<int>( 48 SHOW_ORDER_SUMMARY_BUTTON = static_cast<int>(
41 payments::PaymentRequestCommonTags::PAYMENT_REQUEST_COMMON_TAG_MAX), 49 payments::PaymentRequestCommonTags::PAYMENT_REQUEST_COMMON_TAG_MAX),
50 SHOW_PAYMENT_METHOD_BUTTON,
42 }; 51 };
43 52
44 // Creates a clickable row to be displayed in the Payment Sheet. It contains 53 // Creates a clickable row to be displayed in the Payment Sheet. It contains
45 // a section name and some content, followed by a chevron as a clickability 54 // a section name and some content, followed by a chevron as a clickability
46 // affordance. Both, either, or none of |content_view| and |extra_content_view| 55 // affordance. Both, either, or none of |content_view| and |extra_content_view|
47 // may be present, the difference between the two being that content is pinned 56 // may be present, the difference between the two being that content is pinned
48 // to the left and extra_content is pinned to the right. 57 // to the left and extra_content is pinned to the right.
49 // The row also displays a light gray horizontal ruler on its lower boundary. 58 // The row also displays a light gray horizontal ruler on its lower boundary.
59 // The name column has a fixed width equal to |name_column_width|.
50 // +----------------------------+ 60 // +----------------------------+
51 // | Name | Content | Extra | > | 61 // | Name | Content | Extra | > |
52 // +~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ <-- ruler 62 // +~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ <-- ruler
53 class PaymentSheetRow : public views::CustomButton { 63 class PaymentSheetRow : public views::CustomButton {
54 public: 64 public:
55 PaymentSheetRow(views::ButtonListener* listener, 65 PaymentSheetRow(views::ButtonListener* listener,
56 const base::string16& section_name, 66 const base::string16& section_name,
57 std::unique_ptr<views::View> content_view, 67 std::unique_ptr<views::View> content_view,
58 std::unique_ptr<views::View> extra_content_view) 68 std::unique_ptr<views::View> extra_content_view,
69 int name_column_width)
59 : views::CustomButton(listener) { 70 : views::CustomButton(listener) {
60 SetBorder(views::CreateSolidSidedBorder(0, 0, 1, 0, SK_ColorLTGRAY)); 71 SetBorder(views::CreateSolidSidedBorder(0, 0, 1, 0, SK_ColorLTGRAY));
61 views::GridLayout* layout = new views::GridLayout(this); 72 views::GridLayout* layout = new views::GridLayout(this);
62 73
63 constexpr int kRowVerticalInset = 18; 74 constexpr int kRowVerticalInset = 8;
64 // The rows have extra inset compared to the header so that their right edge 75 // The rows have extra inset compared to the header so that their right edge
65 // lines up with the close button's X rather than its invisible right edge. 76 // lines up with the close button's X rather than its invisible right edge.
66 constexpr int kRowExtraRightInset = 8; 77 constexpr int kRowExtraRightInset = 8;
67 layout->SetInsets( 78 layout->SetInsets(
68 kRowVerticalInset, 0, kRowVerticalInset, kRowExtraRightInset); 79 kRowVerticalInset, 0, kRowVerticalInset, kRowExtraRightInset);
69 SetLayoutManager(layout); 80 SetLayoutManager(layout);
70 81
71 views::ColumnSet* columns = layout->AddColumnSet(0); 82 views::ColumnSet* columns = layout->AddColumnSet(0);
72 // A column for the section name. 83 // A column for the section name.
73 columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, 84 columns->AddColumn(views::GridLayout::LEADING,
74 0, views::GridLayout::USE_PREF, 0, 0); 85 views::GridLayout::LEADING,
86 0,
87 views::GridLayout::FIXED,
88 name_column_width,
89 0);
90
91 constexpr int kPaddingColumnsWidth = 25;
92 columns->AddPaddingColumn(0, kPaddingColumnsWidth);
93
75 // A column for the content. 94 // A column for the content.
76 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::CENTER, 95 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::LEADING,
77 1, views::GridLayout::USE_PREF, 0, 0); 96 1, views::GridLayout::USE_PREF, 0, 0);
78 // A column for the extra content. 97 // A column for the extra content.
79 columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::CENTER, 98 columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::CENTER,
80 0, views::GridLayout::USE_PREF, 0, 0); 99 0, views::GridLayout::USE_PREF, 0, 0);
81 100
82 constexpr int kPaddingColumnsWidth = 25;
83 columns->AddPaddingColumn(0, kPaddingColumnsWidth); 101 columns->AddPaddingColumn(0, kPaddingColumnsWidth);
84 // A column for the chevron. 102 // A column for the chevron.
85 columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::CENTER, 103 columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::CENTER,
86 0, views::GridLayout::USE_PREF, 0, 0); 104 0, views::GridLayout::USE_PREF, 0, 0);
87 105
88 layout->StartRow(0, 0); 106 layout->StartRow(0, 0);
89 views::Label* name_label = new views::Label(section_name); 107 views::Label* name_label = new views::Label(section_name);
90 layout->AddView(name_label); 108 layout->AddView(name_label);
91 109
92 if (content_view) { 110 if (content_view) {
(...skipping 16 matching lines...) Expand all
109 } 127 }
110 128
111 DISALLOW_COPY_AND_ASSIGN(PaymentSheetRow); 129 DISALLOW_COPY_AND_ASSIGN(PaymentSheetRow);
112 }; 130 };
113 131
114 } // namespace 132 } // namespace
115 133
116 PaymentSheetViewController::PaymentSheetViewController( 134 PaymentSheetViewController::PaymentSheetViewController(
117 PaymentRequest* request, 135 PaymentRequest* request,
118 PaymentRequestDialog* dialog) 136 PaymentRequestDialog* dialog)
119 : PaymentRequestSheetController(request, dialog) {} 137 : PaymentRequestSheetController(request, dialog),
138 widest_name_column_view_width_(0) {
139 InitWidestNameColumnViewWidth();
140 }
120 141
121 PaymentSheetViewController::~PaymentSheetViewController() {} 142 PaymentSheetViewController::~PaymentSheetViewController() {}
122 143
123 std::unique_ptr<views::View> PaymentSheetViewController::CreateView() { 144 std::unique_ptr<views::View> PaymentSheetViewController::CreateView() {
124 std::unique_ptr<views::View> content_view = base::MakeUnique<views::View>(); 145 std::unique_ptr<views::View> content_view = base::MakeUnique<views::View>();
125 146
126 views::GridLayout* layout = new views::GridLayout(content_view.get()); 147 views::GridLayout* layout = new views::GridLayout(content_view.get());
127 content_view->SetLayoutManager(layout); 148 content_view->SetLayoutManager(layout);
128 views::ColumnSet* columns = layout->AddColumnSet(0); 149 views::ColumnSet* columns = layout->AddColumnSet(0);
129 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::CENTER, 150 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::CENTER,
130 1, views::GridLayout::USE_PREF, 0, 0); 151 1, views::GridLayout::USE_PREF, 0, 0);
131 152
132 layout->StartRow(0, 0); 153 layout->StartRow(0, 0);
133 layout->AddView(CreatePaymentSheetSummaryRow().release()); 154 layout->AddView(CreatePaymentSheetSummaryRow().release());
155 layout->StartRow(0, 0);
156 layout->AddView(CreatePaymentMethodRow().release());
134 157
135 return CreatePaymentView( 158 return CreatePaymentView(
136 CreateSheetHeaderView( 159 CreateSheetHeaderView(
137 false, 160 false,
138 l10n_util::GetStringUTF16(IDS_PAYMENT_REQUEST_PAYMENT_SHEET_TITLE), 161 l10n_util::GetStringUTF16(IDS_PAYMENT_REQUEST_PAYMENT_SHEET_TITLE),
139 this), 162 this),
140 std::move(content_view)); 163 std::move(content_view));
141 } 164 }
142 165
143 void PaymentSheetViewController::ButtonPressed( 166 void PaymentSheetViewController::ButtonPressed(
144 views::Button* sender, const ui::Event& event) { 167 views::Button* sender, const ui::Event& event) {
145 switch (sender->tag()) { 168 switch (sender->tag()) {
146 case static_cast<int>(PaymentRequestCommonTags::CLOSE_BUTTON_TAG): 169 case static_cast<int>(PaymentRequestCommonTags::CLOSE_BUTTON_TAG):
147 dialog()->CloseDialog(); 170 dialog()->CloseDialog();
148 break; 171 break;
149 case static_cast<int>( 172 case static_cast<int>(
150 PaymentSheetViewControllerTags::SHOW_ORDER_SUMMARY_BUTTON): 173 PaymentSheetViewControllerTags::SHOW_ORDER_SUMMARY_BUTTON):
151 dialog()->ShowOrderSummary(); 174 dialog()->ShowOrderSummary();
152 break; 175 break;
176 case static_cast<int>(
177 PaymentSheetViewControllerTags::SHOW_PAYMENT_METHOD_BUTTON):
178 dialog()->ShowPaymentMethodSheet();
179 break;
153 default: 180 default:
154 NOTREACHED(); 181 NOTREACHED();
155 } 182 }
156 } 183 }
157 184
158 std::unique_ptr<views::View> 185 std::unique_ptr<views::View>
159 PaymentSheetViewController::CreateOrderSummarySectionContent() { 186 PaymentSheetViewController::CreateOrderSummarySectionContent() {
160 base::string16 label_value = l10n_util::GetStringFUTF16( 187 base::string16 label_value = l10n_util::GetStringFUTF16(
161 IDS_PAYMENT_REQUEST_ORDER_SUMMARY_SECTION_TOTAL_FORMAT, 188 IDS_PAYMENT_REQUEST_ORDER_SUMMARY_SECTION_TOTAL_FORMAT,
162 base::ASCIIToUTF16(request()->details()->total->label), 189 base::ASCIIToUTF16(request()->details()->total->label),
163 base::ASCIIToUTF16(request()->details()->total->amount->currency), 190 base::ASCIIToUTF16(request()->details()->total->amount->currency),
164 base::ASCIIToUTF16(request()->details()->total->amount->value)); 191 base::ASCIIToUTF16(request()->details()->total->amount->value));
165 192
166 return base::MakeUnique<views::Label>(label_value); 193 return base::MakeUnique<views::Label>(label_value);
167 } 194 }
168 195
169 std::unique_ptr<views::Button> 196 std::unique_ptr<views::Button>
170 PaymentSheetViewController::CreatePaymentSheetSummaryRow() { 197 PaymentSheetViewController::CreatePaymentSheetSummaryRow() {
171 std::unique_ptr<views::Button> section = base::MakeUnique<PaymentSheetRow>( 198 std::unique_ptr<views::Button> section = base::MakeUnique<PaymentSheetRow>(
172 this, 199 this,
173 l10n_util::GetStringUTF16(IDS_PAYMENT_REQUEST_ORDER_SUMMARY_SECTION_NAME), 200 l10n_util::GetStringUTF16(IDS_PAYMENT_REQUEST_ORDER_SUMMARY_SECTION_NAME),
174 std::unique_ptr<views::View>(nullptr), 201 std::unique_ptr<views::View>(nullptr),
175 CreateOrderSummarySectionContent()); 202 CreateOrderSummarySectionContent(),
203 widest_name_column_view_width_);
176 section->set_tag(static_cast<int>( 204 section->set_tag(static_cast<int>(
177 PaymentSheetViewControllerTags::SHOW_ORDER_SUMMARY_BUTTON)); 205 PaymentSheetViewControllerTags::SHOW_ORDER_SUMMARY_BUTTON));
178 return section; 206 return section;
179 } 207 }
180 208
209 std::unique_ptr<views::Button>
210 PaymentSheetViewController::CreatePaymentMethodRow() {
Mathieu 2017/01/12 21:27:11 I really like the ASCII art in the Java Impl, coul
anthonyvd 2017/01/13 16:09:19 Done here and above.
211 autofill::CreditCard* selected_card =
212 request()->GetCurrentlySelectedCreditCard();
213
214 std::unique_ptr<views::View> content_view;
215 std::unique_ptr<views::ImageView> card_icon_view;
216 if (selected_card) {
217 content_view = base::MakeUnique<views::View>();
218
219 views::GridLayout* layout = new views::GridLayout(content_view.get());
220 content_view->SetLayoutManager(layout);
221 views::ColumnSet* columns = layout->AddColumnSet(0);
222 columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER,
223 1, views::GridLayout::USE_PREF, 0, 0);
224
225 layout->StartRow(0, 0);
226 layout->AddView(new views::Label(selected_card->TypeAndLastFourDigits()));
227 layout->StartRow(0, 0);
228 layout->AddView(new views::Label(
229 selected_card->GetInfo(
230 autofill::AutofillType(autofill::CREDIT_CARD_NAME_FULL),
231 g_browser_process->GetApplicationLocale())));
232
233 card_icon_view = base::MakeUnique<views::ImageView>();
234 card_icon_view->SetImage(
235 ResourceBundle::GetSharedInstance()
236 .GetImageNamed(autofill::CreditCard::PaymentRequestIconResourceId(
237 selected_card->type()))
238 .AsImageSkia());
239 card_icon_view->SetBorder(
240 views::CreateRoundedRectBorder(1, 3, SK_ColorLTGRAY));
241
242 constexpr gfx::Size kCardIconSize = gfx::Size(32, 20);
243 card_icon_view->SetImageSize(kCardIconSize);
244 }
245
246 std::unique_ptr<views::Button> section = base::MakeUnique<PaymentSheetRow>(
247 this,
248 l10n_util::GetStringUTF16(
249 IDS_PAYMENT_REQUEST_PAYMENT_METHOD_SECTION_NAME),
250 std::move(content_view),
251 std::move(card_icon_view),
252 widest_name_column_view_width_);
253 section->set_tag(static_cast<int>(
254 PaymentSheetViewControllerTags::SHOW_PAYMENT_METHOD_BUTTON));
255 return section;
256 }
257
258 void PaymentSheetViewController::InitWidestNameColumnViewWidth() {
259 DCHECK_EQ(0, widest_name_column_view_width_);
260
261 // The name colums in each row should all have the same width, large enough to
anthonyvd 2017/01/12 19:18:59 If anyone has a better idea to do this that doesn'
Mathieu 2017/01/12 21:27:11 Idea 1: https://cs.chromium.org/chromium/src/ui/gf
anthonyvd 2017/01/13 16:09:19 It looks like neither of those would take into acc
Mathieu 2017/01/13 16:40:16 Thanks for looking into it! Perhaps a views expert
262 // accomodate the longest piece of text they contain. Because of this, each
263 // row's GridLayout requires its first column to have a fixed width of the
264 // correct size. To measure the required size, layout a label with each
265 // section name, measure its width, then initialize
266 // |widest_name_column_view_width_| with the largest value.
267 // This should only be performed once, when this sheet is shown, because
268 // language/font size can't change while the dialog is open.
269 std::vector<int> section_names {
270 IDS_PAYMENT_REQUEST_ORDER_SUMMARY_SECTION_NAME,
271 IDS_PAYMENT_REQUEST_PAYMENT_METHOD_SECTION_NAME,
272 };
273
274 std::for_each(
275 section_names.begin(),
276 section_names.end(),
277 [=](const int& name) {
278 views::Label label(l10n_util::GetStringUTF16(name));
279 widest_name_column_view_width_ = std::max(
280 label.GetPreferredSize().width(),
281 widest_name_column_view_width_);
282 });
283 }
284
181 } // namespace payments 285 } // namespace payments
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698