MapViewActions.cpp 4.1 KB

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