2023-05-18 19:32:29 +02:00
|
|
|
/*
|
|
|
|
* InputSourceTouch.h, part of VCMI engine
|
|
|
|
*
|
|
|
|
* Authors: listed in file AUTHORS in main folder
|
|
|
|
*
|
|
|
|
* License: GNU General Public License v2.0 or later
|
|
|
|
* Full text of license available in license.txt file, in main folder
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2023-05-26 21:17:36 +02:00
|
|
|
#include "../../lib/Point.h"
|
2023-05-18 19:32:29 +02:00
|
|
|
|
2023-05-26 14:55:31 +02:00
|
|
|
enum class MouseButton;
|
2023-05-18 19:32:29 +02:00
|
|
|
struct SDL_TouchFingerEvent;
|
|
|
|
|
2023-05-26 17:55:26 +02:00
|
|
|
/// Enumeration that describes current state of gesture recognition
|
|
|
|
enum class TouchState
|
|
|
|
{
|
|
|
|
// special state that allows no transitions
|
|
|
|
// used when player selects "relative mode" in Launcher
|
|
|
|
// in this mode touchscreen acts like touchpad, moving cursor at certains speed
|
|
|
|
// and generates events for positions below cursor instead of positions below touch events
|
|
|
|
RELATIVE_MODE,
|
|
|
|
|
|
|
|
// no active touch events
|
|
|
|
// DOWN -> transition to TAP_DOWN_SHORT
|
|
|
|
// MOTION / UP -> not expected
|
|
|
|
IDLE,
|
|
|
|
|
|
|
|
// single finger is touching the screen for a short time
|
|
|
|
// DOWN -> transition to TAP_DOWN_DOUBLE
|
|
|
|
// MOTION -> transition to TAP_DOWN_PANNING
|
|
|
|
// UP -> transition to IDLE, emit onLeftClickDown and onLeftClickUp
|
|
|
|
// on timer -> transition to TAP_DOWN_LONG, emit onRightClickDown event
|
|
|
|
TAP_DOWN_SHORT,
|
|
|
|
|
|
|
|
// single finger is moving across screen
|
|
|
|
// DOWN -> transition to TAP_DOWN_DOUBLE
|
|
|
|
// MOTION -> emit panning event
|
|
|
|
// UP -> transition to IDLE
|
|
|
|
TAP_DOWN_PANNING,
|
|
|
|
|
|
|
|
// two fingers are touching the screen
|
|
|
|
// DOWN -> ??? how to handle 3rd finger? Ignore?
|
|
|
|
// MOTION -> emit pinch event
|
|
|
|
// UP -> transition to TAP_DOWN
|
|
|
|
TAP_DOWN_DOUBLE,
|
|
|
|
|
|
|
|
// single finger is down for long period of time
|
|
|
|
// DOWN -> ignored
|
|
|
|
// MOTION -> ignored
|
2023-05-29 18:21:09 +02:00
|
|
|
// UP -> transition to TAP_DOWN_LONG_AWAIT
|
2023-05-26 17:55:26 +02:00
|
|
|
TAP_DOWN_LONG,
|
|
|
|
|
2023-05-29 18:21:09 +02:00
|
|
|
// right-click popup is active, waiting for new tap to hide popup
|
|
|
|
// DOWN -> ignored
|
|
|
|
// MOTION -> ignored
|
|
|
|
// UP -> transition to IDLE, generate onRightClickUp() event
|
|
|
|
TAP_DOWN_LONG_AWAIT,
|
|
|
|
|
2023-05-26 17:55:26 +02:00
|
|
|
|
|
|
|
// Possible transitions:
|
|
|
|
// -> DOUBLE
|
|
|
|
// -> PANNING -> IDLE
|
|
|
|
// IDLE -> DOWN_SHORT -> IDLE
|
|
|
|
// -> LONG -> IDLE
|
|
|
|
// -> DOUBLE -> PANNING
|
|
|
|
// -> IDLE
|
|
|
|
};
|
|
|
|
|
|
|
|
struct TouchInputParameters
|
|
|
|
{
|
|
|
|
double relativeModeSpeedFactor = 1.0;
|
2023-05-26 21:17:36 +02:00
|
|
|
|
|
|
|
/// tap for period longer than specified here will be qualified as "long tap", triggering corresponding gesture
|
2023-05-26 17:55:26 +02:00
|
|
|
uint32_t longPressTimeMilliseconds = 500;
|
|
|
|
|
2023-05-26 21:17:36 +02:00
|
|
|
/// moving finger for distance larger than specified will be qualified as panning gesture instead of long press
|
|
|
|
uint32_t panningSensitivityThreshold = 16;
|
|
|
|
|
2023-05-26 17:55:26 +02:00
|
|
|
bool useHoldGesture = true;
|
|
|
|
bool usePanGesture = true;
|
|
|
|
bool usePinchGesture = true;
|
|
|
|
bool useRelativeMode = false;
|
|
|
|
};
|
|
|
|
|
2023-05-20 00:51:10 +02:00
|
|
|
/// Class that handles touchscreen input from SDL events
|
2023-05-18 19:32:29 +02:00
|
|
|
class InputSourceTouch
|
|
|
|
{
|
2023-05-26 17:55:26 +02:00
|
|
|
TouchInputParameters params;
|
|
|
|
TouchState state;
|
|
|
|
uint32_t lastTapTimeTicks;
|
2023-05-26 21:17:36 +02:00
|
|
|
Point lastTapPosition;
|
2023-05-18 19:32:29 +02:00
|
|
|
|
|
|
|
Point convertTouchToMouse(const SDL_TouchFingerEvent & current);
|
|
|
|
|
2023-05-26 21:17:36 +02:00
|
|
|
void emitPanningEvent(const SDL_TouchFingerEvent & tfinger);
|
|
|
|
void emitPinchEvent(const SDL_TouchFingerEvent & tfinger);
|
2023-05-18 19:32:29 +02:00
|
|
|
|
|
|
|
public:
|
|
|
|
InputSourceTouch();
|
|
|
|
|
|
|
|
void handleEventFingerMotion(const SDL_TouchFingerEvent & current);
|
|
|
|
void handleEventFingerDown(const SDL_TouchFingerEvent & current);
|
|
|
|
void handleEventFingerUp(const SDL_TouchFingerEvent & current);
|
2023-05-26 14:55:31 +02:00
|
|
|
|
2023-05-26 17:55:26 +02:00
|
|
|
void handleUpdate();
|
|
|
|
|
2023-05-30 19:08:27 +02:00
|
|
|
bool hasTouchInputDevice() const;
|
2023-05-26 14:55:31 +02:00
|
|
|
bool isMouseButtonPressed(MouseButton button) const;
|
2023-05-18 19:32:29 +02:00
|
|
|
};
|