From f920eee6c53f7b09ee53dbf9f0556379248c4d26 Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Sat, 2 May 2020 11:57:58 +0200 Subject: [PATCH] QskIntervalF introduced --- qmlexport/QskQml.cpp | 2 + src/common/QskIntervalF.cpp | 135 +++++++++++++++++++++++ src/common/QskIntervalF.h | 213 ++++++++++++++++++++++++++++++++++++ src/src.pro | 2 + 4 files changed, 352 insertions(+) create mode 100644 src/common/QskIntervalF.cpp create mode 100644 src/common/QskIntervalF.h diff --git a/qmlexport/QskQml.cpp b/qmlexport/QskQml.cpp index b9d31cd8..b132ee02 100644 --- a/qmlexport/QskQml.cpp +++ b/qmlexport/QskQml.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -287,6 +288,7 @@ void QskQml::registerTypes() QSK_REGISTER_GADGET( QskCorner, "Corner" ); QSK_REGISTER_GADGET( QskGradient, "Gradient" ); QSK_REGISTER_GADGET( QskGradientStop, "GradientStop" ); + QSK_REGISTER_GADGET( QskIntervalF, "IntervalF" ); QSK_REGISTER_GADGET( QskSizePolicy, "SizePolicy" ); QSK_REGISTER_GADGET( QskTextOptions, "TextOptions" ); diff --git a/src/common/QskIntervalF.cpp b/src/common/QskIntervalF.cpp new file mode 100644 index 00000000..18f0e381 --- /dev/null +++ b/src/common/QskIntervalF.cpp @@ -0,0 +1,135 @@ +/****************************************************************************** + * QSkinny - Copyright (C) 2016 Uwe Rathmann + * This file may be used under the terms of the QSkinny License, Version 1.0 + *****************************************************************************/ + +#include "QskIntervalF.h" +#include + +void QskIntervalF::unite( const QskIntervalF& other ) noexcept +{ + if ( isValid() ) + { + if ( other.isValid() ) + { + if ( other.m_lowerBound < m_lowerBound ) + { + m_lowerBound = other.m_lowerBound; + } + else if ( other.m_upperBound > m_upperBound ) + { + m_upperBound = other.m_upperBound; + } + } + } + else + { + if ( other.isValid() ) + { + m_lowerBound = other.m_lowerBound; + m_upperBound = other.m_upperBound; + } + } +} + +QskIntervalF QskIntervalF::united( const QskIntervalF& other ) const noexcept +{ + if ( isValid() ) + { + if ( other.isValid() ) + { + const auto min = std::min( m_lowerBound, other.m_lowerBound ); + const auto max = std::max( m_upperBound, other.m_upperBound ); + + return QskIntervalF( min, max ); + } + } + else + { + if ( other.isValid() ) + return other; + } + + return *this; +} + +QskIntervalF QskIntervalF::intersected( const QskIntervalF& other ) const noexcept +{ + if ( !isValid() ) + return *this; + + if ( !other.isValid() ) + return other; + + if ( m_lowerBound <= other.m_lowerBound ) + { + if ( m_upperBound < other.m_lowerBound ) + return QskIntervalF(); + + const qreal max = std::min( m_upperBound, other.m_upperBound ); + return QskIntervalF( other.m_lowerBound, max ); + } + else + { + if ( other.m_upperBound < m_lowerBound ) + return QskIntervalF(); + + const qreal max = std::min( m_upperBound, other.m_upperBound ); + return QskIntervalF( m_lowerBound, max ); + } +} + +bool QskIntervalF::intersects( const QskIntervalF& other ) const noexcept +{ + if ( !isValid() || !other.isValid() ) + return false; + + if ( m_lowerBound <= other.m_lowerBound ) + return m_upperBound >= other.m_lowerBound; + else + return m_lowerBound <= other.m_upperBound; +} + +void QskIntervalF::extend( qreal value ) noexcept +{ + if ( !isValid() ) + { + m_lowerBound = value; + m_upperBound = value; + } + else if ( value < m_lowerBound ) + { + m_lowerBound = value; + } + else if ( value >= m_upperBound ) + { + m_upperBound = value; + } +} + +QskIntervalF QskIntervalF::extended( qreal value ) const noexcept +{ + if ( !isValid() ) + return QskIntervalF( value, value ); + + const qreal lower = std::min( value, m_lowerBound ); + const qreal upper = std::max( value, m_upperBound ); + + return QskIntervalF( lower, upper ); +} + +#ifndef QT_NO_DEBUG_STREAM + +#include + +QDebug operator<<( QDebug debug, const QskIntervalF& interval ) +{ + debug.nospace() << "QskIntervalF(" + << interval.lowerBound() << "," << interval.upperBound() << ")"; + + return debug.space(); +} + +#endif + +#include "moc_QskIntervalF.cpp" diff --git a/src/common/QskIntervalF.h b/src/common/QskIntervalF.h new file mode 100644 index 00000000..aa21e1f7 --- /dev/null +++ b/src/common/QskIntervalF.h @@ -0,0 +1,213 @@ +/****************************************************************************** + * QSkinny - Copyright (C) 2016 Uwe Rathmann + * This file may be used under the terms of the QSkinny License, Version 1.0 + *****************************************************************************/ + +#ifndef QSK_INTERVAL_H +#define QSK_INTERVAL_H + +#include "QskGlobal.h" +#include +#include + +class QSK_EXPORT QskIntervalF +{ + Q_GADGET + + Q_PROPERTY( qreal lowerBound READ lowerBound WRITE setLowerBound ) + Q_PROPERTY( qreal upperBound READ upperBound WRITE setUpperBound ) + Q_PROPERTY( qreal width READ width ) + + public: + constexpr QskIntervalF() noexcept = default; + constexpr QskIntervalF( qreal lowerBound, qreal upperBound ) noexcept; + + void setInterval( qreal lowerBound, qreal upperBound ) noexcept; + + constexpr bool operator==( const QskIntervalF& ) const noexcept; + constexpr bool operator!=( const QskIntervalF& ) const noexcept; + + constexpr qreal lowerBound() const noexcept; + void setLowerBound( qreal ) noexcept; + + constexpr qreal upperBound() const noexcept; + void setUpperBound( qreal ) noexcept; + + constexpr qreal width() const noexcept; + void setWidth( qreal ) noexcept; + + constexpr bool contains( qreal value ) const noexcept; + + static constexpr QskIntervalF normalized( qreal value1, qreal value2 ) noexcept; + + void translate( qreal offset ) noexcept; + constexpr QskIntervalF translated( qreal offset ) const noexcept; + + bool intersects( const QskIntervalF& ) const noexcept; + QskIntervalF intersected( const QskIntervalF& ) const noexcept; + + void unite( const QskIntervalF& ) noexcept; + QskIntervalF united( const QskIntervalF& ) const noexcept; + + void extend( qreal value ) noexcept; + QskIntervalF extended( qreal value ) const noexcept; + + QskIntervalF operator|( const QskIntervalF& ) const noexcept; + QskIntervalF operator&( const QskIntervalF& ) const noexcept; + + QskIntervalF& operator|=( const QskIntervalF& ) noexcept; + QskIntervalF& operator&=( const QskIntervalF& ) noexcept; + + QskIntervalF operator|( qreal ) const noexcept; + QskIntervalF& operator|=( qreal ) noexcept; + + constexpr bool isValid() const noexcept; + constexpr bool isNull() const noexcept; + + void invalidate() noexcept; + + private: + qreal m_lowerBound = 0.0; + qreal m_upperBound = -1.0; +}; + +Q_DECLARE_TYPEINFO( QskIntervalF, Q_MOVABLE_TYPE ); +Q_DECLARE_METATYPE( QskIntervalF ) + +QT_WARNING_PUSH +QT_WARNING_DISABLE_CLANG("-Wfloat-equal") +QT_WARNING_DISABLE_GCC("-Wfloat-equal") +QT_WARNING_DISABLE_INTEL(1572) + +inline constexpr QskIntervalF::QskIntervalF( qreal lowerBound, qreal upperBound ) noexcept + : m_lowerBound( lowerBound ) + , m_upperBound( upperBound ) +{ +} + +inline void QskIntervalF::setInterval( qreal lowerBound, qreal upperBound ) noexcept +{ + m_lowerBound = lowerBound; + m_upperBound = upperBound; +} + +inline void QskIntervalF::setLowerBound( qreal value ) noexcept +{ + m_lowerBound = value; +} + +inline void QskIntervalF::setUpperBound( qreal value ) noexcept +{ + m_upperBound = value; +} + +inline constexpr qreal QskIntervalF::lowerBound() const noexcept +{ + return m_lowerBound; +} + +inline constexpr qreal QskIntervalF::upperBound() const noexcept +{ + return m_upperBound; +} + +inline constexpr qreal QskIntervalF::width() const noexcept +{ + return ( m_upperBound > m_lowerBound ) ? m_upperBound - m_upperBound : 0.0; +} + +inline void QskIntervalF::setWidth( qreal width ) noexcept +{ + m_upperBound = m_lowerBound + width; +} + +inline constexpr bool QskIntervalF::isValid() const noexcept +{ + return m_lowerBound <= m_upperBound; +} + +inline constexpr bool QskIntervalF::isNull() const noexcept +{ + return m_lowerBound == m_upperBound; +} + +inline void QskIntervalF::invalidate() noexcept +{ + m_lowerBound = 0.0; + m_upperBound = -1.0; +} + +inline constexpr bool QskIntervalF::contains( qreal value ) const noexcept +{ + return ( value >= m_lowerBound ) && ( value <= m_upperBound ); +} + +inline void QskIntervalF::translate( qreal offset ) noexcept +{ + m_lowerBound += offset; + m_upperBound += offset; +} + +inline constexpr QskIntervalF QskIntervalF::translated( qreal offset ) const noexcept +{ + return QskIntervalF( m_lowerBound + offset, m_upperBound + offset ); +} + +inline constexpr QskIntervalF QskIntervalF::normalized( qreal value1, qreal value2 ) noexcept +{ + return ( value1 < value2 ) ? QskIntervalF( value1, value2 ) : QskIntervalF( value2, value1 ); +} + +inline QskIntervalF QskIntervalF::operator&( const QskIntervalF& other ) const noexcept +{ + return intersected( other ); +} + +inline QskIntervalF QskIntervalF::operator|( const QskIntervalF& other ) const noexcept +{ + return united( other ); +} + +inline QskIntervalF& QskIntervalF::operator|=( const QskIntervalF& other ) noexcept +{ + unite( other ); + return *this; +} + +inline QskIntervalF& QskIntervalF::operator&=( const QskIntervalF& other ) noexcept +{ + *this = intersected( other ); + return *this; +} + +inline constexpr bool QskIntervalF::operator==( const QskIntervalF& other ) const noexcept +{ + return qFuzzyCompare( m_lowerBound, other.m_lowerBound ) && + qFuzzyCompare( m_upperBound, other.m_upperBound ); +} + +inline constexpr bool QskIntervalF::operator!=( const QskIntervalF& other ) const noexcept +{ + return ( !( *this == other ) ); +} + +inline QskIntervalF QskIntervalF::operator|( qreal value ) const noexcept +{ + return extended( value ); +} + +inline QskIntervalF& QskIntervalF::operator|=( qreal value ) noexcept +{ + *this = *this | value; + return *this; +} + +QT_WARNING_POP + +#ifndef QT_NO_DEBUG_STREAM + +class QDebug; +QSK_EXPORT QDebug operator<<( QDebug, const QskIntervalF& ); +#endif + +#endif diff --git a/src/src.pro b/src/src.pro index 70b7ce3a..50a189c0 100644 --- a/src/src.pro +++ b/src/src.pro @@ -21,6 +21,7 @@ HEADERS += \ common/QskFunctions.h \ common/QskGlobal.h \ common/QskGradient.h \ + common/QskIntervalF.h \ common/QskMargins.h \ common/QskMetaFunction.h \ common/QskMetaFunction.hpp \ @@ -40,6 +41,7 @@ SOURCES += \ common/QskCorner.cpp \ common/QskFunctions.cpp \ common/QskGradient.cpp \ + common/QskIntervalF.cpp \ common/QskMargins.cpp \ common/QskMetaFunction.cpp \ common/QskMetaInvokable.cpp \