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 GFX_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 GFX_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 GFX_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 GFX_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 GFX_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 GFX_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 GFX_EXPORT InterpolatedTransformAboutPivot
    216     : public InterpolatedTransform {
    217  public:
    218   // Takes ownership of the passed transform.
    219   InterpolatedTransformAboutPivot(const gfx::Point& pivot,
    220                                   InterpolatedTransform* transform);
    221 
    222   // Takes ownership of the passed transform.
    223   InterpolatedTransformAboutPivot(const gfx::Point& pivot,
    224                                   InterpolatedTransform* transform,
    225                                   float start_time,
    226                                   float end_time);
    227   virtual ~InterpolatedTransformAboutPivot();
    228 
    229  protected:
    230   virtual gfx::Transform InterpolateButDoNotCompose(float t) const OVERRIDE;
    231 
    232  private:
    233   void Init(const gfx::Point& pivot, InterpolatedTransform* transform);
    234 
    235   scoped_ptr<InterpolatedTransform> transform_;
    236 
    237   DISALLOW_COPY_AND_ASSIGN(InterpolatedTransformAboutPivot);
    238 };
    239 
    240 class GFX_EXPORT InterpolatedMatrixTransform : public InterpolatedTransform {
    241  public:
    242   InterpolatedMatrixTransform(const gfx::Transform& start_transform,
    243                               const gfx::Transform& end_transform);
    244 
    245   InterpolatedMatrixTransform(const gfx::Transform& start_transform,
    246                               const gfx::Transform& end_transform,
    247                               float start_time,
    248                               float end_time);
    249 
    250   virtual ~InterpolatedMatrixTransform();
    251 
    252  protected:
    253   virtual gfx::Transform InterpolateButDoNotCompose(float t) const OVERRIDE;
    254 
    255  private:
    256   void Init(const gfx::Transform& start_transform,
    257             const gfx::Transform& end_transform);
    258 
    259   gfx::DecomposedTransform start_decomp_;
    260   gfx::DecomposedTransform end_decomp_;
    261 };
    262 
    263 } // namespace ui
    264 
    265 #endif  // UI_GFX_INTERPOLATED_TRANSFORM_H_
    266