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

Side by Side Diff: ui/gfx/compositor/layer_animator.cc

Issue 7972023: Implicit animations through Layer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: More tweaks Created 9 years, 2 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 | Annotate | Revision Log
« no previous file with comments | « ui/gfx/compositor/layer_animator.h ('k') | ui/gfx/compositor/layer_animator_delegate.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "ui/gfx/compositor/layer_animator.h" 5 #include "ui/gfx/compositor/layer_animator.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/stl_util.h" 8 #include "base/stl_util.h"
9 #include "ui/base/animation/animation_container.h" 9 #include "ui/base/animation/animation_container.h"
10 #include "ui/base/animation/multi_animation.h" 10 #include "ui/base/animation/animation.h"
11 #include "ui/base/animation/tween.h"
11 #include "ui/gfx/compositor/compositor.h" 12 #include "ui/gfx/compositor/compositor.h"
12 #include "ui/gfx/compositor/layer.h" 13 #include "ui/gfx/compositor/layer.h"
14 #include "ui/gfx/compositor/layer_animator_delegate.h"
13 #include "ui/gfx/transform.h" 15 #include "ui/gfx/transform.h"
14 #include "ui/gfx/rect.h" 16 #include "ui/gfx/rect.h"
15 17
16 namespace { 18 namespace {
17 19
18 void SetMatrixElement(SkMatrix44& matrix, int index, SkMScalar value) { 20 void SetMatrixElement(SkMatrix44& matrix, int index, SkMScalar value) {
19 int row = index / 4; 21 int row = index / 4;
20 int col = index % 4; 22 int col = index % 4;
21 matrix.set(row, col, value); 23 matrix.set(row, col, value);
22 } 24 }
23 25
24 SkMScalar GetMatrixElement(const SkMatrix44& matrix, int index) { 26 SkMScalar GetMatrixElement(const SkMatrix44& matrix, int index) {
25 int row = index / 4; 27 int row = index / 4;
26 int col = index % 4; 28 int col = index % 4;
27 return matrix.get(row, col); 29 return matrix.get(row, col);
28 } 30 }
29 31
30 } // anonymous namespace 32 } // anonymous namespace
31 33
32 namespace ui { 34 namespace ui {
33 35
34 LayerAnimator::LayerAnimator(Layer* layer) 36 LayerAnimator::LayerAnimator(Layer* layer)
35 : layer_(layer), 37 : layer_(layer),
36 duration_in_ms_(200), 38 got_initial_tick_(false) {
37 animation_type_(ui::Tween::EASE_IN) {
38 } 39 }
39 40
40 LayerAnimator::~LayerAnimator() { 41 LayerAnimator::~LayerAnimator() {
41 for (Elements::iterator i = elements_.begin(); i != elements_.end(); ++i)
42 delete i->second.animation;
43 elements_.clear();
44 } 42 }
45 43
46 void LayerAnimator::SetAnimationDurationAndType(int duration, 44 void LayerAnimator::SetAnimation(Animation* animation) {
47 ui::Tween::Type tween_type) { 45 animation_.reset(animation);
48 DCHECK_GT(duration, 0); 46 if (animation_.get()) {
49 duration_in_ms_ = duration; 47 static ui::AnimationContainer* container = NULL;
50 animation_type_ = tween_type; 48 if (!container) {
49 container = new AnimationContainer;
50 container->AddRef();
51 }
52 animation_->set_delegate(this);
53 animation_->SetContainer(container);
54 got_initial_tick_ = false;
55 }
51 } 56 }
52 57
53 void LayerAnimator::AnimateToPoint(const gfx::Point& target) { 58 void LayerAnimator::AnimateToPoint(const gfx::Point& target) {
54 StopAnimating(LOCATION); 59 StopAnimating(LOCATION);
55 const gfx::Rect& layer_bounds = layer_->bounds(); 60 const gfx::Rect& layer_bounds = layer_->bounds();
56 if (target == layer_bounds.origin()) 61 if (target == layer_bounds.origin())
57 return; // Already there. 62 return; // Already there.
58 63
59 Element& element = elements_[LOCATION]; 64 Params& element = elements_[LOCATION];
60 element.params.location.start_x = layer_bounds.origin().x(); 65 element.location.target_x = target.x();
61 element.params.location.start_y = layer_bounds.origin().y(); 66 element.location.target_y = target.y();
62 element.params.location.target_x = target.x(); 67 element.location.start_x = layer_bounds.origin().x();
63 element.params.location.target_y = target.y(); 68 element.location.start_y = layer_bounds.origin().y();
64 element.animation = CreateAndStartAnimation();
65 } 69 }
66 70
67 void LayerAnimator::AnimateTransform(const Transform& transform) { 71 void LayerAnimator::AnimateTransform(const Transform& transform) {
68 StopAnimating(TRANSFORM); 72 StopAnimating(TRANSFORM);
69 const Transform& layer_transform = layer_->transform(); 73 const Transform& layer_transform = layer_->transform();
70 if (transform == layer_transform) 74 if (transform == layer_transform)
71 return; // Already there. 75 return; // Already there.
72 76
73 Element& element = elements_[TRANSFORM]; 77 Params& element = elements_[TRANSFORM];
74 for (int i = 0; i < 16; ++i) { 78 for (int i = 0; i < 16; ++i) {
75 element.params.transform.start[i] = 79 element.transform.start[i] =
76 GetMatrixElement(layer_transform.matrix(), i); 80 GetMatrixElement(layer_transform.matrix(), i);
77 element.params.transform.target[i] = 81 element.transform.target[i] =
78 GetMatrixElement(transform.matrix(), i); 82 GetMatrixElement(transform.matrix(), i);
79 } 83 }
80 element.animation = CreateAndStartAnimation(); 84 }
85
86 void LayerAnimator::AnimateOpacity(float target_opacity) {
87 StopAnimating(OPACITY);
88 if (layer_->opacity() == target_opacity)
89 return;
90
91 Params& element = elements_[OPACITY];
92 element.opacity.start = layer_->opacity();
93 element.opacity.target = target_opacity;
94 }
95
96 gfx::Point LayerAnimator::GetTargetPoint() {
97 return IsAnimating(LOCATION) ?
98 gfx::Point(elements_[LOCATION].location.target_x,
99 elements_[LOCATION].location.target_y) :
100 layer_->bounds().origin();
101 }
102
103 float LayerAnimator::GetTargetOpacity() {
104 return IsAnimating(OPACITY) ?
105 elements_[OPACITY].opacity.target : layer_->opacity();
106 }
107
108 ui::Transform LayerAnimator::GetTargetTransform() {
109 if (IsAnimating(TRANSFORM)) {
110 Transform transform;
111 for (int i = 0; i < 16; ++i) {
112 SetMatrixElement(transform.matrix(), i,
113 elements_[TRANSFORM].transform.target[i]);
114 }
115 return transform;
116 }
117 return layer_->transform();
118 }
119
120 bool LayerAnimator::IsAnimating(AnimationProperty property) const {
121 return elements_.count(property) > 0;
122 }
123
124 bool LayerAnimator::IsRunning() const {
125 return animation_.get() && animation_->is_animating();
81 } 126 }
82 127
83 void LayerAnimator::AnimationProgressed(const ui::Animation* animation) { 128 void LayerAnimator::AnimationProgressed(const ui::Animation* animation) {
84 Elements::iterator e = GetElementByAnimation( 129 got_initial_tick_ = true;
85 static_cast<const ui::MultiAnimation*>(animation)); 130 for (Elements::const_iterator i = elements_.begin(); i != elements_.end();
86 DCHECK(e != elements_.end()); 131 ++i) {
87 switch (e->first) { 132 switch (i->first) {
88 case LOCATION: { 133 case LOCATION: {
89 const gfx::Rect& current_bounds(layer_->bounds()); 134 const gfx::Rect& current_bounds(layer_->bounds());
90 gfx::Rect new_bounds = e->second.animation->CurrentValueBetween( 135 gfx::Rect new_bounds = animation_->CurrentValueBetween(
91 gfx::Rect(gfx::Point(e->second.params.location.start_x, 136 gfx::Rect(gfx::Point(i->second.location.start_x,
92 e->second.params.location.start_y), 137 i->second.location.start_y),
93 current_bounds.size()), 138 current_bounds.size()),
94 gfx::Rect(gfx::Point(e->second.params.location.target_x, 139 gfx::Rect(gfx::Point(i->second.location.target_x,
95 e->second.params.location.target_y), 140 i->second.location.target_y),
96 current_bounds.size())); 141 current_bounds.size()));
97 layer_->SetBounds(new_bounds); 142 delegate()->SetBoundsFromAnimator(new_bounds);
98 break; 143 break;
144 }
145
146 case TRANSFORM: {
147 Transform transform;
148 for (int j = 0; j < 16; ++j) {
149 SkMScalar value = animation_->CurrentValueBetween(
150 i->second.transform.start[j],
151 i->second.transform.target[j]);
152 SetMatrixElement(transform.matrix(), j, value);
153 }
154 delegate()->SetTransformFromAnimator(transform);
155 break;
156 }
157
158 case OPACITY: {
159 delegate()->SetOpacityFromAnimator(animation_->CurrentValueBetween(
160 i->second.opacity.start, i->second.opacity.target));
161 break;
162 }
163
164 default:
165 NOTREACHED();
99 } 166 }
100
101 case TRANSFORM: {
102 Transform transform;
103 for (int i = 0; i < 16; ++i) {
104 SkMScalar value = e->second.animation->CurrentValueBetween(
105 e->second.params.transform.start[i],
106 e->second.params.transform.target[i]);
107 SetMatrixElement(transform.matrix(), i, value);
108 }
109 layer_->SetTransform(transform);
110 break;
111 }
112
113 default:
114 NOTREACHED();
115 } 167 }
116 layer_->GetCompositor()->SchedulePaint(); 168 layer_->GetCompositor()->SchedulePaint();
117 } 169 }
118 170
119 void LayerAnimator::AnimationEnded(const ui::Animation* animation) { 171 void LayerAnimator::AnimationEnded(const ui::Animation* animation) {
120 Elements::iterator e = GetElementByAnimation( 172 AnimationProgressed(animation);
121 static_cast<const ui::MultiAnimation*>(animation));
122 DCHECK(e != elements_.end());
123 switch (e->first) {
124 case LOCATION: {
125 gfx::Rect new_bounds(
126 gfx::Point(e->second.params.location.target_x,
127 e->second.params.location.target_y),
128 layer_->bounds().size());
129 layer_->SetBounds(new_bounds);
130 break;
131 }
132
133 case TRANSFORM: {
134 Transform transform;
135 for (int i = 0; i < 16; ++i) {
136 SetMatrixElement(transform.matrix(),
137 i,
138 e->second.params.transform.target[i]);
139 }
140 layer_->SetTransform(transform);
141 break;
142 }
143
144 default:
145 NOTREACHED();
146 }
147 StopAnimating(e->first);
148 // StopAnimating removes from the map, invalidating 'e'.
149 e = elements_.end();
150 layer_->GetCompositor()->SchedulePaint();
151 } 173 }
152 174
153 void LayerAnimator::StopAnimating(AnimationProperty property) { 175 void LayerAnimator::StopAnimating(AnimationProperty property) {
154 if (elements_.count(property) == 0) 176 if (!IsAnimating(property))
155 return; 177 return;
156 178
157 // Reset the delegate so that we don't attempt to update the layer.
158 elements_[property].animation->set_delegate(NULL);
159 delete elements_[property].animation;
160 elements_.erase(property); 179 elements_.erase(property);
161 } 180 }
162 181
163 ui::MultiAnimation* LayerAnimator::CreateAndStartAnimation() { 182 LayerAnimatorDelegate* LayerAnimator::delegate() {
164 static ui::AnimationContainer* container = NULL; 183 return static_cast<LayerAnimatorDelegate*>(layer_);
165 if (!container) {
166 container = new AnimationContainer;
167 container->AddRef();
168 }
169 ui::MultiAnimation::Parts parts;
170 parts.push_back(ui::MultiAnimation::Part(duration_in_ms_, animation_type_));
171 ui::MultiAnimation* animation = new ui::MultiAnimation(parts);
172 animation->SetContainer(container);
173 animation->set_delegate(this);
174 animation->set_continuous(false);
175 animation->Start();
176 return animation;
177 }
178
179 LayerAnimator::Elements::iterator LayerAnimator::GetElementByAnimation(
180 const ui::MultiAnimation* animation) {
181 for (Elements::iterator i = elements_.begin(); i != elements_.end(); ++i) {
182 if (i->second.animation == animation)
183 return i;
184 }
185 NOTREACHED();
186 return elements_.end();
187 } 184 }
188 185
189 } // namespace ui 186 } // namespace ui
OLDNEW
« no previous file with comments | « ui/gfx/compositor/layer_animator.h ('k') | ui/gfx/compositor/layer_animator_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698