MapViewActions.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /*
  2. * MapViewActions.cpp, 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. #include "StdInc.h"
  11. #include "MapViewActions.h"
  12. #include "IMapRendererContext.h"
  13. #include "MapView.h"
  14. #include "MapViewModel.h"
  15. #include "../CGameInfo.h"
  16. #include "../adventureMap/AdventureMapInterface.h"
  17. #include "../gui/CGuiHandler.h"
  18. #include "../gui/CursorHandler.h"
  19. #include "../../lib/CConfigHandler.h"
  20. MapViewActions::MapViewActions(MapView & owner, const std::shared_ptr<MapViewModel> & model)
  21. : model(model)
  22. , owner(owner)
  23. , isSwiping(false)
  24. {
  25. pos.w = model->getPixelsVisibleDimensions().x;
  26. pos.h = model->getPixelsVisibleDimensions().y;
  27. addUsedEvents(LCLICK | RCLICK | MCLICK | HOVER | MOVE);
  28. }
  29. bool MapViewActions::swipeEnabled() const
  30. {
  31. #if defined(VCMI_ANDROID) || defined(VCMI_IOS)
  32. return settings["general"]["swipe"].Bool();
  33. #else
  34. return settings["general"]["swipeDesktop"].Bool();
  35. #endif
  36. }
  37. void MapViewActions::setContext(const std::shared_ptr<IMapRendererContext> & context)
  38. {
  39. this->context = context;
  40. }
  41. void MapViewActions::clickLeft(tribool down, bool previousState)
  42. {
  43. if(indeterminate(down))
  44. return;
  45. if(swipeEnabled())
  46. {
  47. if(handleSwipeStateChange(static_cast<bool>(down)))
  48. {
  49. return; // if swipe is enabled, we don't process "down" events and wait for "up" (to make sure this wasn't a swiping gesture)
  50. }
  51. }
  52. else
  53. {
  54. if(down == false)
  55. return;
  56. }
  57. int3 tile = model->getTileAtPoint(GH.getCursorPosition() - pos.topLeft());
  58. if(context->isInMap(tile))
  59. adventureInt->onTileLeftClicked(tile);
  60. }
  61. void MapViewActions::clickRight(tribool down, bool previousState)
  62. {
  63. if(isSwiping)
  64. return;
  65. int3 tile = model->getTileAtPoint(GH.getCursorPosition() - pos.topLeft());
  66. if(down && context->isInMap(tile))
  67. adventureInt->onTileRightClicked(tile);
  68. }
  69. void MapViewActions::clickMiddle(tribool down, bool previousState)
  70. {
  71. handleSwipeStateChange(static_cast<bool>(down));
  72. }
  73. void MapViewActions::mouseMoved(const Point & cursorPosition)
  74. {
  75. handleHover(cursorPosition);
  76. handleSwipeMove(cursorPosition);
  77. }
  78. void MapViewActions::handleSwipeMove(const Point & cursorPosition)
  79. {
  80. // unless swipe is enabled, swipe move only works with middle mouse button
  81. if(!swipeEnabled() && !GH.isMouseButtonPressed(MouseButton::MIDDLE))
  82. return;
  83. // on mobile platforms with enabled swipe we use left button
  84. if(swipeEnabled() && !GH.isMouseButtonPressed(MouseButton::LEFT))
  85. return;
  86. if(!isSwiping)
  87. {
  88. static constexpr int touchSwipeSlop = 16;
  89. Point distance = (cursorPosition - swipeInitialRealPos);
  90. // try to distinguish if this touch was meant to be a swipe or just fat-fingering press
  91. if(std::abs(distance.x) + std::abs(distance.y) > touchSwipeSlop)
  92. isSwiping = true;
  93. }
  94. if(isSwiping)
  95. {
  96. Point swipeTargetPosition = swipeInitialViewPos + swipeInitialRealPos - cursorPosition;
  97. owner.onMapSwiped(swipeTargetPosition);
  98. }
  99. }
  100. bool MapViewActions::handleSwipeStateChange(bool btnPressed)
  101. {
  102. if(btnPressed)
  103. {
  104. swipeInitialRealPos = GH.getCursorPosition();
  105. swipeInitialViewPos = model->getMapViewCenter();
  106. return true;
  107. }
  108. if(isSwiping) // only accept this touch if it wasn't a swipe
  109. {
  110. owner.onMapSwipeEnded();
  111. isSwiping = false;
  112. return true;
  113. }
  114. return false;
  115. }
  116. void MapViewActions::handleHover(const Point & cursorPosition)
  117. {
  118. int3 tile = model->getTileAtPoint(cursorPosition - pos.topLeft());
  119. if(!context->isInMap(tile))
  120. {
  121. CCS->curh->set(Cursor::Map::POINTER);
  122. return;
  123. }
  124. adventureInt->onTileHovered(tile);
  125. }
  126. void MapViewActions::hover(bool on)
  127. {
  128. if(!on)
  129. {
  130. GH.statusbar()->clear();
  131. CCS->curh->set(Cursor::Map::POINTER);
  132. }
  133. }