OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "base/strings/utf_string_conversions.h" | 5 #include "base/strings/utf_string_conversions.h" |
6 #include "chrome/browser/payments/ui/payment_request_dialog.h" | 6 #include "chrome/browser/payments/ui/payment_request_dialog.h" |
7 #include "content/public/browser/browser_thread.h" | 7 #include "content/public/browser/browser_thread.h" |
| 8 #include "ui/views/animation/bounds_animator_observer.h" |
8 #include "ui/views/layout/fill_layout.h" | 9 #include "ui/views/layout/fill_layout.h" |
9 | 10 |
10 namespace payments { | 11 namespace payments { |
11 | 12 |
| 13 // Observes the Slide Out state animation and removes the view when it's done |
| 14 // being animated, then deletes itself. This takes ownership of the state so |
| 15 // it's garanteed to be properly disposed of when the animation is over. |
| 16 class SlideOutObserver : public views::BoundsAnimatorObserver { |
| 17 public: |
| 18 SlideOutObserver(std::unique_ptr<PaymentDialogState> state_animating_out, |
| 19 views::View* parent_view) |
| 20 : state_animating_out_(std::move(state_animating_out)), |
| 21 parent_view_(parent_view) {} |
| 22 |
| 23 views::View* GetAnimatedView() { |
| 24 return state_animating_out_->GetView(); |
| 25 } |
| 26 |
| 27 private: |
| 28 // views::BoundsAnimatorObserver: |
| 29 void OnBoundsAnimatorProgressed(views::BoundsAnimator* animator) override {} |
| 30 |
| 31 void OnBoundsAnimatorDone(views::BoundsAnimator* animator) override { |
| 32 animator->RemoveObserver(this); |
| 33 parent_view_->RemoveChildView(state_animating_out_->GetView()); |
| 34 delete this; |
| 35 } |
| 36 |
| 37 std::unique_ptr<PaymentDialogState> state_animating_out_; |
| 38 views::View* parent_view_; |
| 39 }; |
| 40 |
12 PaymentRequestDialog::PaymentRequestDialog( | 41 PaymentRequestDialog::PaymentRequestDialog( |
13 payments::mojom::PaymentRequestClientPtr client) | 42 payments::mojom::PaymentRequestClientPtr client) |
14 : client_(std::move(client)), | 43 : client_(std::move(client)), |
15 label_(new views::Label(base::ASCIIToUTF16("Payments dialog"))) { | 44 slide_in_animator_(new views::BoundsAnimator(this)), |
| 45 slide_out_animator_(new views::BoundsAnimator(this)) { |
16 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 46 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
17 SetLayoutManager(new views::FillLayout()); | 47 SetLayoutManager(new views::FillLayout()); |
18 AddChildView(label_.get()); | 48 |
| 49 std::unique_ptr<PaymentSheetState> initial_state = |
| 50 base::MakeUnique<PaymentSheetState>(); |
| 51 initial_state->AddObserver(this); |
| 52 state_stack_.push(std::move(initial_state)); |
| 53 |
| 54 AddChildView(state_stack_.top()->GetView()); |
19 } | 55 } |
20 | 56 |
21 PaymentRequestDialog::~PaymentRequestDialog() {} | 57 PaymentRequestDialog::~PaymentRequestDialog() { |
| 58 // Cancel animations to make sure their observer's OnBoundsAnimatorDone is |
| 59 // called. |
| 60 slide_in_animator_->Cancel(); |
| 61 slide_out_animator_->Cancel(); |
| 62 } |
| 63 |
| 64 void PaymentRequestDialog::PushState( |
| 65 std::unique_ptr<PaymentDialogState> state) { |
| 66 state_stack_.top()->SetInteractable(false); |
| 67 |
| 68 // First add the new view out of bounds since it'll slide in from right to |
| 69 // left. |
| 70 state->GetView()->SetPosition(gfx::Point(x() + width(), y())); |
| 71 |
| 72 AddChildView(state->GetView()); |
| 73 // Animate the new view to be right on top of this one. |
| 74 slide_in_animator_->AnimateViewTo(state->GetView(), bounds()); |
| 75 |
| 76 // Add the new state to the stack so it can be popped later when navigating |
| 77 // back to the previous screen. |
| 78 state_stack_.push(std::move(state)); |
| 79 state_stack_.top()->SetInteractable(true); |
| 80 } |
| 81 |
| 82 void PaymentRequestDialog::PopState() { |
| 83 state_stack_.top()->SetInteractable(false); |
| 84 |
| 85 gfx::Rect destination = bounds(); |
| 86 destination.Offset(width(), 0); |
| 87 |
| 88 // This deletes itself. |
| 89 SlideOutObserver* observer = |
| 90 new SlideOutObserver(std::move(state_stack_.top()), this); |
| 91 slide_out_animator_->AddObserver(observer); |
| 92 |
| 93 state_stack_.pop(); |
| 94 DCHECK(!state_stack_.empty()) << "State stack should never be empty"; |
| 95 |
| 96 slide_out_animator_->AnimateViewTo(observer->GetAnimatedView(), destination); |
| 97 state_stack_.top()->SetInteractable(true); |
| 98 } |
22 | 99 |
23 ui::ModalType PaymentRequestDialog::GetModalType() const { | 100 ui::ModalType PaymentRequestDialog::GetModalType() const { |
24 return ui::MODAL_TYPE_CHILD; | 101 return ui::MODAL_TYPE_CHILD; |
25 } | 102 } |
26 | 103 |
27 gfx::Size PaymentRequestDialog::GetPreferredSize() const { | 104 gfx::Size PaymentRequestDialog::GetPreferredSize() const { |
28 gfx::Size ps = label_->GetPreferredSize(); | 105 return gfx::Size(300, 300); |
29 ps.Enlarge(200, 200); | |
30 return ps; | |
31 } | 106 } |
32 | 107 |
33 bool PaymentRequestDialog::Cancel() { | 108 bool PaymentRequestDialog::Cancel() { |
34 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 109 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
35 client_->OnError(payments::mojom::PaymentErrorReason::USER_CANCEL); | 110 client_->OnError(payments::mojom::PaymentErrorReason::USER_CANCEL); |
36 return true; | 111 return true; |
37 } | 112 } |
38 | 113 |
| 114 void PaymentRequestDialog::OnOrderSummaryClicked() { |
| 115 std::unique_ptr<OrderSummaryState> order_summary = |
| 116 base::MakeUnique<OrderSummaryState>(); |
| 117 order_summary->AddObserver(this); |
| 118 PushState(std::move(order_summary)); |
| 119 } |
| 120 |
| 121 void PaymentRequestDialog::OnBackClicked() { |
| 122 PopState(); |
| 123 } |
| 124 |
39 } // namespace payments | 125 } // namespace payments |
OLD | NEW |