Index: views/animator.cc |
=================================================================== |
--- views/animator.cc (revision 0) |
+++ views/animator.cc (revision 0) |
@@ -0,0 +1,151 @@ |
+// Copyright (c) 2009 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/animator.h" |
+ |
+#include <algorithm> |
+ |
+#include "app/slide_animation.h" |
+#include "views/view.h" |
+ |
+namespace views { |
+ |
+//////////////////////////////////////////////////////////////////////////////// |
+// Animator, public: |
+ |
+Animator::Animator(View* host) |
+ : host_(host), |
+ delegate_(NULL), |
+ direction_(ANIMATE_NONE) { |
+ InitAnimation(); |
+} |
+ |
+Animator::Animator(View* host, AnimatorDelegate* delegate) |
+ : host_(host), |
+ animation_(NULL), |
+ delegate_(delegate), |
+ direction_(ANIMATE_NONE) { |
+ InitAnimation(); |
+} |
+ |
+Animator::~Animator() { |
+ // Explicitly NULL the delegate so we don't call back through to the delegate |
+ // when the animation is stopped. The Animator is designed to be owned by a |
+ // View and at this point the View is dust. |
+ delegate_ = NULL; |
+ animation_->Stop(); |
+} |
+ |
+bool Animator::IsAnimating() const { |
+ return animation_->IsAnimating(); |
+} |
+ |
+void Animator::AnimateToBounds(const gfx::Rect& bounds, int direction) { |
+ direction_ = direction; |
+ start_bounds_ = host_->bounds(); |
+ target_bounds_ = bounds; |
+ |
+ // Stop any running animation before we have a chance to return. |
+ animation_->Stop(); |
+ |
+ if (bounds == host_->bounds()) |
+ return; |
+ |
+ if (direction_ == ANIMATE_NONE) { |
+ host_->SetBounds(bounds); |
+ return; |
+ } |
+ |
+ if (direction_ & ANIMATE_X) { |
+ if (direction_ & ANIMATE_CLAMP) |
+ start_bounds_.set_x(GetClampedX()); |
+ } else { |
+ start_bounds_.set_x(target_bounds_.x()); |
+ } |
+ |
+ if (direction_ & ANIMATE_Y) { |
+ if (direction_ & ANIMATE_CLAMP) |
+ start_bounds_.set_y(GetClampedY()); |
+ } else { |
+ start_bounds_.set_y(target_bounds_.y()); |
+ } |
+ |
+ if (!(direction_ & ANIMATE_WIDTH)) |
+ start_bounds_.set_width(target_bounds_.width()); |
+ if (!(direction_ & ANIMATE_HEIGHT)) |
+ start_bounds_.set_height(target_bounds_.height()); |
+ |
+ // Make sure the host view has the start bounds to avoid a flicker. |
+ host_->SetBounds(start_bounds_); |
+ |
+ // Start the animation from the beginning. |
+ animation_->Reset(0.0); |
+ animation_->Show(); |
+} |
+ |
+//////////////////////////////////////////////////////////////////////////////// |
+// Animator, AnimationDelegate: |
+ |
+void Animator::AnimationEnded(const Animation* animation) { |
+ // |delegate_| could be NULL if we're called back from the destructor. |
+ if (delegate_) |
+ delegate_->AnimationCompletedForHost(host_); |
+} |
+ |
+void Animator::AnimationProgressed(const Animation* animation) { |
+ int delta_x = target_bounds_.x() - start_bounds_.x(); |
+ int delta_y = target_bounds_.y() - start_bounds_.y(); |
+ int delta_width = target_bounds_.width() - start_bounds_.width(); |
+ int delta_height = target_bounds_.height() - start_bounds_.height(); |
+ |
+ // The current frame's position and size is the animation's progress percent |
+ // multiplied by the delta between the start and target position/size... |
+ double cv = animation_->GetCurrentValue(); |
+ int frame_x = start_bounds_.x() + static_cast<int>(delta_x * cv); |
+ int frame_y = start_bounds_.y() + static_cast<int>(delta_y * cv); |
+ // ... except for clamped positions, which remain clamped at the right/bottom |
+ // edge of the previous view in the layout flow. |
+ if (direction_ & ANIMATE_CLAMP && direction_ & ANIMATE_X) |
+ frame_x = GetClampedX(); |
+ if (direction_ & ANIMATE_CLAMP && direction_ & ANIMATE_Y) |
+ frame_y = GetClampedY(); |
+ int frame_width = start_bounds_.width() + static_cast<int>(delta_width * cv); |
+ int frame_height = |
+ start_bounds_.height() + static_cast<int>(delta_height * cv); |
+ host_->SetBounds(frame_x, frame_y, frame_width, frame_height); |
+ host_->GetParent()->SchedulePaint(); |
+} |
+ |
+void Animator::AnimationCanceled(const Animation* animation) { |
+ AnimationEnded(animation); |
+} |
+ |
+//////////////////////////////////////////////////////////////////////////////// |
+// Animator, private: |
+ |
+void Animator::InitAnimation() { |
+ animation_.reset(new SlideAnimation(this)); |
+ animation_->SetSlideDuration(150); |
+ animation_->SetTweenType(SlideAnimation::EASE_OUT); |
+} |
+ |
+int Animator::GetClampedX() const { |
+ if (delegate_ && direction_ & ANIMATE_CLAMP && direction_ & ANIMATE_X) { |
+ View* previous_view = delegate_->GetClampedView(host_); |
+ if (previous_view) |
+ return previous_view->bounds().right(); |
+ } |
+ return host_->x(); |
+} |
+ |
+int Animator::GetClampedY() const { |
+ if (delegate_ && direction_ & ANIMATE_CLAMP && direction_ & ANIMATE_Y) { |
+ View* previous_view = delegate_->GetClampedView(host_); |
+ if (previous_view) |
+ return previous_view->bounds().bottom(); |
+ } |
+ return host_->y(); |
+} |
+ |
+} // namespace views |
Property changes on: views\animator.cc |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |