From e5f770d75396bfb41eb9f631a23645185977013a Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Fri, 9 Oct 2020 08:21:30 +0200 Subject: [PATCH] QskShadowMetrics added --- src/common/QskShadowMetrics.cpp | 106 +++++++++++++++++++++++ src/common/QskShadowMetrics.h | 149 ++++++++++++++++++++++++++++++++ src/src.pro | 2 + 3 files changed, 257 insertions(+) create mode 100644 src/common/QskShadowMetrics.cpp create mode 100644 src/common/QskShadowMetrics.h diff --git a/src/common/QskShadowMetrics.cpp b/src/common/QskShadowMetrics.cpp new file mode 100644 index 00000000..048e761c --- /dev/null +++ b/src/common/QskShadowMetrics.cpp @@ -0,0 +1,106 @@ +/****************************************************************************** + * QSkinny - Copyright (C) 2016 Uwe Rathmann + * This file may be used under the terms of the QSkinny License, Version 1.0 + *****************************************************************************/ + +#include "QskShadowMetrics.h" + +#include +#include +#include + +static void qskRegisterShadowMetrics() +{ + qRegisterMetaType< QskShadowMetrics >(); +} + +Q_CONSTRUCTOR_FUNCTION( qskRegisterShadowMetrics ) + +static inline qreal qskInterpolated( qreal from, qreal to, qreal ratio ) +{ + return from + ( to - from ) * ratio; +} + +static inline qreal qskToAbsolute( qreal length, qreal percentage ) +{ + percentage = qBound( 0.0, percentage, 100.0 ); + return percentage / 100.0 * length; +} + +QskShadowMetrics QskShadowMetrics::toAbsolute( const QSizeF& size ) const noexcept +{ + if ( m_sizeMode != Qt::RelativeSize ) + return *this; + + if ( size.isEmpty() ) + return QskShadowMetrics( 0.0, 0.0, QPointF() ); + + const qreal length = std::max( size.width(), size.height() ); + + const qreal spreadRadius = qskToAbsolute( length, m_spreadRadius ); + const qreal blurRadius = qskToAbsolute( length, m_spreadRadius ); + const qreal dx = qskToAbsolute( size.width(), m_offset.x() ); + const qreal dy = qskToAbsolute( size.height(), m_offset.x() ); + + return QskShadowMetrics( spreadRadius, blurRadius, QPointF( dx, dy ) ); +} + +QskShadowMetrics QskShadowMetrics::interpolated( + const QskShadowMetrics& to, qreal ratio ) const noexcept +{ + if ( ( *this == to ) || ( m_sizeMode != to.m_sizeMode ) ) + return to; + + const QPointF offset( + qskInterpolated( m_offset.x(), to.m_offset.x(), ratio ), + qskInterpolated( m_offset.y(), to.m_offset.y(), ratio ) ); + + QskShadowMetrics metrics( + qskInterpolated( m_spreadRadius, to.m_spreadRadius, ratio ), + qskInterpolated( m_blurRadius, to.m_blurRadius, ratio ), + offset ); + metrics.m_sizeMode = m_sizeMode; + + return metrics; +} + +QVariant QskShadowMetrics::interpolate( + const QskShadowMetrics& from, const QskShadowMetrics& to, + qreal progress ) +{ + return QVariant::fromValue( from.interpolated( to, progress ) ); +} + +uint QskShadowMetrics::hash( uint seed ) const noexcept +{ + uint hash; + + hash = qHash( m_offset.x(), seed ); + hash = qHash( m_offset.y(), seed ); + hash = qHash( m_spreadRadius, hash ); + hash = qHash( m_blurRadius, hash ); + hash = qHash( static_cast< int >( m_sizeMode ), hash ); + + return hash; +} + +#ifndef QT_NO_DEBUG_STREAM + +#include + +QDebug operator<<( QDebug debug, const QskShadowMetrics& metrics ) +{ + QDebugStateSaver saver( debug ); + debug.nospace(); + + debug << "Shadow" << '('; + debug << " spread:" << metrics.spreadRadius(); + debug << " blur:" << metrics.blurRadius(); + debug << " dx:" << metrics.offset().x(); + debug << " dy:" << metrics.offset().y(); + debug << " )"; + + return debug; +} + +#endif diff --git a/src/common/QskShadowMetrics.h b/src/common/QskShadowMetrics.h new file mode 100644 index 00000000..deef0314 --- /dev/null +++ b/src/common/QskShadowMetrics.h @@ -0,0 +1,149 @@ +/****************************************************************************** + * QSkinny - Copyright (C) 2016 Uwe Rathmann + * This file may be used under the terms of the QSkinny License, Version 1.0 + *****************************************************************************/ + +#ifndef QSK_SHADOW_METRICS_H +#define QSK_SHADOW_METRICS_H + +#include "QskGlobal.h" + +#include +#include +#include + +class QVariant; + +class QSK_EXPORT QskShadowMetrics +{ + public: + constexpr QskShadowMetrics( const QPointF& offset = QPointF() ) noexcept; + + constexpr QskShadowMetrics( qreal spreadRadius, qreal blurRadius, + const QPointF& offset = QPointF() ) noexcept; + + constexpr bool operator==( const QskShadowMetrics& ) const noexcept; + constexpr bool operator!=( const QskShadowMetrics& ) const noexcept; + + void setSpreadRadius( qreal ) noexcept; + constexpr qreal spreadRadius() const noexcept; + + void setBlurRadius( qreal ) noexcept; + constexpr qreal blurRadius() const noexcept; + + constexpr qreal totalRadius() const noexcept; + + void setOffset( qreal dx, qreal dy ) noexcept; + void setOffset( const QPointF& ) noexcept; + + constexpr QPointF offset() const noexcept; + + void setSizeMode( Qt::SizeMode ) noexcept; + constexpr Qt::SizeMode sizeMode() const noexcept; + + QskShadowMetrics interpolated( + const QskShadowMetrics&, qreal value ) const noexcept; + + QskShadowMetrics toAbsolute( const QSizeF& ) const noexcept; + + uint hash( uint seed = 0 ) const noexcept; + + static QVariant interpolate( const QskShadowMetrics&, + const QskShadowMetrics&, qreal progress ); + + private: + QPointF m_offset; + qreal m_spreadRadius = 0.0; + qreal m_blurRadius = 0.0; + Qt::SizeMode m_sizeMode = Qt::AbsoluteSize; +}; + +inline constexpr QskShadowMetrics::QskShadowMetrics( const QPointF& offset ) noexcept + : m_offset( offset ) +{ +} + +inline constexpr QskShadowMetrics::QskShadowMetrics( + qreal spreadRadius, qreal blurRadius, const QPointF& offset ) noexcept + : m_offset( offset ) + , m_spreadRadius( spreadRadius ) + , m_blurRadius( blurRadius ) +{ +} + +inline constexpr bool QskShadowMetrics::operator==( + const QskShadowMetrics& other ) const noexcept +{ + return ( m_sizeMode == other.m_sizeMode ) + && ( m_spreadRadius == other.m_spreadRadius ) + && ( m_blurRadius == other.m_blurRadius ) + && ( m_sizeMode == other.m_sizeMode ); +} + +inline constexpr bool QskShadowMetrics::operator!=( + const QskShadowMetrics& other ) const noexcept +{ + return !( *this == other ); +} + +inline void QskShadowMetrics::setSpreadRadius( qreal radius ) noexcept +{ + m_spreadRadius = radius; +} + +inline constexpr qreal QskShadowMetrics::spreadRadius() const noexcept +{ + return m_spreadRadius; +} + +inline void QskShadowMetrics::setBlurRadius( qreal radius ) noexcept +{ + m_blurRadius = radius; +} + +inline constexpr qreal QskShadowMetrics::blurRadius() const noexcept +{ + return m_blurRadius; +} + +inline constexpr qreal QskShadowMetrics::totalRadius() const noexcept +{ + return m_spreadRadius + m_blurRadius; +} + +inline void QskShadowMetrics::setSizeMode( Qt::SizeMode sizeMode ) noexcept +{ + m_sizeMode = sizeMode; +} + +inline constexpr Qt::SizeMode QskShadowMetrics::sizeMode() const noexcept +{ + return m_sizeMode; +} + +void QskShadowMetrics::setOffset( qreal dx, qreal dy ) noexcept +{ + m_offset.rx() = dx; + m_offset.ry() = dy; +} + +void QskShadowMetrics::setOffset( const QPointF& offset ) noexcept +{ + m_offset = offset; +} + +inline constexpr QPointF QskShadowMetrics::offset() const noexcept +{ + return m_offset; +} + +#ifndef QT_NO_DEBUG_STREAM + +QSK_EXPORT QDebug operator<<( QDebug, const QskShadowMetrics& ); + +#endif + +Q_DECLARE_TYPEINFO( QskShadowMetrics, Q_MOVABLE_TYPE ); +Q_DECLARE_METATYPE( QskShadowMetrics ) + +#endif diff --git a/src/src.pro b/src/src.pro index a396b450..d19b034f 100644 --- a/src/src.pro +++ b/src/src.pro @@ -30,6 +30,7 @@ HEADERS += \ common/QskObjectCounter.h \ common/QskRgbValue.h \ common/QskRgbPalette.h \ + common/QskShadowMetrics.h \ common/QskSizePolicy.h \ common/QskTextColors.h \ common/QskTextOptions.h @@ -49,6 +50,7 @@ SOURCES += \ common/QskObjectCounter.cpp \ common/QskRgbValue.cpp \ common/QskRgbPalette.cpp \ + common/QskShadowMetrics.cpp \ common/QskSizePolicy.cpp \ common/QskTextColors.cpp \ common/QskTextOptions.cpp