summaryrefslogtreecommitdiffstats
path: root/views
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-11 04:55:07 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-11 04:55:07 +0000
commit1b1be7c0dafd41d2d66a6c6ec1790a43b676c1b0 (patch)
tree020c667ccae41bf9fa5d4856d635d71ab440b8b7 /views
parente7a1258df3b509726bc4dffe2a520c6318d45af3 (diff)
downloadchromium_src-1b1be7c0dafd41d2d66a6c6ec1790a43b676c1b0.zip
chromium_src-1b1be7c0dafd41d2d66a6c6ec1790a43b676c1b0.tar.gz
chromium_src-1b1be7c0dafd41d2d66a6c6ec1790a43b676c1b0.tar.bz2
Adds a simple class for animating a views bounds from one location to
another. This is just a starting point, I need to integrate a lot of other things to make this really useful, but it's a start and something I'm going to use for the login manager. BUG=none TEST=none Review URL: http://codereview.chromium.org/593051 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38742 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views')
-rw-r--r--views/animation/bounds_animator.cc110
-rw-r--r--views/animation/bounds_animator.h88
-rw-r--r--views/views.gyp2
3 files changed, 200 insertions, 0 deletions
diff --git a/views/animation/bounds_animator.cc b/views/animation/bounds_animator.cc
new file mode 100644
index 0000000..4ea34b0
--- /dev/null
+++ b/views/animation/bounds_animator.cc
@@ -0,0 +1,110 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "views/animation/bounds_animator.h"
+
+#include "app/slide_animation.h"
+#include "base/compiler_specific.h"
+#include "views/view.h"
+
+namespace views {
+
+BoundsAnimator::BoundsAnimator()
+ : ALLOW_THIS_IN_INITIALIZER_LIST(animation_(new SlideAnimation(this))),
+ is_slide_(true) {
+}
+
+BoundsAnimator::~BoundsAnimator() {
+ data_.clear();
+ animation_->set_delegate(NULL);
+ animation_.reset();
+}
+
+void BoundsAnimator::AnimateViewTo(View* view,
+ const gfx::Rect& target,
+ bool delete_when_done) {
+ Data& data = data_[view];
+ data.start_bounds = view->bounds();
+ data.target_bounds = target;
+ data.delete_when_done = delete_when_done;
+}
+
+bool BoundsAnimator::IsAnimating(View* view) const {
+ return data_.find(view) != data_.end();
+}
+
+void BoundsAnimator::Start() {
+ // Unset the delegate so that we don't attempt to cleanup if the animation is
+ // running and we cancel it.
+ animation_->set_delegate(NULL);
+
+ animation_->Stop();
+
+ if (is_slide_) {
+ // TODO(sky): this is yucky, need a better way to express this.
+ static_cast<SlideAnimation*>(animation_.get())->Hide();
+ static_cast<SlideAnimation*>(animation_.get())->Reset();
+ static_cast<SlideAnimation*>(animation_.get())->Show();
+ } else {
+ animation_->Start();
+ }
+
+ animation_->set_delegate(this);
+}
+
+void BoundsAnimator::Stop() {
+ animation_->set_delegate(NULL);
+ animation_->Stop();
+ animation_->set_delegate(this);
+
+ DeleteViews();
+ data_.clear();
+}
+
+void BoundsAnimator::SetAnimation(Animation* animation, bool is_slide) {
+ animation_.reset(animation);
+ is_slide_ = is_slide;
+}
+
+void BoundsAnimator::AnimationProgressed(const Animation* animation) {
+ gfx::Rect repaint_bounds;
+
+ for (ViewToDataMap::const_iterator i = data_.begin(); i != data_.end(); ++i) {
+ View* view = i->first;
+ gfx::Rect new_bounds =
+ animation_->CurrentValueBetween(i->second.start_bounds,
+ i->second.target_bounds);
+ if (new_bounds != view->bounds()) {
+ gfx::Rect total_bounds = new_bounds.Union(view->bounds());
+ if (repaint_bounds.IsEmpty())
+ repaint_bounds = total_bounds;
+ else
+ repaint_bounds = repaint_bounds.Union(total_bounds);
+ view->SetBounds(new_bounds);
+ }
+ }
+
+ if (!data_.empty() && !repaint_bounds.IsEmpty())
+ data_.begin()->first->GetParent()->SchedulePaint(repaint_bounds, false);
+}
+
+void BoundsAnimator::AnimationEnded(const Animation* animation) {
+ DeleteViews();
+}
+
+void BoundsAnimator::AnimationCanceled(const Animation* animation) {
+}
+
+void BoundsAnimator::DeleteViews() {
+ for (ViewToDataMap::iterator i = data_.begin(); i != data_.end(); ++i) {
+ if (i->second.delete_when_done) {
+ View* view = i->first;
+ view->GetParent()->RemoveChildView(view);
+ delete view;
+ }
+ }
+ data_.clear();
+}
+
+} // namespace views
diff --git a/views/animation/bounds_animator.h b/views/animation/bounds_animator.h
new file mode 100644
index 0000000..2882819
--- /dev/null
+++ b/views/animation/bounds_animator.h
@@ -0,0 +1,88 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef VIEWS_ANIMATION_BOUNDS_ANIMATOR_H_
+#define VIEWS_ANIMATION_BOUNDS_ANIMATOR_H_
+
+#include <map>
+
+#include "app/animation.h"
+#include "base/gfx/rect.h"
+#include "base/scoped_ptr.h"
+
+namespace views {
+
+class View;
+
+// Bounds animator is responsible for animating the bounds of a view from the
+// the views current location and size to a target position and size. To use
+// BoundsAnimator invoke AnimateViewTo for the set of views you want to
+// animate, followed by Start to start the animation.
+class BoundsAnimator : public AnimationDelegate {
+ public:
+ BoundsAnimator();
+ ~BoundsAnimator();
+
+ // Schedules |view| to animate from it's current bounds to |target|. If
+ // |delete_when_done| is true the view is deleted when the animation
+ // completes. Invoke Start to start the animation.
+ void AnimateViewTo(View* view,
+ const gfx::Rect& target,
+ bool delete_when_done);
+
+ // Returns true if BoundsAnimator is animating the bounds of |view|.
+ bool IsAnimating(View* view) const;
+
+ // Starts the animation.
+ void Start();
+
+ // Stops the animation.
+ void Stop();
+
+ // Sets the animation to use when animating changes. BoundsAnimator takes
+ // ownership of |animation|. Set |is_slide| to true if |animation| is a
+ // SlideAnimation.
+ void SetAnimation(Animation* animation, bool is_slide);
+
+ // AnimationDelegate overrides.
+ virtual void AnimationProgressed(const Animation* animation);
+ virtual void AnimationEnded(const Animation* animation);
+ virtual void AnimationCanceled(const Animation* animation);
+
+ private:
+ // Tracks data about the view being animated.
+ struct Data {
+ Data() : delete_when_done(false) {}
+
+ // Should the view be deleted when done?
+ bool delete_when_done;
+
+ // The initial bounds.
+ gfx::Rect start_bounds;
+
+ // Target bounds.
+ gfx::Rect target_bounds;
+ };
+
+ typedef std::map<View*, Data> ViewToDataMap;
+
+ // Empties data_, deleting any views that have been marked as needing to be
+ // deleted.
+ void DeleteViews();
+
+ // Mapes from view being animated to info about the view.
+ ViewToDataMap data_;
+
+ // The animation.
+ scoped_ptr<Animation> animation_;
+
+ // Is |animation_| a SlideAnimation?
+ bool is_slide_;
+
+ DISALLOW_COPY_AND_ASSIGN(BoundsAnimator);
+};
+
+} // namespace views
+
+#endif // VIEWS_ANIMATION_BOUNDS_ANIMATOR_H_
diff --git a/views/views.gyp b/views/views.gyp
index 144f17f..9888628 100644
--- a/views/views.gyp
+++ b/views/views.gyp
@@ -55,6 +55,8 @@
'accessibility/view_accessibility.h',
'accessibility/view_accessibility_wrapper.cc',
'accessibility/view_accessibility_wrapper.h',
+ 'animation/bounds_animator.cc',
+ 'animation/bounds_animator.h',
'background.cc',
'background.h',
'border.cc',