OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/ui/views/payments/view_stack.h" | |
6 | |
7 #include "chrome/browser/ui/views/payments/view_stack_state.h" | |
8 #include "ui/views/layout/fill_layout.h" | |
9 | |
10 // Observes the Slide Out state animation and removes the view when it's done | |
11 // being animated, then deletes itself. This takes ownership of the state so | |
12 // it's garanteed to be properly disposed of when the animation is over. | |
13 class SlideOutObserver : public views::BoundsAnimatorObserver { | |
sky
2016/12/12 01:54:32
Move to anonymous namespace?
anthonyvd
2016/12/12 17:01:56
Done.
| |
14 public: | |
15 explicit SlideOutObserver(std::unique_ptr<ViewStackState> state_animating_out) | |
16 : state_animating_out_(std::move(state_animating_out)) {} | |
17 | |
18 views::View* GetAnimatedView() { | |
19 return state_animating_out_->GetView(); | |
20 } | |
21 | |
22 private: | |
23 // views::BoundsAnimatorObserver: | |
24 void OnBoundsAnimatorProgressed(views::BoundsAnimator* animator) override {} | |
25 | |
26 void OnBoundsAnimatorDone(views::BoundsAnimator* animator) override { | |
27 animator->RemoveObserver(this); | |
28 delete this; | |
29 } | |
30 | |
31 std::unique_ptr<ViewStackState> state_animating_out_; | |
32 | |
33 DISALLOW_COPY_AND_ASSIGN(SlideOutObserver); | |
34 }; | |
35 | |
36 ViewStack::ViewStack(std::unique_ptr<ViewStackState> initial_state) | |
37 : slide_in_animator_(new views::BoundsAnimator(this)), | |
38 slide_out_animator_(new views::BoundsAnimator(this)), | |
39 can_process_events_within_subtree_(true) { | |
40 SetLayoutManager(new views::FillLayout()); | |
41 | |
42 state_stack_.push(std::move(initial_state)); | |
43 AddChildView(state_stack_.top()->GetView()); | |
44 | |
45 slide_in_animator_->AddObserver(this); | |
46 slide_out_animator_->AddObserver(this); | |
47 } | |
48 | |
49 ViewStack::~ViewStack() { | |
50 // Cancel animations to make sure their observer's OnBoundsAnimatorDone is | |
51 // called. | |
52 slide_in_animator_->Cancel(); | |
53 slide_out_animator_->Cancel(); | |
54 } | |
55 | |
56 void ViewStack::PushState(std::unique_ptr<ViewStackState> state) { | |
57 can_process_events_within_subtree_ = false; | |
58 | |
59 // First add the new view out of bounds since it'll slide in from right to | |
60 // left. | |
61 state->GetView()->SetBounds(width(), 0, width(), height()); | |
sky
2016/12/12 01:54:32
You should call Layout() on the view after changin
anthonyvd
2016/12/12 17:01:56
Done.
| |
62 | |
63 AddChildView(state->GetView()); | |
64 // Animate the new view to be right on top of this one. | |
65 gfx::Rect destination = bounds(); | |
66 destination.set_origin(gfx::Point(0, 0)); | |
67 slide_in_animator_->AnimateViewTo(state->GetView(), destination); | |
68 | |
69 // Add the new state to the stack so it can be popped later when navigating | |
70 // back to the previous screen. | |
71 state_stack_.push(std::move(state)); | |
72 } | |
73 | |
74 void ViewStack::PopState() { | |
75 can_process_events_within_subtree_ = false; | |
76 | |
77 gfx::Rect destination = bounds(); | |
78 destination.set_origin(gfx::Point(width(), 0)); | |
79 | |
80 // This deletes itself. | |
81 SlideOutObserver* observer = | |
82 new SlideOutObserver(std::move(state_stack_.top())); | |
83 slide_out_animator_->AddObserver(observer); | |
84 | |
85 state_stack_.pop(); | |
86 DCHECK(!state_stack_.empty()) << "State stack should never be empty"; | |
87 | |
88 slide_out_animator_->AnimateViewTo(observer->GetAnimatedView(), destination); | |
89 } | |
90 | |
91 bool ViewStack::CanProcessEventsWithinSubtree() const { | |
92 return can_process_events_within_subtree_; | |
93 } | |
94 | |
95 void ViewStack::OnBoundsAnimatorDone( | |
96 views::BoundsAnimator* animator) { | |
97 can_process_events_within_subtree_ = true; | |
98 } | |
OLD | NEW |