| 754 | } |
| 755 | |
| 756 | void updateFromPoint(const QPointF& pos) |
| 757 | { |
| 758 | const QRectF knob = wheelRect(); |
| 759 | if (!pointerCanAnchor(pos, knob)) { |
| 760 | m_hasPointerAnchor = false; |
| 761 | m_pointerClock.restart(); |
| 762 | return; |
| 763 | } |
| 764 | |
| 765 | const double angle = angleForPoint(pos); |
| 766 | if (!m_hasPointerAnchor) { |
| 767 | m_hasPointerAnchor = true; |
| 768 | m_lastAngle = angle; |
| 769 | m_pointerClock.restart(); |
| 770 | m_spinClock.restart(); |
| 771 | return; |
| 772 | } |
| 773 | const double delta = clampWheelPointerDelta( |
| 774 | normalizeWheelAngle(angle - m_lastAngle)); |
| 775 | m_lastAngle = angle; |
| 776 | const double scaledDelta = delta * sensitivityScale(); |
| 777 | |
| 778 | const double elapsedMs = std::max<qint64>(m_pointerClock.restart(), 1); |
| 779 | const double dt = static_cast<double>(elapsedMs) / 1000.0; |
| 780 | const double instantVelocity = scaledDelta / dt; |
| 781 | m_stepMultiplier = accelerationForVelocity(instantVelocity); |
| 782 | applyRotationDelta(scaledDelta, true); |
| 783 | |
| 784 | const double loose = static_cast<double>(m_looseness) / 100.0; |
| 785 | const double blend = 0.24 + loose * 0.34; |
| 786 | m_velocity = m_velocity * (1.0 - blend) + instantVelocity * blend; |
| 787 | m_spinDispatchesSteps = true; |
| 788 | const bool fastEnoughToCoast = |
| 789 | std::abs(instantVelocity) >= kWheelCoastStartVelocity |
| 790 | && std::abs(m_velocity) >= kWheelCoastStartVelocity; |
| 791 | if (fastEnoughToCoast && !m_spinTimer.isActive()) { |
| 792 | m_spinClock.restart(); |
| 793 | m_spinTimer.start(); |
| 794 | } else if (!fastEnoughToCoast && m_spinTimer.isActive()) { |
| 795 | m_spinTimer.stop(); |
| 796 | } |
| 797 | } |
| 798 | |
| 799 | void tickSpin() |
| 800 | { |
nothing calls this directly
no test coverage detected