From 69e4152b4ccf1eb7d64e96fe42dc7c5607ea2a3c Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Fri, 8 Apr 2022 16:46:20 +0200 Subject: [PATCH] QskPlacementPolicy introduced --- examples/thumbnails/main.cpp | 2 +- playground/grids/GridSkinny.cpp | 5 +- src/common/QskPlacementPolicy.cpp | 25 ++++ src/common/QskPlacementPolicy.h | 159 +++++++++++++++++++++++ src/controls/QskCheckBoxSkinlet.cpp | 2 +- src/controls/QskControl.cpp | 49 ++++--- src/controls/QskControl.h | 30 ++--- src/controls/QskControlPrivate.cpp | 41 +++++- src/controls/QskControlPrivate.h | 26 +++- src/controls/QskFocusIndicator.cpp | 2 +- src/controls/QskInputGrabber.cpp | 2 +- src/controls/QskPopup.cpp | 2 +- src/controls/QskQuick.cpp | 95 ++++++++------ src/controls/QskQuick.h | 11 +- src/controls/QskQuickItem.cpp | 15 --- src/controls/QskQuickItem.h | 6 - src/inputpanel/QskInputContext.cpp | 2 +- src/inputpanel/QskInputPredictionBar.cpp | 2 +- src/layouts/QskGridBox.cpp | 6 +- src/layouts/QskGridLayoutEngine.cpp | 2 +- src/layouts/QskIndexedLayoutBox.cpp | 2 +- src/layouts/QskLayoutEngine2D.cpp | 17 --- src/layouts/QskLayoutEngine2D.h | 1 - src/layouts/QskLinearBox.cpp | 6 +- src/layouts/QskLinearLayoutEngine.cpp | 2 +- src/layouts/QskStackBox.cpp | 28 ++-- src/src.pro | 2 + 27 files changed, 389 insertions(+), 153 deletions(-) create mode 100644 src/common/QskPlacementPolicy.cpp create mode 100644 src/common/QskPlacementPolicy.h diff --git a/examples/thumbnails/main.cpp b/examples/thumbnails/main.cpp index 9944871d..0f797af8 100644 --- a/examples/thumbnails/main.cpp +++ b/examples/thumbnails/main.cpp @@ -133,7 +133,7 @@ class IconGrid : public QskLinearBox if ( auto control = qskControlCast( itemAtIndex( i ) ) ) { // to support the optimizations in ScrollArea::updateVisibilities - control->setLayoutHint( RetainSizeWhenHidden, true ); + control->setPlacementPolicy( Qsk::Hidden, QskPlacementPolicy::Reserve ); control->setVisible( false ); } } diff --git a/playground/grids/GridSkinny.cpp b/playground/grids/GridSkinny.cpp index a4ce1f85..7b747c7d 100644 --- a/playground/grids/GridSkinny.cpp +++ b/playground/grids/GridSkinny.cpp @@ -119,7 +119,10 @@ void GridSkinny::setAlignmentAt( int index, Qt::Alignment alignment ) void GridSkinny::setRetainSizeWhenHiddenAt( int index, bool on ) { if ( auto control = qskControlCast( m_grid->itemAtIndex( index ) ) ) - control->setLayoutHint( QskControl::RetainSizeWhenHidden, on ); + { + control->setPlacementPolicy( Qsk::Hidden, + on ? QskPlacementPolicy::Reserve : QskPlacementPolicy::Ignore ); + } } void GridSkinny::setVisibleAt( int index, bool on ) diff --git a/src/common/QskPlacementPolicy.cpp b/src/common/QskPlacementPolicy.cpp new file mode 100644 index 00000000..49c7940e --- /dev/null +++ b/src/common/QskPlacementPolicy.cpp @@ -0,0 +1,25 @@ +/****************************************************************************** + * QSkinny - Copyright (C) 2016 Uwe Rathmann + * This file may be used under the terms of the QSkinny License, Version 1.0 + *****************************************************************************/ + +#include "QskPlacementPolicy.h" + +#ifndef QT_NO_DEBUG_STREAM + +#include + +QDebug operator<<( QDebug debug, const QskPlacementPolicy policy ) +{ + QDebugStateSaver saver( debug ); + debug.nospace(); + debug << "PlacementPolicy" << '('; + debug << policy.visiblePolicy() << ", " << policy.hiddenPolicy(); + debug << ')'; + + return debug; +} + +#endif + +#include "moc_QskPlacementPolicy.cpp" diff --git a/src/common/QskPlacementPolicy.h b/src/common/QskPlacementPolicy.h new file mode 100644 index 00000000..5b147c2e --- /dev/null +++ b/src/common/QskPlacementPolicy.h @@ -0,0 +1,159 @@ +/****************************************************************************** + * QSkinny - Copyright (C) 2016 Uwe Rathmann + * This file may be used under the terms of the QSkinny License, Version 1.0 + *****************************************************************************/ + +#ifndef QSK_PLACEMENT_POLICY_H +#define QSK_PLACEMENT_POLICY_H + +#include "QskGlobal.h" +#include "QskNamespace.h" +#include + +class QskPlacementPolicy +{ + Q_GADGET + + Q_PROPERTY( Policy visiblePolicy READ visiblePolicy WRITE setVisiblePolicy ) + Q_PROPERTY( Policy hiddenPolicy READ hiddenPolicy WRITE setHiddenPolicy ) + + public: + + enum Policy + { + Ignore, + Reserve, + Adjust + }; + Q_ENUM( Policy ) + + constexpr QskPlacementPolicy() noexcept; + constexpr QskPlacementPolicy( Policy ) noexcept; + constexpr QskPlacementPolicy( Policy visiblePolicy, Policy hiddenPolicy ) noexcept; + constexpr QskPlacementPolicy( Qsk::Visibilities, Policy ) noexcept; + + constexpr bool operator==( const QskPlacementPolicy& ) const noexcept; + constexpr bool operator!=( const QskPlacementPolicy& ) const noexcept; + + void setPolicy( Qsk::Visibilities, Policy ) noexcept; + constexpr Policy policy( Qsk::Visibility ) const noexcept; + + constexpr bool isEffective() const noexcept; + + constexpr bool isIgnoring( Qsk::Visibility ) const noexcept; + constexpr bool isAdjusting( Qsk::Visibility ) const noexcept; + + void setVisiblePolicy( Policy ) noexcept; + constexpr Policy visiblePolicy() const noexcept; + + void setHiddenPolicy( Policy ) noexcept; + constexpr Policy hiddenPolicy() const noexcept; + + private: + Policy m_visiblePolicy : 2; + Policy m_hiddenPolicy : 2; +}; + +inline constexpr QskPlacementPolicy::QskPlacementPolicy() noexcept + : m_visiblePolicy( Adjust ) + , m_hiddenPolicy( Ignore ) +{ +} + +inline constexpr QskPlacementPolicy::QskPlacementPolicy( + Policy visiblePolicy, Policy hiddenPolicy ) noexcept + : m_visiblePolicy( visiblePolicy ) + , m_hiddenPolicy( hiddenPolicy ) +{ +} + +constexpr QskPlacementPolicy::QskPlacementPolicy( Policy policy ) noexcept + : m_visiblePolicy( policy ) + , m_hiddenPolicy( policy ) +{ +} + +constexpr QskPlacementPolicy::QskPlacementPolicy( + Qsk::Visibilities visibilities, Policy policy ) noexcept + : m_visiblePolicy( visibilities & Qsk::Visible ? policy : Adjust ) + , m_hiddenPolicy( visibilities & Qsk::Hidden ? policy : Ignore ) +{ +} + +inline constexpr bool QskPlacementPolicy::operator==( + const QskPlacementPolicy& other ) const noexcept +{ + return ( other.m_visiblePolicy == m_visiblePolicy ) && + ( other.m_hiddenPolicy == m_hiddenPolicy ); +} + +inline constexpr bool QskPlacementPolicy::operator!=( + const QskPlacementPolicy& other ) const noexcept +{ + return !( *this == other ); +} + +inline void QskPlacementPolicy::setPolicy( + Qsk::Visibilities visibilities, Policy policy ) noexcept +{ + if ( visibilities & Qsk::Visible ) + m_visiblePolicy = policy; + + if ( visibilities & Qsk::Hidden ) + m_hiddenPolicy = policy; +} + +inline constexpr QskPlacementPolicy::Policy +QskPlacementPolicy::policy( Qsk::Visibility visibility ) const noexcept +{ + return ( visibility == Qsk::Hidden ) ? m_hiddenPolicy : m_visiblePolicy; +} + +inline void QskPlacementPolicy::setVisiblePolicy( Policy policy ) noexcept +{ + m_visiblePolicy = policy; +} + +inline constexpr QskPlacementPolicy::Policy QskPlacementPolicy::visiblePolicy() const noexcept +{ + return m_visiblePolicy; +} + +inline void QskPlacementPolicy::setHiddenPolicy( Policy policy ) noexcept +{ + m_hiddenPolicy = policy; +} + +inline constexpr QskPlacementPolicy::Policy QskPlacementPolicy::hiddenPolicy() const noexcept +{ + return m_hiddenPolicy; +} + +inline constexpr bool QskPlacementPolicy::isEffective() const noexcept +{ + return ( m_visiblePolicy != Ignore ) || ( m_hiddenPolicy != Ignore ); +} + +inline constexpr bool QskPlacementPolicy::isIgnoring( Qsk::Visibility visibility ) const noexcept +{ + return ( visibility == Qsk::Visible ) + ? ( m_visiblePolicy == Ignore ) : ( m_hiddenPolicy == Ignore ); +} + +inline constexpr bool QskPlacementPolicy::isAdjusting( Qsk::Visibility visibility ) const noexcept +{ + return ( visibility == Qsk::Visible ) + ? ( m_visiblePolicy == Adjust ) : ( m_hiddenPolicy == Adjust ); +} + +Q_DECLARE_TYPEINFO( QskPlacementPolicy, Q_MOVABLE_TYPE ); +Q_DECLARE_METATYPE( QskPlacementPolicy ) + +#ifndef QT_NO_DEBUG_STREAM + + class QDebug; + QSK_EXPORT QDebug operator<<( QDebug, QskPlacementPolicy ); + +#endif + +#endif diff --git a/src/controls/QskCheckBoxSkinlet.cpp b/src/controls/QskCheckBoxSkinlet.cpp index 10fa4421..92f21d83 100644 --- a/src/controls/QskCheckBoxSkinlet.cpp +++ b/src/controls/QskCheckBoxSkinlet.cpp @@ -57,7 +57,7 @@ namespace points[1].set( x + w / 3, y + h ); points[2].set( x + w, y ); } - + markDirty( QSGNode::DirtyGeometry ); } } diff --git a/src/controls/QskControl.cpp b/src/controls/QskControl.cpp index 276d78e9..407444fb 100644 --- a/src/controls/QskControl.cpp +++ b/src/controls/QskControl.cpp @@ -350,44 +350,55 @@ Qt::Alignment QskControl::layoutAlignmentHint() const return static_cast< Qt::Alignment >( d_func()->layoutAlignmentHint ); } -void QskControl::setLayoutHint( LayoutHint flag, bool on ) +void QskControl::setPlacementPolicy( + Qsk::Visibilities visibilities, QskPlacementPolicy::Policy policy ) +{ + auto placementPolicy = this->placementPolicy(); + placementPolicy.setPolicy( visibilities, policy ); + + setPlacementPolicy( placementPolicy ); +} + +void QskControl::setPlacementPolicy( + QskPlacementPolicy::Policy visiblePolicy, QskPlacementPolicy::Policy hiddenPolicy ) +{ + setPlacementPolicy( QskPlacementPolicy( visiblePolicy, hiddenPolicy ) ); +} + +void QskControl::setPlacementPolicy( QskPlacementPolicy policy ) { Q_D( QskControl ); - if ( ( d->layoutHints & flag ) != on ) + + if ( policy != placementPolicy() ) { - if ( on ) - d->layoutHints |= flag; - else - d->layoutHints &= ~flag; + d->setPlacementPolicy( true, policy.visiblePolicy() ); + d->setPlacementPolicy( false, policy.hiddenPolicy() ); d->layoutConstraintChanged(); } } -bool QskControl::testLayoutHint( LayoutHint hint ) const +QskPlacementPolicy QskControl::placementPolicy() const { - return d_func()->layoutHints & hint; + Q_D( const QskControl ); + + return QskPlacementPolicy( + d->placementPolicy( true ), d->placementPolicy( false ) ); } -void QskControl::setLayoutHints( LayoutHints hints ) +QskPlacementPolicy::Policy QskControl::placementPolicy( Qsk::Visibility visiblity ) const { - Q_D( QskControl ); - if ( hints != layoutHints() ) - { - d->layoutHints = hints; - d->layoutConstraintChanged(); - } + return d_func()->placementPolicy( visiblity == Qsk::Visible ); } -QskControl::LayoutHints QskControl::layoutHints() const +QskPlacementPolicy::Policy QskControl::effectivePlacementPolicy() const { - return static_cast< LayoutHints >( d_func()->layoutHints ); + return d_func()->placementPolicy( isVisibleToParent() ); } bool QskControl::isVisibleToLayout() const { - return !isTransparentForPositioner() - && ( isVisibleToParent() || ( layoutHints() & RetainSizeWhenHidden ) ); + return qskIsVisibleToLayout( this ); } void QskControl::setPreferredSize( const QSizeF& size ) diff --git a/src/controls/QskControl.h b/src/controls/QskControl.h index 6dd60830..f59e541d 100644 --- a/src/controls/QskControl.h +++ b/src/controls/QskControl.h @@ -11,6 +11,7 @@ #include "QskAspect.h" #include "QskGradient.h" #include "QskSizePolicy.h" +#include "QskPlacementPolicy.h" #include #include @@ -57,22 +58,6 @@ class QSK_EXPORT QskControl : public QskQuickItem, public QskSkinnable public: QSK_STATES( Disabled, Hovered, Focused ) - enum LayoutHint - { - // How to be treated by layouts - RetainSizeWhenHidden = 1 << 0, - - /* - Adjust the item even, even when being hidden - Depending on the type of layout the value only works - in combination with RetainSizeWhenHidden - */ - LayoutWhenHidden = 1 << 1 - }; - - Q_ENUM( LayoutHint ) - Q_DECLARE_FLAGS( LayoutHints, LayoutHint ) - QskControl( QQuickItem* parent = nullptr ); ~QskControl() override; @@ -117,8 +102,8 @@ class QSK_EXPORT QskControl : public QskQuickItem, public QskSkinnable void setFocusPolicy( Qt::FocusPolicy ); Qt::FocusPolicy focusPolicy() const; - void setSizePolicy( QskSizePolicy::Policy, QskSizePolicy::Policy ); void setSizePolicy( QskSizePolicy ); + void setSizePolicy( QskSizePolicy::Policy, QskSizePolicy::Policy ); void setSizePolicy( Qt::Orientation, QskSizePolicy::Policy ); QskSizePolicy sizePolicy() const; @@ -128,11 +113,14 @@ class QSK_EXPORT QskControl : public QskQuickItem, public QskSkinnable void setLayoutAlignmentHint( Qt::Alignment ); Qt::Alignment layoutAlignmentHint() const; - void setLayoutHint( LayoutHint, bool on = true ); - bool testLayoutHint( LayoutHint ) const; + void setPlacementPolicy( QskPlacementPolicy ); + void setPlacementPolicy( QskPlacementPolicy::Policy, QskPlacementPolicy::Policy ); + void setPlacementPolicy( Qsk::Visibilities, QskPlacementPolicy::Policy ); - void setLayoutHints( LayoutHints ); - LayoutHints layoutHints() const; + QskPlacementPolicy placementPolicy() const; + QskPlacementPolicy::Policy placementPolicy( Qsk::Visibility ) const; + + QskPlacementPolicy::Policy effectivePlacementPolicy() const; bool isVisibleToLayout() const; diff --git a/src/controls/QskControlPrivate.cpp b/src/controls/QskControlPrivate.cpp index 7863fdfd..b7571af0 100644 --- a/src/controls/QskControlPrivate.cpp +++ b/src/controls/QskControlPrivate.cpp @@ -48,7 +48,8 @@ static inline QPointF qskScenePosition( const QMouseEvent* event ) QskControlPrivate::QskControlPrivate() : explicitSizeHints( nullptr ) , sizePolicy( QskSizePolicy::Preferred, QskSizePolicy::Preferred ) - , layoutHints( 0 ) + , visiblePlacementPolicy( 0 ) + , hiddenPlacementPolicy( 0 ) , layoutAlignmentHint( 0 ) , explicitLocale( false ) , autoFillBackground( false ) @@ -265,3 +266,41 @@ void QskControlPrivate::resolveLocale( QskControl* control ) qskSetup->inheritLocale( control, locale ); } } + +void QskControlPrivate::setPlacementPolicy( + bool visible, QskPlacementPolicy::Policy policy ) +{ + if ( visible ) + { + /* + Ignore corresponds to transparentForPositioner() what is + also respected by Qt/Quick layout classes. So we use this + bit instead of storing it locally. + */ + if ( policy == QskPlacementPolicy::Ignore ) + { + this->visiblePlacementPolicy = 0; + setTransparentForPositioner( true ); + } + else + { + this->visiblePlacementPolicy = + ( policy == QskPlacementPolicy::Reserve ) ? 1 : 0; + + if ( isTransparentForPositioner() ) + { + /* + This bit is stored in an extra data section, that + gets allocated, when being used the first time. + This also happens when setting it to false, what does + not make much sense, when it has not been allocated before. + */ + setTransparentForPositioner( false ); + } + } + } + else + { + this->hiddenPlacementPolicy = policy; + } +} diff --git a/src/controls/QskControlPrivate.h b/src/controls/QskControlPrivate.h index e7fdb4c0..61fe3be7 100644 --- a/src/controls/QskControlPrivate.h +++ b/src/controls/QskControlPrivate.h @@ -35,6 +35,9 @@ class QskControlPrivate : public QskQuickItemPrivate bool maybeGesture( QQuickItem*, QEvent* ); + QskPlacementPolicy::Policy placementPolicy( bool visible ) const noexcept; + void setPlacementPolicy( bool visible, QskPlacementPolicy::Policy ); + private: Q_DECLARE_PUBLIC( QskControl ) @@ -43,7 +46,10 @@ class QskControlPrivate : public QskQuickItemPrivate QLocale locale; QskSizePolicy sizePolicy; - int layoutHints : 4; + + unsigned int visiblePlacementPolicy : 1; + unsigned int hiddenPlacementPolicy : 2; + unsigned int layoutAlignmentHint : 8; bool explicitLocale : 1; @@ -57,4 +63,22 @@ class QskControlPrivate : public QskQuickItemPrivate mutable bool blockLayoutRequestEvents : 1; }; +inline QskPlacementPolicy::Policy + QskControlPrivate::placementPolicy( const bool visible ) const noexcept +{ + using PP = QskPlacementPolicy; + + if ( visible ) + { + if ( isTransparentForPositioner() ) + return PP::Ignore; + + return this->visiblePlacementPolicy ? PP::Reserve : PP::Adjust; + } + else + { + return static_cast< PP::Policy >( this->hiddenPlacementPolicy ); + } +} + #endif diff --git a/src/controls/QskFocusIndicator.cpp b/src/controls/QskFocusIndicator.cpp index 5e4f18aa..bcb2c1c4 100644 --- a/src/controls/QskFocusIndicator.cpp +++ b/src/controls/QskFocusIndicator.cpp @@ -63,7 +63,7 @@ QskFocusIndicator::QskFocusIndicator( QQuickItem* parent ) : Inherited( parent ) // parentItem() might change, but parent() stays , m_data( new PrivateData() ) { - setTransparentForPositioner( true ); + setPlacementPolicy( QskPlacementPolicy::Ignore ); connectWindow( window(), true ); } diff --git a/src/controls/QskInputGrabber.cpp b/src/controls/QskInputGrabber.cpp index 2bad7493..e0604310 100644 --- a/src/controls/QskInputGrabber.cpp +++ b/src/controls/QskInputGrabber.cpp @@ -112,7 +112,7 @@ QskInputGrabber::QskInputGrabber( QQuickItem* parent ) setAcceptTouchEvents( true ); setAcceptHoverEvents( true ); - setTransparentForPositioner( true ); + setPlacementPolicy( QskPlacementPolicy::Ignore ); setFlag( QQuickItem::ItemHasContents, false ); m_data->setup( parent ); diff --git a/src/controls/QskPopup.cpp b/src/controls/QskPopup.cpp index 49533dbd..62764268 100644 --- a/src/controls/QskPopup.cpp +++ b/src/controls/QskPopup.cpp @@ -168,7 +168,7 @@ QskPopup::QskPopup( QQuickItem* parent ) setWheelEnabled( true ); // we don't want to be resized by layout code - setTransparentForPositioner( true ); + setPlacementPolicy( QskPlacementPolicy::Ignore ); setFlag( ItemIsFocusScope, true ); setTabFence( true ); diff --git a/src/controls/QskQuick.cpp b/src/controls/QskQuick.cpp index 3522c49d..3c02c3ac 100644 --- a/src/controls/QskQuick.cpp +++ b/src/controls/QskQuick.cpp @@ -117,43 +117,14 @@ bool qskIsShortcutScope( const QQuickItem* item ) return item->isFocusScope() && QQuickItemPrivate::get( item )->isTabFence; } -void qskSetTransparentForPositioner( QQuickItem* item, bool on ) -{ - if ( item ) - QQuickItemPrivate::get( item )->setTransparentForPositioner( on ); -} - -bool qskIsTransparentForPositioner( const QQuickItem* item ) -{ - if ( item == nullptr ) - return true; - - return QQuickItemPrivate::get( item )->isTransparentForPositioner(); -} - bool qskIsVisibleToLayout( const QQuickItem* item ) { - if ( item == nullptr ) - return false; - - const auto d = QQuickItemPrivate::get( item ); - return !d->isTransparentForPositioner() - && ( d->explicitVisible || qskRetainSizeWhenHidden( item ) ); + return qskEffectivePlacementPolicy( item ) != QskPlacementPolicy::Ignore; } bool qskIsAdjustableByLayout( const QQuickItem* item ) { - if ( qskIsTransparentForPositioner( item ) ) - return false; - - bool adjustable = qskIsVisibleToParent( item ); - if ( !adjustable ) - { - if ( auto control = qskControlCast( item ) ) - adjustable = control->testLayoutHint( QskControl::LayoutWhenHidden ); - } - - return adjustable; + return qskEffectivePlacementPolicy( item ) == QskPlacementPolicy::Adjust; } QskSizePolicy qskSizePolicy( const QQuickItem* item ) @@ -186,19 +157,65 @@ Qt::Alignment qskLayoutAlignmentHint( const QQuickItem* item ) return Qt::Alignment(); } -bool qskRetainSizeWhenHidden( const QQuickItem* item ) +void qskSetPlacementPolicy( QQuickItem* item, const QskPlacementPolicy policy ) { + if ( item == nullptr ) + return; + if ( auto control = qskControlCast( item ) ) - return control->layoutHints() & QskControl::RetainSizeWhenHidden; - - if ( item ) { - const QVariant v = item->property( "retainSizeWhenHidden" ); - if ( v.canConvert< bool >() ) - return v.value< bool >(); + control->setPlacementPolicy( policy ); } + else + { + item->setProperty( "layoutPolicy", QVariant::fromValue( policy ) ); - return false; + auto d = QQuickItemPrivate::get( item ); + + const bool ignore = policy.visiblePolicy() == QskPlacementPolicy::Ignore; + if ( ignore != d->isTransparentForPositioner() ) + d->setTransparentForPositioner( ignore ); + + // sending a LayoutRequest ? + } +} + +QskPlacementPolicy qskPlacementPolicy( const QQuickItem* item ) +{ + if ( item == nullptr ) + return QskPlacementPolicy( QskPlacementPolicy::Ignore, QskPlacementPolicy::Ignore ); + + if ( auto control = qskControlCast( item ) ) + { + return control->placementPolicy(); + } + else + { + QskPlacementPolicy policy; + + const auto v = item->property( "layoutPolicy" ); + if ( v.canConvert< QskPlacementPolicy >() ) + policy = v.value< QskPlacementPolicy >(); + + auto d = QQuickItemPrivate::get( item ); + if ( d->isTransparentForPositioner() ) + policy.setVisiblePolicy( QskPlacementPolicy::Ignore ); + + return policy; + } +} + +QskPlacementPolicy::Policy qskEffectivePlacementPolicy( const QQuickItem* item ) +{ + if ( item == nullptr ) + return QskPlacementPolicy::Ignore; + + const auto policy = qskPlacementPolicy( item ); + + if ( qskIsVisibleToParent( item ) ) + return policy.visiblePolicy(); + else + return policy.hiddenPolicy(); } QQuickItem* qskNearestFocusScope( const QQuickItem* item ) diff --git a/src/controls/QskQuick.h b/src/controls/QskQuick.h index 2883a798..e2137453 100644 --- a/src/controls/QskQuick.h +++ b/src/controls/QskQuick.h @@ -7,6 +7,8 @@ #define QSK_QUICK_H #include "QskGlobal.h" +#include "QskPlacementPolicy.h" + #include #include @@ -30,9 +32,6 @@ QSK_EXPORT bool qskIsVisibleTo( const QQuickItem* item, const QQuickItem* ancest QSK_EXPORT bool qskIsVisibleToParent( const QQuickItem* ); QSK_EXPORT bool qskIsPolishScheduled( const QQuickItem* ); -QSK_EXPORT void qskSetTransparentForPositioner( QQuickItem*, bool ); -QSK_EXPORT bool qskIsTransparentForPositioner( const QQuickItem* ); - QSK_EXPORT bool qskIsVisibleToLayout( const QQuickItem* ); QSK_EXPORT bool qskIsAdjustableByLayout( const QQuickItem* ); @@ -48,7 +47,11 @@ QSK_EXPORT QRectF qskConstrainedItemRect( QSK_EXPORT QskSizePolicy qskSizePolicy( const QQuickItem* ); QSK_EXPORT Qt::Alignment qskLayoutAlignmentHint( const QQuickItem* ); -QSK_EXPORT bool qskRetainSizeWhenHidden( const QQuickItem* ); + +QSK_EXPORT QskPlacementPolicy qskPlacementPolicy( const QQuickItem* ); +QSK_EXPORT void qskSetPlacementPolicy( QQuickItem*, QskPlacementPolicy ); + +QSK_EXPORT QskPlacementPolicy::Policy qskEffectivePlacementPolicy( const QQuickItem* ); QSK_EXPORT QRectF qskItemRect( const QQuickItem* ); diff --git a/src/controls/QskQuickItem.cpp b/src/controls/QskQuickItem.cpp index b60016eb..195d0f2e 100644 --- a/src/controls/QskQuickItem.cpp +++ b/src/controls/QskQuickItem.cpp @@ -323,21 +323,6 @@ QRectF QskQuickItem::geometry() const return QRectF( d->x, d->y, d->width, d->height ); } -void QskQuickItem::setTransparentForPositioner( bool on ) -{ - Q_D( QQuickItem ); - if ( on != d->isTransparentForPositioner() ) - { - d->setTransparentForPositioner( on ); - Q_EMIT itemFlagsChanged(); - } -} - -bool QskQuickItem::isTransparentForPositioner() const -{ - return d_func()->isTransparentForPositioner(); -} - void QskQuickItem::setTabFence( bool on ) { Q_D( QQuickItem ); diff --git a/src/controls/QskQuickItem.h b/src/controls/QskQuickItem.h index c66f7826..0607a95c 100644 --- a/src/controls/QskQuickItem.h +++ b/src/controls/QskQuickItem.h @@ -20,9 +20,6 @@ class QSK_EXPORT QskQuickItem : public QQuickItem Q_PROPERTY( QRectF geometry READ geometry WRITE setGeometry ) Q_PROPERTY( QRectF rect READ rect ) - Q_PROPERTY( bool transparentForPositioners READ isTransparentForPositioner - WRITE setTransparentForPositioner NOTIFY itemFlagsChanged ) - Q_PROPERTY( bool tabFence READ isTabFence WRITE setTabFence NOTIFY itemFlagsChanged ) @@ -78,9 +75,6 @@ class QSK_EXPORT QskQuickItem : public QQuickItem void setPolishOnResize( bool ); bool polishOnResize() const; - void setTransparentForPositioner( bool ); - bool isTransparentForPositioner() const; - void setTabFence( bool ); bool isTabFence() const; diff --git a/src/inputpanel/QskInputContext.cpp b/src/inputpanel/QskInputContext.cpp index 4d59d36e..236c191f 100644 --- a/src/inputpanel/QskInputContext.cpp +++ b/src/inputpanel/QskInputContext.cpp @@ -249,7 +249,7 @@ class QskInputContext::PrivateData auto popup = new QskPopup(); popup->setAutoLayoutChildren( true ); - popup->setTransparentForPositioner( false ); + popup->setPlacementPolicy( QskPlacementPolicy() ); popup->setMargins( 5 ); popup->setModal( true ); diff --git a/src/inputpanel/QskInputPredictionBar.cpp b/src/inputpanel/QskInputPredictionBar.cpp index 3675b302..dc44a732 100644 --- a/src/inputpanel/QskInputPredictionBar.cpp +++ b/src/inputpanel/QskInputPredictionBar.cpp @@ -88,7 +88,7 @@ QskInputPredictionBar::QskInputPredictionBar( QQuickItem* parent ) if ( i == 0 ) { // to keep the height - button->setLayoutHint( QskControl::RetainSizeWhenHidden, true ); + button->setPlacementPolicy( Qsk::Hidden, QskPlacementPolicy::Reserve ); } } } diff --git a/src/layouts/QskGridBox.cpp b/src/layouts/QskGridBox.cpp index 40548887..fbee94af 100644 --- a/src/layouts/QskGridBox.cpp +++ b/src/layouts/QskGridBox.cpp @@ -133,12 +133,12 @@ int QskGridBox::addItem( QQuickItem* item, if ( item == nullptr || item == this || row < 0 || column < 0 ) return -1; - if ( qskIsTransparentForPositioner( item ) ) + if ( !qskPlacementPolicy( item ).isEffective() ) { - qWarning() << "Inserting an item that is marked as transparent for layouting:" + qWarning() << "Inserting an item that is to be ignored for layouting:" << item->metaObject()->className(); - qskSetTransparentForPositioner( item, false ); + qskSetPlacementPolicy( item, QskPlacementPolicy() ); } rowSpan = qMax( rowSpan, -1 ); diff --git a/src/layouts/QskGridLayoutEngine.cpp b/src/layouts/QskGridLayoutEngine.cpp index f957a491..4655131c 100644 --- a/src/layouts/QskGridLayoutEngine.cpp +++ b/src/layouts/QskGridLayoutEngine.cpp @@ -592,7 +592,7 @@ void QskGridLayoutEngine::layoutItems() { auto item = element.item(); - if ( requiresAdjustment( item ) ) + if ( qskIsAdjustableByLayout( item ) ) { const auto grid = m_data->effectiveGrid( element ); layoutItem( item, grid ); diff --git a/src/layouts/QskIndexedLayoutBox.cpp b/src/layouts/QskIndexedLayoutBox.cpp index b7a81f4f..cca48c53 100644 --- a/src/layouts/QskIndexedLayoutBox.cpp +++ b/src/layouts/QskIndexedLayoutBox.cpp @@ -53,7 +53,7 @@ void QskIndexedLayoutBox::itemChange( { if ( m_data->autoAddChildren && !m_data->blockChildAddedRemoved ) { - if ( !qskIsTransparentForPositioner( value.item ) ) + if ( qskPlacementPolicy( value.item ).isEffective() ) autoAddItem( value.item ); } diff --git a/src/layouts/QskLayoutEngine2D.cpp b/src/layouts/QskLayoutEngine2D.cpp index d721665c..34c484d6 100644 --- a/src/layouts/QskLayoutEngine2D.cpp +++ b/src/layouts/QskLayoutEngine2D.cpp @@ -652,20 +652,3 @@ QskSizePolicy::ConstraintType QskLayoutEngine2D::constraintType() const return static_cast< QskSizePolicy::ConstraintType >( m_data->constraintType ); } - -bool QskLayoutEngine2D::requiresAdjustment( const QQuickItem* item ) const -{ - if ( qskIsVisibleToParent( item ) ) - return true; - - if ( auto control = qskControlCast( item ) ) - { - constexpr auto mask = - QskControl::RetainSizeWhenHidden | QskControl::LayoutWhenHidden; - - if ( control->layoutHints() & mask ) - return true; - } - - return false; -} diff --git a/src/layouts/QskLayoutEngine2D.h b/src/layouts/QskLayoutEngine2D.h index 7af37eb4..85fb1923 100644 --- a/src/layouts/QskLayoutEngine2D.h +++ b/src/layouts/QskLayoutEngine2D.h @@ -67,7 +67,6 @@ class QskLayoutEngine2D }; void invalidate( int what ); - bool requiresAdjustment( const QQuickItem* ) const; private: Q_DISABLE_COPY( QskLayoutEngine2D ) diff --git a/src/layouts/QskLinearBox.cpp b/src/layouts/QskLinearBox.cpp index ae4a520b..6248d458 100644 --- a/src/layouts/QskLinearBox.cpp +++ b/src/layouts/QskLinearBox.cpp @@ -403,12 +403,12 @@ int QskLinearBox::insertItem( int index, QQuickItem* item ) if ( item == nullptr || item == this ) return -1; - if ( qskIsTransparentForPositioner( item ) ) + if ( !qskPlacementPolicy( item ).isEffective() ) { - qWarning() << "Inserting an item that is marked as transparent for layouting:" + qWarning() << "Inserting an item that is to be ignored for layouting:" << item->metaObject()->className(); - qskSetTransparentForPositioner( item, false ); + qskSetPlacementPolicy( item, QskPlacementPolicy() ); } auto& engine = m_data->engine; diff --git a/src/layouts/QskLinearLayoutEngine.cpp b/src/layouts/QskLinearLayoutEngine.cpp index 5ff1727e..b499d23b 100644 --- a/src/layouts/QskLinearLayoutEngine.cpp +++ b/src/layouts/QskLinearLayoutEngine.cpp @@ -359,7 +359,7 @@ void QskLinearLayoutEngine::layoutItems() if ( auto item = element.item() ) { - if ( requiresAdjustment( item ) ) + if ( qskIsAdjustableByLayout( item ) ) { const QRect grid( col, row, 1, 1 ); layoutItem( item, grid ); diff --git a/src/layouts/QskStackBox.cpp b/src/layouts/QskStackBox.cpp index 44206cb4..caf2bf52 100644 --- a/src/layouts/QskStackBox.cpp +++ b/src/layouts/QskStackBox.cpp @@ -201,10 +201,12 @@ void QskStackBox::insertItem( int index, QQuickItem* item ) reparentItem( item ); - if ( qskIsTransparentForPositioner( item ) ) + if ( !qskPlacementPolicy( item ).isEffective() ) { - // giving a warning, or ignoring the insert ??? - qskSetTransparentForPositioner( item, false ); + qWarning() << "Inserting an item that is to be ignored for layouting" + << item->metaObject()->className(); + + qskSetPlacementPolicy( item, QskPlacementPolicy() ); } const bool doAppend = ( index < 0 ) || ( index >= itemCount() ); @@ -354,16 +356,18 @@ void QskStackBox::updateLayout() if ( maybeUnresized() ) return; -#if 1 - // what about QskControl::LayoutOutWhenHidden -#endif - - const auto index = m_data->currentIndex; - - if ( index >= 0 ) + for ( int i = 0; i < m_data->items.count(); i++ ) { - const auto rect = geometryForItemAt( index ); - qskSetItemGeometry( m_data->items[ index ], rect ); + auto item = m_data->items[ i ]; + + const auto visibility = + ( i == m_data->currentIndex ) ? Qsk::Visible : Qsk::Hidden; + + if ( qskPlacementPolicy( item ).isAdjusting( visibility ) ) + { + const auto rect = geometryForItemAt( i ); + qskSetItemGeometry( m_data->items[ i ], rect ); + } } } diff --git a/src/src.pro b/src/src.pro index 5a4089d9..9a345f05 100644 --- a/src/src.pro +++ b/src/src.pro @@ -30,6 +30,7 @@ HEADERS += \ common/QskMetaInvokable.h \ common/QskNamespace.h \ common/QskObjectCounter.h \ + common/QskPlacementPolicy.h \ common/QskPlatform.h \ common/QskRgbValue.h \ common/QskRgbPalette.h \ @@ -57,6 +58,7 @@ SOURCES += \ common/QskMetaInvokable.cpp \ common/QskObjectCounter.cpp \ common/QskPlatform.cpp \ + common/QskPlacementPolicy.cpp \ common/QskRgbValue.cpp \ common/QskRgbPalette.cpp \ common/QskScaleEngine.cpp \