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 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 99 | 99 |
| 100 std::unique_ptr<views::View> EditorViewController::CreateHeaderView() { | 100 std::unique_ptr<views::View> EditorViewController::CreateHeaderView() { |
| 101 return nullptr; | 101 return nullptr; |
| 102 } | 102 } |
| 103 | 103 |
| 104 std::unique_ptr<views::View> EditorViewController::CreateCustomFieldView( | 104 std::unique_ptr<views::View> EditorViewController::CreateCustomFieldView( |
| 105 autofill::ServerFieldType type) { | 105 autofill::ServerFieldType type) { |
| 106 return nullptr; | 106 return nullptr; |
| 107 } | 107 } |
| 108 | 108 |
| 109 std::unique_ptr<views::View> EditorViewController::CreateExtraViewForField( | |
| 110 autofill::ServerFieldType type) { | |
| 111 return nullptr; | |
| 112 } | |
| 113 | |
| 109 std::unique_ptr<views::Button> EditorViewController::CreatePrimaryButton() { | 114 std::unique_ptr<views::Button> EditorViewController::CreatePrimaryButton() { |
| 110 std::unique_ptr<views::Button> button( | 115 std::unique_ptr<views::Button> button( |
| 111 views::MdTextButton::CreateSecondaryUiBlueButton( | 116 views::MdTextButton::CreateSecondaryUiBlueButton( |
| 112 this, l10n_util::GetStringUTF16(IDS_DONE))); | 117 this, l10n_util::GetStringUTF16(IDS_DONE))); |
| 113 button->set_tag(static_cast<int>(EditorViewControllerTags::SAVE_BUTTON)); | 118 button->set_tag(static_cast<int>(EditorViewControllerTags::SAVE_BUTTON)); |
| 114 button->set_id(static_cast<int>(DialogViewID::EDITOR_SAVE_BUTTON)); | 119 button->set_id(static_cast<int>(DialogViewID::EDITOR_SAVE_BUTTON)); |
| 115 return button; | 120 return button; |
| 116 } | 121 } |
| 117 | 122 |
| 118 void EditorViewController::FillContentView(views::View* content_view) { | 123 void EditorViewController::FillContentView(views::View* content_view) { |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 198 | 203 |
| 199 void EditorViewController::OnPerformAction(views::Combobox* sender) { | 204 void EditorViewController::OnPerformAction(views::Combobox* sender) { |
| 200 static_cast<ValidatingCombobox*>(sender)->OnContentsChanged(); | 205 static_cast<ValidatingCombobox*>(sender)->OnContentsChanged(); |
| 201 } | 206 } |
| 202 | 207 |
| 203 std::unique_ptr<views::View> EditorViewController::CreateEditorView() { | 208 std::unique_ptr<views::View> EditorViewController::CreateEditorView() { |
| 204 std::unique_ptr<views::View> editor_view = base::MakeUnique<views::View>(); | 209 std::unique_ptr<views::View> editor_view = base::MakeUnique<views::View>(); |
| 205 text_fields_.clear(); | 210 text_fields_.clear(); |
| 206 comboboxes_.clear(); | 211 comboboxes_.clear(); |
| 207 | 212 |
| 208 std::unique_ptr<views::GridLayout> editor_layout = | |
| 209 base::MakeUnique<views::GridLayout>(editor_view.get()); | |
| 210 | |
| 211 // The editor view is padded horizontally. | 213 // The editor view is padded horizontally. |
| 212 editor_view->SetBorder(views::CreateEmptyBorder( | 214 editor_view->SetBorder(views::CreateEmptyBorder( |
| 213 0, payments::kPaymentRequestRowHorizontalInsets, 0, | 215 0, payments::kPaymentRequestRowHorizontalInsets, 0, |
| 214 payments::kPaymentRequestRowHorizontalInsets)); | 216 payments::kPaymentRequestRowHorizontalInsets)); |
| 215 | 217 |
| 216 views::ColumnSet* columns = editor_layout->AddColumnSet(0); | 218 // All views have fixed size except the Field which stretches. The fixed |
| 217 columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, 0, | 219 // padding at the end is computed so that Field views have a minimum of |
| 218 views::GridLayout::USE_PREF, 0, 0); | 220 // 176/272dp (short/long fields) as per spec. |
| 221 // ___________________________________________________________________________ | |
| 222 // | | | |
|
anthonyvd
2017/05/11 00:32:14
nit: remove this empty line?
Mathieu
2017/05/11 01:16:24
Done.
| |
| 223 // |Label | 16dp pad | Field (flex) | 8dp pad | Extra View | Computed Padding| | |
| 224 // |_________________________________________________________________________| | |
| 225 constexpr int kLabelWidth = 140; | |
| 226 // This is the horizontal padding between the label and the field. | |
| 227 constexpr int kLabelInputFieldHorizontalPadding = 16; | |
| 228 // This is the horizontal padding between the field and the extra view. | |
| 229 constexpr int kFieldExtraViewHorizontalPadding = 8; | |
| 230 constexpr int kShortFieldMinimumWidth = 176; | |
| 231 constexpr int kLongFieldMinimumWidth = 272; | |
| 219 | 232 |
| 220 // This is the horizontal padding between the label and the input field. | 233 std::unique_ptr<views::GridLayout> editor_layout = |
| 221 constexpr int kLabelInputFieldHorizontalPadding = 16; | 234 base::MakeUnique<views::GridLayout>(editor_view.get()); |
| 222 columns->AddPaddingColumn(0, kLabelInputFieldHorizontalPadding); | 235 // Column set for short fields. |
| 236 views::ColumnSet* columns_short = editor_layout->AddColumnSet(0); | |
| 237 columns_short->AddColumn(views::GridLayout::LEADING, | |
| 238 views::GridLayout::CENTER, 0, | |
| 239 views::GridLayout::FIXED, kLabelWidth, 0); | |
| 240 columns_short->AddPaddingColumn(0, kLabelInputFieldHorizontalPadding); | |
| 241 // The field view column stretches. | |
| 242 columns_short->AddColumn(views::GridLayout::LEADING, | |
| 243 views::GridLayout::CENTER, 1, | |
| 244 views::GridLayout::USE_PREF, 0, 0); | |
| 245 columns_short->AddPaddingColumn(0, kFieldExtraViewHorizontalPadding); | |
| 246 // The extra field view column is fixed size, computed from the largest | |
| 247 // extra view. | |
| 248 int short_extra_view_width = | |
| 249 ComputeWidestExtraViewWidth(EditorField::LengthHint::HINT_SHORT); | |
| 250 columns_short->AddColumn(views::GridLayout::LEADING, | |
| 251 views::GridLayout::CENTER, 0, | |
| 252 views::GridLayout::FIXED, short_extra_view_width, 0); | |
| 253 // The padding at the end is fixed, computed to make sure the short field | |
| 254 // maintains its minimum width. | |
| 255 int short_padding = kDialogMinWidth - kShortFieldMinimumWidth - kLabelWidth - | |
| 256 (2 * kPaymentRequestRowHorizontalInsets) - | |
| 257 kLabelInputFieldHorizontalPadding - | |
| 258 kFieldExtraViewHorizontalPadding - short_extra_view_width; | |
| 259 columns_short->AddPaddingColumn(0, short_padding); | |
| 223 | 260 |
| 224 columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, 0, | 261 // Column set for long fields. |
| 225 views::GridLayout::USE_PREF, 0, 0); | 262 views::ColumnSet* columns_long = editor_layout->AddColumnSet(1); |
| 263 columns_long->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, | |
| 264 0, views::GridLayout::FIXED, kLabelWidth, 0); | |
| 265 columns_long->AddPaddingColumn(0, kLabelInputFieldHorizontalPadding); | |
| 266 // The field view column stretches. | |
| 267 columns_long->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, | |
| 268 1, views::GridLayout::USE_PREF, 0, 0); | |
| 269 columns_long->AddPaddingColumn(0, kFieldExtraViewHorizontalPadding); | |
| 270 // The extra field view column is fixed size, computed from the largest | |
| 271 // extra view. | |
| 272 int long_extra_view_width = | |
| 273 ComputeWidestExtraViewWidth(EditorField::LengthHint::HINT_LONG); | |
| 274 columns_long->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, | |
| 275 0, views::GridLayout::FIXED, long_extra_view_width, | |
| 276 0); | |
| 277 // The padding at the end is fixed, computed to make sure the long field | |
| 278 // maintains its minimum width. | |
| 279 int long_padding = kDialogMinWidth - kLongFieldMinimumWidth - kLabelWidth - | |
| 280 (2 * kPaymentRequestRowHorizontalInsets) - | |
| 281 kLabelInputFieldHorizontalPadding - | |
| 282 kFieldExtraViewHorizontalPadding - long_extra_view_width; | |
| 283 columns_long->AddPaddingColumn(0, long_padding); | |
| 226 | 284 |
| 227 editor_view->SetLayoutManager(editor_layout.release()); | 285 editor_view->SetLayoutManager(editor_layout.release()); |
| 228 std::vector<EditorField> fields = GetFieldDefinitions(); | 286 for (const auto& field : GetFieldDefinitions()) { |
| 229 for (const auto& field : fields) { | |
| 230 CreateInputField( | 287 CreateInputField( |
| 231 static_cast<views::GridLayout*>(editor_view->GetLayoutManager()), | 288 static_cast<views::GridLayout*>(editor_view->GetLayoutManager()), |
| 232 field); | 289 field); |
| 233 } | 290 } |
| 234 | 291 |
| 235 return editor_view; | 292 return editor_view; |
| 236 } | 293 } |
| 237 | 294 |
| 238 // Each input field is a 4-quadrant grid. | 295 // Each input field is a 4-quadrant grid. |
| 239 // +----------------------------------------------------------+ | 296 // +----------------------------------------------------------+ |
| 240 // | Field Label | Input field (textfield/combobox) | | 297 // | Field Label | Input field (textfield/combobox) | |
| 241 // |_______________________|__________________________________| | 298 // |_______________________|__________________________________| |
| 242 // | (empty) | Error label | | 299 // | (empty) | Error label | |
| 243 // +----------------------------------------------------------+ | 300 // +----------------------------------------------------------+ |
| 244 void EditorViewController::CreateInputField(views::GridLayout* layout, | 301 void EditorViewController::CreateInputField(views::GridLayout* layout, |
| 245 const EditorField& field) { | 302 const EditorField& field) { |
| 303 int column_set = | |
| 304 field.length_hint == EditorField::LengthHint::HINT_SHORT ? 0 : 1; | |
| 305 | |
| 246 // This is the top padding for every row. | 306 // This is the top padding for every row. |
| 247 constexpr int kInputRowSpacing = 6; | 307 constexpr int kInputRowSpacing = 6; |
| 248 layout->StartRowWithPadding(0, 0, 0, kInputRowSpacing); | 308 layout->StartRowWithPadding(0, column_set, 0, kInputRowSpacing); |
| 249 | 309 |
| 250 std::unique_ptr<views::Label> label = base::MakeUnique<views::Label>( | 310 std::unique_ptr<views::Label> label = base::MakeUnique<views::Label>( |
| 251 field.required ? field.label + base::ASCIIToUTF16("*") : field.label); | 311 field.required ? field.label + base::ASCIIToUTF16("*") : field.label); |
| 252 | 312 |
| 253 label->SetMultiLine(true); | 313 label->SetMultiLine(true); |
| 254 label->SetMaximumWidth(kMaximumLabelWidth); | |
| 255 layout->AddView(label.release()); | 314 layout->AddView(label.release()); |
| 256 | 315 |
| 257 constexpr int kInputFieldHeight = 28; | 316 constexpr int kInputFieldHeight = 28; |
| 258 if (field.control_type == EditorField::ControlType::TEXTFIELD) { | 317 if (field.control_type == EditorField::ControlType::TEXTFIELD) { |
| 259 ValidatingTextfield* text_field = | 318 ValidatingTextfield* text_field = |
| 260 new ValidatingTextfield(CreateValidationDelegate(field)); | 319 new ValidatingTextfield(CreateValidationDelegate(field)); |
| 261 text_field->SetText(GetInitialValueForType(field.type)); | 320 text_field->SetText(GetInitialValueForType(field.type)); |
| 262 text_field->set_controller(this); | 321 text_field->set_controller(this); |
| 263 // Using autofill field type as a view ID (for testing). | 322 // Using autofill field type as a view ID (for testing). |
| 264 text_field->set_id(static_cast<int>(field.type)); | 323 text_field->set_id(static_cast<int>(field.type)); |
| 265 text_fields_.insert(std::make_pair(text_field, field)); | 324 text_fields_.insert(std::make_pair(text_field, field)); |
| 266 | 325 |
| 267 // TODO(crbug.com/718582): Make the initial focus the first incomplete/empty | 326 // TODO(crbug.com/718582): Make the initial focus the first incomplete/empty |
| 268 // field. | 327 // field. |
| 269 if (!first_field_view_) | 328 if (!first_field_view_) |
| 270 first_field_view_ = text_field; | 329 first_field_view_ = text_field; |
| 271 | 330 |
| 272 // |text_field| will now be owned by |row|. | 331 // |text_field| will now be owned by |row|. |
| 273 layout->AddView(text_field, 1, 1, views::GridLayout::FILL, | 332 layout->AddView(text_field, 1, 1, views::GridLayout::FILL, |
| 274 views::GridLayout::FILL, 0, kInputFieldHeight); | 333 views::GridLayout::FILL, 0, kInputFieldHeight); |
| 275 } else if (field.control_type == EditorField::ControlType::COMBOBOX) { | 334 } else if (field.control_type == EditorField::ControlType::COMBOBOX) { |
| 276 ValidatingCombobox* combobox = new ValidatingCombobox( | 335 ValidatingCombobox* combobox = new ValidatingCombobox( |
| 277 GetComboboxModelForType(field.type), CreateValidationDelegate(field)); | 336 GetComboboxModelForType(field.type), CreateValidationDelegate(field)); |
| 278 combobox->SelectValue(GetInitialValueForType(field.type)); | 337 base::string16 initial_value = GetInitialValueForType(field.type); |
| 279 // Using autofill field type as a view ID (for testing). | 338 if (!initial_value.empty()) |
| 339 combobox->SelectValue(initial_value); | |
| 340 // Using autofill field type as a view ID. | |
| 280 combobox->set_id(static_cast<int>(field.type)); | 341 combobox->set_id(static_cast<int>(field.type)); |
| 281 combobox->set_listener(this); | 342 combobox->set_listener(this); |
| 282 comboboxes_.insert(std::make_pair(combobox, field)); | 343 comboboxes_.insert(std::make_pair(combobox, field)); |
| 283 | 344 |
| 284 if (!first_field_view_) | 345 if (!first_field_view_) |
| 285 first_field_view_ = combobox; | 346 first_field_view_ = combobox; |
| 286 | 347 |
| 287 // |combobox| will now be owned by |row|. | 348 // |combobox| will now be owned by |row|. |
| 288 layout->AddView(combobox, 1, 1, views::GridLayout::FILL, | 349 layout->AddView(combobox, 1, 1, views::GridLayout::FILL, |
| 289 views::GridLayout::FILL, 0, kInputFieldHeight); | 350 views::GridLayout::FILL, 0, kInputFieldHeight); |
| 290 } else { | 351 } else { |
| 291 // Custom field view will now be owned by |row|. And it must be valid since | 352 // Custom field view will now be owned by |row|. And it must be valid since |
| 292 // the derived class specified a custom view for this field. | 353 // the derived class specified a custom view for this field. |
| 293 layout->AddView(CreateCustomFieldView(field.type).release()); | 354 std::unique_ptr<views::View> field_view = CreateCustomFieldView(field.type); |
| 355 DCHECK(field_view); | |
| 356 layout->AddView(field_view.release()); | |
| 294 } | 357 } |
| 295 | 358 |
| 296 layout->StartRow(0, 0); | 359 // If an extra view needs to go alongside the input field view, add it. Else, |
| 360 // skip that column. | |
| 361 std::unique_ptr<views::View> extra_view = CreateExtraViewForField(field.type); | |
| 362 if (extra_view) { | |
| 363 layout->AddView(extra_view.release()); | |
| 364 } else { | |
| 365 layout->SkipColumns(1); | |
|
anthonyvd
2017/05/11 00:32:14
nit: I'm not sure this skip is required since this
Mathieu
2017/05/11 01:16:24
Done.
| |
| 366 } | |
| 367 | |
| 368 layout->StartRow(0, column_set); | |
| 297 layout->SkipColumns(1); | 369 layout->SkipColumns(1); |
| 298 std::unique_ptr<views::View> error_label_view = | 370 std::unique_ptr<views::View> error_label_view = |
| 299 base::MakeUnique<views::View>(); | 371 base::MakeUnique<views::View>(); |
| 300 error_label_view->SetLayoutManager(new views::FillLayout); | 372 error_label_view->SetLayoutManager(new views::FillLayout); |
| 301 error_labels_[field] = error_label_view.get(); | 373 error_labels_[field] = error_label_view.get(); |
| 302 layout->AddView(error_label_view.release()); | 374 layout->AddView(error_label_view.release()); |
| 303 | 375 |
| 304 // Bottom padding for the row. | 376 // Bottom padding for the row. |
| 305 layout->AddPaddingRow(0, kInputRowSpacing); | 377 layout->AddPaddingRow(0, kInputRowSpacing); |
| 306 } | 378 } |
| 307 | 379 |
| 380 int EditorViewController::ComputeWidestExtraViewWidth( | |
| 381 EditorField::LengthHint size) { | |
| 382 int widest_column_width = 0; | |
| 383 | |
| 384 for (const auto& field : GetFieldDefinitions()) { | |
| 385 if (field.length_hint != size) | |
| 386 continue; | |
| 387 | |
| 388 std::unique_ptr<views::View> extra_view = | |
| 389 CreateExtraViewForField(field.type); | |
| 390 if (!extra_view) | |
| 391 continue; | |
| 392 widest_column_width = | |
| 393 std::max(extra_view->GetPreferredSize().width(), widest_column_width); | |
| 394 } | |
| 395 return widest_column_width; | |
| 396 } | |
| 397 | |
| 308 } // namespace payments | 398 } // namespace payments |
| OLD | NEW |