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/payment_request_sheet_controller.h" | 5 #include "chrome/browser/ui/views/payments/payment_request_sheet_controller.h" |
| 6 | 6 |
| 7 #include "chrome/browser/ui/views/payments/payment_request_dialog_view.h" | 7 #include "chrome/browser/ui/views/payments/payment_request_dialog_view.h" |
| 8 #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h" | 8 #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h" |
| 9 #include "chrome/browser/ui/views/payments/payment_request_views_util.h" | 9 #include "chrome/browser/ui/views/payments/payment_request_views_util.h" |
| 10 #include "components/payments/content/payment_request.h" | 10 #include "components/payments/content/payment_request.h" |
| 11 #include "components/strings/grit/components_strings.h" | 11 #include "components/strings/grit/components_strings.h" |
| 12 #include "ui/base/l10n/l10n_util.h" | 12 #include "ui/base/l10n/l10n_util.h" |
| 13 #include "ui/views/background.h" | 13 #include "ui/views/background.h" |
| 14 #include "ui/views/controls/button/md_text_button.h" | 14 #include "ui/views/controls/button/md_text_button.h" |
| 15 #include "ui/views/controls/scroll_view.h" | 15 #include "ui/views/controls/scroll_view.h" |
| 16 #include "ui/views/focus/focus_search.h" | 16 #include "ui/views/focus/focus_search.h" |
| 17 #include "ui/views/layout/box_layout.h" | 17 #include "ui/views/layout/box_layout.h" |
| 18 #include "ui/views/layout/fill_layout.h" | 18 #include "ui/views/layout/fill_layout.h" |
| 19 #include "ui/views/layout/grid_layout.h" | 19 #include "ui/views/layout/grid_layout.h" |
| 20 | 20 |
| 21 namespace payments { | 21 namespace payments { |
| 22 | 22 |
| 23 namespace { | 23 namespace { |
| 24 | 24 |
| 25 // This event is used to pass to ButtonPressed when its event parameter doesn't | |
| 26 // matter, only the sender. | |
| 27 class DummyEvent : public ui::Event { | |
| 28 public: | |
| 29 DummyEvent() : ui::Event(ui::ET_UNKNOWN, base::TimeTicks(), 0) {} | |
| 30 }; | |
| 31 | |
| 25 // This class is the actual sheet that gets pushed on the view_stack_. It | 32 // This class is the actual sheet that gets pushed on the view_stack_. It |
| 26 // implements views::FocusTraversable to trap focus within its hierarchy. This | 33 // implements views::FocusTraversable to trap focus within its hierarchy. This |
| 27 // way, focus doesn't leave the topmost sheet on the view stack to go on views | 34 // way, focus doesn't leave the topmost sheet on the view stack to go on views |
| 28 // that happen to be underneath. | 35 // that happen to be underneath. |
| 29 // This class also overrides RequestFocus() to allow consumers to specify which | 36 // This class also overrides RequestFocus() to allow consumers to specify which |
| 30 // view should be focused first (through SetFirstFocusableView). If no initial | 37 // view should be focused first (through SetFirstFocusableView). If no initial |
| 31 // view is specified, the first view added to the hierarchy will get focus when | 38 // view is specified, the first view added to the hierarchy will get focus when |
| 32 // this SheetView's RequestFocus() is called. | 39 // this SheetView's RequestFocus() is called. |
| 33 class SheetView : public views::View, public views::FocusTraversable { | 40 class SheetView : public views::View, public views::FocusTraversable { |
| 34 public: | 41 public: |
| 35 SheetView() | 42 explicit SheetView(const base::Callback<bool()>& confirm_accelerator_callback) |
| 36 : first_focusable_(nullptr), | 43 : first_focusable_(nullptr), |
| 37 focus_search_(base::MakeUnique<views::FocusSearch>(this, true, false)) { | 44 focus_search_(base::MakeUnique<views::FocusSearch>(this, true, false)), |
| 45 confirm_accelerator_(ui::Accelerator(ui::VKEY_RETURN, ui::EF_NONE)), | |
|
Mathieu
2017/05/04 17:12:43
nit: I would prefer |enter_key_accelerator|, becau
anthonyvd
2017/05/04 18:56:46
Done.
| |
| 46 confirm_accelerator_callback_(confirm_accelerator_callback) { | |
| 47 if (confirm_accelerator_callback_) | |
| 48 AddAccelerator(confirm_accelerator_); | |
| 38 } | 49 } |
| 39 | 50 |
| 40 // Sets |view| as the first focusable view in this pane. If it's nullptr, the | 51 // Sets |view| as the first focusable view in this pane. If it's nullptr, the |
| 41 // fallback is to use focus_search_ to find the first focusable view. | 52 // fallback is to use focus_search_ to find the first focusable view. |
| 42 void SetFirstFocusableView(views::View* view) { first_focusable_ = view; } | 53 void SetFirstFocusableView(views::View* view) { first_focusable_ = view; } |
| 43 | 54 |
| 44 private: | 55 private: |
| 45 // views::FocusTraversable: | 56 // views::FocusTraversable: |
| 46 views::FocusSearch* GetFocusSearch() override { return focus_search_.get(); } | 57 views::FocusSearch* GetFocusSearch() override { return focus_search_.get(); } |
| 47 | 58 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 62 views::View* dummy_focus_traversable_view; | 73 views::View* dummy_focus_traversable_view; |
| 63 first_focusable = focus_search_->FindNextFocusableView( | 74 first_focusable = focus_search_->FindNextFocusableView( |
| 64 nullptr, false, views::FocusSearch::DOWN, false, | 75 nullptr, false, views::FocusSearch::DOWN, false, |
| 65 &dummy_focus_traversable, &dummy_focus_traversable_view); | 76 &dummy_focus_traversable, &dummy_focus_traversable_view); |
| 66 } | 77 } |
| 67 | 78 |
| 68 if (first_focusable) | 79 if (first_focusable) |
| 69 first_focusable->RequestFocus(); | 80 first_focusable->RequestFocus(); |
| 70 } | 81 } |
| 71 | 82 |
| 83 bool AcceleratorPressed(const ui::Accelerator& accelerator) override { | |
| 84 if (accelerator == confirm_accelerator_ && confirm_accelerator_callback_) { | |
|
Mathieu
2017/05/04 17:12:43
no curlies?
anthonyvd
2017/05/04 18:56:46
Since enter_key_accelerator is longer, the conditi
| |
| 85 return confirm_accelerator_callback_.Run(); | |
| 86 } | |
| 87 return views::View::AcceleratorPressed(accelerator); | |
| 88 } | |
| 89 | |
| 72 views::View* first_focusable_; | 90 views::View* first_focusable_; |
| 73 std::unique_ptr<views::FocusSearch> focus_search_; | 91 std::unique_ptr<views::FocusSearch> focus_search_; |
| 92 ui::Accelerator confirm_accelerator_; | |
| 93 base::Callback<bool()> confirm_accelerator_callback_; | |
| 74 | 94 |
| 75 DISALLOW_COPY_AND_ASSIGN(SheetView); | 95 DISALLOW_COPY_AND_ASSIGN(SheetView); |
| 76 }; | 96 }; |
| 77 | 97 |
| 78 } // namespace | 98 } // namespace |
| 79 | 99 |
| 80 PaymentRequestSheetController::PaymentRequestSheetController( | 100 PaymentRequestSheetController::PaymentRequestSheetController( |
| 81 PaymentRequestSpec* spec, | 101 PaymentRequestSpec* spec, |
| 82 PaymentRequestState* state, | 102 PaymentRequestState* state, |
| 83 PaymentRequestDialogView* dialog) | 103 PaymentRequestDialogView* dialog) |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 132 dialog()->Pay(); | 152 dialog()->Pay(); |
| 133 break; | 153 break; |
| 134 case PaymentRequestCommonTags::PAYMENT_REQUEST_COMMON_TAG_MAX: | 154 case PaymentRequestCommonTags::PAYMENT_REQUEST_COMMON_TAG_MAX: |
| 135 NOTREACHED(); | 155 NOTREACHED(); |
| 136 break; | 156 break; |
| 137 } | 157 } |
| 138 } | 158 } |
| 139 | 159 |
| 140 std::unique_ptr<views::View> | 160 std::unique_ptr<views::View> |
| 141 PaymentRequestSheetController::CreatePaymentView() { | 161 PaymentRequestSheetController::CreatePaymentView() { |
| 142 std::unique_ptr<SheetView> view = base::MakeUnique<SheetView>(); | 162 // Create the footer now so that it's known if there's a primary button or not |
| 163 // before creating the sheet view. This way, it's possible to determine | |
| 164 // whether there's something to do when the user hits enter. | |
| 165 std::unique_ptr<views::View> footer = CreateFooterView(); | |
| 166 std::unique_ptr<SheetView> view = base::MakeUnique<SheetView>( | |
| 167 primary_button_ | |
| 168 ? base::Bind( | |
| 169 &PaymentRequestSheetController::PerformPrimaryButtonAction, | |
| 170 base::Unretained(this)) | |
| 171 : base::Callback<bool()>()); | |
| 143 view->set_background(views::Background::CreateSolidBackground(SK_ColorWHITE)); | 172 view->set_background(views::Background::CreateSolidBackground(SK_ColorWHITE)); |
| 144 | 173 |
| 145 // Paint the sheets to layers, otherwise the MD buttons (which do paint to a | 174 // Paint the sheets to layers, otherwise the MD buttons (which do paint to a |
| 146 // layer) won't do proper clipping. | 175 // layer) won't do proper clipping. |
| 147 view->SetPaintToLayer(); | 176 view->SetPaintToLayer(); |
| 148 | 177 |
| 149 views::GridLayout* layout = new views::GridLayout(view.get()); | 178 views::GridLayout* layout = new views::GridLayout(view.get()); |
| 150 view->SetLayoutManager(layout); | 179 view->SetLayoutManager(layout); |
| 151 | 180 |
| 152 // Note: each view is responsible for its own padding (insets). | 181 // Note: each view is responsible for its own padding (insets). |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 179 pane_->SizeToPreferredSize(); | 208 pane_->SizeToPreferredSize(); |
| 180 | 209 |
| 181 scroll_ = base::MakeUnique<views::ScrollView>(); | 210 scroll_ = base::MakeUnique<views::ScrollView>(); |
| 182 scroll_->set_owned_by_client(); | 211 scroll_->set_owned_by_client(); |
| 183 scroll_->EnableViewPortLayer(); | 212 scroll_->EnableViewPortLayer(); |
| 184 scroll_->set_hide_horizontal_scrollbar(true); | 213 scroll_->set_hide_horizontal_scrollbar(true); |
| 185 scroll_->SetContents(pane_); | 214 scroll_->SetContents(pane_); |
| 186 layout->AddView(scroll_.get()); | 215 layout->AddView(scroll_.get()); |
| 187 | 216 |
| 188 layout->StartRow(0, 0); | 217 layout->StartRow(0, 0); |
| 189 layout->AddView(CreateFooterView().release()); | 218 layout->AddView(footer.release()); |
| 190 | 219 |
| 191 view->SetFirstFocusableView(GetFirstFocusedView()); | 220 view->SetFirstFocusableView(GetFirstFocusedView()); |
| 192 | 221 |
| 193 return std::move(view); | 222 return std::move(view); |
| 194 } | 223 } |
| 195 | 224 |
| 196 std::unique_ptr<views::View> PaymentRequestSheetController::CreateFooterView() { | 225 std::unique_ptr<views::View> PaymentRequestSheetController::CreateFooterView() { |
| 197 std::unique_ptr<views::View> container = base::MakeUnique<views::View>(); | 226 std::unique_ptr<views::View> container = base::MakeUnique<views::View>(); |
| 198 | 227 |
| 199 views::GridLayout* layout = new views::GridLayout(container.get()); | 228 views::GridLayout* layout = new views::GridLayout(container.get()); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 249 | 278 |
| 250 views::View* PaymentRequestSheetController::GetFirstFocusedView() { | 279 views::View* PaymentRequestSheetController::GetFirstFocusedView() { |
| 251 if (primary_button_ && primary_button_->enabled()) | 280 if (primary_button_ && primary_button_->enabled()) |
| 252 return primary_button_.get(); | 281 return primary_button_.get(); |
| 253 | 282 |
| 254 DCHECK(secondary_button_); | 283 DCHECK(secondary_button_); |
| 255 | 284 |
| 256 return secondary_button_.get(); | 285 return secondary_button_.get(); |
| 257 } | 286 } |
| 258 | 287 |
| 288 bool PaymentRequestSheetController::PerformPrimaryButtonAction() { | |
| 289 if (primary_button_ && primary_button_->enabled()) { | |
| 290 ButtonPressed(primary_button_.get(), DummyEvent()); | |
|
Mathieu
2017/05/04 17:12:43
could we inline ui::Event(ui::ET_UNKNOWN, base::Ti
anthonyvd
2017/05/04 18:56:46
That constructor is protected.
| |
| 291 return true; | |
| 292 } | |
| 293 return false; | |
| 294 } | |
| 295 | |
| 259 } // namespace payments | 296 } // namespace payments |
| OLD | NEW |