InputSourceTouch.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*
  2. * InputSourceTouch.h, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #pragma once
  11. #include "SDL_touch.h"
  12. #include "../../lib/Point.h"
  13. // Debug option. If defined, mouse events will instead generate touch events, allowing testing of touch input on desktop
  14. // #define VCMI_EMULATE_TOUCHSCREEN_WITH_MOUSE
  15. enum class MouseButton;
  16. struct SDL_TouchFingerEvent;
  17. /// Enumeration that describes current state of gesture recognition
  18. enum class TouchState
  19. {
  20. // special state that allows no transitions
  21. // used when player selects "relative mode" in Launcher
  22. // in this mode touchscreen acts like touchpad, moving cursor at certains speed
  23. // and generates events for positions below cursor instead of positions below touch events
  24. RELATIVE_MODE,
  25. // no active touch events
  26. // DOWN -> transition to TAP_DOWN_SHORT
  27. // MOTION / UP -> not expected
  28. IDLE,
  29. // single finger is touching the screen for a short time
  30. // DOWN -> transition to TAP_DOWN_DOUBLE
  31. // MOTION -> transition to TAP_DOWN_PANNING
  32. // UP -> transition to IDLE, emit onLeftClickDown and onLeftClickUp
  33. // on timer -> transition to TAP_DOWN_LONG, emit showPopup() event
  34. TAP_DOWN_SHORT,
  35. // single finger is moving across screen
  36. // DOWN -> transition to TAP_DOWN_DOUBLE
  37. // MOTION -> emit panning event
  38. // UP -> transition to IDLE
  39. TAP_DOWN_PANNING,
  40. // single finger is moving across screen
  41. // DOWN -> ignored
  42. // MOTION -> emit panning event
  43. // UP -> transition to TAP_DOWN_LONG_AWAIT
  44. TAP_DOWN_PANNING_POPUP,
  45. // two fingers are touching the screen
  46. // DOWN -> ??? how to handle 3rd finger? Ignore?
  47. // MOTION -> emit pinch event
  48. // UP -> transition to TAP_DOWN
  49. TAP_DOWN_DOUBLE,
  50. // single finger is down for long period of time
  51. // DOWN -> ignored
  52. // MOTION -> ignored
  53. // UP -> transition to TAP_DOWN_LONG_AWAIT
  54. TAP_DOWN_LONG,
  55. // right-click popup is active, waiting for new tap to hide popup
  56. // DOWN -> ignored
  57. // MOTION -> transition to TAP_DOWN_PANNING_POPUP
  58. // UP -> transition to IDLE, generate closePopup() event
  59. TAP_DOWN_LONG_AWAIT,
  60. };
  61. struct TouchInputParameters
  62. {
  63. /// Speed factor of mouse pointer when relative mode is used
  64. double relativeModeSpeedFactor = 1.0;
  65. /// tap for period longer than specified here will be qualified as "long tap", triggering corresponding gesture
  66. uint32_t longTouchTimeMilliseconds = 750;
  67. /// time span in where the second tap has to happen for qualifing as "double click"
  68. uint32_t doubleTouchTimeMilliseconds = 500;
  69. /// max distance in where the second tap has to happen for qualifing as "double click"
  70. uint32_t doubleTouchToleranceDistance = 50;
  71. /// moving finger for distance larger than specified will be qualified as panning gesture instead of long press
  72. uint32_t panningSensitivityThreshold = 15;
  73. /// gesture will be qualified as pinch if distance between fingers is at least specified here
  74. uint32_t pinchSensitivityThreshold = 10;
  75. /// touch event will trigger clicking of elements up to X pixels away from actual touch position
  76. uint32_t touchToleranceDistance = 20;
  77. bool useRelativeMode = false;
  78. bool hapticFeedbackEnabled = false;
  79. };
  80. /// Class that handles touchscreen input from SDL events
  81. class InputSourceTouch
  82. {
  83. TouchInputParameters params;
  84. TouchState state;
  85. uint32_t lastTapTimeTicks;
  86. Point lastTapPosition;
  87. uint32_t lastLeftClickTimeTicks;
  88. Point lastLeftClickPosition;
  89. int numTouchFingers;
  90. std::map<SDL_FingerID, float> motionAccumulatedX;
  91. std::map<SDL_FingerID, float> motionAccumulatedY;
  92. Point convertTouchToMouse(const SDL_TouchFingerEvent & current);
  93. Point convertTouchToMouse(float x, float y);
  94. void emitPanningEvent(const SDL_TouchFingerEvent & tfinger);
  95. void emitPinchEvent(const SDL_TouchFingerEvent & tfinger);
  96. public:
  97. InputSourceTouch();
  98. void handleEventFingerMotion(const SDL_TouchFingerEvent & current);
  99. void handleEventFingerDown(const SDL_TouchFingerEvent & current);
  100. void handleEventFingerUp(const SDL_TouchFingerEvent & current);
  101. void hapticFeedback();
  102. void handleUpdate();
  103. bool hasTouchInputDevice() const;
  104. int getNumTouchFingers() const;
  105. };