| Index: ui/gfx/interpolated_transform.cc
|
| diff --git a/ui/gfx/interpolated_transform.cc b/ui/gfx/interpolated_transform.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..1f37f84909a35d6e12c290aad8fb1e614474af05
|
| --- /dev/null
|
| +++ b/ui/gfx/interpolated_transform.cc
|
| @@ -0,0 +1,219 @@
|
| +// Copyright (c) 2011 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 "ui/gfx/interpolated_transform.h"
|
| +
|
| +#include "base/logging.h"
|
| +#include "ui/base/animation/tween.h"
|
| +
|
| +namespace ui {
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +// InterpolatedTransform
|
| +//
|
| +
|
| +InterpolatedTransform::InterpolatedTransform()
|
| + : start_time_(0.0f),
|
| + end_time_(1.0f) {
|
| +}
|
| +
|
| +InterpolatedTransform::InterpolatedTransform(float start_time,
|
| + float end_time)
|
| + : start_time_(start_time),
|
| + end_time_(end_time) {
|
| +}
|
| +
|
| +InterpolatedTransform::~InterpolatedTransform() {}
|
| +
|
| +ui::Transform InterpolatedTransform::Interpolate(float t) const {
|
| + ui::Transform result = InterpolateButDoNotCompose(t);
|
| + if (child_.get()) {
|
| + result.ConcatTransform(child_->Interpolate(t));
|
| + }
|
| + return result;
|
| +}
|
| +
|
| +void InterpolatedTransform::SetChild(InterpolatedTransform* child) {
|
| + child_.reset(child);
|
| +}
|
| +
|
| +inline float InterpolatedTransform::ValueBetween(float time,
|
| + float start_value,
|
| + float end_value) const {
|
| + // can't handle NaN
|
| + DCHECK(time == time && start_time_ == start_time_ && end_time_ == end_time_);
|
| + if (time != time || start_time_ != start_time_ || end_time_ != end_time_)
|
| + return start_value;
|
| +
|
| + // Ok if equal -- we'll get a step function. Note: if end_time_ ==
|
| + // start_time_ == x, then if none of the numbers are NaN, then it
|
| + // must be true that time < x or time >= x, so we will return early
|
| + // due to one of the following if statements.
|
| + DCHECK(end_time_ >= start_time_);
|
| +
|
| + if (time < start_time_)
|
| + return start_value;
|
| +
|
| + if (time >= end_time_)
|
| + return end_value;
|
| +
|
| + float t = (time - start_time_) / (end_time_ - start_time_);
|
| + return static_cast<float>(Tween::ValueBetween(t, start_value, end_value));
|
| +}
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +// InterpolatedRotation
|
| +//
|
| +
|
| +InterpolatedRotation::InterpolatedRotation(float start_degrees,
|
| + float end_degrees)
|
| + : InterpolatedTransform(),
|
| + start_degrees_(start_degrees),
|
| + end_degrees_(end_degrees) {
|
| +}
|
| +
|
| +InterpolatedRotation::InterpolatedRotation(float start_degrees,
|
| + float end_degrees,
|
| + float start_time,
|
| + float end_time)
|
| + : InterpolatedTransform(start_time, end_time),
|
| + start_degrees_(start_degrees),
|
| + end_degrees_(end_degrees) {
|
| +}
|
| +
|
| +InterpolatedRotation::~InterpolatedRotation() {}
|
| +
|
| +ui::Transform InterpolatedRotation::InterpolateButDoNotCompose(float t) const {
|
| + ui::Transform result;
|
| + result.SetRotate(ValueBetween(t, start_degrees_, end_degrees_));
|
| + return result;
|
| +}
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +// InterpolatedScale
|
| +//
|
| +
|
| +InterpolatedScale::InterpolatedScale(float start_scale,
|
| + float end_scale)
|
| + : InterpolatedTransform(),
|
| + start_scale_(start_scale),
|
| + end_scale_(end_scale) {
|
| +}
|
| +
|
| +InterpolatedScale::InterpolatedScale(float start_scale,
|
| + float end_scale,
|
| + float start_time,
|
| + float end_time)
|
| + : InterpolatedTransform(start_time, end_time),
|
| + start_scale_(start_scale),
|
| + end_scale_(end_scale) {
|
| +}
|
| +
|
| +InterpolatedScale::~InterpolatedScale() {}
|
| +
|
| +ui::Transform InterpolatedScale::InterpolateButDoNotCompose(float t) const {
|
| + ui::Transform result;
|
| + float interpolated_scale = ValueBetween(t, start_scale_, end_scale_);
|
| + // TODO(vollick) 3d xforms.
|
| + result.SetScale(interpolated_scale, interpolated_scale);
|
| + return result;
|
| +}
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +// InterpolatedTranslation
|
| +//
|
| +
|
| +InterpolatedTranslation::InterpolatedTranslation(const gfx::Point& start_pos,
|
| + const gfx::Point& end_pos)
|
| + : InterpolatedTransform(),
|
| + start_pos_(start_pos),
|
| + end_pos_(end_pos) {
|
| +}
|
| +
|
| +InterpolatedTranslation::InterpolatedTranslation(const gfx::Point& start_pos,
|
| + const gfx::Point& end_pos,
|
| + float start_time,
|
| + float end_time)
|
| + : InterpolatedTransform(start_time, end_time),
|
| + start_pos_(start_pos),
|
| + end_pos_(end_pos) {
|
| +}
|
| +
|
| +InterpolatedTranslation::~InterpolatedTranslation() {}
|
| +
|
| +ui::Transform
|
| +InterpolatedTranslation::InterpolateButDoNotCompose(float t) const {
|
| + ui::Transform result;
|
| + // TODO(vollick) 3d xforms.
|
| + result.SetTranslate(ValueBetween(t, start_pos_.x(), end_pos_.x()),
|
| + ValueBetween(t, start_pos_.y(), end_pos_.y()));
|
| +
|
| + return result;
|
| +}
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +// InterpolatedConstantTransform
|
| +//
|
| +
|
| +InterpolatedConstantTransform::InterpolatedConstantTransform(
|
| + const ui::Transform& transform)
|
| + : InterpolatedTransform(),
|
| + transform_(transform) {
|
| +}
|
| +
|
| +ui::Transform
|
| +InterpolatedConstantTransform::InterpolateButDoNotCompose(float t) const {
|
| + return transform_;
|
| +}
|
| +
|
| +InterpolatedConstantTransform::~InterpolatedConstantTransform() {}
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +// InterpolatedTransformAboutPivot
|
| +//
|
| +
|
| +InterpolatedTransformAboutPivot::InterpolatedTransformAboutPivot(
|
| + const gfx::Point& pivot,
|
| + InterpolatedTransform* transform)
|
| + : InterpolatedTransform() {
|
| + Init(pivot, transform);
|
| +}
|
| +
|
| +InterpolatedTransformAboutPivot::InterpolatedTransformAboutPivot(
|
| + const gfx::Point& pivot,
|
| + InterpolatedTransform* transform,
|
| + float start_time,
|
| + float end_time)
|
| + : InterpolatedTransform() {
|
| + Init(pivot, transform);
|
| +}
|
| +
|
| +InterpolatedTransformAboutPivot::~InterpolatedTransformAboutPivot() {}
|
| +
|
| +ui::Transform
|
| +InterpolatedTransformAboutPivot::InterpolateButDoNotCompose(float t) const {
|
| + if (transform_.get()) {
|
| + return transform_->Interpolate(t);
|
| + }
|
| + return ui::Transform();
|
| +}
|
| +
|
| +void InterpolatedTransformAboutPivot::Init(const gfx::Point& pivot,
|
| + InterpolatedTransform* xform) {
|
| + ui::Transform to_pivot;
|
| + ui::Transform from_pivot;
|
| + to_pivot.SetTranslate(-pivot.x(), -pivot.y());
|
| + from_pivot.SetTranslate(pivot.x(), pivot.y());
|
| +
|
| + scoped_ptr<InterpolatedTransform> pre_transform(
|
| + new InterpolatedConstantTransform(to_pivot));
|
| + scoped_ptr<InterpolatedTransform> post_transform(
|
| + new InterpolatedConstantTransform(from_pivot));
|
| +
|
| + pre_transform->SetChild(xform);
|
| + xform->SetChild(post_transform.release());
|
| + transform_.reset(pre_transform.release());
|
| +}
|
| +
|
| +} // namespace ui
|
|
|