mirror of
https://github.com/vcmi/vcmi.git
synced 2025-03-17 20:58:07 +02:00
commit
461aa97d7e
@ -48,7 +48,7 @@ void InputSourceMouse::handleEventMouseButtonDown(const SDL_MouseButtonEvent & b
|
||||
{
|
||||
case SDL_BUTTON_LEFT:
|
||||
if(button.clicks > 1)
|
||||
GH.events().dispatchMouseDoubleClick(position);
|
||||
GH.events().dispatchMouseDoubleClick(position, 0);
|
||||
else
|
||||
GH.events().dispatchMouseLeftButtonPressed(position, 0);
|
||||
break;
|
||||
|
@ -33,7 +33,7 @@
|
||||
#include <SDL_timer.h>
|
||||
|
||||
InputSourceTouch::InputSourceTouch()
|
||||
: lastTapTimeTicks(0)
|
||||
: lastTapTimeTicks(0), lastLeftClickTimeTicks(0)
|
||||
{
|
||||
params.useRelativeMode = settings["general"]["userRelativePointer"].Bool();
|
||||
params.relativeModeSpeedFactor = settings["general"]["relativePointerSpeedMultiplier"].Float();
|
||||
@ -181,8 +181,18 @@ void InputSourceTouch::handleEventFingerUp(const SDL_TouchFingerEvent & tfinger)
|
||||
case TouchState::TAP_DOWN_SHORT:
|
||||
{
|
||||
GH.input().setCursorPosition(convertTouchToMouse(tfinger));
|
||||
GH.events().dispatchMouseLeftButtonPressed(convertTouchToMouse(tfinger), params.touchToleranceDistance);
|
||||
GH.events().dispatchMouseLeftButtonReleased(convertTouchToMouse(tfinger), params.touchToleranceDistance);
|
||||
if(tfinger.timestamp - lastLeftClickTimeTicks < params.doubleTouchTimeMilliseconds && (convertTouchToMouse(tfinger) - lastLeftClickPosition).length() < params.doubleTouchToleranceDistance)
|
||||
{
|
||||
GH.events().dispatchMouseDoubleClick(convertTouchToMouse(tfinger), params.touchToleranceDistance);
|
||||
GH.events().dispatchMouseLeftButtonReleased(convertTouchToMouse(tfinger), params.touchToleranceDistance);
|
||||
}
|
||||
else
|
||||
{
|
||||
GH.events().dispatchMouseLeftButtonPressed(convertTouchToMouse(tfinger), params.touchToleranceDistance);
|
||||
GH.events().dispatchMouseLeftButtonReleased(convertTouchToMouse(tfinger), params.touchToleranceDistance);
|
||||
lastLeftClickTimeTicks = tfinger.timestamp;
|
||||
lastLeftClickPosition = convertTouchToMouse(tfinger);
|
||||
}
|
||||
state = TouchState::IDLE;
|
||||
break;
|
||||
}
|
||||
|
@ -72,6 +72,12 @@ struct TouchInputParameters
|
||||
/// tap for period longer than specified here will be qualified as "long tap", triggering corresponding gesture
|
||||
uint32_t longTouchTimeMilliseconds = 750;
|
||||
|
||||
/// time span in where the second tap has to happen for qualifing as "double click"
|
||||
uint32_t doubleTouchTimeMilliseconds = 500;
|
||||
|
||||
/// max distance in where the second tap has to happen for qualifing as "double click"
|
||||
uint32_t doubleTouchToleranceDistance = 50;
|
||||
|
||||
/// moving finger for distance larger than specified will be qualified as panning gesture instead of long press
|
||||
uint32_t panningSensitivityThreshold = 10;
|
||||
|
||||
@ -94,6 +100,9 @@ class InputSourceTouch
|
||||
uint32_t lastTapTimeTicks;
|
||||
Point lastTapPosition;
|
||||
|
||||
uint32_t lastLeftClickTimeTicks;
|
||||
Point lastLeftClickPosition;
|
||||
|
||||
Point convertTouchToMouse(const SDL_TouchFingerEvent & current);
|
||||
Point convertTouchToMouse(float x, float y);
|
||||
|
||||
|
@ -116,25 +116,9 @@ void EventDispatcher::dispatchShortcutReleased(const std::vector<EShortcut> & sh
|
||||
}
|
||||
}
|
||||
|
||||
void EventDispatcher::dispatchMouseDoubleClick(const Point & position)
|
||||
void EventDispatcher::dispatchMouseDoubleClick(const Point & position, int tolerance)
|
||||
{
|
||||
bool doubleClicked = false;
|
||||
auto hlp = doubleClickInterested;
|
||||
|
||||
for(auto & i : hlp)
|
||||
{
|
||||
if(!vstd::contains(doubleClickInterested, i))
|
||||
continue;
|
||||
|
||||
if(i->receiveEvent(position, AEventsReceiver::DOUBLECLICK))
|
||||
{
|
||||
i->clickDouble(position);
|
||||
doubleClicked = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!doubleClicked)
|
||||
handleLeftButtonClick(position, 0, true);
|
||||
handleDoubleButtonClick(position, tolerance);
|
||||
}
|
||||
|
||||
void EventDispatcher::dispatchMouseLeftButtonPressed(const Point & position, int tolerance)
|
||||
@ -246,6 +230,38 @@ void EventDispatcher::handleLeftButtonClick(const Point & position, int toleranc
|
||||
}
|
||||
}
|
||||
|
||||
void EventDispatcher::handleDoubleButtonClick(const Point & position, int tolerance)
|
||||
{
|
||||
// WARNING: this approach is NOT SAFE
|
||||
// 1) We allow (un)registering elements when list itself is being processed/iterated
|
||||
// 2) To avoid iterator invalidation we create a copy of this list for processing
|
||||
// HOWEVER it is completely possible (as in, actually happen, no just theory) to:
|
||||
// 1) element gets unregistered and deleted from lclickable
|
||||
// 2) element is completely deleted, as in - destructor called, memory freed
|
||||
// 3) new element is created *with exactly same address(!)
|
||||
// 4) new element is registered and code will incorrectly assume that this element is still registered
|
||||
// POSSIBLE SOLUTION: make EventReceivers inherit from create_shared_from this and store weak_ptr's in lists
|
||||
|
||||
AEventsReceiver * nearestElement = findElementInToleranceRange(doubleClickInterested, position, AEventsReceiver::DOUBLECLICK, tolerance);
|
||||
bool doubleClicked = false;
|
||||
auto hlp = doubleClickInterested;
|
||||
|
||||
for(auto & i : hlp)
|
||||
{
|
||||
if(!vstd::contains(doubleClickInterested, i))
|
||||
continue;
|
||||
|
||||
if(i->receiveEvent(position, AEventsReceiver::DOUBLECLICK) || i == nearestElement)
|
||||
{
|
||||
i->clickDouble(position);
|
||||
doubleClicked = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!doubleClicked)
|
||||
handleLeftButtonClick(position, tolerance, true);
|
||||
}
|
||||
|
||||
void EventDispatcher::dispatchMouseScrolled(const Point & distance, const Point & position)
|
||||
{
|
||||
EventReceiversList hlp = wheelInterested;
|
||||
|
@ -36,6 +36,7 @@ class EventDispatcher
|
||||
EventReceiversList panningInterested;
|
||||
|
||||
void handleLeftButtonClick(const Point & position, int tolerance, bool isPressed);
|
||||
void handleDoubleButtonClick(const Point & position, int tolerance);
|
||||
AEventsReceiver * findElementInToleranceRange(const EventReceiversList & list, const Point & position, int eventToTest, int tolerance);
|
||||
|
||||
template<typename Functor>
|
||||
@ -59,7 +60,7 @@ public:
|
||||
void dispatchMouseLeftButtonPressed(const Point & position, int tolerance);
|
||||
void dispatchMouseLeftButtonReleased(const Point & position, int tolerance);
|
||||
void dispatchMouseScrolled(const Point & distance, const Point & position);
|
||||
void dispatchMouseDoubleClick(const Point & position);
|
||||
void dispatchMouseDoubleClick(const Point & position, int tolerance);
|
||||
void dispatchMouseMoved(const Point & distance, const Point & position);
|
||||
|
||||
void dispatchMouseDragged(const Point & currentPosition, const Point & lastUpdateDistance);
|
||||
|
Loading…
x
Reference in New Issue
Block a user