1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-04-11 11:31:52 +02:00

added tolerance

This commit is contained in:
Laserlicht 2023-09-18 20:35:23 +02:00 committed by GitHub
parent 71659f1423
commit 2d2c7ee8e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 21 deletions

View File

@ -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;

View File

@ -182,7 +182,10 @@ void InputSourceTouch::handleEventFingerUp(const SDL_TouchFingerEvent & tfinger)
{
GH.input().setCursorPosition(convertTouchToMouse(tfinger));
if(tfinger.timestamp - lastLeftClickTimeTicks < params.doubleTouchTimeMilliseconds && (convertTouchToMouse(tfinger) - lastLeftClickPosition).length() < params.doubleTouchToleranceDistance)
GH.events().dispatchMouseDoubleClick(convertTouchToMouse(tfinger));
{
GH.events().dispatchMouseDoubleClick(convertTouchToMouse(tfinger), params.touchToleranceDistance);
GH.events().dispatchMouseLeftButtonReleased(convertTouchToMouse(tfinger), params.touchToleranceDistance);
}
else
{
GH.events().dispatchMouseLeftButtonPressed(convertTouchToMouse(tfinger), params.touchToleranceDistance);

View File

@ -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;

View File

@ -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);