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 <algorithm> | |
7 #include <map> | 8 #include <map> |
8 #include <memory> | 9 #include <memory> |
9 #include <utility> | 10 #include <utility> |
10 | 11 |
11 #include "base/memory/ptr_util.h" | 12 #include "base/memory/ptr_util.h" |
12 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
13 #include "chrome/browser/ui/views/payments/payment_request_dialog_view.h" | 14 #include "chrome/browser/ui/views/payments/payment_request_dialog_view.h" |
14 #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h" | 15 #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h" |
15 #include "chrome/browser/ui/views/payments/payment_request_views_util.h" | 16 #include "chrome/browser/ui/views/payments/payment_request_views_util.h" |
16 #include "chrome/browser/ui/views/payments/validating_combobox.h" | 17 #include "chrome/browser/ui/views/payments/validating_combobox.h" |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
95 CreateErrorLabelView(error_message, field).release()); | 96 CreateErrorLabelView(error_message, field).release()); |
96 } | 97 } |
97 RelayoutPane(); | 98 RelayoutPane(); |
98 } | 99 } |
99 | 100 |
100 std::unique_ptr<views::View> EditorViewController::CreateHeaderView() { | 101 std::unique_ptr<views::View> EditorViewController::CreateHeaderView() { |
101 return nullptr; | 102 return nullptr; |
102 } | 103 } |
103 | 104 |
104 std::unique_ptr<views::View> EditorViewController::CreateCustomFieldView( | 105 std::unique_ptr<views::View> EditorViewController::CreateCustomFieldView( |
105 autofill::ServerFieldType type) { | 106 autofill::ServerFieldType type, |
107 views::View** focusable_field) { | |
106 return nullptr; | 108 return nullptr; |
107 } | 109 } |
108 | 110 |
109 std::unique_ptr<views::View> EditorViewController::CreateExtraViewForField( | 111 std::unique_ptr<views::View> EditorViewController::CreateExtraViewForField( |
110 autofill::ServerFieldType type) { | 112 autofill::ServerFieldType type) { |
111 return nullptr; | 113 return nullptr; |
112 } | 114 } |
113 | 115 |
114 std::unique_ptr<views::Button> EditorViewController::CreatePrimaryButton() { | 116 std::unique_ptr<views::Button> EditorViewController::CreatePrimaryButton() { |
115 std::unique_ptr<views::Button> button( | 117 std::unique_ptr<views::Button> button( |
(...skipping 21 matching lines...) Expand all Loading... | |
137 // The heart of the editor dialog: all the input fields with their labels. | 139 // The heart of the editor dialog: all the input fields with their labels. |
138 content_view->AddChildView(CreateEditorView().release()); | 140 content_view->AddChildView(CreateEditorView().release()); |
139 } | 141 } |
140 | 142 |
141 base::string16 EditorViewController::GetSecondaryButtonLabel() { | 143 base::string16 EditorViewController::GetSecondaryButtonLabel() { |
142 return l10n_util::GetStringUTF16(IDS_PAYMENTS_CANCEL_PAYMENT); | 144 return l10n_util::GetStringUTF16(IDS_PAYMENTS_CANCEL_PAYMENT); |
143 } | 145 } |
144 | 146 |
145 void EditorViewController::UpdateEditorView() { | 147 void EditorViewController::UpdateEditorView() { |
146 UpdateContentView(); | 148 UpdateContentView(); |
147 // TODO(crbug.com/704254): Find how to update the parent view bounds so that | |
148 // the vertical scrollbar size gets updated. | |
149 dialog()->EditorViewUpdated(); | 149 dialog()->EditorViewUpdated(); |
150 } | 150 } |
151 | 151 |
152 void EditorViewController::ButtonPressed(views::Button* sender, | 152 void EditorViewController::ButtonPressed(views::Button* sender, |
153 const ui::Event& event) { | 153 const ui::Event& event) { |
154 switch (sender->tag()) { | 154 switch (sender->tag()) { |
155 case static_cast<int>(EditorViewControllerTags::SAVE_BUTTON): | 155 case static_cast<int>(EditorViewControllerTags::SAVE_BUTTON): |
156 if (ValidateModelAndSave()) { | 156 if (ValidateModelAndSave()) { |
157 switch (back_navigation_type_) { | 157 switch (back_navigation_type_) { |
158 case BackNavigationType::kOneStep: | 158 case BackNavigationType::kOneStep: |
(...skipping 23 matching lines...) Expand all Loading... | |
182 } | 182 } |
183 | 183 |
184 void EditorViewController::OnPerformAction(views::Combobox* sender) { | 184 void EditorViewController::OnPerformAction(views::Combobox* sender) { |
185 static_cast<ValidatingCombobox*>(sender)->OnContentsChanged(); | 185 static_cast<ValidatingCombobox*>(sender)->OnContentsChanged(); |
186 } | 186 } |
187 | 187 |
188 std::unique_ptr<views::View> EditorViewController::CreateEditorView() { | 188 std::unique_ptr<views::View> EditorViewController::CreateEditorView() { |
189 std::unique_ptr<views::View> editor_view = base::MakeUnique<views::View>(); | 189 std::unique_ptr<views::View> editor_view = base::MakeUnique<views::View>(); |
190 text_fields_.clear(); | 190 text_fields_.clear(); |
191 comboboxes_.clear(); | 191 comboboxes_.clear(); |
192 first_field_view_ = nullptr; | |
192 | 193 |
193 // The editor view is padded horizontally. | 194 // The editor view is padded horizontally. |
194 editor_view->SetBorder(views::CreateEmptyBorder( | 195 editor_view->SetBorder(views::CreateEmptyBorder( |
195 0, payments::kPaymentRequestRowHorizontalInsets, 0, | 196 0, payments::kPaymentRequestRowHorizontalInsets, 0, |
196 payments::kPaymentRequestRowHorizontalInsets)); | 197 payments::kPaymentRequestRowHorizontalInsets)); |
197 | 198 |
198 // All views have fixed size except the Field which stretches. The fixed | 199 // All views have fixed size except the Field which stretches. The fixed |
199 // padding at the end is computed so that Field views have a minimum of | 200 // padding at the end is computed so that Field views have a minimum of |
200 // 176/272dp (short/long fields) as per spec. | 201 // 176/272dp (short/long fields) as per spec. |
201 // ___________________________________________________________________________ | 202 // ___________________________________________________________________________ |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
273 required_field->SetEnabled(false); | 274 required_field->SetEnabled(false); |
274 | 275 |
275 views::ColumnSet* required_field_columns = editor_layout->AddColumnSet(2); | 276 views::ColumnSet* required_field_columns = editor_layout->AddColumnSet(2); |
276 required_field_columns->AddColumn(views::GridLayout::LEADING, | 277 required_field_columns->AddColumn(views::GridLayout::LEADING, |
277 views::GridLayout::CENTER, 1, | 278 views::GridLayout::CENTER, 1, |
278 views::GridLayout::USE_PREF, 0, 0); | 279 views::GridLayout::USE_PREF, 0, 0); |
279 editor_layout->StartRow(0, 2); | 280 editor_layout->StartRow(0, 2); |
280 editor_layout->AddView(required_field.release()); | 281 editor_layout->AddView(required_field.release()); |
281 | 282 |
282 editor_view->SetLayoutManager(editor_layout.release()); | 283 editor_view->SetLayoutManager(editor_layout.release()); |
284 views::View* potential_first_field_view = nullptr; | |
anthonyvd
2017/05/12 14:19:44
I'm confused: we seem to be creating the fields bo
MAD
2017/05/18 16:01:44
Oups, yes, merge fluke... Sorry about that... :-(
| |
285 for (const auto& field : GetFieldDefinitions()) { | |
286 views::View* focusable_field = CreateInputField( | |
287 static_cast<views::GridLayout*>(editor_view->GetLayoutManager()), | |
288 field); | |
289 if (!potential_first_field_view) | |
290 potential_first_field_view = focusable_field; | |
291 } | |
292 | |
293 if (!first_field_view_) | |
294 first_field_view_ = potential_first_field_view; | |
283 | 295 |
284 return editor_view; | 296 return editor_view; |
285 } | 297 } |
286 | 298 |
287 // Each input field is a 4-quadrant grid. | 299 // Each input field is a 4-quadrant grid. |
288 // +----------------------------------------------------------+ | 300 // +----------------------------------------------------------+ |
289 // | Field Label | Input field (textfield/combobox) | | 301 // | Field Label | Input field (textfield/combobox) | |
290 // |_______________________|__________________________________| | 302 // |_______________________|__________________________________| |
291 // | (empty) | Error label | | 303 // | (empty) | Error label | |
292 // +----------------------------------------------------------+ | 304 // +----------------------------------------------------------+ |
293 void EditorViewController::CreateInputField(views::GridLayout* layout, | 305 views::View* EditorViewController::CreateInputField(views::GridLayout* layout, |
294 const EditorField& field) { | 306 const EditorField& field) { |
295 int column_set = | 307 int column_set = |
296 field.length_hint == EditorField::LengthHint::HINT_SHORT ? 0 : 1; | 308 field.length_hint == EditorField::LengthHint::HINT_SHORT ? 0 : 1; |
297 | 309 |
298 // This is the top padding for every row. | 310 // This is the top padding for every row. |
299 constexpr int kInputRowSpacing = 6; | 311 constexpr int kInputRowSpacing = 6; |
300 layout->StartRowWithPadding(0, column_set, 0, kInputRowSpacing); | 312 layout->StartRowWithPadding(0, column_set, 0, kInputRowSpacing); |
301 | 313 |
302 std::unique_ptr<views::Label> label = base::MakeUnique<views::Label>( | 314 std::unique_ptr<views::Label> label = base::MakeUnique<views::Label>( |
303 field.required ? field.label + base::ASCIIToUTF16("*") : field.label); | 315 field.required ? field.label + base::ASCIIToUTF16("*") : field.label); |
304 | 316 |
305 label->SetMultiLine(true); | 317 label->SetMultiLine(true); |
306 layout->AddView(label.release()); | 318 layout->AddView(label.release()); |
307 | 319 |
320 views::View* focusable_field = nullptr; | |
321 | |
308 constexpr int kInputFieldHeight = 28; | 322 constexpr int kInputFieldHeight = 28; |
309 if (field.control_type == EditorField::ControlType::TEXTFIELD) { | 323 if (field.control_type == EditorField::ControlType::TEXTFIELD) { |
310 ValidatingTextfield* text_field = | 324 ValidatingTextfield* text_field = |
311 new ValidatingTextfield(CreateValidationDelegate(field)); | 325 new ValidatingTextfield(CreateValidationDelegate(field)); |
312 text_field->SetText(GetInitialValueForType(field.type)); | 326 text_field->SetText(GetInitialValueForType(field.type)); |
313 text_field->set_controller(this); | 327 text_field->set_controller(this); |
314 // Using autofill field type as a view ID (for testing). | 328 // Using autofill field type as a view ID (for testing). |
315 text_field->set_id(static_cast<int>(field.type)); | 329 text_field->set_id(static_cast<int>(field.type)); |
316 text_fields_.insert(std::make_pair(text_field, field)); | 330 text_fields_.insert(std::make_pair(text_field, field)); |
317 | 331 focusable_field = text_field; |
318 // TODO(crbug.com/718582): Make the initial focus the first incomplete/empty | 332 if (!first_field_view_) { |
319 // field. | 333 text_field->Validate(/*display_error=*/false); |
320 if (!first_field_view_) | 334 if (text_field->invalid()) { |
321 first_field_view_ = text_field; | 335 first_field_view_ = text_field; |
336 } | |
337 } | |
322 | 338 |
323 // |text_field| will now be owned by |row|. | 339 // |text_field| will now be owned by |row|. |
324 layout->AddView(text_field, 1, 1, views::GridLayout::FILL, | 340 layout->AddView(text_field, 1, 1, views::GridLayout::FILL, |
325 views::GridLayout::FILL, 0, kInputFieldHeight); | 341 views::GridLayout::FILL, 0, kInputFieldHeight); |
326 } else if (field.control_type == EditorField::ControlType::COMBOBOX) { | 342 } else if (field.control_type == EditorField::ControlType::COMBOBOX) { |
327 ValidatingCombobox* combobox = new ValidatingCombobox( | 343 ValidatingCombobox* combobox = new ValidatingCombobox( |
328 GetComboboxModelForType(field.type), CreateValidationDelegate(field)); | 344 GetComboboxModelForType(field.type), CreateValidationDelegate(field)); |
329 base::string16 initial_value = GetInitialValueForType(field.type); | 345 base::string16 initial_value = GetInitialValueForType(field.type); |
330 if (!initial_value.empty()) | 346 if (!initial_value.empty()) |
331 combobox->SelectValue(initial_value); | 347 combobox->SelectValue(initial_value); |
332 // Using autofill field type as a view ID. | 348 // Using autofill field type as a view ID. |
333 combobox->set_id(static_cast<int>(field.type)); | 349 combobox->set_id(static_cast<int>(field.type)); |
334 combobox->set_listener(this); | 350 combobox->set_listener(this); |
335 comboboxes_.insert(std::make_pair(combobox, field)); | 351 comboboxes_.insert(std::make_pair(combobox, field)); |
336 | 352 focusable_field = combobox; |
337 if (!first_field_view_) | 353 if (!first_field_view_) { |
338 first_field_view_ = combobox; | 354 combobox->Validate(/*display_error=*/false); |
355 if (combobox->invalid()) { | |
356 first_field_view_ = combobox; | |
357 } | |
358 } | |
339 | 359 |
340 // |combobox| will now be owned by |row|. | 360 // |combobox| will now be owned by |row|. |
341 layout->AddView(combobox, 1, 1, views::GridLayout::FILL, | 361 layout->AddView(combobox, 1, 1, views::GridLayout::FILL, |
342 views::GridLayout::FILL, 0, kInputFieldHeight); | 362 views::GridLayout::FILL, 0, kInputFieldHeight); |
343 } else { | 363 } else { |
344 // Custom field view will now be owned by |row|. And it must be valid since | 364 // Custom field view will now be owned by |row|. And it must be valid since |
345 // the derived class specified a custom view for this field. | 365 // the derived class specified a custom view for this field. |
346 std::unique_ptr<views::View> field_view = CreateCustomFieldView(field.type); | 366 std::unique_ptr<views::View> field_view = |
367 CreateCustomFieldView(field.type, &focusable_field); | |
347 DCHECK(field_view); | 368 DCHECK(field_view); |
348 layout->AddView(field_view.release()); | 369 layout->AddView(field_view.release()); |
349 } | 370 } |
350 | 371 |
351 // If an extra view needs to go alongside the input field view, add it to the | 372 // If an extra view needs to go alongside the input field view, add it to the |
352 // last column. | 373 // last column. |
353 std::unique_ptr<views::View> extra_view = CreateExtraViewForField(field.type); | 374 std::unique_ptr<views::View> extra_view = CreateExtraViewForField(field.type); |
354 if (extra_view) | 375 if (extra_view) |
355 layout->AddView(extra_view.release()); | 376 layout->AddView(extra_view.release()); |
356 | 377 |
357 layout->StartRow(0, column_set); | 378 layout->StartRow(0, column_set); |
358 layout->SkipColumns(1); | 379 layout->SkipColumns(1); |
359 std::unique_ptr<views::View> error_label_view = | 380 std::unique_ptr<views::View> error_label_view = |
360 base::MakeUnique<views::View>(); | 381 base::MakeUnique<views::View>(); |
361 error_label_view->SetLayoutManager(new views::FillLayout); | 382 error_label_view->SetLayoutManager(new views::FillLayout); |
362 error_labels_[field] = error_label_view.get(); | 383 error_labels_[field] = error_label_view.get(); |
363 layout->AddView(error_label_view.release()); | 384 layout->AddView(error_label_view.release()); |
364 | 385 |
365 // Bottom padding for the row. | 386 // Bottom padding for the row. |
366 layout->AddPaddingRow(0, kInputRowSpacing); | 387 layout->AddPaddingRow(0, kInputRowSpacing); |
388 return focusable_field; | |
367 } | 389 } |
368 | 390 |
369 int EditorViewController::ComputeWidestExtraViewWidth( | 391 int EditorViewController::ComputeWidestExtraViewWidth( |
370 EditorField::LengthHint size) { | 392 EditorField::LengthHint size) { |
371 int widest_column_width = 0; | 393 int widest_column_width = 0; |
372 | 394 |
373 for (const auto& field : GetFieldDefinitions()) { | 395 for (const auto& field : GetFieldDefinitions()) { |
374 if (field.length_hint != size) | 396 if (field.length_hint != size) |
375 continue; | 397 continue; |
376 | 398 |
377 std::unique_ptr<views::View> extra_view = | 399 std::unique_ptr<views::View> extra_view = |
378 CreateExtraViewForField(field.type); | 400 CreateExtraViewForField(field.type); |
379 if (!extra_view) | 401 if (!extra_view) |
380 continue; | 402 continue; |
381 widest_column_width = | 403 widest_column_width = |
382 std::max(extra_view->GetPreferredSize().width(), widest_column_width); | 404 std::max(extra_view->GetPreferredSize().width(), widest_column_width); |
383 } | 405 } |
384 return widest_column_width; | 406 return widest_column_width; |
385 } | 407 } |
386 | 408 |
387 } // namespace payments | 409 } // namespace payments |
OLD | NEW |