InputSourceTouch.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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 "../../lib/Point.h"
  12. enum class MouseButton;
  13. struct SDL_TouchFingerEvent;
  14. /// Enumeration that describes current state of gesture recognition
  15. enum class TouchState
  16. {
  17. // special state that allows no transitions
  18. // used when player selects "relative mode" in Launcher
  19. // in this mode touchscreen acts like touchpad, moving cursor at certains speed
  20. // and generates events for positions below cursor instead of positions below touch events
  21. RELATIVE_MODE,
  22. // no active touch events
  23. // DOWN -> transition to TAP_DOWN_SHORT
  24. // MOTION / UP -> not expected
  25. IDLE,
  26. // single finger is touching the screen for a short time
  27. // DOWN -> transition to TAP_DOWN_DOUBLE
  28. // MOTION -> transition to TAP_DOWN_PANNING
  29. // UP -> transition to IDLE, emit onLeftClickDown and onLeftClickUp
  30. // on timer -> transition to TAP_DOWN_LONG, emit onRightClickDown event
  31. TAP_DOWN_SHORT,
  32. // single finger is moving across screen
  33. // DOWN -> transition to TAP_DOWN_DOUBLE
  34. // MOTION -> emit panning event
  35. // UP -> transition to IDLE
  36. TAP_DOWN_PANNING,
  37. // two fingers are touching the screen
  38. // DOWN -> ??? how to handle 3rd finger? Ignore?
  39. // MOTION -> emit pinch event
  40. // UP -> transition to TAP_DOWN
  41. TAP_DOWN_DOUBLE,
  42. // single finger is down for long period of time
  43. // DOWN -> ignored
  44. // MOTION -> ignored
  45. // UP -> transition to TAP_DOWN_LONG_AWAIT
  46. TAP_DOWN_LONG,
  47. // right-click popup is active, waiting for new tap to hide popup
  48. // DOWN -> ignored
  49. // MOTION -> ignored
  50. // UP -> transition to IDLE, generate onRightClickUp() event
  51. TAP_DOWN_LONG_AWAIT,
  52. // Possible transitions:
  53. // -> DOUBLE
  54. // -> PANNING -> IDLE
  55. // IDLE -> DOWN_SHORT -> IDLE
  56. // -> LONG -> IDLE
  57. // -> DOUBLE -> PANNING
  58. // -> IDLE
  59. };
  60. struct TouchInputParameters
  61. {
  62. /// Speed factor of mouse pointer when relative mode is used
  63. double relativeModeSpeedFactor = 1.0;
  64. /// tap for period longer than specified here will be qualified as "long tap", triggering corresponding gesture
  65. uint32_t longTouchTimeMilliseconds = 750;
  66. /// moving finger for distance larger than specified will be qualified as panning gesture instead of long press
  67. uint32_t panningSensitivityThreshold = 10;
  68. /// gesture will be qualified as pinch if distance between fingers is at least specified here
  69. uint32_t pinchSensitivityThreshold = 10;
  70. bool useRelativeMode = false;
  71. };
  72. /// Class that handles touchscreen input from SDL events
  73. class InputSourceTouch
  74. {
  75. TouchInputParameters params;
  76. TouchState state;
  77. uint32_t lastTapTimeTicks;
  78. Point lastTapPosition;
  79. Point convertTouchToMouse(const SDL_TouchFingerEvent & current);
  80. Point convertTouchToMouse(float x, float y);
  81. void emitPanningEvent(const SDL_TouchFingerEvent & tfinger);
  82. void emitPinchEvent(const SDL_TouchFingerEvent & tfinger);
  83. public:
  84. InputSourceTouch();
  85. void handleEventFingerMotion(const SDL_TouchFingerEvent & current);
  86. void handleEventFingerDown(const SDL_TouchFingerEvent & current);
  87. void handleEventFingerUp(const SDL_TouchFingerEvent & current);
  88. void handleUpdate();
  89. bool hasTouchInputDevice() const;
  90. bool isMouseButtonPressed(MouseButton button) const;
  91. };