QskResizable merged into QskControl. The memory of the explicit size

hints is allocated lazily as in the most cases a control does not
have them at all
This commit is contained in:
Uwe Rathmann 2018-05-08 10:34:00 +02:00
parent 8096ef0eff
commit 1a9a08636b
5 changed files with 317 additions and 334 deletions

View File

@ -32,6 +32,11 @@ QSK_STATE( QskControl, Disabled, QskAspect::FirstSystemState )
QSK_STATE( QskControl, Hovered, QskAspect::LastSystemState >> 1 ) QSK_STATE( QskControl, Hovered, QskAspect::LastSystemState >> 1 )
QSK_STATE( QskControl, Focused, QskAspect::LastSystemState ) 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; typedef quint16 controlFlags_t;
void qskResolveLocale( QskControl* ); // not static as being used from outside ! void qskResolveLocale( QskControl* ); // not static as being used from outside !
@ -161,7 +166,16 @@ class QskControlPrivate final : public QQuickItemPrivate
Q_DECLARE_PUBLIC( QskControl ) Q_DECLARE_PUBLIC( QskControl )
public: public:
class ExplicitSizeData
{
public:
QSizeF sizeHints[3] =
{ qskDefaultSizeHints[0], qskDefaultSizeHints[1], qskDefaultSizeHints[2] };
};
QskControlPrivate(): QskControlPrivate():
explicitSizeData( nullptr ),
sizePolicy( QskSizePolicy::Preferred, QskSizePolicy::Preferred ),
controlFlags( qskControlFlags() ), controlFlags( qskControlFlags() ),
controlFlagsMask( 0 ), controlFlagsMask( 0 ),
explicitLocale( false ), explicitLocale( false ),
@ -197,6 +211,11 @@ public:
} }
} }
virtual ~QskControlPrivate()
{
delete explicitSizeData;
}
virtual void mirrorChange() override final virtual void mirrorChange() override final
{ {
Q_Q( QskControl ); Q_Q( QskControl );
@ -240,6 +259,23 @@ public:
implicitSizeChanged(); 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 ) bool maybeGesture( QQuickItem* child, QEvent* event )
{ {
Q_Q( QskControl ); Q_Q( QskControl );
@ -295,8 +331,14 @@ public:
} }
} }
private:
ExplicitSizeData* explicitSizeData;
public:
QLocale locale; QLocale locale;
QskSizePolicy sizePolicy;
quint16 controlFlags; quint16 controlFlags;
quint16 controlFlagsMask; 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 QSizeF QskControl::effectiveSizeHint( Qt::SizeHint whichHint ) const
{ {
if ( whichHint < Qt::MinimumSize || whichHint > Qt::MaximumSize ) if ( whichHint < Qt::MinimumSize || whichHint > Qt::MaximumSize )

View File

@ -7,9 +7,9 @@
#define QSK_CONTROL_H 1 #define QSK_CONTROL_H 1
#include "QskGlobal.h" #include "QskGlobal.h"
#include "QskResizable.h"
#include "QskSkinnable.h" #include "QskSkinnable.h"
#include "QskGradient.h" #include "QskGradient.h"
#include "QskSizePolicy.h"
#include "QskAspect.h" #include "QskAspect.h"
#include <QQuickItem> #include <QQuickItem>
@ -25,7 +25,7 @@ class QskGestureEvent;
template class QVector< QskAspect::Aspect >; 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 Q_OBJECT
@ -142,6 +142,43 @@ public:
Q_INVOKABLE void resetControlFlag( Flag ); Q_INVOKABLE void resetControlFlag( Flag );
Q_INVOKABLE bool testControlFlag( Flag ) const; 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 sizeHint() const;
QSizeF effectiveSizeHint( Qt::SizeHint ) const; QSizeF effectiveSizeHint( Qt::SizeHint ) const;
@ -201,11 +238,12 @@ protected:
virtual bool gestureFilter( QQuickItem*, QEvent* ); virtual bool gestureFilter( QQuickItem*, QEvent* );
virtual void itemChange( ItemChange, const ItemChangeData& ) override; virtual void itemChange( ItemChange, const ItemChangeData& ) override;
virtual void geometryChanged( const QRectF&, const QRectF& ) override;
virtual void classBegin() override; virtual void classBegin() override;
virtual void componentComplete() override; virtual void componentComplete() override;
virtual void releaseResources() override; virtual void releaseResources() override;
virtual void geometryChanged( const QRectF&, const QRectF& ) override; void initSizePolicy( QskSizePolicy::Policy, QskSizePolicy::Policy );
void cleanupNodes(); void cleanupNodes();
@ -222,8 +260,8 @@ private:
virtual void updatePolish() override final; virtual void updatePolish() override final;
virtual QskControl* owningControl() const override final; virtual QskControl* owningControl() const override final;
virtual void layoutConstraintChanged() override final;
void layoutConstraintChanged();
void updateImplicitSize(); void updateImplicitSize();
void updateControlFlag( uint flag, bool on ); void updateControlFlag( uint flag, bool on );
@ -252,6 +290,21 @@ inline QSizeF QskControl::sizeHint() const
return effectiveSizeHint( Qt::PreferredSize ); 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_OPERATORS_FOR_FLAGS( QskControl::Flags )
Q_DECLARE_METATYPE( QskControl::Flags ) Q_DECLARE_METATYPE( QskControl::Flags )

View File

@ -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()
{
}

View File

@ -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 <QSizeF>
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

View File

@ -147,7 +147,6 @@ HEADERS += \
controls/QskPushButtonSkinlet.h \ controls/QskPushButtonSkinlet.h \
controls/QskQuick.h \ controls/QskQuick.h \
controls/QskRangeControl.h \ controls/QskRangeControl.h \
controls/QskResizable.h \
controls/QskRgbValue.h \ controls/QskRgbValue.h \
controls/QskScrollArea.h \ controls/QskScrollArea.h \
controls/QskScrollView.h \ controls/QskScrollView.h \
@ -213,7 +212,6 @@ SOURCES += \
controls/QskPushButtonSkinlet.cpp \ controls/QskPushButtonSkinlet.cpp \
controls/QskQuick.cpp \ controls/QskQuick.cpp \
controls/QskRangeControl.cpp \ controls/QskRangeControl.cpp \
controls/QskResizable.cpp \
controls/QskRgbValue.cpp \ controls/QskRgbValue.cpp \
controls/QskScrollArea.cpp \ controls/QskScrollArea.cpp \
controls/QskScrollView.cpp \ controls/QskScrollView.cpp \