Modules/Graphics/public/TouchGesture.hpp
Шурупов Илья Викторович 2ce06b4276 Recognize quick multi-finger taps
The gesture tracker follows every finger of a touch. When two or more
fingers touch and all lift within 300 ms without moving more than
20 px, the ending gesture reports how many fingers tapped. Android
passes the motion event time to the tracker.
2026-10-17 11:13:20 +03:00

56 lines
1.3 KiB
C++

#pragma once
#include "Vec.hpp"
#include <cstdint>
#include <vector>
namespace tp {
enum class GesturePhase { Begin, Update, End };
struct TouchGesture {
GesturePhase phase = GesturePhase::Update;
Vec2F center = { 0, 0 };
Vec2F pan = { 0, 0 };
halnf scale = 1;
halnf rotation = 0;
int32_t tapFingers = 0;
[[nodiscard]] bool operator==(const TouchGesture& other) const = default;
};
struct TouchPoint {
int32_t id = 0;
Vec2F position = { 0, 0 };
};
class TouchGestureTracker {
public:
static constexpr uint32_t kTapMaximumMs = 300;
static constexpr halnf kTapMaximumTravel = 20;
void update(const std::vector<TouchPoint>& touches, std::vector<TouchGesture>& gestures, uint32_t timeMs = 0);
void cancel(std::vector<TouchGesture>& gestures);
[[nodiscard]] bool isActive() const { return mActive; }
private:
void track(const TouchPoint& first, const TouchPoint& second);
void followTap(const std::vector<TouchPoint>& touches, uint32_t timeMs);
[[nodiscard]] int32_t finishedTapFingers(uint32_t timeMs) const;
std::vector<TouchPoint> mTapStarts;
uint32_t mTapStartMs = 0;
bool mTapStillPossible = false;
bool mActive = false;
int32_t mFirst = 0;
int32_t mSecond = 0;
Vec2F mCenter = { 0, 0 };
halnf mDistance = 0;
halnf mAngle = 0;
};
void accumulate(TouchGesture& into, const TouchGesture& next);
}