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

Unified 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, 8 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/views/payments/payment_request_sheet_controller.cc
diff --git a/chrome/browser/ui/views/payments/payment_request_sheet_controller.cc b/chrome/browser/ui/views/payments/payment_request_sheet_controller.cc
index 19de912557a8c92d814de67b6f3ac58e3dcdff35..73e1aba66660cc632960531556b8f3fa53a57da0 100644
--- a/chrome/browser/ui/views/payments/payment_request_sheet_controller.cc
+++ b/chrome/browser/ui/views/payments/payment_request_sheet_controller.cc
@@ -13,12 +13,70 @@
#include "ui/views/background.h"
#include "ui/views/controls/button/md_text_button.h"
#include "ui/views/controls/scroll_view.h"
+#include "ui/views/focus/focus_search.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/layout/grid_layout.h"
namespace payments {
+namespace {
+
+// This class is the actual sheet that gets pushed on the view_stack_. It
+// implements views::FocusTraversable to trap focus within its hierarchy. This
+// way, focus doesn't leave the topmost sheet on the view stack to go on views
+// that happen to be underneath.
+// This class also overrides RequestFocus() to allow consumers to specify which
+// view should be focused first (through SetFirstFocusableView). If no initial
+// view is specified, the first view added to the hierarchy will get focus when
+// this SheetView's RequestFocus() is called.
+class SheetView : public views::View, public views::FocusTraversable {
+ public:
+ SheetView()
+ : first_focusable_(nullptr),
+ focus_search_(base::MakeUnique<views::FocusSearch>(this, true, false)) {
+ }
+
+ // Sets |view| as the first focusable view in this pane. If it's nullptr, the
+ // fallback is to use focus_search_ to find the first focusable view.
+ void SetFirstFocusableView(views::View* view) { first_focusable_ = view; }
+
+ private:
+ // views::FocusTraversable:
+ views::FocusSearch* GetFocusSearch() override { return focus_search_.get(); }
+
+ views::FocusTraversable* GetFocusTraversableParent() override {
+ return parent()->GetFocusTraversable();
+ }
+
+ views::View* GetFocusTraversableParentView() override { return this; }
+
+ // views::View:
+ views::FocusTraversable* GetPaneFocusTraversable() override { return this; }
+
+ void RequestFocus() override {
+ views::View* first_focusable = first_focusable_;
+
+ if (!first_focusable) {
+ views::FocusTraversable* dummy_focus_traversable;
+ views::View* dummy_focus_traversable_view;
+ first_focusable = focus_search_->FindNextFocusableView(
+ nullptr, false, views::FocusSearch::DOWN, false,
+ &dummy_focus_traversable, &dummy_focus_traversable_view);
+ }
+
+ if (first_focusable)
+ first_focusable->RequestFocus();
+ }
+
+ views::View* first_focusable_;
+ std::unique_ptr<views::FocusSearch> focus_search_;
+
+ DISALLOW_COPY_AND_ASSIGN(SheetView);
+};
+
+} // namespace
+
PaymentRequestSheetController::PaymentRequestSheetController(
PaymentRequestSpec* spec,
PaymentRequestState* state,
@@ -81,7 +139,7 @@ void PaymentRequestSheetController::ButtonPressed(
std::unique_ptr<views::View>
PaymentRequestSheetController::CreatePaymentView() {
- std::unique_ptr<views::View> view = base::MakeUnique<views::View>();
+ std::unique_ptr<SheetView> view = base::MakeUnique<SheetView>();
view->set_background(views::Background::CreateSolidBackground(SK_ColorWHITE));
// Paint the sheets to layers, otherwise the MD buttons (which do paint to a
@@ -130,6 +188,8 @@ PaymentRequestSheetController::CreatePaymentView() {
layout->StartRow(0, 0);
layout->AddView(CreateFooterView().release());
+ view->SetFirstFocusableView(GetFirstFocusedView());
+
return view;
}
@@ -167,19 +227,33 @@ std::unique_ptr<views::View> PaymentRequestSheetController::CreateFooterView() {
trailing_buttons_container->SetLayoutManager(new views::BoxLayout(
views::BoxLayout::kHorizontal, 0, 0, kPaymentRequestButtonSpacing));
- std::unique_ptr<views::Button> primary_button = CreatePrimaryButton();
- if (primary_button)
- trailing_buttons_container->AddChildView(primary_button.release());
+ primary_button_ = CreatePrimaryButton();
+ if (primary_button_) {
+ primary_button_->set_owned_by_client();
+ trailing_buttons_container->AddChildView(primary_button_.get());
+ }
- views::LabelButton* button = views::MdTextButton::CreateSecondaryUiButton(
- this, GetSecondaryButtonLabel());
- button->set_tag(static_cast<int>(PaymentRequestCommonTags::CLOSE_BUTTON_TAG));
- button->set_id(static_cast<int>(DialogViewID::CANCEL_BUTTON));
- trailing_buttons_container->AddChildView(button);
+ secondary_button_ = std::unique_ptr<views::Button>(
+ views::MdTextButton::CreateSecondaryUiButton(this,
+ GetSecondaryButtonLabel()));
+ secondary_button_->set_owned_by_client();
+ secondary_button_->set_tag(
+ static_cast<int>(PaymentRequestCommonTags::CLOSE_BUTTON_TAG));
+ secondary_button_->set_id(static_cast<int>(DialogViewID::CANCEL_BUTTON));
+ trailing_buttons_container->AddChildView(secondary_button_.get());
layout->AddView(trailing_buttons_container.release());
return container;
}
+views::View* PaymentRequestSheetController::GetFirstFocusedView() {
+ if (primary_button_ && primary_button_->enabled())
+ return primary_button_.get();
+
+ DCHECK(secondary_button_);
+
+ return secondary_button_.get();
+}
+
} // namespace payments

Powered by Google App Engine
This is Rietveld 408576698