qskinny/src/common/QskArcMetrics.cpp

153 lines
3.7 KiB
C++
Raw Normal View History

/******************************************************************************
2023-04-06 07:23:37 +00:00
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#include "QskArcMetrics.h"
#include "QskFunctions.h"
#include <qhashfunctions.h>
#include <qvariant.h>
static void qskRegisterArcMetrics()
{
qRegisterMetaType< QskArcMetrics >();
2022-03-30 16:30:22 +00:00
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
QMetaType::registerEqualsComparator< QskArcMetrics >();
#endif
}
Q_CONSTRUCTOR_FUNCTION( qskRegisterArcMetrics )
static inline qreal qskInterpolated( qreal from, qreal to, qreal ratio )
{
return from + ( to - from ) * ratio;
}
void QskArcMetrics::setThickness( qreal thickness ) noexcept
{
m_thickness = thickness;
}
2021-10-20 07:27:05 +00:00
void QskArcMetrics::setStartAngle( qreal startAngle ) noexcept
{
m_startAngle = qskConstrainedDegrees( startAngle );
}
2021-10-20 07:27:05 +00:00
void QskArcMetrics::setSpanAngle( qreal spanAngle ) noexcept
{
m_spanAngle = qBound( -360.0, spanAngle, 360.0 );
}
void QskArcMetrics::setSizeMode( Qt::SizeMode sizeMode ) noexcept
{
m_sizeMode = sizeMode;
}
2023-04-17 15:28:48 +00:00
bool QskArcMetrics::isClosed() const
{
return qAbs( m_spanAngle ) >= 360.0;
}
bool QskArcMetrics::containsAngle( qreal angle ) const
{
angle = qskConstrainedDegrees( angle );
if ( m_spanAngle >= 0.0 )
{
if ( angle < m_startAngle )
angle += 360.0;
return ( angle >= m_startAngle ) && ( angle <= m_startAngle + m_spanAngle );
}
else
{
if ( angle > m_startAngle )
angle -= 360.0;
return ( angle <= m_startAngle ) && ( angle >= m_startAngle + m_spanAngle );
}
}
QskArcMetrics QskArcMetrics::interpolated(
const QskArcMetrics& to, qreal ratio ) const noexcept
{
if ( ( *this == to ) || ( m_sizeMode != to.m_sizeMode ) )
return to;
const qreal thickness = qskInterpolated( m_thickness, to.m_thickness, ratio );
2021-10-20 07:27:05 +00:00
const qreal s1 = qskInterpolated( m_startAngle, to.m_startAngle, ratio );
const qreal s2 = qskInterpolated( endAngle(), to.endAngle(), ratio );
return QskArcMetrics( s1, s2 - s1, thickness, m_sizeMode );
}
QVariant QskArcMetrics::interpolate(
const QskArcMetrics& from, const QskArcMetrics& to,
qreal progress )
{
return QVariant::fromValue( from.interpolated( to, progress ) );
}
2023-04-14 07:47:10 +00:00
QskArcMetrics QskArcMetrics::toAbsolute( qreal radiusX, qreal radiusY ) const noexcept
{
2023-04-14 07:47:10 +00:00
if ( radiusX < 0.0 )
return toAbsolute( radiusY );
2023-04-14 07:47:10 +00:00
if ( radiusY < 0.0 )
return toAbsolute( radiusX );
2023-04-14 07:47:10 +00:00
return toAbsolute( qMin( radiusX, radiusY ) );
}
2023-04-14 07:47:10 +00:00
QskArcMetrics QskArcMetrics::toAbsolute( qreal radius ) const noexcept
{
if ( m_sizeMode != Qt::RelativeSize )
return *this;
2023-04-14 07:47:10 +00:00
QskArcMetrics m = *this;
2023-04-14 07:47:10 +00:00
if ( radius < 0.0 )
radius = 0.0;
const auto ratio = qBound( 0.0, m.m_thickness, 100.0 ) / 100.0;
2023-04-14 07:47:10 +00:00
m.m_thickness = radius * ratio;
m.m_sizeMode = Qt::AbsoluteSize;
2023-04-14 07:47:10 +00:00
return m;
}
QskHashValue QskArcMetrics::hash( QskHashValue seed ) const noexcept
{
auto hash = qHash( m_thickness, seed );
hash = qHash( m_startAngle, hash );
hash = qHash( m_spanAngle, hash );
2021-10-20 07:27:05 +00:00
const int mode = m_sizeMode;
return qHashBits( &mode, sizeof( mode ), hash );
}
#ifndef QT_NO_DEBUG_STREAM
#include <qdebug.h>
QDebug operator<<( QDebug debug, const QskArcMetrics& metrics )
{
QDebugStateSaver saver( debug );
debug.nospace();
2021-10-20 10:42:48 +00:00
debug << "QskArcMetrics" << '(';
debug << metrics.thickness() << ',' << metrics.sizeMode();
2021-10-20 10:42:48 +00:00
debug << ",[" << metrics.startAngle() << ',' << metrics.spanAngle() << ']';
debug << ')';
return debug;
}
#endif
#include "moc_QskArcMetrics.cpp"