MapViewActions.cpp 4.1 KB

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