Home | History | Annotate | Download | only in gfx
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef UI_GFX_INTERPOLATED_TRANSFORM_H_
      6 #define UI_GFX_INTERPOLATED_TRANSFORM_H_
      7 
      8 #include "base/basictypes.h"
      9 #include "base/memory/scoped_ptr.h"
     10 #include "ui/gfx/point.h"
     11 #include "ui/gfx/point3_f.h"
     12 #include "ui/gfx/transform.h"
     13 #include "ui/gfx/transform_util.h"
     14 #include "ui/gfx/vector3d_f.h"
     15 
     16 namespace ui {
     17 
     18 ///////////////////////////////////////////////////////////////////////////////
     19 // class InterpolatedTransform
     20 //
     21 // Abstract base class for transforms that animate over time. These
     22 // interpolated transforms can be combined to allow for more sophisticated
     23 // animations. For example, you might combine a rotation of 90 degrees between
     24 // times 0 and 1, with a scale from 1 to 0.3 between times 0 and 0.25 and a
     25 // scale from 0.3 to 1 from between times 0.75 and 1.
     26 //
     27 ///////////////////////////////////////////////////////////////////////////////
     28 class UI_EXPORT InterpolatedTransform {
     29  public:
     30   InterpolatedTransform();
     31   // The interpolated transform varies only when t in (start_time, end_time).
     32   // If t <= start_time, Interpolate(t) will return the initial transform, and
     33   // if t >= end_time, Interpolate(t) will return the final transform.
     34   InterpolatedTransform(float start_time, float end_time);
     35   virtual ~InterpolatedTransform();
     36 
     37   // Returns the interpolated transform at time t. Note: not virtual.
     38   gfx::Transform Interpolate(float t) const;
     39 
     40   // The Intepolate ultimately returns the product of our transform at time t
     41   // and our child's transform at time t (if we have one).
     42   //
     43   // This function takes ownership of the passed InterpolatedTransform.
     44   void SetChild(InterpolatedTransform* child);
     45 
     46   // If the interpolated transform is reversed, Interpolate(t) will return
     47   // Interpolate(1 - t)
     48   void SetReversed(bool reversed) { reversed_ = reversed; }
     49   bool Reversed() const { return reversed_; }
     50 
     51  protected:
     52   // Calculates the interpolated transform without considering our child.
     53   virtual gfx::Transform InterpolateButDoNotCompose(float t) const = 0;
     54 
     55   // If time in (start_time_, end_time_], this function linearly interpolates
     56   // between start_value and end_value.  More precisely it returns
     57   // (1 - t) * start_value + t * end_value where
     58   // t = (start_time_ - time) / (end_time_ - start_time_).
     59   // If time < start_time_ it returns start_value, and if time >= end_time_
     60   // it returns end_value.
     61   float ValueBetween(float time, float start_value, float end_value) const;
     62 
     63   float start_time() const { return start_time_; }
     64   float end_time() const { return end_time_; }
     65 
     66  private:
     67   const float start_time_;
     68   const float end_time_;
     69 
     70   // The child transform. If you consider an interpolated transform as a
     71   // function of t. If, without a child, we are f(t), and our child is
     72   // g(t), then with a child we become f'(t) = f(t) * g(t). Using a child
     73   // transform, we can chain collections of transforms together.
     74   scoped_ptr<InterpolatedTransform> child_;
     75 
     76   bool reversed_;
     77 
     78   DISALLOW_COPY_AND_ASSIGN(InterpolatedTransform);
     79 };
     80 
     81 ///////////////////////////////////////////////////////////////////////////////
     82 // class InterpolatedRotation
     83 //
     84 // Represents an animated rotation.
     85 //
     86 ///////////////////////////////////////////////////////////////////////////////
     87 class UI_EXPORT InterpolatedRotation : public InterpolatedTransform {
     88  public:
     89   InterpolatedRotation(float start_degrees, float end_degrees);
     90   InterpolatedRotation(float start_degrees,
     91                        float end_degrees,
     92                        float start_time,
     93                        float end_time);
     94   virtual ~InterpolatedRotation();
     95 
     96  protected:
     97   virtual gfx::Transform InterpolateButDoNotCompose(float t) const OVERRIDE;
     98 
     99  private:
    100   const float start_degrees_;
    101   const float end_degrees_;
    102 
    103   DISALLOW_COPY_AND_ASSIGN(InterpolatedRotation);
    104 };
    105 
    106 ///////////////////////////////////////////////////////////////////////////////
    107 // class InterpolatedAxisAngleRotation
    108 //
    109 // Represents an animated rotation.
    110 //
    111 ///////////////////////////////////////////////////////////////////////////////
    112 class UI_EXPORT InterpolatedAxisAngleRotation : public InterpolatedTransform {
    113  public:
    114   InterpolatedAxisAngleRotation(const gfx::Vector3dF& axis,
    115                                 float start_degrees,
    116                                 float end_degrees);
    117   InterpolatedAxisAngleRotation(const gfx::Vector3dF& axis,
    118                                 float start_degrees,
    119                                 float end_degrees,
    120                                 float start_time,
    121                                 float end_time);
    122   virtual ~InterpolatedAxisAngleRotation();
    123 
    124  protected:
    125   virtual gfx::Transform InterpolateButDoNotCompose(float t) const OVERRIDE;
    126 
    127  private:
    128   gfx::Vector3dF axis_;
    129   const float start_degrees_;
    130   const float end_degrees_;
    131 
    132   DISALLOW_COPY_AND_ASSIGN(InterpolatedAxisAngleRotation);
    133 };
    134 
    135 ///////////////////////////////////////////////////////////////////////////////
    136 // class InterpolatedScale
    137 //
    138 // Represents an animated scale.
    139 //
    140 ///////////////////////////////////////////////////////////////////////////////
    141 class UI_EXPORT InterpolatedScale : public InterpolatedTransform {
    142  public:
    143   InterpolatedScale(float start_scale, float end_scale);
    144   InterpolatedScale(float start_scale, float end_scale,
    145                     float start_time, float end_time);
    146   InterpolatedScale(const gfx::Point3F& start_scale,
    147                     const gfx::Point3F& end_scale);
    148   InterpolatedScale(const gfx::Point3F& start_scale,
    149                     const gfx::Point3F& end_scale,
    150                     float start_time,
    151                     float end_time);
    152   virtual ~InterpolatedScale();
    153 
    154  protected:
    155   virtual gfx::Transform InterpolateButDoNotCompose(float t) const OVERRIDE;
    156 
    157  private:
    158   const gfx::Point3F start_scale_;
    159   const gfx::Point3F end_scale_;
    160 
    161   DISALLOW_COPY_AND_ASSIGN(InterpolatedScale);
    162 };
    163 
    164 class UI_EXPORT InterpolatedTranslation : public InterpolatedTransform {
    165  public:
    166   InterpolatedTranslation(const gfx::Point& start_pos,
    167                           const gfx::Point& end_pos);
    168   InterpolatedTranslation(const gfx::Point& start_pos,
    169                           const gfx::Point& end_pos,
    170                           float start_time,
    171                           float end_time);
    172   virtual ~InterpolatedTranslation();
    173 
    174  protected:
    175   virtual gfx::Transform InterpolateButDoNotCompose(float t) const OVERRIDE;
    176 
    177  private:
    178   const gfx::Point start_pos_;
    179   const gfx::Point end_pos_;
    180 
    181   DISALLOW_COPY_AND_ASSIGN(InterpolatedTranslation);
    182 };
    183 
    184 ///////////////////////////////////////////////////////////////////////////////
    185 // class InterpolatedConstantTransform
    186 //
    187 // Represents a transform that is constant over time. This is only useful when
    188 // composed with other interpolated transforms.
    189 //
    190 // See InterpolatedTransformAboutPivot for an example of its usage.
    191 //
    192 ///////////////////////////////////////////////////////////////////////////////
    193 class UI_EXPORT InterpolatedConstantTransform : public InterpolatedTransform {
    194  public:
    195   explicit InterpolatedConstantTransform(const gfx::Transform& transform);
    196   virtual ~InterpolatedConstantTransform();
    197 
    198  protected:
    199   virtual gfx::Transform InterpolateButDoNotCompose(float t) const OVERRIDE;
    200 
    201  private:
    202   const gfx::Transform transform_;
    203 
    204   DISALLOW_COPY_AND_ASSIGN(InterpolatedConstantTransform);
    205 };
    206 
    207 ///////////////////////////////////////////////////////////////////////////////
    208 // class InterpolatedTransformAboutPivot
    209 //
    210 // Represents an animated transform with a transformed origin. Essentially,
    211 // at each time, t, the interpolated transform is created by composing
    212 // P * T * P^-1 where P is a constant transform to the new origin.
    213 //
    214 ///////////////////////////////////////////////////////////////////////////////
    215 class UI_EXPORT InterpolatedTransformAboutPivot : public InterpolatedTransform {
    216  public:
    217   // Takes ownership of the passed transform.
    218   InterpolatedTransformAboutPivot(const gfx::Point& pivot,
    219                                   InterpolatedTransform* transform);
    220 
    221   // Takes ownership of the passed transform.
    222   InterpolatedTransformAboutPivot(const gfx::Point& pivot,
    223                                   InterpolatedTransform* transform,
    224                                   float start_time,
    225                                   float end_time);
    226   virtual ~InterpolatedTransformAboutPivot();
    227 
    228  protected:
    229   virtual gfx::Transform InterpolateButDoNotCompose(float t) const OVERRIDE;
    230 
    231  private:
    232   void Init(const gfx::Point& pivot, InterpolatedTransform* transform);
    233 
    234   scoped_ptr<InterpolatedTransform> transform_;
    235 
    236   DISALLOW_COPY_AND_ASSIGN(InterpolatedTransformAboutPivot);
    237 };
    238 
    239 class UI_EXPORT InterpolatedMatrixTransform : public InterpolatedTransform {
    240  public:
    241   InterpolatedMatrixTransform(const gfx::Transform& start_transform,
    242                               const gfx::Transform& end_transform);
    243 
    244   InterpolatedMatrixTransform(const gfx::Transform& start_transform,
    245                               const gfx::Transform& end_transform,
    246                               float start_time,
    247                               float end_time);
    248 
    249   virtual ~InterpolatedMatrixTransform();
    250 
    251  protected:
    252   virtual gfx::Transform InterpolateButDoNotCompose(float t) const OVERRIDE;
    253 
    254  private:
    255   void Init(const gfx::Transform& start_transform,
    256             const gfx::Transform& end_transform);
    257 
    258   gfx::DecomposedTransform start_decomp_;
    259   gfx::DecomposedTransform end_decomp_;
    260 };
    261 
    262 } // namespace ui
    263 
    264 #endif  // UI_GFX_INTERPOLATED_TRANSFORM_H_
    265