improve gesture recognition
In order to not make misdetections with sub-pixel movements the gesture recognizer completely ignored those. This fails however when you move your fingers very slowly, so instead accumulate the delta and only use it for direction detection if it's high enough.
This commit is contained in:
parent
eb62dbb9c5
commit
fe11219a0c
2 changed files with 21 additions and 7 deletions
|
@ -142,24 +142,30 @@ int GestureRecognizer::startSwipeGesture(uint fingerCount, const QPointF &startP
|
|||
void GestureRecognizer::updateSwipeGesture(const QSizeF &delta)
|
||||
{
|
||||
m_swipeUpdates << delta;
|
||||
if (std::abs(delta.width()) < 1 && std::abs(delta.height()) < 1) {
|
||||
// some (touch) devices report sub-pixel movement on screen edges
|
||||
// this often cancels gestures -> ignore these movements
|
||||
m_currentDelta += delta;
|
||||
// with high resolution touch(pad) gestures can be cancelled without intention
|
||||
// -> don't cancel movements if their accumulated values are too small but also still update the gesture for animations
|
||||
if (std::abs(m_currentDelta.width()) > 1 || std::abs(m_currentDelta.height()) > 1) {
|
||||
m_lastDelta = m_currentDelta;
|
||||
m_currentDelta = QSizeF(0, 0);
|
||||
} else if (std::abs(m_lastDelta.width()) < 1 && std::abs(m_lastDelta.height()) < 1) {
|
||||
// no direction yet
|
||||
return;
|
||||
}
|
||||
|
||||
// determine the direction of the swipe
|
||||
if (delta.width() == delta.height()) {
|
||||
if (m_lastDelta.width() == m_lastDelta.height()) {
|
||||
// special case of diagonal, this is not yet supported, thus cancel all gestures
|
||||
cancelActiveSwipeGestures();
|
||||
return;
|
||||
}
|
||||
SwipeGesture::Direction direction;
|
||||
if (std::abs(delta.width()) > std::abs(delta.height())) {
|
||||
if (std::abs(m_lastDelta.width()) > std::abs(m_lastDelta.height())) {
|
||||
// horizontal
|
||||
direction = delta.width() < 0 ? SwipeGesture::Direction::Left : SwipeGesture::Direction::Right;
|
||||
direction = m_lastDelta.width() < 0 ? SwipeGesture::Direction::Left : SwipeGesture::Direction::Right;
|
||||
} else {
|
||||
// vertical
|
||||
direction = delta.height() < 0 ? SwipeGesture::Direction::Up : SwipeGesture::Direction::Down;
|
||||
direction = m_lastDelta.height() < 0 ? SwipeGesture::Direction::Up : SwipeGesture::Direction::Down;
|
||||
}
|
||||
const QSizeF combinedDelta = std::accumulate(m_swipeUpdates.constBegin(), m_swipeUpdates.constEnd(), QSizeF(0, 0));
|
||||
for (auto it = m_activeSwipeGestures.begin(); it != m_activeSwipeGestures.end();) {
|
||||
|
@ -182,12 +188,16 @@ void GestureRecognizer::cancelActiveSwipeGestures()
|
|||
Q_EMIT g->cancelled();
|
||||
}
|
||||
m_activeSwipeGestures.clear();
|
||||
m_currentDelta = QSizeF(0, 0);
|
||||
m_lastDelta = QSizeF(0, 0);
|
||||
}
|
||||
|
||||
void GestureRecognizer::cancelSwipeGesture()
|
||||
{
|
||||
cancelActiveSwipeGestures();
|
||||
m_swipeUpdates.clear();
|
||||
m_currentDelta = QSizeF(0, 0);
|
||||
m_lastDelta = QSizeF(0, 0);
|
||||
}
|
||||
|
||||
void GestureRecognizer::endSwipeGesture()
|
||||
|
@ -202,6 +212,8 @@ void GestureRecognizer::endSwipeGesture()
|
|||
}
|
||||
m_activeSwipeGestures.clear();
|
||||
m_swipeUpdates.clear();
|
||||
m_currentDelta = QSizeF(0, 0);
|
||||
m_lastDelta = QSizeF(0, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -201,6 +201,8 @@ private:
|
|||
QVector<Gesture*> m_activeSwipeGestures;
|
||||
QMap<Gesture*, QMetaObject::Connection> m_destroyConnections;
|
||||
QVector<QSizeF> m_swipeUpdates;
|
||||
QSizeF m_lastDelta = QSizeF(0, 0);
|
||||
QSizeF m_currentDelta = QSizeF(0, 0);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue