mirror of
https://github.com/vcmi/vcmi.git
synced 2025-03-21 21:17:49 +02:00
Implemented pinch gesture to scale adventure map
This commit is contained in:
parent
a08ff1e6ef
commit
0f2a339ab5
@ -204,7 +204,12 @@ void InputSourceTouch::handleUpdate()
|
|||||||
|
|
||||||
Point InputSourceTouch::convertTouchToMouse(const SDL_TouchFingerEvent & tfinger)
|
Point InputSourceTouch::convertTouchToMouse(const SDL_TouchFingerEvent & tfinger)
|
||||||
{
|
{
|
||||||
return Point(tfinger.x * GH.screenDimensions().x, tfinger.y * GH.screenDimensions().y);
|
return convertTouchToMouse(tfinger.x, tfinger.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
Point InputSourceTouch::convertTouchToMouse(float x, float y)
|
||||||
|
{
|
||||||
|
return Point(x * GH.screenDimensions().x, y * GH.screenDimensions().y);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InputSourceTouch::hasTouchInputDevice() const
|
bool InputSourceTouch::hasTouchInputDevice() const
|
||||||
@ -225,12 +230,51 @@ bool InputSourceTouch::isMouseButtonPressed(MouseButton button) const
|
|||||||
|
|
||||||
void InputSourceTouch::emitPanningEvent(const SDL_TouchFingerEvent & tfinger)
|
void InputSourceTouch::emitPanningEvent(const SDL_TouchFingerEvent & tfinger)
|
||||||
{
|
{
|
||||||
Point distance(-tfinger.dx * GH.screenDimensions().x, -tfinger.dy * GH.screenDimensions().y);
|
Point distance = convertTouchToMouse(-tfinger.dx, -tfinger.dy);
|
||||||
|
|
||||||
GH.events().dispatchGesturePanning(lastTapPosition, convertTouchToMouse(tfinger), distance);
|
GH.events().dispatchGesturePanning(lastTapPosition, convertTouchToMouse(tfinger), distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputSourceTouch::emitPinchEvent(const SDL_TouchFingerEvent & tfinger)
|
void InputSourceTouch::emitPinchEvent(const SDL_TouchFingerEvent & tfinger)
|
||||||
{
|
{
|
||||||
// TODO
|
int fingers = SDL_GetNumTouchFingers(tfinger.touchId);
|
||||||
|
|
||||||
|
if (fingers < 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool otherFingerFound = false;
|
||||||
|
double otherX;
|
||||||
|
double otherY;
|
||||||
|
|
||||||
|
for (int i = 0; i < fingers; ++i)
|
||||||
|
{
|
||||||
|
SDL_Finger * finger = SDL_GetTouchFinger(tfinger.touchId, i);
|
||||||
|
|
||||||
|
if (finger && finger->id != tfinger.fingerId)
|
||||||
|
{
|
||||||
|
otherX = finger->x * GH.screenDimensions().x;
|
||||||
|
otherY = finger->y * GH.screenDimensions().y;
|
||||||
|
otherFingerFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!otherFingerFound)
|
||||||
|
return; // should be impossible, but better to avoid weird edge cases
|
||||||
|
|
||||||
|
float thisX = tfinger.x * GH.screenDimensions().x;
|
||||||
|
float thisY = tfinger.y * GH.screenDimensions().y;
|
||||||
|
float deltaX = tfinger.dx * GH.screenDimensions().x;
|
||||||
|
float deltaY = tfinger.dy * GH.screenDimensions().y;
|
||||||
|
|
||||||
|
float oldX = thisX - deltaX - otherX;
|
||||||
|
float oldY = thisY - deltaY - otherY;
|
||||||
|
float newX = thisX - otherX;
|
||||||
|
float newY = thisY - otherY;
|
||||||
|
|
||||||
|
double distanceOld = std::sqrt(oldX * oldX + oldY + oldY);
|
||||||
|
double distanceNew = std::sqrt(newX * newX + newY + newY);
|
||||||
|
|
||||||
|
if (distanceOld > params.pinchSensitivityThreshold)
|
||||||
|
GH.events().dispatchGesturePinch(lastTapPosition, distanceNew / distanceOld);
|
||||||
}
|
}
|
||||||
|
@ -81,6 +81,9 @@ struct TouchInputParameters
|
|||||||
/// moving finger for distance larger than specified will be qualified as panning gesture instead of long press
|
/// moving finger for distance larger than specified will be qualified as panning gesture instead of long press
|
||||||
uint32_t panningSensitivityThreshold = 10;
|
uint32_t panningSensitivityThreshold = 10;
|
||||||
|
|
||||||
|
/// gesture will be qualified as pinch if distance between fingers is at least specified here
|
||||||
|
uint32_t pinchSensitivityThreshold = 10;
|
||||||
|
|
||||||
bool useRelativeMode = false;
|
bool useRelativeMode = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -93,6 +96,7 @@ class InputSourceTouch
|
|||||||
Point lastTapPosition;
|
Point lastTapPosition;
|
||||||
|
|
||||||
Point convertTouchToMouse(const SDL_TouchFingerEvent & current);
|
Point convertTouchToMouse(const SDL_TouchFingerEvent & current);
|
||||||
|
Point convertTouchToMouse(float x, float y);
|
||||||
|
|
||||||
void emitPanningEvent(const SDL_TouchFingerEvent & tfinger);
|
void emitPanningEvent(const SDL_TouchFingerEvent & tfinger);
|
||||||
void emitPinchEvent(const SDL_TouchFingerEvent & tfinger);
|
void emitPinchEvent(const SDL_TouchFingerEvent & tfinger);
|
||||||
|
@ -254,6 +254,15 @@ void EventDispatcher::dispatchGesturePanning(const Point & initialPosition, cons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EventDispatcher::dispatchGesturePinch(const Point & initialPosition, double distance)
|
||||||
|
{
|
||||||
|
for(auto it : panningInterested)
|
||||||
|
{
|
||||||
|
if (it->isPanning())
|
||||||
|
it->gesturePinch(initialPosition, distance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void EventDispatcher::dispatchMouseMoved(const Point & position)
|
void EventDispatcher::dispatchMouseMoved(const Point & position)
|
||||||
{
|
{
|
||||||
EventReceiversList newlyHovered;
|
EventReceiversList newlyHovered;
|
||||||
|
@ -65,6 +65,7 @@ public:
|
|||||||
void dispatchGesturePanningStarted(const Point & initialPosition);
|
void dispatchGesturePanningStarted(const Point & initialPosition);
|
||||||
void dispatchGesturePanningEnded(const Point & initialPosition, const Point & finalPosition);
|
void dispatchGesturePanningEnded(const Point & initialPosition, const Point & finalPosition);
|
||||||
void dispatchGesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance);
|
void dispatchGesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance);
|
||||||
|
void dispatchGesturePinch(const Point & initialPosition, double distance);
|
||||||
|
|
||||||
/// Text input events
|
/// Text input events
|
||||||
void dispatchTextInput(const std::string & text);
|
void dispatchTextInput(const std::string & text);
|
||||||
|
@ -42,6 +42,8 @@ protected:
|
|||||||
/// Called when user pans screen by specified distance
|
/// Called when user pans screen by specified distance
|
||||||
virtual void gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) {}
|
virtual void gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) {}
|
||||||
|
|
||||||
|
virtual void gesturePinch(const Point & centerPosition, double lastUpdateFactor) {}
|
||||||
|
|
||||||
virtual void wheelScrolled(int distance) {}
|
virtual void wheelScrolled(int distance) {}
|
||||||
virtual void mouseMoved(const Point & cursorPosition) {}
|
virtual void mouseMoved(const Point & cursorPosition) {}
|
||||||
|
|
||||||
|
@ -20,11 +20,15 @@
|
|||||||
#include "../gui/CursorHandler.h"
|
#include "../gui/CursorHandler.h"
|
||||||
#include "../gui/MouseButton.h"
|
#include "../gui/MouseButton.h"
|
||||||
|
|
||||||
|
#include "../CPlayerInterface.h"
|
||||||
|
#include "../adventureMap/CInGameConsole.h"
|
||||||
|
|
||||||
#include "../../lib/CConfigHandler.h"
|
#include "../../lib/CConfigHandler.h"
|
||||||
|
|
||||||
MapViewActions::MapViewActions(MapView & owner, const std::shared_ptr<MapViewModel> & model)
|
MapViewActions::MapViewActions(MapView & owner, const std::shared_ptr<MapViewModel> & model)
|
||||||
: model(model)
|
: model(model)
|
||||||
, owner(owner)
|
, owner(owner)
|
||||||
|
, pinchZoomFactor(1.0)
|
||||||
{
|
{
|
||||||
pos.w = model->getPixelsVisibleDimensions().x;
|
pos.w = model->getPixelsVisibleDimensions().x;
|
||||||
pos.h = model->getPixelsVisibleDimensions().y;
|
pos.h = model->getPixelsVisibleDimensions().y;
|
||||||
@ -66,7 +70,7 @@ void MapViewActions::mouseMoved(const Point & cursorPosition)
|
|||||||
|
|
||||||
void MapViewActions::wheelScrolled(int distance)
|
void MapViewActions::wheelScrolled(int distance)
|
||||||
{
|
{
|
||||||
adventureInt->hotkeyZoom(distance);
|
adventureInt->hotkeyZoom(distance * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapViewActions::gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance)
|
void MapViewActions::gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance)
|
||||||
@ -74,6 +78,24 @@ void MapViewActions::gesturePanning(const Point & initialPosition, const Point &
|
|||||||
owner.onMapSwiped(lastUpdateDistance);
|
owner.onMapSwiped(lastUpdateDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MapViewActions::gesturePinch(const Point & centerPosition, double lastUpdateFactor)
|
||||||
|
{
|
||||||
|
double newZoom = pinchZoomFactor * lastUpdateFactor;
|
||||||
|
|
||||||
|
int newZoomSteps = std::round(std::log(newZoom) / std::log(1.01));
|
||||||
|
int oldZoomSteps = std::round(std::log(pinchZoomFactor) / std::log(1.01));
|
||||||
|
|
||||||
|
if (newZoomSteps != oldZoomSteps)
|
||||||
|
adventureInt->hotkeyZoom(newZoomSteps - oldZoomSteps);
|
||||||
|
|
||||||
|
pinchZoomFactor = newZoom;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapViewActions::panning(bool on, const Point & initialPosition, const Point & finalPosition)
|
||||||
|
{
|
||||||
|
pinchZoomFactor = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
void MapViewActions::handleHover(const Point & cursorPosition)
|
void MapViewActions::handleHover(const Point & cursorPosition)
|
||||||
{
|
{
|
||||||
int3 tile = model->getTileAtPoint(cursorPosition - pos.topLeft());
|
int3 tile = model->getTileAtPoint(cursorPosition - pos.topLeft());
|
||||||
|
@ -22,6 +22,8 @@ class MapViewActions : public CIntObject
|
|||||||
std::shared_ptr<MapViewModel> model;
|
std::shared_ptr<MapViewModel> model;
|
||||||
std::shared_ptr<IMapRendererContext> context;
|
std::shared_ptr<IMapRendererContext> context;
|
||||||
|
|
||||||
|
double pinchZoomFactor;
|
||||||
|
|
||||||
void handleHover(const Point & cursorPosition);
|
void handleHover(const Point & cursorPosition);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -32,7 +34,9 @@ public:
|
|||||||
void clickLeft(tribool down, bool previousState) override;
|
void clickLeft(tribool down, bool previousState) override;
|
||||||
void clickRight(tribool down, bool previousState) override;
|
void clickRight(tribool down, bool previousState) override;
|
||||||
void gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) override;
|
void gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) override;
|
||||||
|
void gesturePinch(const Point & centerPosition, double lastUpdateFactor) override;
|
||||||
void hover(bool on) override;
|
void hover(bool on) override;
|
||||||
|
void panning(bool on, const Point & initialPosition, const Point & finalPosition) override;
|
||||||
void mouseMoved(const Point & cursorPosition) override;
|
void mouseMoved(const Point & cursorPosition) override;
|
||||||
void wheelScrolled(int distance) override;
|
void wheelScrolled(int distance) override;
|
||||||
};
|
};
|
||||||
|
@ -91,9 +91,9 @@ void MapViewController::modifyTileSize(int stepsChange)
|
|||||||
// so, zooming in for 5 steps will put game at 1.1^5 = 1.61 scale
|
// so, zooming in for 5 steps will put game at 1.1^5 = 1.61 scale
|
||||||
// try to determine current zooming level and change it by requested number of steps
|
// try to determine current zooming level and change it by requested number of steps
|
||||||
double currentZoomFactor = model->getSingleTileSize().x / 32.0;
|
double currentZoomFactor = model->getSingleTileSize().x / 32.0;
|
||||||
double currentZoomSteps = std::round(std::log(currentZoomFactor) / std::log(1.1));
|
double currentZoomSteps = std::round(std::log(currentZoomFactor) / std::log(1.01));
|
||||||
double newZoomSteps = stepsChange != 0 ? currentZoomSteps + stepsChange : stepsChange;
|
double newZoomSteps = stepsChange != 0 ? currentZoomSteps + stepsChange : stepsChange;
|
||||||
double newZoomFactor = std::pow(1.1, newZoomSteps);
|
double newZoomFactor = std::pow(1.01, newZoomSteps);
|
||||||
|
|
||||||
Point currentZoom = model->getSingleTileSize();
|
Point currentZoom = model->getSingleTileSize();
|
||||||
Point desiredZoom = Point(32,32) * newZoomFactor;
|
Point desiredZoom = Point(32,32) * newZoomFactor;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user