only move knob when drawing along the arc

This commit is contained in:
Peter Hartmann 2021-11-07 09:22:57 +01:00
parent 78bc34743b
commit 0067cdfd8f
3 changed files with 49 additions and 4 deletions

View File

@ -6,8 +6,11 @@
#include "LightDisplay.h" #include "LightDisplay.h"
#include "Skin.h" #include "Skin.h"
#include <QskArcMetrics.h>
#include <QskEvent.h> #include <QskEvent.h>
#include <QtMath>
QSK_SUBCONTROL( LightDisplay, Panel ) QSK_SUBCONTROL( LightDisplay, Panel )
QSK_SUBCONTROL( LightDisplay, Groove ) QSK_SUBCONTROL( LightDisplay, Groove )
QSK_SUBCONTROL( LightDisplay, ColdAndWarmArc ) QSK_SUBCONTROL( LightDisplay, ColdAndWarmArc )
@ -88,11 +91,17 @@ void LightDisplay::mouseMoveEvent( QMouseEvent* event )
if ( !isPressed() ) if ( !isPressed() )
return; return;
// ### check if arc contains the position
const auto mousePos = qskMousePosition( event ); const auto mousePos = qskMousePosition( event );
const auto rect = subControlRect( ColdAndWarmArc ); const auto rect = subControlRect( ColdAndWarmArc );
bool arcContainsMousePos = arcContainsPoint( rect, mousePos );
if( !arcContainsMousePos )
{
setSkinStateFlag( Pressed, false );
return;
}
const qreal ratioX = ( mousePos.x() - rect.x() ) / rect.width(); const qreal ratioX = ( mousePos.x() - rect.x() ) / rect.width();
setValueAsRatio( ratioX ); setValueAsRatio( ratioX );
@ -103,4 +112,38 @@ void LightDisplay::mouseReleaseEvent( QMouseEvent* /*event*/ )
setSkinStateFlag( Pressed, false ); setSkinStateFlag( Pressed, false );
} }
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;
// 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 );
// 2. check whether point is on arc
const qreal radiusMax = rect.width() / 2;
const qreal arcWidth = metrics.width();
const qreal radiusMin = radiusMax - arcWidth;
const qreal polarRadius = qSqrt( qPow( circlePos.x(), 2 ) + qPow( circlePos.y(), 2 ) );
const bool pointOnArc = ( polarRadius + tolerance ) > radiusMin
&& ( polarRadius - tolerance ) < radiusMax;
qDebug() << angleWithinRange << angle << pointOnArc;
bool ret = angleWithinRange && pointOnArc;
return ret;
}
#include "moc_LightDisplay.cpp" #include "moc_LightDisplay.cpp"

View File

@ -37,6 +37,8 @@ class LightDisplay : public QskBoundedValueInput
void mouseReleaseEvent( QMouseEvent* e ) override; void mouseReleaseEvent( QMouseEvent* e ) override;
private: private:
bool arcContainsPoint( const QRectF&, const QPointF& ) const;
QskShadowMetrics m_shadow; QskShadowMetrics m_shadow;
QColor m_shadowColor = Qt::black; QColor m_shadowColor = Qt::black;

View File

@ -184,7 +184,7 @@ void Skin::initHints( const Palette& palette )
// light intensity: // light intensity:
ed.setBoxShape( LightDisplay::Panel, 100, Qt::RelativeSize ); ed.setBoxShape( LightDisplay::Panel, 100, Qt::RelativeSize );
ed.setArcMetrics( LightDisplay::ColdAndWarmArc, 8.785, 0, 0 ); ed.setArcMetrics( LightDisplay::ColdAndWarmArc, 8.785, 0, 180 * 16 );
QskGradient coldGradient( Qt::Horizontal, { { 0.0, 0xffff3122 }, QskGradient coldGradient( Qt::Horizontal, { { 0.0, 0xffff3122 },
{ 0.2, 0xfffeeeb7 }, { 0.2, 0xfffeeeb7 },
{ 0.3, 0xffa7b0ff }, { 0.3, 0xffa7b0ff },
@ -195,7 +195,7 @@ void Skin::initHints( const Palette& palette )
ed.setFontRole( LightDisplay::ValueText, QskSkin::LargeFont ); ed.setFontRole( LightDisplay::ValueText, QskSkin::LargeFont );
ed.setColor( LightDisplay::ValueText, "#929cb2" ); ed.setColor( LightDisplay::ValueText, "#929cb2" );
ed.setStrutSize( LightDisplay::Knob, { 15.65, 15.65 } ); ed.setStrutSize( LightDisplay::Knob, { 20, 20 } );
ed.setBoxBorderMetrics( LightDisplay::Knob, 1 ); ed.setBoxBorderMetrics( LightDisplay::Knob, 1 );
ed.setBoxBorderColors( LightDisplay::Knob, 0xffc4c4c4 ); ed.setBoxBorderColors( LightDisplay::Knob, 0xffc4c4c4 );
ed.setBoxShape( LightDisplay::Knob, 100, Qt::RelativeSize ); ed.setBoxShape( LightDisplay::Knob, 100, Qt::RelativeSize );