Chromium Code Reviews| 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 <map> | 7 #include <map> |
| 8 #include <memory> | 8 #include <memory> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 39 // The tag for the button that saves the model being edited. Starts at | 39 // The tag for the button that saves the model being edited. Starts at |
| 40 // |kFirstTagValue| not to conflict with tags common to all views. | 40 // |kFirstTagValue| not to conflict with tags common to all views. |
| 41 SAVE_BUTTON = kFirstTagValue, | 41 SAVE_BUTTON = kFirstTagValue, |
| 42 }; | 42 }; |
| 43 | 43 |
| 44 constexpr int kNumCharactersInShortField = 8; | 44 constexpr int kNumCharactersInShortField = 8; |
| 45 constexpr int kNumCharactersInLongField = 20; | 45 constexpr int kNumCharactersInLongField = 20; |
| 46 | 46 |
| 47 } // namespace | 47 } // namespace |
| 48 | 48 |
| 49 EditorViewController::EditorViewController(PaymentRequestSpec* spec, | 49 EditorViewController::EditorViewController( |
| 50 PaymentRequestState* state, | 50 PaymentRequestSpec* spec, |
| 51 PaymentRequestDialogView* dialog) | 51 PaymentRequestState* state, |
| 52 : PaymentRequestSheetController(spec, state, dialog) {} | 52 PaymentRequestDialogView* dialog, |
| 53 BackNavigationType back_navigation_type) | |
| 54 : PaymentRequestSheetController(spec, state, dialog), | |
| 55 back_navigation_type_(back_navigation_type) {} | |
| 53 | 56 |
| 54 EditorViewController::~EditorViewController() {} | 57 EditorViewController::~EditorViewController() {} |
| 55 | 58 |
| 56 void EditorViewController::DisplayErrorMessageForField( | 59 void EditorViewController::DisplayErrorMessageForField( |
| 57 const EditorField& field, | 60 const EditorField& field, |
| 58 const base::string16& error_message) { | 61 const base::string16& error_message) { |
| 59 const auto& label_it = error_labels_.find(field); | 62 const auto& label_it = error_labels_.find(field); |
| 60 DCHECK(label_it != error_labels_.end()); | 63 DCHECK(label_it != error_labels_.end()); |
| 61 label_it->second->SetText(error_message); | 64 label_it->second->SetText(error_message); |
| 62 label_it->second->SchedulePaint(); | 65 label_it->second->SchedulePaint(); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 79 layout->set_cross_axis_alignment( | 82 layout->set_cross_axis_alignment( |
| 80 views::BoxLayout::CROSS_AXIS_ALIGNMENT_STRETCH); | 83 views::BoxLayout::CROSS_AXIS_ALIGNMENT_STRETCH); |
| 81 content_view->SetLayoutManager(layout); | 84 content_view->SetLayoutManager(layout); |
| 82 // No insets. Child views below are responsible for their padding. | 85 // No insets. Child views below are responsible for their padding. |
| 83 | 86 |
| 84 // An editor can optionally have a header view specific to it. | 87 // An editor can optionally have a header view specific to it. |
| 85 content_view->AddChildView(CreateHeaderView().release()); | 88 content_view->AddChildView(CreateHeaderView().release()); |
| 86 | 89 |
| 87 // The heart of the editor dialog: all the input fields with their labels. | 90 // The heart of the editor dialog: all the input fields with their labels. |
| 88 content_view->AddChildView(CreateEditorView().release()); | 91 content_view->AddChildView(CreateEditorView().release()); |
| 92 | |
| 93 // Room for custom fields that can't be expressed with a field definition. | |
| 94 content_view->AddChildView(CreateCustomFieldsView().release()); | |
| 89 } | 95 } |
| 90 | 96 |
| 91 // Adds the "required fields" label in disabled text, to obtain this result. | 97 // Adds the "required fields" label in disabled text, to obtain this result. |
| 92 // +---------------------------------------------------------+ | 98 // +---------------------------------------------------------+ |
| 93 // | "* indicates required fields" | CANCEL | DONE | | 99 // | "* indicates required fields" | CANCEL | DONE | |
| 94 // +---------------------------------------------------------+ | 100 // +---------------------------------------------------------+ |
| 95 std::unique_ptr<views::View> EditorViewController::CreateExtraFooterView() { | 101 std::unique_ptr<views::View> EditorViewController::CreateExtraFooterView() { |
| 96 std::unique_ptr<views::View> content_view = base::MakeUnique<views::View>(); | 102 std::unique_ptr<views::View> content_view = base::MakeUnique<views::View>(); |
| 97 | 103 |
| 98 views::BoxLayout* layout = | 104 views::BoxLayout* layout = |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 116 UpdateContentView(); | 122 UpdateContentView(); |
| 117 // TODO(crbug.com/704254): Find how to update the parent view bounds so that | 123 // TODO(crbug.com/704254): Find how to update the parent view bounds so that |
| 118 // the vertical scrollbar size gets updated. | 124 // the vertical scrollbar size gets updated. |
| 119 dialog()->EditorViewUpdated(); | 125 dialog()->EditorViewUpdated(); |
| 120 } | 126 } |
| 121 | 127 |
| 122 void EditorViewController::ButtonPressed(views::Button* sender, | 128 void EditorViewController::ButtonPressed(views::Button* sender, |
| 123 const ui::Event& event) { | 129 const ui::Event& event) { |
| 124 switch (sender->tag()) { | 130 switch (sender->tag()) { |
| 125 case static_cast<int>(EditorViewControllerTags::SAVE_BUTTON): | 131 case static_cast<int>(EditorViewControllerTags::SAVE_BUTTON): |
| 126 if (ValidateModelAndSave()) | 132 if (ValidateModelAndSave()) { |
| 127 dialog()->GoBackToPaymentSheet(); | 133 switch (back_navigation_type_) { |
| 134 case BackNavigationType::kOneStep: | |
| 135 dialog()->GoBack(); | |
| 136 break; | |
| 137 case BackNavigationType::kPaymentSheet: | |
| 138 dialog()->GoBackToPaymentSheet(); | |
| 139 break; | |
| 140 } | |
| 141 } | |
| 128 break; | 142 break; |
| 129 default: | 143 default: |
| 130 PaymentRequestSheetController::ButtonPressed(sender, event); | 144 PaymentRequestSheetController::ButtonPressed(sender, event); |
| 131 break; | 145 break; |
| 132 } | 146 } |
| 133 } | 147 } |
| 134 | 148 |
| 135 void EditorViewController::ContentsChanged(views::Textfield* sender, | 149 void EditorViewController::ContentsChanged(views::Textfield* sender, |
| 136 const base::string16& new_contents) { | 150 const base::string16& new_contents) { |
| 137 static_cast<ValidatingTextfield*>(sender)->OnContentsChanged(); | 151 static_cast<ValidatingTextfield*>(sender)->OnContentsChanged(); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 161 columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, 0, | 175 columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, 0, |
| 162 views::GridLayout::USE_PREF, 0, 0); | 176 views::GridLayout::USE_PREF, 0, 0); |
| 163 | 177 |
| 164 // This is the horizontal padding between the label and the input field. | 178 // This is the horizontal padding between the label and the input field. |
| 165 constexpr int kLabelInputFieldHorizontalPadding = 16; | 179 constexpr int kLabelInputFieldHorizontalPadding = 16; |
| 166 columns->AddPaddingColumn(0, kLabelInputFieldHorizontalPadding); | 180 columns->AddPaddingColumn(0, kLabelInputFieldHorizontalPadding); |
| 167 | 181 |
| 168 columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, 0, | 182 columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, 0, |
| 169 views::GridLayout::USE_PREF, 0, 0); | 183 views::GridLayout::USE_PREF, 0, 0); |
| 170 | 184 |
| 171 // The LayoutManager needs to be set before input fields are created, so we | |
| 172 // keep a handle to it before we release it to the view. | |
| 173 views::GridLayout* layout_handle = editor_layout.get(); | |
| 174 editor_view->SetLayoutManager(editor_layout.release()); | 185 editor_view->SetLayoutManager(editor_layout.release()); |
| 175 std::vector<EditorField> fields = GetFieldDefinitions(); | 186 std::vector<EditorField> fields = GetFieldDefinitions(); |
| 176 for (const auto& field : fields) { | 187 for (const auto& field : fields) { |
| 177 CreateInputField(layout_handle, field); | 188 CreateInputField( |
| 189 static_cast<views::GridLayout*>(editor_view->GetLayoutManager()), | |
| 190 field); | |
| 178 } | 191 } |
| 179 | 192 |
| 180 return editor_view; | 193 return editor_view; |
| 181 } | 194 } |
| 182 | 195 |
| 183 // Each input field is a 4-quadrant grid. | 196 // Each input field is a 4-quadrant grid. |
| 184 // +----------------------------------------------------------+ | 197 // +----------------------------------------------------------+ |
| 185 // | Field Label | Input field (textfield/combobox) | | 198 // | Field Label | Input field (textfield/combobox) | |
| 186 // |_______________________|__________________________________| | 199 // |_______________________|__________________________________| |
| 187 // | (empty) | Error label | | 200 // | (empty) | Error label | |
| 188 // +----------------------------------------------------------+ | 201 // +----------------------------------------------------------+ |
| 189 void EditorViewController::CreateInputField(views::GridLayout* layout, | 202 void EditorViewController::CreateInputField(views::GridLayout* layout, |
| 190 const EditorField& field) { | 203 const EditorField& field) { |
| 191 // This is the top padding for every row. | 204 // This is the top padding for every row. |
| 192 constexpr int kInputRowSpacing = 6; | |
| 193 layout->StartRowWithPadding(0, 0, 0, kInputRowSpacing); | 205 layout->StartRowWithPadding(0, 0, 0, kInputRowSpacing); |
| 194 | 206 |
| 195 std::unique_ptr<views::Label> label = base::MakeUnique<views::Label>( | 207 std::unique_ptr<views::Label> label = base::MakeUnique<views::Label>( |
| 196 field.required ? field.label + base::ASCIIToUTF16("*") : field.label); | 208 field.required ? field.label + base::ASCIIToUTF16("*") : field.label); |
| 197 // A very long label will wrap. Value picked so that left + right label | 209 |
| 198 // padding bring the label to half-way in the dialog (~225). | 210 // A very long label will wrap. |
| 199 constexpr int kMaximumLabelWidth = 192; | |
| 200 label->SetMultiLine(true); | 211 label->SetMultiLine(true); |
| 201 label->SetMaximumWidth(kMaximumLabelWidth); | 212 label->SetMaximumWidth(kMaximumLabelWidth); |
| 202 layout->AddView(label.release()); | 213 layout->AddView(label.release()); |
| 203 | 214 |
| 204 if (field.control_type == EditorField::ControlType::TEXTFIELD) { | 215 if (field.control_type == EditorField::ControlType::TEXTFIELD) { |
| 205 ValidatingTextfield* text_field = | 216 ValidatingTextfield* text_field = |
| 206 new ValidatingTextfield(CreateValidationDelegate(field)); | 217 new ValidatingTextfield(CreateValidationDelegate(field)); |
| 207 text_field->SetText(GetInitialValueForType(field.type)); | 218 text_field->SetText(GetInitialValueForType(field.type)); |
| 208 text_field->set_controller(this); | 219 text_field->set_controller(this); |
| 209 // Using autofill field type as a view ID (for testing). | 220 // Using autofill field type as a view ID (for testing). |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 220 ValidatingCombobox* combobox = new ValidatingCombobox( | 231 ValidatingCombobox* combobox = new ValidatingCombobox( |
| 221 GetComboboxModelForType(field.type), CreateValidationDelegate(field)); | 232 GetComboboxModelForType(field.type), CreateValidationDelegate(field)); |
| 222 combobox->SelectValue(GetInitialValueForType(field.type)); | 233 combobox->SelectValue(GetInitialValueForType(field.type)); |
| 223 // Using autofill field type as a view ID (for testing). | 234 // Using autofill field type as a view ID (for testing). |
| 224 combobox->set_id(static_cast<int>(field.type)); | 235 combobox->set_id(static_cast<int>(field.type)); |
| 225 combobox->set_listener(this); | 236 combobox->set_listener(this); |
| 226 comboboxes_.insert(std::make_pair(combobox, field)); | 237 comboboxes_.insert(std::make_pair(combobox, field)); |
| 227 // |combobox| will now be owned by |row|. | 238 // |combobox| will now be owned by |row|. |
| 228 layout->AddView(combobox); | 239 layout->AddView(combobox); |
| 229 } else { | 240 } else { |
| 230 NOTREACHED(); | 241 NOTREACHED(); |
|
Mathieu
2017/05/04 20:29:19
I add an idea when looking at this. You could defi
MAD
2017/05/05 00:50:07
Excellent idea... Done!
| |
| 231 } | 242 } |
| 232 | 243 |
| 233 // This is the vertical space between the input field and its error label. | 244 // This is the vertical space between the input field and its error label. |
| 234 constexpr int kInputErrorLabelPadding = 6; | 245 constexpr int kInputErrorLabelPadding = 6; |
| 235 layout->StartRowWithPadding(0, 0, 0, kInputErrorLabelPadding); | 246 layout->StartRowWithPadding(0, 0, 0, kInputErrorLabelPadding); |
| 236 layout->SkipColumns(1); | 247 layout->SkipColumns(1); |
| 237 // Error label is initially empty. | 248 // Error label is initially empty. |
| 238 std::unique_ptr<views::Label> error_label = | 249 std::unique_ptr<views::Label> error_label = |
| 239 base::MakeUnique<views::Label>(base::ASCIIToUTF16("")); | 250 base::MakeUnique<views::Label>(base::ASCIIToUTF16("")); |
| 240 error_label->set_id(static_cast<int>(DialogViewID::ERROR_LABEL_OFFSET) + | 251 error_label->set_id(static_cast<int>(DialogViewID::ERROR_LABEL_OFFSET) + |
| 241 field.type); | 252 field.type); |
| 242 error_label->SetFontList( | 253 error_label->SetFontList( |
| 243 error_label->GetDefaultFontList().DeriveWithSizeDelta(-1)); | 254 error_label->GetDefaultFontList().DeriveWithSizeDelta(-1)); |
| 244 error_label->SetEnabledColor(error_label->GetNativeTheme()->GetSystemColor( | 255 error_label->SetEnabledColor(error_label->GetNativeTheme()->GetSystemColor( |
| 245 ui::NativeTheme::kColorId_AlertSeverityHigh)); | 256 ui::NativeTheme::kColorId_AlertSeverityHigh)); |
| 246 error_labels_[field] = error_label.get(); | 257 error_labels_[field] = error_label.get(); |
| 247 | 258 |
| 248 layout->AddView(error_label.release()); | 259 layout->AddView(error_label.release()); |
| 249 } | 260 } |
| 250 | 261 |
| 251 } // namespace payments | 262 } // namespace payments |
| OLD | NEW |