diff options
author | jdduke <jdduke@chromium.org> | 2014-10-10 11:00:18 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-10-10 18:00:37 +0000 |
commit | 1d6fc87072bd9f8ea7908cb5af19d7ef6cd0e18c (patch) | |
tree | 0f62f5a9f499e5926e764d4495bda2331fbb66d2 /ui/events/gestures | |
parent | bee8d3d4e4b4c2f22b15f3a598a38a6b2c7c5fe2 (diff) | |
download | chromium_src-1d6fc87072bd9f8ea7908cb5af19d7ef6cd0e18c.zip chromium_src-1d6fc87072bd9f8ea7908cb5af19d7ef6cd0e18c.tar.gz chromium_src-1d6fc87072bd9f8ea7908cb5af19d7ef6cd0e18c.tar.bz2 |
Consolidate content fling implementations
Provide a single implementation of WebGestureCurve, instead relying on
platform-specific ui::GestureCurve implementations for core
functionality. This eliminates the duplicated curve code used for
content and view-targetted flings on Aura.
BUG=420214
Review URL: https://codereview.chromium.org/634373003
Cr-Commit-Position: refs/heads/master@{#299136}
Diffstat (limited to 'ui/events/gestures')
-rw-r--r-- | ui/events/gestures/fling_curve.cc | 61 | ||||
-rw-r--r-- | ui/events/gestures/fling_curve.h | 19 | ||||
-rw-r--r-- | ui/events/gestures/fling_curve_unittest.cc | 36 |
3 files changed, 77 insertions, 39 deletions
diff --git a/ui/events/gestures/fling_curve.cc b/ui/events/gestures/fling_curve.cc index 6f63019..00d29a4 100644 --- a/ui/events/gestures/fling_curve.cc +++ b/ui/events/gestures/fling_curve.cc @@ -38,8 +38,10 @@ FlingCurve::FlingCurve(const gfx::Vector2dF& velocity, base::TimeTicks start_timestamp) : curve_duration_(GetTimeAtVelocity(0)), start_timestamp_(start_timestamp), + previous_timestamp_(start_timestamp_), time_offset_(0), position_offset_(0) { + DCHECK(!velocity.IsZero()); float max_start_velocity = std::max(fabs(velocity.x()), fabs(velocity.y())); if (max_start_velocity > GetVelocityAtTime(0)) max_start_velocity = GetVelocityAtTime(0); @@ -49,32 +51,57 @@ FlingCurve::FlingCurve(const gfx::Vector2dF& velocity, velocity.y() / max_start_velocity); time_offset_ = GetTimeAtVelocity(max_start_velocity); position_offset_ = GetPositionAtTime(time_offset_); - last_timestamp_ = start_timestamp_ + base::TimeDelta::FromSecondsD( - curve_duration_ - time_offset_); } FlingCurve::~FlingCurve() { } -gfx::Vector2dF FlingCurve::GetScrollAmountAtTime(base::TimeTicks current) { - if (current < start_timestamp_) - return gfx::Vector2dF(); +bool FlingCurve::ComputeScrollOffset(base::TimeTicks time, + gfx::Vector2dF* offset, + gfx::Vector2dF* velocity) { + DCHECK(offset); + DCHECK(velocity); + base::TimeDelta elapsed_time = time - start_timestamp_; + if (elapsed_time < base::TimeDelta()) { + *offset = gfx::Vector2dF(); + *velocity = gfx::Vector2dF(); + return true; + } - float displacement = 0; - if (current < last_timestamp_) { - float time = time_offset_ + (current - start_timestamp_).InSecondsF(); - CHECK_LT(time, curve_duration_); - displacement = GetPositionAtTime(time) - position_offset_; + bool still_active = true; + float scalar_offset; + float scalar_velocity; + double offset_time = elapsed_time.InSecondsF() + time_offset_; + if (offset_time < curve_duration_) { + scalar_offset = GetPositionAtTime(offset_time) - position_offset_; + scalar_velocity = GetVelocityAtTime(offset_time); } else { - displacement = GetPositionAtTime(curve_duration_) - position_offset_; + scalar_offset = GetPositionAtTime(curve_duration_) - position_offset_; + scalar_velocity = 0; + still_active = false; } - gfx::Vector2dF scroll(displacement * displacement_ratio_.x(), - displacement * displacement_ratio_.y()); - gfx::Vector2dF scroll_increment(scroll.x() - cumulative_scroll_.x(), - scroll.y() - cumulative_scroll_.y()); - cumulative_scroll_ = scroll; - return scroll_increment; + *offset = gfx::ScaleVector2d(displacement_ratio_, scalar_offset); + *velocity = gfx::ScaleVector2d(displacement_ratio_, scalar_velocity); + return still_active; +} + +bool FlingCurve::ComputeScrollDeltaAtTime(base::TimeTicks current, + gfx::Vector2dF* delta) { + DCHECK(delta); + if (current <= previous_timestamp_) { + *delta = gfx::Vector2dF(); + return true; + } + + previous_timestamp_ = current; + + gfx::Vector2dF offset, velocity; + bool still_active = ComputeScrollOffset(current, &offset, &velocity); + + *delta = offset - cumulative_scroll_; + cumulative_scroll_ = offset; + return still_active; } } // namespace ui diff --git a/ui/events/gestures/fling_curve.h b/ui/events/gestures/fling_curve.h index 583e172..bebf6ab 100644 --- a/ui/events/gestures/fling_curve.h +++ b/ui/events/gestures/fling_curve.h @@ -7,6 +7,7 @@ #include "base/time/time.h" #include "ui/events/events_base_export.h" +#include "ui/events/gesture_curve.h" #include "ui/gfx/geometry/point_f.h" #include "ui/gfx/geometry/vector2d_f.h" @@ -14,13 +15,21 @@ namespace ui { // FlingCurve can be used to scroll a UI element suitable for touch screen-based // flings. -class EVENTS_BASE_EXPORT FlingCurve { +class EVENTS_BASE_EXPORT FlingCurve : public GestureCurve { public: FlingCurve(const gfx::Vector2dF& velocity, base::TimeTicks start_timestamp); - ~FlingCurve(); + virtual ~FlingCurve(); - gfx::Vector2dF GetScrollAmountAtTime(base::TimeTicks current_timestamp); - base::TimeTicks start_timestamp() const { return start_timestamp_; } + // GestureCurve implementation. + virtual bool ComputeScrollOffset(base::TimeTicks time, + gfx::Vector2dF* offset, + gfx::Vector2dF* velocity) override; + + // In contrast to |ComputeScrollOffset()|, this method is stateful and + // returns the *change* in scroll offset between successive calls. + // Returns true as long as the curve is still active and requires additional + // animation ticks. + bool ComputeScrollDeltaAtTime(base::TimeTicks current, gfx::Vector2dF* delta); private: const float curve_duration_; @@ -28,7 +37,7 @@ class EVENTS_BASE_EXPORT FlingCurve { gfx::Vector2dF displacement_ratio_; gfx::Vector2dF cumulative_scroll_; - base::TimeTicks last_timestamp_; + base::TimeTicks previous_timestamp_; float time_offset_; float position_offset_; diff --git a/ui/events/gestures/fling_curve_unittest.cc b/ui/events/gestures/fling_curve_unittest.cc index 653a5ef..d6dffef 100644 --- a/ui/events/gestures/fling_curve_unittest.cc +++ b/ui/events/gestures/fling_curve_unittest.cc @@ -14,23 +14,25 @@ TEST(FlingCurveTest, Basic) { base::TimeTicks now = gfx::FrameTime::Now(); FlingCurve curve(velocity, now); - gfx::Vector2dF scroll = - curve.GetScrollAmountAtTime(now + base::TimeDelta::FromMilliseconds(20)); - EXPECT_EQ(0, scroll.x()); - EXPECT_NEAR(scroll.y(), 96, 1); - - scroll = - curve.GetScrollAmountAtTime(now + base::TimeDelta::FromMilliseconds(250)); - EXPECT_EQ(0, scroll.x()); - EXPECT_NEAR(scroll.y(), 705, 1); - - scroll = - curve.GetScrollAmountAtTime(now + base::TimeDelta::FromSeconds(10)); - EXPECT_EQ(0, scroll.x()); - EXPECT_NEAR(scroll.y(), 392, 1); - - EXPECT_TRUE(curve.GetScrollAmountAtTime( - now + base::TimeDelta::FromSeconds(20)).IsZero()); + gfx::Vector2dF delta; + EXPECT_TRUE(curve.ComputeScrollDeltaAtTime( + now + base::TimeDelta::FromMilliseconds(20), &delta)); + EXPECT_EQ(0, delta.x()); + EXPECT_NEAR(delta.y(), 96, 1); + + EXPECT_TRUE(curve.ComputeScrollDeltaAtTime( + now + base::TimeDelta::FromMilliseconds(250), &delta)); + EXPECT_EQ(0, delta.x()); + EXPECT_NEAR(delta.y(), 705, 1); + + EXPECT_FALSE(curve.ComputeScrollDeltaAtTime( + now + base::TimeDelta::FromSeconds(10), &delta)); + EXPECT_EQ(0, delta.x()); + EXPECT_NEAR(delta.y(), 392, 1); + + EXPECT_FALSE(curve.ComputeScrollDeltaAtTime( + now + base::TimeDelta::FromSeconds(20), &delta)); + EXPECT_TRUE(delta.IsZero()); } } // namespace ui |