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/layout/box_layout.h" | 17 #include "ui/views/layout/box_layout.h" |
17 #include "ui/views/layout/fill_layout.h" | 18 #include "ui/views/layout/fill_layout.h" |
18 #include "ui/views/layout/grid_layout.h" | 19 #include "ui/views/layout/grid_layout.h" |
19 | 20 |
20 namespace payments { | 21 namespace payments { |
21 | 22 |
| 23 namespace { |
| 24 |
| 25 // 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 |
| 27 // way, focus doesn't leave the topmost sheet on the view stack to go on views |
| 28 // that happen to be underneath. |
| 29 // This class also overrides RequestFocus() to allow consumers to specify which |
| 30 // 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 |
| 32 // this SheetView's RequestFocus() is called. |
| 33 class SheetView : public views::View, public views::FocusTraversable { |
| 34 public: |
| 35 SheetView() |
| 36 : first_focusable_(nullptr), |
| 37 focus_search_(base::MakeUnique<views::FocusSearch>(this, true, false)) { |
| 38 } |
| 39 |
| 40 // 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. |
| 42 void SetFirstFocusableView(views::View* view) { first_focusable_ = view; } |
| 43 |
| 44 private: |
| 45 // views::FocusTraversable: |
| 46 views::FocusSearch* GetFocusSearch() override { return focus_search_.get(); } |
| 47 |
| 48 views::FocusTraversable* GetFocusTraversableParent() override { |
| 49 return parent()->GetFocusTraversable(); |
| 50 } |
| 51 |
| 52 views::View* GetFocusTraversableParentView() override { return this; } |
| 53 |
| 54 // views::View: |
| 55 views::FocusTraversable* GetPaneFocusTraversable() override { return this; } |
| 56 |
| 57 void RequestFocus() override { |
| 58 views::View* first_focusable = first_focusable_; |
| 59 |
| 60 if (!first_focusable) { |
| 61 views::FocusTraversable* dummy_focus_traversable; |
| 62 views::View* dummy_focus_traversable_view; |
| 63 first_focusable = focus_search_->FindNextFocusableView( |
| 64 nullptr, false, views::FocusSearch::DOWN, false, |
| 65 &dummy_focus_traversable, &dummy_focus_traversable_view); |
| 66 } |
| 67 |
| 68 if (first_focusable) |
| 69 first_focusable->RequestFocus(); |
| 70 } |
| 71 |
| 72 views::View* first_focusable_; |
| 73 std::unique_ptr<views::FocusSearch> focus_search_; |
| 74 |
| 75 DISALLOW_COPY_AND_ASSIGN(SheetView); |
| 76 }; |
| 77 |
| 78 } // namespace |
| 79 |
22 PaymentRequestSheetController::PaymentRequestSheetController( | 80 PaymentRequestSheetController::PaymentRequestSheetController( |
23 PaymentRequestSpec* spec, | 81 PaymentRequestSpec* spec, |
24 PaymentRequestState* state, | 82 PaymentRequestState* state, |
25 PaymentRequestDialogView* dialog) | 83 PaymentRequestDialogView* dialog) |
26 : spec_(spec), state_(state), dialog_(dialog) {} | 84 : spec_(spec), state_(state), dialog_(dialog) {} |
27 | 85 |
28 PaymentRequestSheetController::~PaymentRequestSheetController() {} | 86 PaymentRequestSheetController::~PaymentRequestSheetController() {} |
29 | 87 |
30 std::unique_ptr<views::View> PaymentRequestSheetController::CreateView() { | 88 std::unique_ptr<views::View> PaymentRequestSheetController::CreateView() { |
31 std::unique_ptr<views::View> view = CreatePaymentView(); | 89 std::unique_ptr<views::View> view = CreatePaymentView(); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 dialog()->Pay(); | 132 dialog()->Pay(); |
75 break; | 133 break; |
76 case PaymentRequestCommonTags::PAYMENT_REQUEST_COMMON_TAG_MAX: | 134 case PaymentRequestCommonTags::PAYMENT_REQUEST_COMMON_TAG_MAX: |
77 NOTREACHED(); | 135 NOTREACHED(); |
78 break; | 136 break; |
79 } | 137 } |
80 } | 138 } |
81 | 139 |
82 std::unique_ptr<views::View> | 140 std::unique_ptr<views::View> |
83 PaymentRequestSheetController::CreatePaymentView() { | 141 PaymentRequestSheetController::CreatePaymentView() { |
84 std::unique_ptr<views::View> view = base::MakeUnique<views::View>(); | 142 std::unique_ptr<SheetView> view = base::MakeUnique<SheetView>(); |
85 view->set_background(views::Background::CreateSolidBackground(SK_ColorWHITE)); | 143 view->set_background(views::Background::CreateSolidBackground(SK_ColorWHITE)); |
86 | 144 |
87 // Paint the sheets to layers, otherwise the MD buttons (which do paint to a | 145 // Paint the sheets to layers, otherwise the MD buttons (which do paint to a |
88 // layer) won't do proper clipping. | 146 // layer) won't do proper clipping. |
89 view->SetPaintToLayer(); | 147 view->SetPaintToLayer(); |
90 | 148 |
91 views::GridLayout* layout = new views::GridLayout(view.get()); | 149 views::GridLayout* layout = new views::GridLayout(view.get()); |
92 view->SetLayoutManager(layout); | 150 view->SetLayoutManager(layout); |
93 | 151 |
94 // Note: each view is responsible for its own padding (insets). | 152 // Note: each view is responsible for its own padding (insets). |
(...skipping 28 matching lines...) Expand all Loading... |
123 scroll_ = base::MakeUnique<views::ScrollView>(); | 181 scroll_ = base::MakeUnique<views::ScrollView>(); |
124 scroll_->set_owned_by_client(); | 182 scroll_->set_owned_by_client(); |
125 scroll_->EnableViewPortLayer(); | 183 scroll_->EnableViewPortLayer(); |
126 scroll_->set_hide_horizontal_scrollbar(true); | 184 scroll_->set_hide_horizontal_scrollbar(true); |
127 scroll_->SetContents(pane_); | 185 scroll_->SetContents(pane_); |
128 layout->AddView(scroll_.get()); | 186 layout->AddView(scroll_.get()); |
129 | 187 |
130 layout->StartRow(0, 0); | 188 layout->StartRow(0, 0); |
131 layout->AddView(CreateFooterView().release()); | 189 layout->AddView(CreateFooterView().release()); |
132 | 190 |
| 191 view->SetFirstFocusableView(GetFirstFocusedView()); |
| 192 |
133 return view; | 193 return view; |
134 } | 194 } |
135 | 195 |
136 std::unique_ptr<views::View> PaymentRequestSheetController::CreateFooterView() { | 196 std::unique_ptr<views::View> PaymentRequestSheetController::CreateFooterView() { |
137 std::unique_ptr<views::View> container = base::MakeUnique<views::View>(); | 197 std::unique_ptr<views::View> container = base::MakeUnique<views::View>(); |
138 | 198 |
139 views::GridLayout* layout = new views::GridLayout(container.get()); | 199 views::GridLayout* layout = new views::GridLayout(container.get()); |
140 container->SetLayoutManager(layout); | 200 container->SetLayoutManager(layout); |
141 | 201 |
142 views::ColumnSet* columns = layout->AddColumnSet(0); | 202 views::ColumnSet* columns = layout->AddColumnSet(0); |
(...skipping 17 matching lines...) Expand all Loading... |
160 layout->AddView(extra_view.release()); | 220 layout->AddView(extra_view.release()); |
161 else | 221 else |
162 layout->SkipColumns(1); | 222 layout->SkipColumns(1); |
163 | 223 |
164 std::unique_ptr<views::View> trailing_buttons_container = | 224 std::unique_ptr<views::View> trailing_buttons_container = |
165 base::MakeUnique<views::View>(); | 225 base::MakeUnique<views::View>(); |
166 | 226 |
167 trailing_buttons_container->SetLayoutManager(new views::BoxLayout( | 227 trailing_buttons_container->SetLayoutManager(new views::BoxLayout( |
168 views::BoxLayout::kHorizontal, 0, 0, kPaymentRequestButtonSpacing)); | 228 views::BoxLayout::kHorizontal, 0, 0, kPaymentRequestButtonSpacing)); |
169 | 229 |
170 std::unique_ptr<views::Button> primary_button = CreatePrimaryButton(); | 230 primary_button_ = CreatePrimaryButton(); |
171 if (primary_button) | 231 if (primary_button_) { |
172 trailing_buttons_container->AddChildView(primary_button.release()); | 232 primary_button_->set_owned_by_client(); |
| 233 trailing_buttons_container->AddChildView(primary_button_.get()); |
| 234 } |
173 | 235 |
174 views::LabelButton* button = views::MdTextButton::CreateSecondaryUiButton( | 236 secondary_button_ = std::unique_ptr<views::Button>( |
175 this, GetSecondaryButtonLabel()); | 237 views::MdTextButton::CreateSecondaryUiButton(this, |
176 button->set_tag(static_cast<int>(PaymentRequestCommonTags::CLOSE_BUTTON_TAG)); | 238 GetSecondaryButtonLabel())); |
177 button->set_id(static_cast<int>(DialogViewID::CANCEL_BUTTON)); | 239 secondary_button_->set_owned_by_client(); |
178 trailing_buttons_container->AddChildView(button); | 240 secondary_button_->set_tag( |
| 241 static_cast<int>(PaymentRequestCommonTags::CLOSE_BUTTON_TAG)); |
| 242 secondary_button_->set_id(static_cast<int>(DialogViewID::CANCEL_BUTTON)); |
| 243 trailing_buttons_container->AddChildView(secondary_button_.get()); |
179 | 244 |
180 layout->AddView(trailing_buttons_container.release()); | 245 layout->AddView(trailing_buttons_container.release()); |
181 | 246 |
182 return container; | 247 return container; |
183 } | 248 } |
184 | 249 |
| 250 views::View* PaymentRequestSheetController::GetFirstFocusedView() { |
| 251 if (primary_button_ && primary_button_->enabled()) |
| 252 return primary_button_.get(); |
| 253 |
| 254 DCHECK(secondary_button_); |
| 255 |
| 256 return secondary_button_.get(); |
| 257 } |
| 258 |
185 } // namespace payments | 259 } // namespace payments |
OLD | NEW |