diff --git a/src/controls/QskControl.cpp b/src/controls/QskControl.cpp index 7176de57..c2946bd1 100644 --- a/src/controls/QskControl.cpp +++ b/src/controls/QskControl.cpp @@ -32,6 +32,11 @@ QSK_STATE( QskControl, Disabled, QskAspect::FirstSystemState ) QSK_STATE( QskControl, Hovered, QskAspect::LastSystemState >> 1 ) QSK_STATE( QskControl, Focused, QskAspect::LastSystemState ) +// QGridLayoutEngine internally uses FLT_MAX +static constexpr qreal qskSizeHintMax = std::numeric_limits< float >::max(); +static QSizeF qskDefaultSizeHints[3] = + { { 0, 0 }, { -1, -1 }, { qskSizeHintMax, qskSizeHintMax } }; + typedef quint16 controlFlags_t; void qskResolveLocale( QskControl* ); // not static as being used from outside ! @@ -161,7 +166,16 @@ class QskControlPrivate final : public QQuickItemPrivate Q_DECLARE_PUBLIC( QskControl ) public: + class ExplicitSizeData + { + public: + QSizeF sizeHints[3] = + { qskDefaultSizeHints[0], qskDefaultSizeHints[1], qskDefaultSizeHints[2] }; + }; + QskControlPrivate(): + explicitSizeData( nullptr ), + sizePolicy( QskSizePolicy::Preferred, QskSizePolicy::Preferred ), controlFlags( qskControlFlags() ), controlFlagsMask( 0 ), explicitLocale( false ), @@ -197,6 +211,11 @@ public: } } + virtual ~QskControlPrivate() + { + delete explicitSizeData; + } + virtual void mirrorChange() override final { Q_Q( QskControl ); @@ -240,6 +259,23 @@ public: implicitSizeChanged(); } + inline void setExplicitSizeHint( Qt::SizeHint whichHint, const QSizeF& size ) + { + if ( explicitSizeData == nullptr ) + explicitSizeData = new ExplicitSizeData; + + explicitSizeData->sizeHints[ whichHint ] = size; + } + + inline QSizeF explicitSizeHint( Qt::SizeHint whichHint ) const + { + if ( explicitSizeData ) + return explicitSizeData->sizeHints[ whichHint ]; + + return qskDefaultSizeHints[ whichHint ]; + } + + bool maybeGesture( QQuickItem* child, QEvent* event ) { Q_Q( QskControl ); @@ -295,8 +331,14 @@ public: } } +private: + ExplicitSizeData* explicitSizeData; + +public: QLocale locale; + QskSizePolicy sizePolicy; + quint16 controlFlags; quint16 controlFlagsMask; @@ -924,6 +966,224 @@ void qskResolveLocale( QskControl* control ) } } +void QskControl::initSizePolicy( + QskSizePolicy::Policy horizontalPolicy, + QskSizePolicy::Policy verticalPolicy ) +{ + Q_D( QskControl ); + + /* + In constructors of derived classes you don't need + to propagate changes by layoutConstraintChanged. + Sometimes it is even worse as the parent might not be + even prepared to handle the LayouRequest event. + */ + + d->sizePolicy.setHorizontalPolicy( horizontalPolicy ); + d->sizePolicy.setVerticalPolicy( verticalPolicy ); +} + +void QskControl::setSizePolicy( const QskSizePolicy& policy ) +{ + Q_D( QskControl ); + + if ( policy != d->sizePolicy ) + { + d->sizePolicy = policy; + layoutConstraintChanged(); + } +} + +void QskControl::setSizePolicy( + QskSizePolicy::Policy horizontalPolicy, + QskSizePolicy::Policy verticalPolicy ) +{ + setSizePolicy( QskSizePolicy( horizontalPolicy, verticalPolicy ) ); +} + +void QskControl::setSizePolicy( + Qt::Orientation orientation, QskSizePolicy::Policy policy ) +{ + Q_D( QskControl ); + + if ( d->sizePolicy.policy( orientation ) != policy ) + { + d->sizePolicy.setPolicy( orientation, policy ); + layoutConstraintChanged(); + } +} + +const QskSizePolicy& QskControl::sizePolicy() const +{ + return d_func()->sizePolicy; +} + +QskSizePolicy::Policy QskControl::sizePolicy( Qt::Orientation orientation ) const +{ + return d_func()->sizePolicy.policy( orientation ); +} + +void QskControl::setPreferredSize( const QSizeF& size ) +{ + setExplicitSizeHint( Qt::PreferredSize, size ); +} + +void QskControl::setPreferredSize( qreal width, qreal height ) +{ + setPreferredSize( QSizeF( width, height ) ); +} + +void QskControl::setPreferredWidth( qreal width ) +{ + setPreferredSize( QSizeF( width, preferredSize().height() ) ); +} + +void QskControl::setPreferredHeight( qreal height ) +{ + setPreferredSize( QSizeF( preferredSize().width(), height ) ); +} + +void QskControl::setMinimumSize( const QSizeF& size ) +{ + setExplicitSizeHint( Qt::MinimumSize, size ); +} + +void QskControl::setMinimumSize( qreal width, qreal height ) +{ + setMinimumSize( QSizeF( width, height ) ); +} + +void QskControl::setMinimumWidth( qreal width ) +{ + setMinimumSize( QSizeF( width, minimumSize().height() ) ); +} + +void QskControl::setMinimumHeight( qreal height ) +{ + setMinimumSize( QSizeF( minimumSize().width(), height ) ); +} + +void QskControl::setMaximumSize( const QSizeF& size ) +{ + setExplicitSizeHint( Qt::MaximumSize, size ); +} + +void QskControl::setMaximumSize( qreal width, qreal height ) +{ + setMaximumSize( QSizeF( width, height ) ); +} + +void QskControl::setMaximumWidth( qreal width ) +{ + setMaximumSize( QSizeF( width, maximumSize().height() ) ); +} + +void QskControl::setMaximumHeight( qreal height ) +{ + setMaximumSize( QSizeF( maximumSize().width(), height ) ); +} + +void QskControl::setFixedSize( const QSizeF& size ) +{ + const QSizeF newSize = size.expandedTo( QSizeF( 0, 0 ) ); + + const QskSizePolicy policy( QskSizePolicy::Fixed, QskSizePolicy::Fixed ); + + Q_D( QskControl ); + + if ( policy != d->sizePolicy || + d->explicitSizeHint( Qt::PreferredSize ) != newSize ) + { + d->sizePolicy = policy; + d->setExplicitSizeHint( Qt::PreferredSize, newSize ); + + layoutConstraintChanged(); + } +} + +void QskControl::setFixedSize( qreal width, qreal height ) +{ + setFixedSize( QSizeF( width, height ) ); +} + +void QskControl::setFixedWidth( qreal width ) +{ + if ( width < 0 ) + width = 0; + + Q_D( QskControl ); + + auto size = d->explicitSizeHint( Qt::PreferredSize ); + + if ( ( d->sizePolicy.horizontalPolicy() != QskSizePolicy::Fixed ) + || ( size.width() != width ) ) + { + size.setWidth( width ); + + d->sizePolicy.setHorizontalPolicy( QskSizePolicy::Fixed ); + d->setExplicitSizeHint( Qt::PreferredSize, size ); + + layoutConstraintChanged(); + } +} + +void QskControl::setFixedHeight( qreal height ) +{ + if ( height < 0 ) + height = 0; + + Q_D( QskControl ); + + auto size = d->explicitSizeHint( Qt::PreferredSize ); + + if ( ( d->sizePolicy.verticalPolicy() != QskSizePolicy::Fixed ) + || ( size.height() != height ) ) + { + size.setHeight( height ); + + d->sizePolicy.setVerticalPolicy( QskSizePolicy::Fixed ); + d->setExplicitSizeHint( Qt::PreferredSize, size ); + + layoutConstraintChanged(); + } +} + +void QskControl::resetExplicitSizeHint( Qt::SizeHint whichHint ) +{ + if ( whichHint >= Qt::MinimumSize && whichHint <= Qt::MaximumSize ) + setExplicitSizeHint( whichHint, qskDefaultSizeHints[ whichHint ] ); +} + +void QskControl::setExplicitSizeHint( Qt::SizeHint whichHint, const QSizeF& size ) +{ + if ( whichHint >= Qt::MinimumSize && whichHint <= Qt::MaximumSize ) + { + const QSizeF newSize( ( size.width() < 0 ) ? -1.0 : size.width(), + ( size.width() < 0 ) ? -1.0 : size.width() ); + + Q_D( QskControl ); + + if ( newSize != d->explicitSizeHint( whichHint ) ) + { + d->setExplicitSizeHint( whichHint, newSize ); + layoutConstraintChanged(); + } + } +} + +void QskControl::setExplicitSizeHint( Qt::SizeHint whichHint, qreal width, qreal height ) +{ + setExplicitSizeHint( whichHint, QSizeF( width, height ) ); +} + +QSizeF QskControl::explicitSizeHint( Qt::SizeHint whichHint ) const +{ + if ( whichHint >= Qt::MinimumSize && whichHint <= Qt::MaximumSize ) + return d_func()->explicitSizeHint( whichHint ); + + return QSizeF( -1, -1 ); +} + QSizeF QskControl::effectiveSizeHint( Qt::SizeHint whichHint ) const { if ( whichHint < Qt::MinimumSize || whichHint > Qt::MaximumSize ) diff --git a/src/controls/QskControl.h b/src/controls/QskControl.h index bd11fcf4..6a3dd124 100644 --- a/src/controls/QskControl.h +++ b/src/controls/QskControl.h @@ -7,9 +7,9 @@ #define QSK_CONTROL_H 1 #include "QskGlobal.h" -#include "QskResizable.h" #include "QskSkinnable.h" #include "QskGradient.h" +#include "QskSizePolicy.h" #include "QskAspect.h" #include @@ -25,7 +25,7 @@ class QskGestureEvent; template class QVector< QskAspect::Aspect >; -class QSK_EXPORT QskControl : public QQuickItem, public QskResizable, public QskSkinnable +class QSK_EXPORT QskControl : public QQuickItem, public QskSkinnable { Q_OBJECT @@ -142,6 +142,43 @@ public: Q_INVOKABLE void resetControlFlag( Flag ); Q_INVOKABLE bool testControlFlag( Flag ) const; + void setSizePolicy( QskSizePolicy::Policy, QskSizePolicy::Policy ); + void setSizePolicy( const QskSizePolicy& ); + void setSizePolicy( Qt::Orientation, QskSizePolicy::Policy ); + + const QskSizePolicy& sizePolicy() const; + QskSizePolicy::Policy sizePolicy( Qt::Orientation ) const; + + void setMinimumSize( const QSizeF& ); + void setMinimumSize( qreal width, qreal height ); + void setMinimumWidth( qreal width ); + void setMinimumHeight( qreal height ); + + void setMaximumSize( const QSizeF& ); + void setMaximumSize( qreal width, qreal height ); + void setMaximumWidth( qreal width ); + void setMaximumHeight( qreal height ); + + void setPreferredSize( const QSizeF& ); + void setPreferredSize( qreal width, qreal height ); + void setPreferredWidth( qreal width ); + void setPreferredHeight( qreal height ); + + void setFixedSize( const QSizeF& ); + void setFixedSize( qreal width, qreal height ); + void setFixedWidth( qreal width ); + void setFixedHeight( qreal height ); + + void setExplicitSizeHint( Qt::SizeHint, const QSizeF& ); + void setExplicitSizeHint( Qt::SizeHint, qreal width, qreal height ); + void resetExplicitSizeHint( Qt::SizeHint ); + + QSizeF minimumSize() const; + QSizeF maximumSize() const; + QSizeF preferredSize() const; + + QSizeF explicitSizeHint( Qt::SizeHint ) const; + QSizeF sizeHint() const; QSizeF effectiveSizeHint( Qt::SizeHint ) const; @@ -201,11 +238,12 @@ protected: virtual bool gestureFilter( QQuickItem*, QEvent* ); virtual void itemChange( ItemChange, const ItemChangeData& ) override; + virtual void geometryChanged( const QRectF&, const QRectF& ) override; virtual void classBegin() override; virtual void componentComplete() override; virtual void releaseResources() override; - virtual void geometryChanged( const QRectF&, const QRectF& ) override; + void initSizePolicy( QskSizePolicy::Policy, QskSizePolicy::Policy ); void cleanupNodes(); @@ -222,8 +260,8 @@ private: virtual void updatePolish() override final; virtual QskControl* owningControl() const override final; - virtual void layoutConstraintChanged() override final; + void layoutConstraintChanged(); void updateImplicitSize(); void updateControlFlag( uint flag, bool on ); @@ -252,6 +290,21 @@ inline QSizeF QskControl::sizeHint() const return effectiveSizeHint( Qt::PreferredSize ); } +inline QSizeF QskControl::minimumSize() const +{ + return explicitSizeHint( Qt::MinimumSize ); +} + +inline QSizeF QskControl::maximumSize() const +{ + return explicitSizeHint( Qt::MaximumSize ); +} + +inline QSizeF QskControl::preferredSize() const +{ + return explicitSizeHint( Qt::PreferredSize ); +} + Q_DECLARE_OPERATORS_FOR_FLAGS( QskControl::Flags ) Q_DECLARE_METATYPE( QskControl::Flags ) diff --git a/src/controls/QskResizable.cpp b/src/controls/QskResizable.cpp deleted file mode 100644 index 52e87a94..00000000 --- a/src/controls/QskResizable.cpp +++ /dev/null @@ -1,260 +0,0 @@ -/****************************************************************************** - * QSkinny - Copyright (C) 2016 Uwe Rathmann - * This file may be used under the terms of the QSkinny License, Version 1.0 - *****************************************************************************/ - -#include "QskResizable.h" - -// QGridLayoutEngine internally uses FLT_MAX -static constexpr qreal c_max = std::numeric_limits< float >::max(); - -QskResizable::QskResizable(): - m_sizePolicy( QskSizePolicy::Preferred, QskSizePolicy::Preferred ), - m_sizeHints{ { 0, 0 }, { -1, -1 }, { c_max, c_max } } -{ -} - -QskResizable::~QskResizable() -{ -} - -void QskResizable::initSizePolicy( - QskSizePolicy::Policy horizontalPolicy, - QskSizePolicy::Policy verticalPolicy ) -{ - /* - In constructors of derived classes you don't need - to propagate changes by layoutConstraintChanged. - Sometimes it is even worse as the parent might not be - even prepared to handle the LayouRequest event. - */ - - m_sizePolicy.setHorizontalPolicy( horizontalPolicy ); - m_sizePolicy.setVerticalPolicy( verticalPolicy ); -} - -void QskResizable::setSizePolicy( const QskSizePolicy& policy ) -{ - if ( policy != m_sizePolicy ) - { - m_sizePolicy = policy; - layoutConstraintChanged(); - } -} - -void QskResizable::setSizePolicy( - QskSizePolicy::Policy horizontalPolicy, - QskSizePolicy::Policy verticalPolicy ) -{ - setSizePolicy( QskSizePolicy( horizontalPolicy, verticalPolicy ) ); -} - -void QskResizable::setSizePolicy( - Qt::Orientation orientation, QskSizePolicy::Policy policy ) -{ - if ( m_sizePolicy.policy( orientation ) != policy ) - { - m_sizePolicy.setPolicy( orientation, policy ); - layoutConstraintChanged(); - } -} - -const QskSizePolicy& QskResizable::sizePolicy() const -{ - return m_sizePolicy; -} - -QskSizePolicy::Policy QskResizable::sizePolicy( Qt::Orientation orientation ) const -{ - return m_sizePolicy.policy( orientation ); -} - -QSizeF QskResizable::preferredSize() const -{ - return explicitSizeHint( Qt::PreferredSize ); -} - -void QskResizable::setPreferredSize( const QSizeF& size ) -{ - setExplicitSizeHint( Qt::PreferredSize, size ); -} - -void QskResizable::setPreferredSize( qreal width, qreal height ) -{ - setPreferredSize( QSizeF( width, height ) ); -} - -void QskResizable::setPreferredWidth( qreal width ) -{ - setPreferredSize( QSizeF( width, preferredSize().height() ) ); -} - -void QskResizable::setPreferredHeight( qreal height ) -{ - setPreferredSize( QSizeF( preferredSize().width(), height ) ); -} - -QSizeF QskResizable::minimumSize() const -{ - return explicitSizeHint( Qt::MinimumSize ); -} - -void QskResizable::setMinimumSize( const QSizeF& size ) -{ - setExplicitSizeHint( Qt::MinimumSize, size ); -} - -void QskResizable::setMinimumSize( qreal width, qreal height ) -{ - setMinimumSize( QSizeF( width, height ) ); -} - -void QskResizable::setMinimumWidth( qreal width ) -{ - setMinimumSize( QSizeF( width, minimumSize().height() ) ); -} - -void QskResizable::setMinimumHeight( qreal height ) -{ - setMinimumSize( QSizeF( minimumSize().width(), height ) ); -} - -QSizeF QskResizable::maximumSize() const -{ - return explicitSizeHint( Qt::MaximumSize ); -} - -void QskResizable::setMaximumSize( const QSizeF& size ) -{ - setExplicitSizeHint( Qt::MaximumSize, size ); -} - -void QskResizable::setMaximumSize( qreal width, qreal height ) -{ - setMaximumSize( QSizeF( width, height ) ); -} - -void QskResizable::setMaximumWidth( qreal width ) -{ - setMaximumSize( QSizeF( width, maximumSize().height() ) ); -} - -void QskResizable::setMaximumHeight( qreal height ) -{ - setMaximumSize( QSizeF( maximumSize().width(), height ) ); -} - -void QskResizable::setFixedSize( const QSizeF& size ) -{ - const QSizeF newSize = size.expandedTo( QSizeF( 0, 0 ) ); - - const QskSizePolicy policy( QskSizePolicy::Fixed, QskSizePolicy::Fixed ); - - if ( policy != m_sizePolicy || m_sizeHints[Qt::PreferredSize] != newSize ) - { - m_sizePolicy = policy; - m_sizeHints[Qt::PreferredSize] = newSize; - - layoutConstraintChanged(); - } -} - -void QskResizable::setFixedSize( qreal width, qreal height ) -{ - setFixedSize( QSizeF( width, height ) ); -} - -void QskResizable::setFixedWidth( qreal width ) -{ - if ( width < 0 ) - width = 0; - - if ( m_sizePolicy.horizontalPolicy() != QskSizePolicy::Fixed - || m_sizeHints[Qt::PreferredSize].width() != width ) - { - m_sizePolicy.setHorizontalPolicy( QskSizePolicy::Fixed ); - m_sizeHints[Qt::PreferredSize].setWidth( width ); - - layoutConstraintChanged(); - } -} - -void QskResizable::setFixedHeight( qreal height ) -{ - if ( height < 0 ) - height = 0; - - if ( m_sizePolicy.verticalPolicy() != QskSizePolicy::Fixed - || m_sizeHints[Qt::PreferredSize].height() != height ) - { - m_sizePolicy.setVerticalPolicy( QskSizePolicy::Fixed ); - m_sizeHints[Qt::PreferredSize].setHeight( height ); - - layoutConstraintChanged(); - } -} - -void QskResizable::resetExplicitSizeHint( Qt::SizeHint whichHint ) -{ - QSizeF hint; - - switch( whichHint ) - { - case Qt::MinimumSize: - { - hint = QSizeF( 0, 0 ); - break; - } - case Qt::MaximumSize: - { - hint = QSizeF( c_max, c_max ); - break; - } - case Qt::PreferredSize: - { - hint = QSizeF( -1, -1 ); - break; - } - default: - return; - } - - if ( hint != m_sizeHints[whichHint] ) - { - m_sizeHints[whichHint] = hint; - layoutConstraintChanged(); - } -} - -void QskResizable::setExplicitSizeHint( Qt::SizeHint whichHint, const QSizeF& size ) -{ - if ( whichHint >= Qt::MinimumSize && whichHint <= Qt::MaximumSize ) - { - const QSizeF newSize( ( size.width() < 0 ) ? -1.0 : size.width(), - ( size.width() < 0 ) ? -1.0 : size.width() ); - - if ( m_sizeHints[whichHint] != size ) - { - m_sizeHints[whichHint] = size; - layoutConstraintChanged(); - } - } -} - -void QskResizable::setExplicitSizeHint( Qt::SizeHint whichHint, qreal width, qreal height ) -{ - setExplicitSizeHint( whichHint, QSizeF( width, height ) ); -} - -QSizeF QskResizable::explicitSizeHint( Qt::SizeHint whichHint ) const -{ - if ( whichHint >= Qt::MinimumSize && whichHint <= Qt::MaximumSize ) - return m_sizeHints[whichHint]; - - // Qt::MinimumDescent ??? - return QSizeF( -1, -1 ); -} - -void QskResizable::layoutConstraintChanged() -{ -} diff --git a/src/controls/QskResizable.h b/src/controls/QskResizable.h deleted file mode 100644 index c8baca49..00000000 --- a/src/controls/QskResizable.h +++ /dev/null @@ -1,68 +0,0 @@ -/****************************************************************************** - * QSkinny - Copyright (C) 2016 Uwe Rathmann - * This file may be used under the terms of the QSkinny License, Version 1.0 - *****************************************************************************/ - -#ifndef QSK_RESIZABLE_H -#define QSK_RESIZABLE_H 1 - -#include "QskGlobal.h" -#include "QskSizePolicy.h" -#include - -class QSK_EXPORT QskResizable -{ -public: - QskResizable(); - virtual ~QskResizable(); - - void setSizePolicy( QskSizePolicy::Policy, QskSizePolicy::Policy ); - void setSizePolicy( const QskSizePolicy& ); - void setSizePolicy( Qt::Orientation, QskSizePolicy::Policy ); - - const QskSizePolicy& sizePolicy() const; - QskSizePolicy::Policy sizePolicy( Qt::Orientation ) const; - - void setMinimumSize( const QSizeF& ); - void setMinimumSize( qreal width, qreal height ); - void setMinimumWidth( qreal width ); - void setMinimumHeight( qreal height ); - - void setMaximumSize( const QSizeF& ); - void setMaximumSize( qreal width, qreal height ); - void setMaximumWidth( qreal width ); - void setMaximumHeight( qreal height ); - - void setPreferredSize( const QSizeF& ); - void setPreferredSize( qreal width, qreal height ); - void setPreferredWidth( qreal width ); - void setPreferredHeight( qreal height ); - - void setFixedSize( const QSizeF& ); - void setFixedSize( qreal width, qreal height ); - void setFixedWidth( qreal width ); - void setFixedHeight( qreal height ); - - void setExplicitSizeHint( Qt::SizeHint, const QSizeF& ); - void setExplicitSizeHint( Qt::SizeHint, qreal width, qreal height ); - void resetExplicitSizeHint( Qt::SizeHint ); - - QSizeF minimumSize() const; - QSizeF maximumSize() const; - QSizeF preferredSize() const; - - QSizeF explicitSizeHint( Qt::SizeHint ) const; - -protected: - void initSizePolicy( QskSizePolicy::Policy, QskSizePolicy::Policy ); - -private: - virtual void layoutConstraintChanged(); - -private: - QskSizePolicy m_sizePolicy; - QSizeF m_sizeHints[3]; -}; - -#endif - diff --git a/src/src.pro b/src/src.pro index 242d1a20..4acd8e6d 100644 --- a/src/src.pro +++ b/src/src.pro @@ -147,7 +147,6 @@ HEADERS += \ controls/QskPushButtonSkinlet.h \ controls/QskQuick.h \ controls/QskRangeControl.h \ - controls/QskResizable.h \ controls/QskRgbValue.h \ controls/QskScrollArea.h \ controls/QskScrollView.h \ @@ -213,7 +212,6 @@ SOURCES += \ controls/QskPushButtonSkinlet.cpp \ controls/QskQuick.cpp \ controls/QskRangeControl.cpp \ - controls/QskResizable.cpp \ controls/QskRgbValue.cpp \ controls/QskScrollArea.cpp \ controls/QskScrollView.cpp \