Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(210)

Side by Side Diff: chrome/browser/ui/views/payments/payment_request_sheet_controller.cc

Issue 2853163002: [Web Payments] Implement proper focusing in Payment Request (Closed)
Patch Set: Address comments. Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698