OLD | NEW |
---|---|
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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/editor_view_controller.h" | 5 #include "chrome/browser/ui/views/payments/editor_view_controller.h" |
6 | 6 |
7 #include <memory> | |
7 #include <utility> | 8 #include <utility> |
8 | 9 |
10 #include "base/memory/ptr_util.h" | |
9 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
10 #include "chrome/browser/ui/views/payments/payment_request_dialog_view.h" | 12 #include "chrome/browser/ui/views/payments/payment_request_dialog_view.h" |
11 #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h" | 13 #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h" |
12 #include "chrome/browser/ui/views/payments/payment_request_views_util.h" | 14 #include "chrome/browser/ui/views/payments/payment_request_views_util.h" |
13 #include "chrome/grit/generated_resources.h" | 15 #include "chrome/grit/generated_resources.h" |
16 #include "components/autofill/core/browser/validation.h" | |
14 #include "components/payments/payment_request.h" | 17 #include "components/payments/payment_request.h" |
15 #include "components/strings/grit/components_strings.h" | 18 #include "components/strings/grit/components_strings.h" |
16 #include "ui/base/l10n/l10n_util.h" | 19 #include "ui/base/l10n/l10n_util.h" |
17 #include "ui/views/border.h" | 20 #include "ui/views/border.h" |
18 #include "ui/views/controls/button/label_button.h" | 21 #include "ui/views/controls/button/label_button.h" |
19 #include "ui/views/controls/button/md_text_button.h" | 22 #include "ui/views/controls/button/md_text_button.h" |
20 #include "ui/views/controls/label.h" | 23 #include "ui/views/controls/label.h" |
21 #include "ui/views/controls/styled_label.h" | 24 #include "ui/views/controls/styled_label.h" |
22 #include "ui/views/controls/textfield/textfield.h" | 25 #include "ui/views/controls/textfield/textfield.h" |
23 #include "ui/views/layout/box_layout.h" | 26 #include "ui/views/layout/box_layout.h" |
24 #include "ui/views/layout/grid_layout.h" | 27 #include "ui/views/layout/grid_layout.h" |
25 #include "ui/views/view.h" | 28 #include "ui/views/view.h" |
26 | 29 |
27 namespace payments { | 30 namespace payments { |
28 namespace { | 31 namespace { |
29 | 32 |
30 constexpr int kFirstTagValue = static_cast<int>( | 33 constexpr int kFirstTagValue = static_cast<int>( |
31 payments::PaymentRequestCommonTags::PAYMENT_REQUEST_COMMON_TAG_MAX); | 34 payments::PaymentRequestCommonTags::PAYMENT_REQUEST_COMMON_TAG_MAX); |
32 | 35 |
33 enum class EditorViewControllerTags : int { | 36 enum class EditorViewControllerTags : int { |
34 // The tag for the button that saves the model being edited. Starts at | 37 // The tag for the button that saves the model being edited. Starts at |
35 // |kFirstTagValue| not to conflict with tags common to all views. | 38 // |kFirstTagValue| not to conflict with tags common to all views. |
36 SAVE_BUTTON = kFirstTagValue, | 39 SAVE_BUTTON = kFirstTagValue, |
37 }; | 40 }; |
38 | 41 |
39 constexpr int kNumCharactersInShortField = 6; | 42 constexpr int kNumCharactersInShortField = 8; |
40 constexpr int kNumCharactersInLongField = 20; | 43 constexpr int kNumCharactersInLongField = 20; |
41 | 44 |
42 } // namespace | 45 } // namespace |
43 | 46 |
44 EditorViewController::EditorViewController(PaymentRequest* request, | 47 EditorViewController::EditorViewController(PaymentRequest* request, |
45 PaymentRequestDialogView* dialog) | 48 PaymentRequestDialogView* dialog) |
46 : PaymentRequestSheetController(request, dialog) {} | 49 : PaymentRequestSheetController(request, dialog) {} |
47 | 50 |
48 EditorViewController::~EditorViewController() {} | 51 EditorViewController::~EditorViewController() {} |
49 | 52 |
50 std::unique_ptr<views::View> EditorViewController::CreateView() { | 53 std::unique_ptr<views::View> EditorViewController::CreateView() { |
51 std::unique_ptr<views::View> content_view = base::MakeUnique<views::View>(); | 54 std::unique_ptr<views::View> content_view = base::MakeUnique<views::View>(); |
52 | 55 |
53 views::BoxLayout* layout = | 56 views::BoxLayout* layout = |
54 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0); | 57 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0); |
55 layout->set_main_axis_alignment(views::BoxLayout::MAIN_AXIS_ALIGNMENT_START); | 58 layout->set_main_axis_alignment(views::BoxLayout::MAIN_AXIS_ALIGNMENT_START); |
56 layout->set_cross_axis_alignment( | 59 layout->set_cross_axis_alignment( |
57 views::BoxLayout::CROSS_AXIS_ALIGNMENT_STRETCH); | 60 views::BoxLayout::CROSS_AXIS_ALIGNMENT_STRETCH); |
58 content_view->SetLayoutManager(layout); | 61 content_view->SetLayoutManager(layout); |
59 | 62 |
60 // Create an input label/textfield for each field definition. | 63 // Create an input label/textfield for each field definition. |
61 std::vector<EditorField> fields = GetFieldDefinitions(); | 64 std::vector<EditorField> fields = GetFieldDefinitions(); |
62 for (const auto& field : fields) { | 65 for (const auto& field : fields) { |
63 views::Textfield* text_field = nullptr; | 66 ValidatingTextfield* text_field = nullptr; |
64 content_view->AddChildView(CreateInputField(field, &text_field).release()); | 67 content_view->AddChildView(CreateInputField(field, &text_field).release()); |
anthonyvd
2017/02/08 15:28:28
I'd remove the ValidatingTextField** parameter and
Mathieu
2017/02/08 21:21:50
I'll still keep the map, for controllers to be abl
anthonyvd
2017/02/09 14:29:27
sgtm
| |
65 // |field| is moved out of the |fields| structure and should not be | 68 // |field| is moved out of the |fields| structure and should not be |
66 // referenced after the following line. | 69 // referenced after the following line. |
67 text_fields_.insert(std::make_pair(text_field, std::move(field))); | 70 text_fields_.insert(std::make_pair(text_field, std::move(field))); |
68 } | 71 } |
69 | 72 |
70 // TODO(mathp): Use the save button in the footer once it's built. | |
71 views::LabelButton* button = views::MdTextButton::CreateSecondaryUiButton( | |
72 this, l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_SAVE_BUTTON)); | |
73 button->set_tag(static_cast<int>(EditorViewControllerTags::SAVE_BUTTON)); | |
74 button->set_id(static_cast<int>(DialogViewID::EDITOR_SAVE_BUTTON)); | |
75 content_view->AddChildView(button); | |
76 | |
77 return CreatePaymentView( | 73 return CreatePaymentView( |
78 CreateSheetHeaderView( | 74 CreateSheetHeaderView( |
79 true, l10n_util::GetStringUTF16( | 75 true, l10n_util::GetStringUTF16( |
80 IDS_PAYMENT_REQUEST_CREDIT_CARD_EDITOR_ADD_TITLE), | 76 IDS_PAYMENT_REQUEST_CREDIT_CARD_EDITOR_ADD_TITLE), |
81 this), | 77 this), |
82 std::move(content_view)); | 78 std::move(content_view)); |
83 } | 79 } |
84 | 80 |
81 bool EditorViewController::ValidateTextfield(ValidatingTextfield* textfield) { | |
82 base::string16 error_message; | |
83 const auto field = text_fields_.find(textfield); | |
84 DCHECK(field != text_fields_.end()); | |
85 // TODO(mathp): Display |error_message| around |textfield|. | |
anthonyvd
2017/02/08 15:28:27
So the issue I see happening here in the future is
Mathieu
2017/02/08 21:21:50
OK you make good points, I've changed it. To expla
anthonyvd
2017/02/09 14:29:27
Ah, I didn't think about the linked validation use
| |
86 return autofill::IsValidForType(textfield->text(), field->second.type, | |
87 &error_message); | |
88 } | |
89 | |
90 std::unique_ptr<views::Button> EditorViewController::CreatePrimaryButton() { | |
91 std::unique_ptr<views::Button> button( | |
92 views::MdTextButton::CreateSecondaryUiBlueButton( | |
93 this, l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_SAVE_BUTTON))); | |
94 button->set_tag(static_cast<int>(EditorViewControllerTags::SAVE_BUTTON)); | |
95 button->set_id(static_cast<int>(DialogViewID::EDITOR_SAVE_BUTTON)); | |
96 return button; | |
97 } | |
98 | |
85 void EditorViewController::ButtonPressed(views::Button* sender, | 99 void EditorViewController::ButtonPressed(views::Button* sender, |
86 const ui::Event& event) { | 100 const ui::Event& event) { |
87 switch (sender->tag()) { | 101 switch (sender->tag()) { |
88 case static_cast<int>(EditorViewControllerTags::SAVE_BUTTON): | 102 case static_cast<int>(EditorViewControllerTags::SAVE_BUTTON): |
89 if (ValidateModelAndSave()) | 103 if (ValidateModelAndSave()) |
90 dialog()->GoBack(); | 104 dialog()->GoBack(); |
91 break; | 105 break; |
92 default: | 106 default: |
93 PaymentRequestSheetController::ButtonPressed(sender, event); | 107 PaymentRequestSheetController::ButtonPressed(sender, event); |
94 break; | 108 break; |
95 } | 109 } |
96 } | 110 } |
97 | 111 |
98 void EditorViewController::ContentsChanged(views::Textfield* sender, | 112 void EditorViewController::ContentsChanged(views::Textfield* sender, |
99 const base::string16& new_contents) { | 113 const base::string16& new_contents) { |
100 // TODO(mathp): Validate the |sender| textfield and display errors. | 114 static_cast<ValidatingTextfield*>(sender)->OnContentsChanged(); |
101 } | 115 } |
102 | 116 |
103 std::unique_ptr<views::View> EditorViewController::CreateInputField( | 117 std::unique_ptr<views::View> EditorViewController::CreateInputField( |
104 const EditorField& field, | 118 const EditorField& field, |
105 views::Textfield** text_field) { | 119 ValidatingTextfield** text_field) { |
106 std::unique_ptr<views::View> row = base::MakeUnique<views::View>(); | 120 std::unique_ptr<views::View> row = base::MakeUnique<views::View>(); |
107 | 121 |
108 row->SetBorder(payments::CreatePaymentRequestRowBorder()); | 122 row->SetBorder(payments::CreatePaymentRequestRowBorder()); |
109 | 123 |
110 views::GridLayout* layout = new views::GridLayout(row.get()); | 124 views::GridLayout* layout = new views::GridLayout(row.get()); |
111 | 125 |
112 // The vertical spacing for these rows is slightly different than the spacing | 126 // The vertical spacing for these rows is slightly different than the spacing |
113 // spacing for clickable rows, so don't use kPaymentRequestRowVerticalInsets. | 127 // spacing for clickable rows, so don't use kPaymentRequestRowVerticalInsets. |
114 constexpr int kRowVerticalInset = 12; | 128 constexpr int kRowVerticalInset = 12; |
115 layout->SetInsets( | 129 layout->SetInsets( |
116 kRowVerticalInset, payments::kPaymentRequestRowHorizontalInsets, | 130 kRowVerticalInset, payments::kPaymentRequestRowHorizontalInsets, |
117 kRowVerticalInset, payments::kPaymentRequestRowHorizontalInsets); | 131 kRowVerticalInset, payments::kPaymentRequestRowHorizontalInsets); |
118 | 132 |
119 row->SetLayoutManager(layout); | 133 row->SetLayoutManager(layout); |
120 views::ColumnSet* columns = layout->AddColumnSet(0); | 134 views::ColumnSet* columns = layout->AddColumnSet(0); |
121 columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, 0, | 135 columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, 0, |
122 views::GridLayout::USE_PREF, 0, 0); | 136 views::GridLayout::USE_PREF, 0, 0); |
123 columns->AddPaddingColumn(1, 0); | 137 columns->AddPaddingColumn(1, 0); |
124 columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::CENTER, 0, | 138 columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::CENTER, 0, |
125 views::GridLayout::USE_PREF, 0, 0); | 139 views::GridLayout::USE_PREF, 0, 0); |
126 | 140 |
127 layout->StartRow(0, 0); | 141 layout->StartRow(0, 0); |
128 layout->AddView(new views::Label(field.label)); | 142 layout->AddView(new views::Label(field.label)); |
129 | 143 |
130 *text_field = new views::Textfield(); | 144 *text_field = new ValidatingTextfield(this); |
131 (*text_field)->set_controller(this); | 145 (*text_field)->set_controller(this); |
146 // Using autofill field type as a view ID (for testing). | |
147 (*text_field)->set_id(static_cast<int>(field.type)); | |
132 (*text_field) | 148 (*text_field) |
133 ->set_default_width_in_chars(field.length_hint == | 149 ->set_default_width_in_chars(field.length_hint == |
134 EditorField::LengthHint::HINT_SHORT | 150 EditorField::LengthHint::HINT_SHORT |
135 ? kNumCharactersInShortField | 151 ? kNumCharactersInShortField |
136 : kNumCharactersInLongField); | 152 : kNumCharactersInLongField); |
137 // |text_field| will now be owned by the layout, but the caller kept a | 153 // |text_field| will now be owned by the layout, but the caller kept a |
138 // reference. | 154 // reference. |
139 layout->AddView(*text_field); | 155 layout->AddView(*text_field); |
140 | 156 |
141 return row; | 157 return row; |
142 } | 158 } |
143 | 159 |
144 } // namespace payments | 160 } // namespace payments |
OLD | NEW |