From d2b6847d0b6c54aa216160dc93b43d98e62d41bc Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Mon, 8 Nov 2021 16:22:22 +0100 Subject: [PATCH] improve input handling --- examples/iotdashboard/LightDisplay.cpp | 29 ++++++++++++------- examples/iotdashboard/LightDisplay.h | 1 + examples/iotdashboard/LightDisplaySkinlet.cpp | 5 +--- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/examples/iotdashboard/LightDisplay.cpp b/examples/iotdashboard/LightDisplay.cpp index c613b7f4..2585986a 100644 --- a/examples/iotdashboard/LightDisplay.cpp +++ b/examples/iotdashboard/LightDisplay.cpp @@ -102,9 +102,11 @@ void LightDisplay::mouseMoveEvent( QMouseEvent* event ) return; } - const qreal ratioX = ( mousePos.x() - rect.x() ) / rect.width(); - - setValueAsRatio( ratioX ); + const QskArcMetrics metrics = arcMetricsHint( ColdAndWarmArc ); + const qreal angle = angleFromPoint( rect, mousePos ); + qDebug() << "angle:" << angle; + const qreal ratio = ( metrics.spanAngle() - angle * 16 ) / metrics.spanAngle(); + setValueAsRatio( ratio ); } void LightDisplay::mouseReleaseEvent( QMouseEvent* /*event*/ ) @@ -112,24 +114,31 @@ void LightDisplay::mouseReleaseEvent( QMouseEvent* /*event*/ ) setSkinStateFlag( Pressed, false ); } +qreal LightDisplay::angleFromPoint( const QRectF& rect, const QPointF& point ) const +{ + QPointF circlePos( point.x() - rect.center().x(), + rect.center().y() - point.y() ); + + const qreal atan = qAtan2( circlePos.y(), circlePos.x() ); + const qreal angle = qRadiansToDegrees( atan ); + return angle; +} + bool LightDisplay::arcContainsPoint( const QRectF& rect, const QPointF& point ) const { // putting this in an own function just because it might be useful // at other places in the future const QskArcMetrics metrics = arcMetricsHint( ColdAndWarmArc ); - const int tolerance = 10; + const int tolerance = 20; // 1. check angle QPointF circlePos( point.x() - rect.center().x(), rect.center().y() - point.y() ); - const qreal atan = qAtan2( circlePos.y(), circlePos.x() ); - const qreal angle = qRadiansToDegrees( atan ); - // the qAbs() actually only works for the 180 degrees case, - // we might want to generalize this later: - const bool angleWithinRange = ( qAbs( angle ) + tolerance ) > metrics.startAngle() - && qAbs( angle ) < ( metrics.startAngle() + metrics.spanAngle() - tolerance ); + const qreal angle = angleFromPoint( rect, point ); + const bool angleWithinRange = ( angle + tolerance ) > metrics.startAngle() + && angle < ( metrics.startAngle() + metrics.spanAngle() - tolerance ); // 2. check whether point is on arc const qreal radiusMax = rect.width() / 2; diff --git a/examples/iotdashboard/LightDisplay.h b/examples/iotdashboard/LightDisplay.h index 4f121a03..f310a736 100644 --- a/examples/iotdashboard/LightDisplay.h +++ b/examples/iotdashboard/LightDisplay.h @@ -37,6 +37,7 @@ class LightDisplay : public QskBoundedValueInput void mouseReleaseEvent( QMouseEvent* e ) override; private: + qreal angleFromPoint( const QRectF&, const QPointF& ) const; bool arcContainsPoint( const QRectF&, const QPointF& ) const; QskShadowMetrics m_shadow; diff --git a/examples/iotdashboard/LightDisplaySkinlet.cpp b/examples/iotdashboard/LightDisplaySkinlet.cpp index 2340bead..4cb96045 100644 --- a/examples/iotdashboard/LightDisplaySkinlet.cpp +++ b/examples/iotdashboard/LightDisplaySkinlet.cpp @@ -140,10 +140,7 @@ QSGNode* LightDisplaySkinlet::updateSubNode( } case ColdAndWarmArcRole: { - const qreal startAngle = 0; - const qreal spanAngle = 180 * 16; - return updateArcNode( skinnable, node, startAngle, spanAngle, - LightDisplay::ColdAndWarmArc ); + return updateArcNode( skinnable, node, LightDisplay::ColdAndWarmArc ); } case ValueTextRole: {