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

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: SetAnimator 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
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),
37 animation_type_(ui::Tween::EASE_IN) {
38 } 38 }
39 39
40 LayerAnimator::~LayerAnimator() { 40 LayerAnimator::~LayerAnimator() {
41 for (Elements::iterator i = elements_.begin(); i != elements_.end(); ++i)
42 delete i->second.animation;
43 elements_.clear();
44 } 41 }
45 42
46 void LayerAnimator::SetAnimationDurationAndType(int duration, 43 void LayerAnimator::SetAnimation(Animation* animation) {
47 ui::Tween::Type tween_type) { 44 animation_.reset(animation);
48 DCHECK_GT(duration, 0); 45 if (animation_.get()) {
49 duration_in_ms_ = duration; 46 static ui::AnimationContainer* container = NULL;
50 animation_type_ = tween_type; 47 if (!container) {
48 container = new AnimationContainer;
49 container->AddRef();
50 }
51 animation_->set_delegate(this);
52 animation_->SetContainer(container);
53 }
51 } 54 }
52 55
53 void LayerAnimator::AnimateToPoint(const gfx::Point& target) { 56 void LayerAnimator::AnimateToPoint(const gfx::Point& target) {
54 StopAnimating(LOCATION); 57 StopAnimating(LOCATION);
55 const gfx::Rect& layer_bounds = layer_->bounds(); 58 const gfx::Rect& layer_bounds = layer_->bounds();
56 if (target == layer_bounds.origin()) 59 if (target == layer_bounds.origin())
57 return; // Already there. 60 return; // Already there.
58 61
59 Element& element = elements_[LOCATION]; 62 Params& element = elements_[LOCATION];
60 element.params.location.start_x = layer_bounds.origin().x(); 63 element.location.target_x = target.x();
61 element.params.location.start_y = layer_bounds.origin().y(); 64 element.location.target_y = target.y();
62 element.params.location.target_x = target.x(); 65 element.location.start_x = layer_bounds.origin().x();
63 element.params.location.target_y = target.y(); 66 element.location.start_y = layer_bounds.origin().y();
64 element.animation = CreateAndStartAnimation();
65 } 67 }
66 68
67 void LayerAnimator::AnimateTransform(const Transform& transform) { 69 void LayerAnimator::AnimateTransform(const Transform& transform) {
68 StopAnimating(TRANSFORM); 70 StopAnimating(TRANSFORM);
69 const Transform& layer_transform = layer_->transform(); 71 const Transform& layer_transform = layer_->transform();
70 if (transform == layer_transform) 72 if (transform == layer_transform)
71 return; // Already there. 73 return; // Already there.
72 74
73 Element& element = elements_[TRANSFORM]; 75 Params& element = elements_[TRANSFORM];
74 for (int i = 0; i < 16; ++i) { 76 for (int i = 0; i < 16; ++i) {
75 element.params.transform.start[i] = 77 element.transform.start[i] =
76 GetMatrixElement(layer_transform.matrix(), i); 78 GetMatrixElement(layer_transform.matrix(), i);
77 element.params.transform.target[i] = 79 element.transform.target[i] =
78 GetMatrixElement(transform.matrix(), i); 80 GetMatrixElement(transform.matrix(), i);
79 } 81 }
80 element.animation = CreateAndStartAnimation(); 82 }
83
84 void LayerAnimator::AnimateOpacity(float target_opacity) {
85 StopAnimating(OPACITY);
86 if (layer_->opacity() == target_opacity)
87 return;
88
89 Params& element = elements_[OPACITY];
90 element.opacity.start = layer_->opacity();
91 element.opacity.target = target_opacity;
92 }
93
94 bool LayerAnimator::IsRunning() const {
95 return animation_.get() && animation_->is_animating();
81 } 96 }
82 97
83 void LayerAnimator::AnimationProgressed(const ui::Animation* animation) { 98 void LayerAnimator::AnimationProgressed(const ui::Animation* animation) {
84 Elements::iterator e = GetElementByAnimation( 99 for (Elements::const_iterator i = elements_.begin(); i != elements_.end();
85 static_cast<const ui::MultiAnimation*>(animation)); 100 ++i) {
86 DCHECK(e != elements_.end()); 101 switch (i->first) {
87 switch (e->first) { 102 case LOCATION: {
88 case LOCATION: { 103 const gfx::Rect& current_bounds(layer_->bounds());
89 const gfx::Rect& current_bounds(layer_->bounds()); 104 gfx::Rect new_bounds = animation_->CurrentValueBetween(
90 gfx::Rect new_bounds = e->second.animation->CurrentValueBetween( 105 gfx::Rect(gfx::Point(i->second.location.start_x,
91 gfx::Rect(gfx::Point(e->second.params.location.start_x, 106 i->second.location.start_y),
92 e->second.params.location.start_y), 107 current_bounds.size()),
93 current_bounds.size()), 108 gfx::Rect(gfx::Point(i->second.location.target_x,
94 gfx::Rect(gfx::Point(e->second.params.location.target_x, 109 i->second.location.target_y),
95 e->second.params.location.target_y), 110 current_bounds.size()));
96 current_bounds.size())); 111 delegate()->SetBoundsFromAnimator(new_bounds);
97 layer_->SetBounds(new_bounds); 112 break;
98 break; 113 }
114
115 case TRANSFORM: {
116 Transform transform;
117 for (int j = 0; j < 16; ++j) {
118 SkMScalar value = animation_->CurrentValueBetween(
119 i->second.transform.start[j],
120 i->second.transform.target[j]);
121 SetMatrixElement(transform.matrix(), j, value);
122 }
123 delegate()->SetTransformFromAnimator(transform);
124 break;
125 }
126
127 case OPACITY: {
128 delegate()->SetOpacityFromAnimator(animation_->CurrentValueBetween(
129 i->second.opacity.start, i->second.opacity.target));
130 break;
131 }
132
133 default:
134 NOTREACHED();
99 } 135 }
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 } 136 }
116 layer_->compositor()->SchedulePaint(); 137 layer_->compositor()->SchedulePaint();
117 } 138 }
118 139
119 void LayerAnimator::AnimationEnded(const ui::Animation* animation) { 140 void LayerAnimator::AnimationEnded(const ui::Animation* animation) {
120 Elements::iterator e = GetElementByAnimation( 141 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_->compositor()->SchedulePaint();
151 } 142 }
152 143
153 void LayerAnimator::StopAnimating(AnimationProperty property) { 144 void LayerAnimator::StopAnimating(AnimationProperty property) {
154 if (elements_.count(property) == 0) 145 if (elements_.count(property) == 0)
155 return; 146 return;
156 147
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); 148 elements_.erase(property);
161 } 149 }
162 150
163 ui::MultiAnimation* LayerAnimator::CreateAndStartAnimation() { 151 LayerAnimatorDelegate* LayerAnimator::delegate() {
164 static ui::AnimationContainer* container = NULL; 152 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 } 153 }
188 154
189 } // namespace ui 155 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698