#ifndef CC_INPUT_SNAP_FLING_CONTROLLER_H_
#define CC_INPUT_SNAP_FLING_CONTROLLER_H_
#include <memory>
#include "base/memory/raw_ptr.h"
#include "base/time/time.h"
#include "cc/cc_export.h"
#include "ui/gfx/geometry/point_f.h"
#include "ui/gfx/geometry/vector2d_f.h"
namespace cc {
namespace test {
class SnapFlingControllerTest;
}
class SnapFlingCurve;
class SnapFlingClient {
public:
virtual bool GetSnapFlingInfoAndSetAnimatingSnapTarget(
const gfx::Vector2dF& current_delta,
const gfx::Vector2dF& natural_displacement,
gfx::PointF* out_initial_position,
gfx::PointF* out_target_position) const = 0;
virtual gfx::PointF ScrollByForSnapFling(const gfx::Vector2dF& delta) = 0;
virtual void ScrollEndForSnapFling(bool did_finish) = 0;
virtual void RequestAnimationForSnapFling() = 0;
};
class CC_EXPORT SnapFlingController {
public:
enum class GestureScrollType { kBegin, kUpdate, kEnd };
struct GestureScrollUpdateInfo {
gfx::Vector2dF delta;
bool is_in_inertial_phase;
bool is_overscroll;
base::TimeTicks event_time;
};
explicit SnapFlingController(SnapFlingClient* client);
static std::unique_ptr<SnapFlingController> CreateForTests(
SnapFlingClient* client,
std::unique_ptr<SnapFlingCurve> curve);
SnapFlingController(const SnapFlingController&) = delete;
~SnapFlingController();
SnapFlingController& operator=(const SnapFlingController&) = delete;
bool FilterEventForSnap(GestureScrollType gesture_scroll_type);
bool HandleGestureScrollUpdate(const GestureScrollUpdateInfo& info);
void Animate(base::TimeTicks time);
private:
friend class test::SnapFlingControllerTest;
enum class State {
kIdle,
kIgnored,
kActive,
kFinished,
};
SnapFlingController(SnapFlingClient* client,
std::unique_ptr<SnapFlingCurve> curve);
void ClearSnapFling();
void SetCurveForTest(std::unique_ptr<SnapFlingCurve> curve);
void SetActiveStateForTest() { state_ = State::kActive; }
raw_ptr<SnapFlingClient> client_;
State state_ = State::kIdle;
std::unique_ptr<SnapFlingCurve> curve_;
};
}
#endif